This is an automated email from the ASF dual-hosted git repository.
dyankiv pushed a commit to branch DATALAB-2648
in repository https://gitbox.apache.org/repos/asf/incubator-datalab.git
The following commit(s) were added to refs/heads/DATALAB-2648 by this push:
new 21fea4270 add support for terminating user image
21fea4270 is described below
commit 21fea427071fca74d845059aae7dfddada92ace0
Author: Denys Yankiv <[email protected]>
AuthorDate: Thu Aug 25 17:44:37 2022 +0300
add support for terminating user image
---
.../epam/datalab/dto/exploratory/ImageStatus.java | 2 ++
.../datalab/rest/contracts/ExploratoryAPI.java | 1 +
.../backendapi/core/commands/DockerAction.java | 1 +
.../backendapi/resources/ImageResource.java | 13 +++++++++
.../backendapi/dao/ImageExploratoryDAO.java | 2 ++
.../backendapi/dao/ImageExploratoryDAOImpl.java | 7 +++++
.../resources/ImageExploratoryResource.java | 22 +++++++++------
.../resources/callback/ImageCallback.java | 10 +++++--
.../service/ImageExploratoryService.java | 4 +++
.../service/impl/ImageExploratoryServiceImpl.java | 33 ++++++++++++++++++++--
.../main/resources/mongo/general/mongo_roles.json | 12 ++++++++
11 files changed, 94 insertions(+), 13 deletions(-)
diff --git
a/services/datalab-model/src/main/java/com/epam/datalab/dto/exploratory/ImageStatus.java
b/services/datalab-model/src/main/java/com/epam/datalab/dto/exploratory/ImageStatus.java
index fb2133aaf..80ec6f0cc 100644
---
a/services/datalab-model/src/main/java/com/epam/datalab/dto/exploratory/ImageStatus.java
+++
b/services/datalab-model/src/main/java/com/epam/datalab/dto/exploratory/ImageStatus.java
@@ -26,6 +26,8 @@ import java.util.Arrays;
public enum ImageStatus {
CREATING,
ACTIVE,
+ TERMINATING,
+ TERMINATED,
FAILED;
@JsonCreator
diff --git
a/services/datalab-webapp-common/src/main/java/com/epam/datalab/rest/contracts/ExploratoryAPI.java
b/services/datalab-webapp-common/src/main/java/com/epam/datalab/rest/contracts/ExploratoryAPI.java
index d153a15f7..bce4eb29a 100644
---
a/services/datalab-webapp-common/src/main/java/com/epam/datalab/rest/contracts/ExploratoryAPI.java
+++
b/services/datalab-webapp-common/src/main/java/com/epam/datalab/rest/contracts/ExploratoryAPI.java
@@ -31,4 +31,5 @@ public interface ExploratoryAPI {
String EXPLORATORY_LIB_LIST = LIBRARY + EXPLORATORY + "/lib_list";
String EXPLORATORY_GIT_CREDS = EXPLORATORY + "/git_creds";
String EXPLORATORY_IMAGE = EXPLORATORY + "/image";
+ String EXPLORATORY_IMAGE_TERMINATE = EXPLORATORY + "/image" + "/terminate";
}
diff --git
a/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/core/commands/DockerAction.java
b/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/core/commands/DockerAction.java
index d61bac680..a801aefc0 100644
---
a/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/core/commands/DockerAction.java
+++
b/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/core/commands/DockerAction.java
@@ -32,6 +32,7 @@ public enum DockerAction {
LIB_INSTALL,
GIT_CREDS,
CREATE_IMAGE,
+ TERMINATE_IMAGE,
STATUS,
REUPLOAD_KEY,
RECONFIGURE_SPARK,
diff --git
a/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/resources/ImageResource.java
b/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/resources/ImageResource.java
index b565556b1..1e4347431 100644
---
a/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/resources/ImageResource.java
+++
b/services/provisioning-service/src/main/java/com/epam/datalab/backendapi/resources/ImageResource.java
@@ -59,6 +59,19 @@ public class ImageResource extends DockerService implements
DockerCommands {
return Response.accepted(uuid).build();
}
+ @POST
+ @Path("/terminate")
+ public Response terminateImage(@Auth UserInfo ui, ExploratoryImageDTO
image) throws JsonProcessingException{
+ final String uuid = DockerCommands.generateUUID();
+ log.info("terminate image dto {}",image);
+
+ folderListenerExecutor.start(configuration.getImagesDirectory(),
configuration.getResourceStatusPollTimeout(),
+ new ImageCreateCallbackHandler(selfService, uuid,
DockerAction.TERMINATE_IMAGE, image));
+ String command =
commandBuilder.buildCommand(getDockerCommand(DockerAction.TERMINATE_IMAGE,
uuid, image), image);
+ commandExecutor.executeAsync(ui.getName(), uuid, command);
+ log.debug("Docker command: " + command);
+ return Response.accepted(uuid).build();
+ }
@Override
public String getResourceType() {
diff --git
a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAO.java
b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAO.java
index 4b67166b6..be068d546 100644
---
a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAO.java
+++
b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAO.java
@@ -36,6 +36,8 @@ public interface ImageExploratoryDAO {
void updateImageFields(Image image);
+ void updateImageStatus(String user, String imageName, String project,
String endpoint, ImageStatus status);
+
List<ImageInfoRecord> getImages(String user, String dockerImage, String
project, String endpoint, ImageStatus... statuses);
List<ImageInfoRecord> getImages(String project, String endpoint, String
dockerImage);
diff --git
a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAOImpl.java
b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAOImpl.java
index d4fde8042..b52c35010 100644
---
a/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAOImpl.java
+++
b/services/self-service/src/main/java/com/epam/datalab/backendapi/dao/ImageExploratoryDAOImpl.java
@@ -42,6 +42,7 @@ import static com.mongodb.client.model.Projections.elemMatch;
import static com.mongodb.client.model.Projections.excludeId;
import static com.mongodb.client.model.Projections.fields;
import static com.mongodb.client.model.Projections.include;
+import static com.mongodb.client.model.Updates.set;
@Singleton
public class ImageExploratoryDAOImpl extends BaseDAO implements
ImageExploratoryDAO {
@@ -72,6 +73,12 @@ public class ImageExploratoryDAOImpl extends BaseDAO
implements ImageExploratory
updateOne(MongoCollections.IMAGES, condition, new Document(SET,
updatedFields));
}
+ @Override
+ public void updateImageStatus(String user, String imageName, String
project, String endpoint, ImageStatus status) {
+ final Bson condition = userImageCondition(user, imageName, project,
endpoint);
+ updateOne(MongoCollections.IMAGES, condition,
set(STATUS,status.toString()));
+ }
+
@Override
public List<ImageInfoRecord> getImages(String user, String dockerImage,
String project, String endpoint, ImageStatus... statuses) {
return find(MongoCollections.IMAGES,
diff --git
a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ImageExploratoryResource.java
b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ImageExploratoryResource.java
index 3c7085ec5..1950b224e 100644
---
a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ImageExploratoryResource.java
+++
b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/ImageExploratoryResource.java
@@ -27,15 +27,10 @@ import com.google.inject.Inject;
import io.dropwizard.auth.Auth;
import lombok.extern.slf4j.Slf4j;
+import javax.annotation.security.RolesAllowed;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
+import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
@@ -129,8 +124,19 @@ public class ImageExploratoryResource {
@Path("share")
public Response shareImageWithProjectGroups(@Auth UserInfo ui, @Valid
@NotNull ImageProjectGroupsShareDTO dto) {
log.debug("Sharing user image {} with project {} groups",
dto.getImageName(), dto.getProjectName());
- imageExploratoryService.shareImageWithProjectGroups(ui,
dto.getImageName(), dto.getProjectName(), dto.getEndpoint());
+ imageExploratoryService.shareImageWithProjectGroups(ui,
dto.getImageName(), dto.getProjectName(), dto.getEndpoint());
return
Response.ok(imageExploratoryService.getImagesOfUser(ui)).build();
}
+ @RolesAllowed("/api/image/terminate")
+ @DELETE
+ @Path("/{projectName}/{endpoint}/{imageName}/terminate")
+ public Response terminateUserImage(@Auth UserInfo ui,
+ @PathParam("imageName") String
imageName,
+ @PathParam("projectName") String
projectName,
+ @PathParam("endpoint") String endpoint)
{
+ log.debug("Terminating image {} of user {} groups", imageName,
ui.getName());
+
imageExploratoryService.terminateImage(ui,projectName,endpoint,imageName);
+ return
Response.ok(imageExploratoryService.getImagesOfUser(ui)).build();
+ }
}
diff --git
a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/callback/ImageCallback.java
b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/callback/ImageCallback.java
index 587c8ea41..d66d550f3 100644
---
a/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/callback/ImageCallback.java
+++
b/services/self-service/src/main/java/com/epam/datalab/backendapi/resources/callback/ImageCallback.java
@@ -51,8 +51,14 @@ public class ImageCallback {
public Response imageCreateStatus(ImageCreateStatusDTO dto) {
log.debug("Updating status of image {} for user {} to {}",
dto.getName(), dto.getUser(), dto);
requestId.remove(dto.getRequestId());
- imageExploratoryService.finishImageCreate(getImage(dto),
dto.getExploratoryName(), dto.getImageCreateDTO()
- .getIp());
+
+
if(dto.getStatus().equalsIgnoreCase(String.valueOf(ImageStatus.TERMINATED))){
+
imageExploratoryService.finishTerminateImage(dto.getImageCreateDTO().getExternalName());
+ } else {
+ imageExploratoryService.finishImageCreate(getImage(dto),
dto.getExploratoryName(), dto.getImageCreateDTO()
+ .getIp());
+ }
+
return Response.status(Response.Status.CREATED).build();
}
diff --git
a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ImageExploratoryService.java
b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ImageExploratoryService.java
index b07a83616..889aa8f44 100644
---
a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ImageExploratoryService.java
+++
b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/ImageExploratoryService.java
@@ -32,6 +32,10 @@ public interface ImageExploratoryService {
String createImage(UserInfo user, String project, String exploratoryName,
String imageName, String imageDescription, String info);
+ void terminateImage(UserInfo user, String project, String endpoint, String
imageName);
+
+ void finishTerminateImage(String fullImageName);
+
void finishImageCreate(Image image, String exploratoryName, String
newNotebookIp);
List<ImageInfoRecord> getNotFailedImages(UserInfo user, String
dockerImage, String project, String endpoint);
diff --git
a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ImageExploratoryServiceImpl.java
b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ImageExploratoryServiceImpl.java
index ee2e83677..691800e8d 100644
---
a/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ImageExploratoryServiceImpl.java
+++
b/services/self-service/src/main/java/com/epam/datalab/backendapi/service/impl/ImageExploratoryServiceImpl.java
@@ -60,6 +60,7 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import static com.epam.datalab.backendapi.domain.AuditActionEnum.CREATE;
+import static com.epam.datalab.backendapi.domain.AuditActionEnum.TERMINATE;
import static com.epam.datalab.backendapi.domain.AuditResourceTypeEnum.IMAGE;
@Singleton
@@ -69,7 +70,7 @@ public class ImageExploratoryServiceImpl implements
ImageExploratoryService {
private static final String IMAGE_NOT_FOUND_MSG = "Image with name %s was
not found for user %s";
private static final String SHARE_OWN_IMAGES_PAGE = "/api/image/share";
- private static final String TERMINATE_OWN_IMAGES_PAGE =
"/api/image/delete";
+ private static final String TERMINATE_OWN_IMAGES_PAGE =
"/api/image/terminate";
private static final String SHARE_RECEIVED_IMAGES_PAGE =
"/api/image/shareReceived";
private static final String IMAGE_ROLE = "img_%s_%s_%s_%s";
private static final String IMAGE_ROLE_DESCRIPTION = "Create Notebook from
image %s";
@@ -143,6 +144,30 @@ public class ImageExploratoryServiceImpl implements
ImageExploratoryService {
requestBuilder.newExploratoryImageCreate(user, userInstance,
imageName, endpointDTO, projectDTO), String.class);
}
+ @Audit(action = TERMINATE, type = IMAGE)
+ @Override
+ public void terminateImage(@User UserInfo user, @Project String project,
String endpoint, String imageName) {
+ Optional<ImageInfoRecord> image =
imageExploratoryDao.getImage(user.getName(), imageName, project, endpoint);
+ if(image.isPresent()){
+ ImageInfoRecord imageInfoRecord = image.get();
+
imageExploratoryDao.updateImageStatus(user.getName(),imageName,project,endpoint,ImageStatus.TERMINATING);
+ EndpointDTO endpointDTO = endpointService.get(endpoint);
+ ProjectDTO projectDTO = projectService.get(project);
+ UserInstanceDTO userInstance =
exploratoryDAO.fetchExploratoryFields(user.getName(), project,
imageInfoRecord.getInstanceName());
+
+ log.info("ExploratoryImageCreate {}",
requestBuilder.newExploratoryImageCreate(user, userInstance, imageName,
endpointDTO, projectDTO));
+ provisioningService.post(endpointDTO.getUrl() +
ExploratoryAPI.EXPLORATORY_IMAGE_TERMINATE,
+ user.getAccessToken(),
requestBuilder.newExploratoryImageCreate(user, userInstance, imageName,
endpointDTO, projectDTO)
+ , String.class);
+ }
+
+ }
+
+ @Override
+ public void finishTerminateImage(String fullImageName) {
+
+ }
+
@Override
public void finishImageCreate(Image image, String exploratoryName, String
newNotebookIp) {
log.debug("Returning exploratory status with name {} to RUNNING for
user {}",
@@ -325,16 +350,18 @@ public class ImageExploratoryServiceImpl implements
ImageExploratoryService {
@Override
public ImageUserPermissions getUserImagePermissions(UserInfo userInfo,
ImageInfoRecord image) {
boolean canShare;
- boolean canTerminate = false;
+ boolean canTerminate;
if(!image.getStatus().equals(ImageStatus.ACTIVE)){
- return new ImageUserPermissions(false,canTerminate);
+ return new ImageUserPermissions(false,false);
}
if(image.getUser().equals(userInfo.getName())){
canShare = UserRoles.checkAccess(userInfo, RoleType.PAGE,
SHARE_OWN_IMAGES_PAGE,userInfo.getRoles());
+ canTerminate = UserRoles.checkAccess(userInfo, RoleType.PAGE,
TERMINATE_OWN_IMAGES_PAGE,userInfo.getRoles());
} else {
canShare = UserRoles.checkAccess(userInfo, RoleType.PAGE,
SHARE_RECEIVED_IMAGES_PAGE,userInfo.getRoles());
+ canTerminate = false;
}
return new ImageUserPermissions(canShare,canTerminate);
}
diff --git
a/services/self-service/src/main/resources/mongo/general/mongo_roles.json
b/services/self-service/src/main/resources/mongo/general/mongo_roles.json
index b4c7d25b4..fd5ca0b08 100644
--- a/services/self-service/src/main/resources/mongo/general/mongo_roles.json
+++ b/services/self-service/src/main/resources/mongo/general/mongo_roles.json
@@ -24,6 +24,18 @@
"$anyuser"
]
},
+ {
+ "_id": "imgTerminateOwnImages",
+ "description": "Allow to terminate own images",
+ "type": "IMAGE",
+ "cloud": "GENERAL",
+ "pages": [
+ "/api/image/terminate"
+ ],
+ "groups": [
+ "$anyuser"
+ ]
+ },
{
"_id": "nbBillingReportFull",
"description": "View full billing report for all users",
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]