Java tutorial
/** * Copyright (C) 2012-2013 Dell, Inc. * See annotations for authorship information * * ==================================================================== * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ==================================================================== */ package org.dasein.cloud.cloudsigma.compute.image; import org.dasein.cloud.compute.*; import org.dasein.util.CalendarWrapper; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.apache.log4j.Logger; import org.dasein.cloud.AsynchronousTask; import org.dasein.cloud.CloudException; import org.dasein.cloud.InternalException; import org.dasein.cloud.OperationNotSupportedException; import org.dasein.cloud.ProviderContext; import org.dasein.cloud.Requirement; import org.dasein.cloud.ResourceStatus; import org.dasein.cloud.cloudsigma.CloudSigma; import org.dasein.cloud.cloudsigma.CloudSigmaConfigurationException; import org.dasein.cloud.cloudsigma.CloudSigmaMethod; import org.dasein.cloud.cloudsigma.NoContextException; import org.dasein.util.uom.storage.Storage; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collections; import java.util.Locale; /** * Maps CloudSigma drives to the concept of machine images. While there's a fairly huge disconnect between the * CloudSigma concept of drives and what Dasein Cloud thinks of as a machine image, this implementation attempts * to bridge that gap. * <p>Created by Danielle Mayne: 02/20/13 12:03 PM</p> * @author George Reese * @author Danielle Mayne * @version 2013.02 initial version * @since 2013.02 */ public class BootDriveSupport extends AbstractImageSupport { static private final Logger logger = CloudSigma.getLogger(BootDriveSupport.class); private CloudSigma provider; public BootDriveSupport(@Nonnull CloudSigma provider) { super(provider); this.provider = provider; } public @Nonnull JSONObject cloneDrive(@Nonnull String driveId, @Nonnull String name, Platform os) throws CloudException, InternalException { JSONObject currentDrive = getDrive(driveId); if (currentDrive == null) { throw new CloudException("No such drive: " + driveId); } try { logger.debug("Cloning volume: " + driveId + " with new name " + name); JSONObject newDrive = new JSONObject(); newDrive.put("name", name.replaceAll("\n", " ")); CloudSigmaMethod method = new CloudSigmaMethod(provider); JSONObject jDrive = null; //dmayne 20130529: determine if this is private or library drive boolean publicImage = false; if (currentDrive.has("image_type")) { publicImage = true; //library image: now check it is definitely a disk and not CDROM if (currentDrive.has("media") && !currentDrive.isNull("media")) { String media = currentDrive.getString("media"); if (media.equalsIgnoreCase("cdrom")) { logger.info("Can't clone drive as image is cdrom"); throw new InternalException("Can't clone drive as image is cdrom"); } } else { throw new CloudException("Can't clone drive: unknown media " + driveId); } } JSONObject obj; if (publicImage) { obj = new JSONObject( method.postString(toPublicImageURL(driveId, "action/?do=clone"), newDrive.toString())); } else { obj = new JSONObject( method.postString(toDriveURL(driveId, "action/?do=clone"), newDrive.toString())); } if (obj != null) { jDrive = (JSONObject) obj; } if (jDrive == null) { throw new CloudException("Clone supposedly succeeded, but no drive information was provided"); } return jDrive; } catch (JSONException e) { throw new InternalException(e); } } public @Nullable JSONObject getDrive(String driveId) throws CloudException, InternalException { CloudSigmaMethod method = new CloudSigmaMethod(provider); String body = method.getString(toDriveURL(driveId, "")); try { JSONObject jDrive = null; if (body != null) { jDrive = new JSONObject(body); //dmayne 20130529: library drive can be returned in above call // check if owner is null and if so, call the library endpoint if (!jDrive.has("owner") || jDrive.isNull("owner")) { jDrive = null; } } if (jDrive == null) { logger.debug("Failed " + driveId + ", looking in library..."); body = method.getString(toPublicImageURL(driveId, "")); if (body != null) { jDrive = new JSONObject(body); } logger.debug("SUCCESS: " + (jDrive != null)); } return jDrive; } catch (JSONException e) { throw new InternalException(e); } } @Override public void addImageShare(@Nonnull String providerImageId, @Nonnull String accountNumber) throws CloudException, InternalException { throw new OperationNotSupportedException("No ability to share images"); } @Override public void addPublicShare(@Nonnull String providerImageId) throws CloudException, InternalException { throw new OperationNotSupportedException("No ability to make images public"); } @Override public @Nonnull String bundleVirtualMachine(@Nonnull String virtualMachineId, @Nonnull MachineImageFormat format, @Nonnull String bucket, @Nonnull String name) throws CloudException, InternalException { throw new OperationNotSupportedException("Bundling of virtual machines not supported"); } @Override public void bundleVirtualMachineAsync(@Nonnull String virtualMachineId, @Nonnull MachineImageFormat format, @Nonnull String bucket, @Nonnull String name, @Nonnull AsynchronousTask<String> trackingTask) throws CloudException, InternalException { throw new OperationNotSupportedException("Bundling of virtual machines not supported"); } @Override protected @Nonnull MachineImage capture(@Nonnull ImageCreateOptions options, @Nullable AsynchronousTask<MachineImage> task) throws CloudException, InternalException { try { if (task != null) { task.setStartTime(System.currentTimeMillis()); } VirtualMachine vm; boolean restart = false; vm = provider.getComputeServices().getVirtualMachineSupport() .getVirtualMachine(options.getVirtualMachineId()); if (vm == null) { throw new CloudException("Virtual machine not found: " + options.getVirtualMachineId()); } if (!VmState.STOPPED.equals(vm.getCurrentState())) { restart = true; provider.getComputeServices().getVirtualMachineSupport().stop(options.getVirtualMachineId()); try { long timeout = System.currentTimeMillis() + (CalendarWrapper.MINUTE * 10L); vm = null; while (timeout > System.currentTimeMillis()) { vm = provider.getComputeServices().getVirtualMachineSupport() .getVirtualMachine(options.getVirtualMachineId()); if (vm.getCurrentState().equals(VmState.STOPPED)) { System.out.println("Server stopped"); break; } try { Thread.sleep(15000L); } catch (InterruptedException ignore) { } } } catch (Throwable ignore) { } } String driveId = vm.getProviderMachineImageId(); try { if (driveId != null) { JSONObject object = cloneDrive(driveId, options.getName(), vm.getPlatform()); String id = null; if (object.has("objects")) { JSONArray jDrives = object.getJSONArray("objects"); JSONObject actualDrive = (JSONObject) jDrives.get(0); id = actualDrive.getString("uuid"); } MachineImage img = null; if (id != null) { img = getImage(id); } if (img == null) { throw new CloudException("Drive cloning completed, but no ID was provided for clone"); } if (task != null) { task.completeWithResult(img); } return img; } else { throw new InternalException("Drive id for cloning is null"); } } catch (JSONException e) { throw new InternalException(e); } finally { if (restart) { try { provider.getComputeServices().getVirtualMachineSupport() .start(options.getVirtualMachineId()); } catch (Throwable ignore) { logger.warn("Failed to restart " + options.getVirtualMachineId() + " after drive cloning"); } } } } finally { provider.release(); } } @Override public MachineImage getImage(@Nonnull String providerImageId) throws CloudException, InternalException { return toMachineImage(getDrive(providerImageId)); } @Override public @Nonnull String getProviderTermForImage(@Nonnull Locale locale, @Nonnull ImageClass cls) { switch (cls) { case KERNEL: return "kernel image"; case RAMDISK: return "ramdisk image"; } return "boot drive"; } @Override public @Nonnull String getProviderTermForCustomImage(@Nonnull Locale locale, @Nonnull ImageClass cls) { return getProviderTermForImage(locale, cls); } @Override public boolean hasPublicLibrary() { return true; } @Override public @Nonnull Requirement identifyLocalBundlingRequirement() throws CloudException, InternalException { return Requirement.NONE; } @Override public boolean isImageSharedWithPublic(@Nonnull String machineImageId) throws CloudException, InternalException { MachineImage img = getImage(machineImageId); if (img == null) { return false; } String owner = img.getProviderOwnerId(); return (owner.equals("--public--") || owner.equals("00000000-0000-0000-0000-000000000001")); } @Override public boolean isSubscribed() throws CloudException, InternalException { return provider.getComputeServices().getVirtualMachineSupport().isSubscribed(); } @Override public @Nonnull Iterable<ResourceStatus> listImageStatus(@Nonnull ImageClass cls) throws CloudException, InternalException { if (!cls.equals(ImageClass.MACHINE)) { return Collections.emptyList(); } ProviderContext ctx = provider.getContext(); if (ctx == null) { throw new NoContextException(); } String me = ctx.getAccountNumber(); ArrayList<ResourceStatus> list = new ArrayList<ResourceStatus>(); CloudSigmaMethod method = new CloudSigmaMethod(provider); boolean moreData = true; String baseTarget = "/drives"; String target = "/?limit=0&fields=uuid,meta,name,status,owner"; // while(moreData) { - commented out as it seems paging is no longer supported //but who knows when the api will change back again //dmayne 20130218: JSON Parsing target = baseTarget + target; JSONObject jObject = method.list(target); if (jObject == null) { throw new CloudException("Could not identify drive endpoint for CloudSigma"); } try { JSONArray objects = jObject.getJSONArray("objects"); for (int i = 0; i < objects.length(); i++) { JSONObject jImage = objects.getJSONObject(i); //dmayne 20130522: check that we are looking at an image //(will have an image_type attribute) JSONObject metadata = jImage.getJSONObject("meta"); String name = jImage.getString("name"); if (metadata.has("image_type") || name.startsWith("esimg-")) { JSONObject owner = jImage.getJSONObject("owner"); String id = owner.getString("uuid"); if (id != null && id.trim().equals("")) { id = null; } if (me.equals(id)) { ResourceStatus img = toStatus(jImage); if (img != null) { list.add(img); } } } } /* //dmayne 20130314: check if there are more pages - commented out as it seems paging is no longer supported but who knows when the api will change back again if (jObject.has("meta")) { JSONObject meta = jObject.getJSONObject("meta"); if (meta.has("next") && !(meta.isNull("next")) && !meta.getString("next").equals("")) { target = meta.getString("next"); target = target.substring(target.indexOf("?")); moreData = true; } else { moreData = false; } } */ } catch (JSONException e) { throw new InternalException(e); } // } return list; } @Override public @Nonnull Iterable<MachineImage> listImages(@Nullable ImageFilterOptions options) throws CloudException, InternalException { if (options != null && !ImageClass.MACHINE.equals(options.getImageClass())) { return Collections.emptyList(); } ArrayList<MachineImage> matches = new ArrayList<MachineImage>(); String me = getContext().getAccountNumber(); CloudSigmaMethod method = new CloudSigmaMethod(provider); boolean moreData = true; String baseTarget = "/drives/detail/?limit=0"; String target = ""; // while(moreData) { - commented out as it seems paging is no longer supported //but who knows when the api will change back again //dmayne 20130218: JSON Parsing target = baseTarget + target; JSONObject jObject = method.list(target); try { if (jObject == null) { throw new CloudException("Could not identify drive endpoint for CloudSigma"); } if (jObject.has("objects")) { JSONArray objects = jObject.getJSONArray("objects"); for (int i = 0; i < objects.length(); i++) { JSONObject jImage = objects.getJSONObject(i); //dmayne 20130522: check that we are looking at an image //(will have an image_type attribute) JSONObject metadata = jImage.getJSONObject("meta"); String name = jImage.getString("name"); if (metadata.has("image_type") || name.startsWith("esimg-")) { String id = null; if (jImage.has("owner")) { JSONObject owner = jImage.getJSONObject("owner"); if (owner != null && owner.has("uuid")) { id = owner.getString("uuid"); } } if (id != null && id.trim().equals("")) { id = null; } if (me.equals(id)) { MachineImage img = toMachineImage(jImage); if (img != null && (options == null || options.matches(img))) { matches.add(img); } } } } } /* //dmayne 20130314: check if there are more pages - commented out as it seems paging is no longer supported but who knows when the api will change back again if (jObject.has("meta")) { JSONObject meta = jObject.getJSONObject("meta"); if (meta.has("next") && !(meta.isNull("next")) && !meta.getString("next").equals("")) { target = meta.getString("next"); target = target.substring(target.indexOf("?")); moreData = true; } else { moreData = false; } } */ } catch (JSONException e) { throw new InternalException(e); } // } return matches; } private @Nonnull Iterable<MachineImage> listImagesComplete(@Nullable String accountId) throws CloudException, InternalException { ProviderContext ctx = provider.getContext(); if (ctx == null) { throw new NoContextException(); } String me = ctx.getAccountNumber(); if (me.equals(accountId)) { return listImages(ImageClass.MACHINE); } else if (accountId == null || accountId.equals("")) { accountId = "00000000-0000-0000-0000-000000000001"; } ArrayList<MachineImage> list = new ArrayList<MachineImage>(); CloudSigmaMethod method = new CloudSigmaMethod(provider); boolean moreData = true; String baseTarget = "/libdrives/detail/?limit=0"; String target = ""; // while(moreData) { - commented out as it seems paging is no longer supported // but who knows when the api will change back again //dmayne 20130218: JSON Parsing target = baseTarget + target; JSONObject jObj = method.list(target); try { if (jObj == null) { throw new CloudException("Could not identify drive endpoint for CloudSigma"); } if (jObj.has("objects")) { JSONArray objects = jObj.getJSONArray("objects"); for (int i = 0; i < objects.length(); i++) { JSONObject jImage = objects.getJSONObject(i); String id = null; if (jImage.has("owner") && jImage.isNull("owner")) { id = "00000000-0000-0000-0000-000000000001"; } if (accountId.equals(id)) { MachineImage img = toPublicMachineImage(jImage); if (img != null) { list.add(img); } } } } /* //dmayne 20130314: check if there are more pages - commented out as it seems paging is no longer supported but who knows when the api will change back again if (jObj.has("meta")) { JSONObject meta = jObj.getJSONObject("meta"); if (meta.has("next") && !(meta.isNull("next")) && !meta.getString("next").equals("")) { target = meta.getString("next"); target = target.substring(target.indexOf("?")); moreData = true; } else { moreData = false; } } */ } catch (JSONException e) { throw new InternalException(e); } // } return list; } @Override public @Nonnull Iterable<MachineImageFormat> listSupportedFormats() throws CloudException, InternalException { return Collections.singletonList(MachineImageFormat.OVF); } @Override public @Nonnull Iterable<MachineImageFormat> listSupportedFormatsForBundling() throws CloudException, InternalException { return Collections.emptyList(); } /* private boolean matches(@Nonnull MachineImage image, @Nullable String keyword, @Nullable Platform platform, @Nullable Architecture architecture) { if (architecture != null && !architecture.equals(image.getArchitecture())) { return false; } if (platform != null && !platform.equals(Platform.UNKNOWN)) { Platform mine = image.getPlatform(); if (platform.isWindows() && !mine.isWindows()) { return false; } if (platform.isUnix() && !mine.isUnix()) { return false; } if (platform.isBsd() && !mine.isBsd()) { return false; } if (platform.isLinux() && !mine.isLinux()) { return false; } if (platform.equals(Platform.UNIX)) { if (!mine.isUnix()) { return false; } } else if (!platform.equals(mine)) { return false; } } if (keyword != null) { keyword = keyword.toLowerCase(); if (!image.getDescription().toLowerCase().contains(keyword)) { if (!image.getName().toLowerCase().contains(keyword)) { if (!image.getProviderMachineImageId().toLowerCase().contains(keyword)) { return false; } } } } return true; } */ @Override public @Nonnull Iterable<ImageClass> listSupportedImageClasses() throws CloudException, InternalException { return Collections.singletonList(ImageClass.MACHINE); } @Override public @Nonnull Iterable<MachineImageType> listSupportedImageTypes() throws CloudException, InternalException { return Collections.singletonList(MachineImageType.VOLUME); } @Override public @Nonnull MachineImage registerImageBundle(@Nonnull ImageCreateOptions options) throws CloudException, InternalException { throw new OperationNotSupportedException("No image registering is currently supported"); } @Override public void remove(@Nonnull String machineImageId) throws CloudException, InternalException { remove(machineImageId, false); } @Override public void remove(@Nonnull String providerImageId, boolean checkState) throws CloudException, InternalException { CloudSigmaMethod method = new CloudSigmaMethod(provider); if (method.deleteString(toDriveURL(providerImageId, ""), "") == null) { throw new CloudException("Unable to identify drives endpoint for removal"); } } @Override @Deprecated public @Nonnull Iterable<MachineImage> searchMachineImages(@Nullable String keyword, @Nullable Platform platform, @Nullable Architecture architecture) throws CloudException, InternalException { ArrayList<MachineImage> list = new ArrayList<MachineImage>(); /*for (MachineImage img : listImages(ImageClass.MACHINE)) { if (img != null && matches(img, keyword, platform, architecture)) { list.add(img); } }*/ for (MachineImage img : listImagesComplete(null)) { if (img != null && matches(img, keyword, platform, architecture)) { list.add(img); } } return list; } @Override public @Nonnull Iterable<MachineImage> searchImages(@Nullable String accountNumber, @Nullable String keyword, @Nullable Platform platform, @Nullable Architecture architecture, @Nullable ImageClass... imageClasses) throws CloudException, InternalException { ArrayList<MachineImage> list = new ArrayList<MachineImage>(); if (accountNumber == null) { for (MachineImage img : listImages(ImageClass.MACHINE)) { if (img != null && matches(img, keyword, platform, architecture)) { list.add(img); } } for (MachineImage img : listImagesComplete(null)) { if (img != null && matches(img, keyword, platform, architecture)) { list.add(img); } } } else { for (MachineImage img : listImages(ImageClass.MACHINE, accountNumber)) { if (img != null && matches(img, keyword, platform, architecture)) { list.add(img); } } } return list; } @Override public @Nonnull Iterable<MachineImage> searchPublicImages(@Nonnull ImageFilterOptions options) throws InternalException, CloudException { if (options.getImageClass() != null && !ImageClass.MACHINE.equals(options.getImageClass())) { return Collections.emptyList(); } ArrayList<MachineImage> matches = new ArrayList<MachineImage>(); CloudSigmaMethod method = new CloudSigmaMethod(provider); boolean moreData = true; String baseTarget = "/libdrives/detail/?limit=0"; String target = ""; // while(moreData) { - commented out as it seems paging is no longer supported // but who knows when the api will change back again target = baseTarget + target; JSONObject jObject = method.list(target); try { if (jObject == null) { throw new CloudException("Could not identify drive endpoint for CloudSigma"); } if (jObject.has("objects")) { JSONArray objects = jObject.getJSONArray("objects"); for (int i = 0; i < objects.length(); i++) { JSONObject jImage = objects.getJSONObject(i); String id = null; if (jImage.has("owner") && jImage.isNull("owner")) { id = "00000000-0000-0000-0000-000000000001"; } if (id == null || id.equals("00000000-0000-0000-0000-000000000001")) { MachineImage img = toPublicMachineImage(jImage); if (img != null && options.matches(img)) { matches.add(img); } } } } /*//dmayne 20130314: check if there are more pages - commented out as it seems paging is no longer supported but who knows when the api will change back again if (jObject.has("meta")) { JSONObject meta = jObject.getJSONObject("meta"); if (meta.has("next") && !(meta.isNull("next")) && !meta.getString("next").equals("")) { target = meta.getString("next"); target = target.substring(target.indexOf("?")); moreData = true; } else { moreData = false; } } */ } catch (JSONException e) { throw new InternalException(e); } // } return matches; } @Override public boolean supportsCustomImages() { return true; } @Override public boolean supportsDirectImageUpload() throws CloudException, InternalException { return false; } @Override public boolean supportsImageCapture(@Nonnull MachineImageType type) throws CloudException, InternalException { return true; } @Override public boolean supportsImageSharing() { return false; } @Override public boolean supportsImageSharingWithPublic() { return false; } @Override public boolean supportsPublicLibrary(@Nonnull ImageClass cls) throws CloudException, InternalException { return true; } private @Nullable MachineImage toMachineImage(@Nullable JSONObject drive) throws CloudException, InternalException { if (drive == null) { logger.debug("drive is null"); return null; } try { if (drive.has("image_type")) { //dmayne 20130529: this is a library drive return toPublicMachineImage(drive); } ProviderContext ctx = provider.getContext(); if (ctx == null) { throw new NoContextException(); } String regionId = ctx.getRegionId(); if (regionId == null) { throw new CloudSigmaConfigurationException("No region was specified for this request"); } MachineImage image = new MachineImage(); image.setProviderRegionId(regionId); image.setCurrentState(MachineImageState.PENDING); image.setType(MachineImageType.VOLUME); image.setImageClass(ImageClass.MACHINE); String id = drive.getString("uuid"); if (id != null && !id.equals("")) { image.setProviderMachineImageId(id); } String name = drive.getString("name"); if (name != null && !name.equals("")) { image.setName(name); } String description = null; String os = null; String install_notes = null; if (drive.has("meta")) { JSONObject meta = drive.getJSONObject("meta"); //dmayne 20130220: look for description tag and if not available check install_notes if (meta != null) { if (meta.has("description")) { description = meta.getString("description"); } if (description == null || description.length() == 0) { if (meta.has("install_notes")) { install_notes = meta.getString("install_notes"); } } if (meta.has("os")) { os = meta.getString("os"); } String bits = null; if (meta.has("arch")) { bits = meta.getString("arch"); } if (bits != null && bits.contains("32")) { image.setArchitecture(Architecture.I32); } else { image.setArchitecture(Architecture.I64); } } if (description != null && !description.equals("")) { image.setDescription(description); } else if (install_notes != null && !install_notes.equals("")) { image.setDescription(install_notes); } } String user = null; if (drive.has("owner") && !drive.isNull("owner")) { JSONObject owner = drive.getJSONObject("owner"); if (owner != null && owner.has("uuid")) { user = owner.getString("uuid"); } } if (user != null && !user.equals("")) { image.setProviderOwnerId(user); } else { image.setProviderOwnerId("00000000-0000-0000-0000-000000000001"); } String s = drive.getString("status"); if (s != null) { if (s.equalsIgnoreCase("unmounted") || s.equals("mounted")) { image.setCurrentState(MachineImageState.ACTIVE); } else if (s.equalsIgnoreCase("copying")) { image.setCurrentState(MachineImageState.PENDING); } else if (s.equalsIgnoreCase("unavailable")) { image.setCurrentState(MachineImageState.DELETED); } else { logger.warn("WARN: Unknown drive state for CloudSigma: " + s); } /* if (s.equalsIgnoreCase("mounted") ) { image.setCurrentState(MachineImageState.ACTIVE); } else if (s.equalsIgnoreCase("unmounted") || s.equalsIgnoreCase("unavailable")) { image.setCurrentState(MachineImageState.DELETED); } else if (s.startsWith("copying")) { image.setCurrentState(MachineImageState.PENDING); } else { logger.warn("WARN: Unknown drive state for CloudSigma: " + s); } */ } if (MachineImageState.ACTIVE.equals(image.getCurrentState())) { s = null; //todo: dmayne 20130305: not implemented by cloudsigma yet if (drive.has("imaging")) { s = drive.getString("imaging"); } if (s != null) { image.setCurrentState(MachineImageState.PENDING); } } String size = null; size = drive.getString("size"); if (size != null) { try { image.setTag("size", new Storage<org.dasein.util.uom.storage.Byte>(Long.parseLong(size), Storage.BYTE) .toString()); } catch (NumberFormatException ignore) { logger.warn("Unknown size value: " + size); } } String media = drive.getString("media"); image.setTag("media", media); String software = null; if (drive.has("licenses")) { JSONArray licences = drive.getJSONArray("licenses"); for (int i = 0; i < licences.length(); i++) { JSONObject jlicense = licences.getJSONObject(i); if (jlicense.has("licenses")) { software = jlicense.getString("licenses"); } if (software != null) { image.setSoftware(software); break; } else { image.setSoftware(""); } } } if (image.getSoftware() == null) { image.setSoftware(""); } Platform platform = Platform.UNKNOWN; if (os != null && !os.equals("")) { platform = Platform.guess(os); } if (platform.equals(Platform.UNKNOWN)) { platform = Platform.guess(image.getName()); if (platform.equals(Platform.UNKNOWN)) { //check description followed by install notes platform = Platform.guess(image.getDescription()); if (platform.equals(Platform.UNKNOWN)) { platform = Platform.guess(install_notes); } } } else if (platform.equals(Platform.UNIX)) { Platform p = Platform.guess(image.getName()); if (!p.equals(Platform.UNKNOWN)) { platform = p; } } image.setPlatform(platform); if (image.getProviderOwnerId() == null) { image.setProviderOwnerId(ctx.getAccountNumber()); } if (image.getProviderMachineImageId() == null) { return null; } if (image.getName() == null) { image.setName(image.getProviderMachineImageId()); } if (image.getDescription() == null) { image.setDescription(image.getName()); } return image; } catch (JSONException e) { throw new InternalException(e); } } private @Nullable MachineImage toPublicMachineImage(@Nullable JSONObject drive) throws CloudException, InternalException { if (drive == null) { logger.debug("drive is null"); return null; } try { ProviderContext ctx = provider.getContext(); if (ctx == null) { throw new NoContextException(); } String regionId = ctx.getRegionId(); if (regionId == null) { throw new CloudSigmaConfigurationException("No region was specified for this request"); } MachineImage image = new MachineImage(); image.setProviderRegionId(regionId); image.setCurrentState(MachineImageState.PENDING); image.setType(MachineImageType.VOLUME); image.setImageClass(ImageClass.MACHINE); String id = drive.getString("uuid"); if (id != null && !id.equals("")) { image.setProviderMachineImageId(id); } String name = drive.getString("name"); if (name != null && !name.equals("")) { image.setName(name); } String description = null; String os = null; String install_notes = null; if (drive.has("description")) { description = drive.getString("description"); } if (drive.has("install_notes")) { install_notes = drive.getString("install_notes"); } if (drive.has("os")) { os = drive.getString("os"); } String bits = null; if (drive.has("arch")) { bits = drive.getString("arch"); } if (bits != null && bits.contains("32")) { image.setArchitecture(Architecture.I32); } else { image.setArchitecture(Architecture.I64); } if (description != null && !description.equals("")) { image.setDescription(description); } else if (install_notes != null && !install_notes.equals("")) { image.setDescription(install_notes); } String user = null; if (drive.has("owner") && !drive.isNull("owner")) { JSONObject owner = drive.getJSONObject("owner"); if (owner != null && owner.has("uuid")) { user = owner.getString("uuid"); } } if (user != null && !user.equals("")) { image.setProviderOwnerId(user); } else { image.setProviderOwnerId("00000000-0000-0000-0000-000000000001"); } String s = drive.getString("status"); if (s != null) { if (s.equalsIgnoreCase("unmounted") || s.equals("mounted")) { image.setCurrentState(MachineImageState.ACTIVE); } else if (s.equalsIgnoreCase("copying")) { image.setCurrentState(MachineImageState.PENDING); } else if (s.equalsIgnoreCase("unavailable")) { image.setCurrentState(MachineImageState.DELETED); } else { logger.warn("WARN: Unknown drive state for CloudSigma: " + s); } } String size = null; size = drive.getString("size"); if (size != null) { try { image.setTag("size", new Storage<org.dasein.util.uom.storage.Byte>(Long.parseLong(size), Storage.BYTE) .toString()); } catch (NumberFormatException ignore) { logger.warn("Unknown size value: " + size); } } String media = drive.getString("media"); image.setTag("media", media); String software = null; if (drive.has("licenses") && !drive.isNull("licenses")) { JSONArray licences = drive.getJSONArray("licenses"); for (int i = 0; i < licences.length(); i++) { JSONObject jlicense = licences.getJSONObject(i); if (jlicense.has("license") && !jlicense.isNull("license")) { JSONObject li = jlicense.getJSONObject("license"); if (li.has("long_name") && !li.isNull("long_name")) { software = li.getString("long_name"); } } if (software != null) { image.setSoftware(software); break; } else { image.setSoftware(""); } } } if (image.getSoftware() == null) { image.setSoftware(""); } Platform platform = Platform.UNKNOWN; if (os != null && !os.equals("")) { platform = Platform.guess(os); } if (platform.equals(Platform.UNKNOWN)) { platform = Platform.guess(image.getName()); if (platform.equals(Platform.UNKNOWN)) { //check description followed by install notes platform = Platform.guess(image.getDescription()); if (platform.equals(Platform.UNKNOWN)) { platform = Platform.guess(install_notes); } } } else if (platform.equals(Platform.UNIX)) { Platform p = Platform.guess(image.getName()); if (!p.equals(Platform.UNKNOWN)) { platform = p; } } image.setPlatform(platform); if (image.getProviderOwnerId() == null) { image.setProviderOwnerId(ctx.getAccountNumber()); } if (image.getProviderMachineImageId() == null) { return null; } if (image.getName() == null) { image.setName(image.getProviderMachineImageId()); } if (image.getDescription() == null) { image.setDescription(image.getName()); } return image; } catch (JSONException e) { throw new InternalException(e); } } private @Nullable ResourceStatus toStatus(@Nullable JSONObject drive) throws CloudException, InternalException { if (drive == null) { return null; } try { ProviderContext ctx = provider.getContext(); if (ctx == null) { throw new NoContextException(); } String id = drive.getString("uuid"); if (id == null || id.equals("")) { return null; } MachineImageState state = MachineImageState.PENDING; String s = drive.getString("status"); if (s != null) { if (s.equalsIgnoreCase("mounted") || s.equalsIgnoreCase("unmounted")) { state = MachineImageState.ACTIVE; } else if (s.equalsIgnoreCase("unavailable")) { state = MachineImageState.DELETED; } else if (s.startsWith("copying")) { state = MachineImageState.PENDING; } else { logger.warn("DEBUG: Unknown drive state for CloudSigma: " + s); } } return new ResourceStatus(id, state); } catch (JSONException e) { throw new InternalException(e); } } private @Nonnull String toDriveURL(@Nonnull String vmId, @Nonnull String action) throws InternalException { try { return ("/drives/" + URLEncoder.encode(vmId, "utf-8") + "/" + action); } catch (UnsupportedEncodingException e) { logger.error("UTF-8 not supported: " + e.getMessage()); throw new InternalException(e); } } private @Nonnull String toPublicImageURL(@Nonnull String vmId, @Nonnull String action) throws InternalException { try { return ("/libdrives/" + URLEncoder.encode(vmId, "utf-8") + "/" + action); } catch (UnsupportedEncodingException e) { logger.error("UTF-8 not supported: " + e.getMessage()); throw new InternalException(e); } } }