use of org.eclipse.che.plugin.openshift.client.exception.OpenShiftException in project che by eclipse.
the class OpenShiftConnector method getImageStreamTagFromRepo.
/**
* Gets the ImageStreamTag corresponding to a given tag name (i.e. without the repository)
* @param imageStreamTagName the tag name to search for
* @return
* @throws IOException if either no matching tag is found, or there are multiple matches.
*/
private ImageStreamTag getImageStreamTagFromRepo(String imageStreamTagName) throws IOException {
// Since repository + tag are limited to 63 chars, it's possible that the entire
// tag name did not fit, so we have to match a substring.
String imageTagTrimmed = imageStreamTagName.length() > 30 ? imageStreamTagName.substring(0, 30) : imageStreamTagName;
// Note: ideally, ImageStreamTags could be identified with a label, but it seems like
// ImageStreamTags do not support labels.
List<ImageStreamTag> imageStreams = openShiftClient.imageStreamTags().inNamespace(openShiftCheProjectName).list().getItems();
// We only get ImageStreamTag names here, since these ImageStreamTags do not include
// Docker metadata, for some reason.
List<String> imageStreamTags = imageStreams.stream().filter(e -> e.getMetadata().getName().contains(imageTagTrimmed)).map(e -> e.getMetadata().getName()).collect(Collectors.toList());
if (imageStreamTags.size() < 1) {
throw new OpenShiftException(String.format("ImageStreamTag %s not found!", imageStreamTagName));
} else if (imageStreamTags.size() > 1) {
throw new OpenShiftException(String.format("Multiple ImageStreamTags found for name %s", imageStreamTagName));
}
String imageStreamTag = imageStreamTags.get(0);
// Finally, get the ImageStreamTag, with Docker metadata.
return openShiftClient.imageStreamTags().inNamespace(openShiftCheProjectName).withName(imageStreamTag).get();
}
use of org.eclipse.che.plugin.openshift.client.exception.OpenShiftException in project che by eclipse.
the class OpenShiftConnector method createContainer.
/**
* @param createContainerParams
* @return
* @throws IOException
*/
@Override
public ContainerCreated createContainer(CreateContainerParams createContainerParams) throws IOException {
String containerName = KubernetesStringUtils.convertToContainerName(createContainerParams.getContainerName());
String workspaceID = getCheWorkspaceId(createContainerParams);
// Generate workspaceID if CHE_WORKSPACE_ID env var does not exist
workspaceID = workspaceID.isEmpty() ? KubernetesStringUtils.generateWorkspaceID() : workspaceID;
// imageForDocker is the docker version of the image repository. It's needed for other
// OpenShiftConnector API methods, but is not acceptable as an OpenShift name
String imageForDocker = createContainerParams.getContainerConfig().getImage();
// imageStreamTagName is imageForDocker converted into a form that can be used
// in OpenShift
String imageStreamTagName = KubernetesStringUtils.convertPullSpecToTagName(imageForDocker);
// imageStreamTagName is not enough to fill out a pull spec; it is only the tag, so we
// have to get the ImageStreamTag from the tag, and then get the full ImageStreamTag name
// from that tag. This works because the tags used in Che are unique.
ImageStreamTag imageStreamTag = getImageStreamTagFromRepo(imageStreamTagName);
String imageStreamTagPullSpec = imageStreamTag.getMetadata().getName();
// Next we need to get the address of the registry where the ImageStreamTag is stored
String imageStreamName = KubernetesStringUtils.getImageStreamNameFromPullSpec(imageStreamTagPullSpec);
ImageStream imageStream = openShiftClient.imageStreams().inNamespace(openShiftCheProjectName).withName(imageStreamName).get();
if (imageStream == null) {
throw new OpenShiftException("ImageStream not found");
}
String registryAddress = imageStream.getStatus().getDockerImageRepository().split("/")[0];
// The above needs to be combined to form a pull spec that will work when defining a container.
String dockerPullSpec = String.format("%s/%s/%s", registryAddress, openShiftCheProjectName, imageStreamTagPullSpec);
Set<String> containerExposedPorts = createContainerParams.getContainerConfig().getExposedPorts().keySet();
Set<String> imageExposedPorts = inspectImage(InspectImageParams.create(imageForDocker)).getConfig().getExposedPorts().keySet();
Set<String> exposedPorts = getExposedPorts(containerExposedPorts, imageExposedPorts);
boolean runContainerAsRoot = runContainerAsRoot(imageForDocker);
String[] envVariables = createContainerParams.getContainerConfig().getEnv();
String[] volumes = createContainerParams.getContainerConfig().getHostConfig().getBinds();
Map<String, String> additionalLabels = createContainerParams.getContainerConfig().getLabels();
String containerID;
try {
createOpenShiftService(workspaceID, exposedPorts, additionalLabels);
String deploymentName = createOpenShiftDeployment(workspaceID, dockerPullSpec, containerName, exposedPorts, envVariables, volumes, runContainerAsRoot);
containerID = waitAndRetrieveContainerID(deploymentName);
if (containerID == null) {
throw new OpenShiftException("Failed to get the ID of the container running in the OpenShift pod");
}
} catch (IOException e) {
// Make sure we clean up deployment and service in case of an error -- otherwise Che can end up
// in an inconsistent state.
LOG.info("Error while creating Pod, removing deployment");
String deploymentName = CHE_OPENSHIFT_RESOURCES_PREFIX + workspaceID;
cleanUpWorkspaceResources(deploymentName);
openShiftClient.resource(imageStreamTag).delete();
throw e;
}
return new ContainerCreated(containerID, null);
}
use of org.eclipse.che.plugin.openshift.client.exception.OpenShiftException in project che by eclipse.
the class OpenShiftConnector method cleanUpWorkspaceResources.
private void cleanUpWorkspaceResources(String deploymentName) throws IOException {
Deployment deployment = getDeploymentByName(deploymentName);
Service service = getCheServiceBySelector(OPENSHIFT_DEPLOYMENT_LABEL, deploymentName);
if (service != null) {
LOG.info("Removing OpenShift Service {}", service.getMetadata().getName());
openShiftClient.resource(service).delete();
}
if (deployment != null) {
LOG.info("Removing OpenShift Deployment {}", deployment.getMetadata().getName());
openShiftClient.resource(deployment).delete();
}
// Wait for all pods to terminate before returning.
try {
for (int waitCount = 0; waitCount < OPENSHIFT_WAIT_POD_TIMEOUT; waitCount++) {
List<Pod> pods = openShiftClient.pods().inNamespace(openShiftCheProjectName).withLabel(OPENSHIFT_DEPLOYMENT_LABEL, deploymentName).list().getItems();
if (pods.size() == 0) {
return;
}
Thread.sleep(OPENSHIFT_WAIT_POD_DELAY);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOG.info("Thread interrupted while cleaning up workspace");
}
throw new OpenShiftException("Timeout while waiting for pods to terminate");
}
use of org.eclipse.che.plugin.openshift.client.exception.OpenShiftException in project che by eclipse.
the class OpenShiftConnector method pull.
/**
* Creates an ImageStream that tracks the repository.
*
* <p>Note: This method does not cause the relevant image to actually be pulled to the local
* repository, but creating the ImageStream is necessary as it is used to obtain
* the address of the internal Docker registry later.
*
* @see DockerConnector#pull(PullParams, ProgressMonitor)
*/
@Override
public void pull(final PullParams params, final ProgressMonitor progressMonitor) throws IOException {
// image to be pulled
String repo = params.getFullRepo();
// e.g. latest, usually
String tag = params.getTag();
String imageStreamName = KubernetesStringUtils.convertPullSpecToImageStreamName(repo);
ImageStream existingImageStream = openShiftClient.imageStreams().inNamespace(openShiftCheProjectName).withName(imageStreamName).get();
if (existingImageStream == null) {
openShiftClient.imageStreams().inNamespace(openShiftCheProjectName).createNew().withNewMetadata().withName(// imagestream id
imageStreamName).endMetadata().withNewSpec().addNewTag().withName(tag).endTag().withDockerImageRepository(// tracking repo
repo).endSpec().withNewStatus().withDockerImageRepository("").endStatus().done();
}
// Wait for Image metadata to be obtained.
ImageStream createdImageStream;
for (int waitCount = 0; waitCount < OPENSHIFT_IMAGESTREAM_MAX_WAIT_COUNT; waitCount++) {
try {
Thread.sleep(OPENSHIFT_IMAGESTREAM_WAIT_DELAY);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
createdImageStream = openShiftClient.imageStreams().inNamespace(openShiftCheProjectName).withName(imageStreamName).get();
if (createdImageStream != null && createdImageStream.getStatus().getDockerImageRepository() != null) {
LOG.info(String.format("Created ImageStream %s.", imageStreamName));
return;
}
}
throw new OpenShiftException(String.format("Failed to create ImageStream %s.", imageStreamName));
}
use of org.eclipse.che.plugin.openshift.client.exception.OpenShiftException in project che by eclipse.
the class OpenShiftConnector method waitAndRetrieveContainerID.
private String waitAndRetrieveContainerID(String deploymentName) throws IOException {
for (int i = 0; i < OPENSHIFT_WAIT_POD_TIMEOUT; i++) {
try {
Thread.sleep(OPENSHIFT_WAIT_POD_DELAY);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
List<Pod> pods = openShiftClient.pods().inNamespace(this.openShiftCheProjectName).withLabel(OPENSHIFT_DEPLOYMENT_LABEL, deploymentName).list().getItems();
if (pods.size() < 1) {
throw new OpenShiftException(String.format("Pod with deployment name %s not found", deploymentName));
} else if (pods.size() > 1) {
throw new OpenShiftException(String.format("Multiple pods with deployment name %s found", deploymentName));
}
Pod pod = pods.get(0);
String status = pod.getStatus().getPhase();
if (OPENSHIFT_POD_STATUS_RUNNING.equals(status)) {
String containerID = pod.getStatus().getContainerStatuses().get(0).getContainerID();
String normalizedID = KubernetesStringUtils.normalizeContainerID(containerID);
openShiftClient.pods().inNamespace(openShiftCheProjectName).withName(pod.getMetadata().getName()).edit().editMetadata().addToLabels(CHE_CONTAINER_IDENTIFIER_LABEL_KEY, KubernetesStringUtils.getLabelFromContainerID(normalizedID)).endMetadata().done();
return normalizedID;
}
}
return null;
}
Aggregations