http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunning.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunning.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunning.java deleted file mode 100644 index 90ab02d..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunning.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - -import static com.google.common.base.Throwables.propagate; - -import javax.annotation.Resource; -import javax.inject.Named; - -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.logging.Logger; -import org.jclouds.virtualbox.domain.ErrorCode; -import org.jclouds.virtualbox.domain.ExecutionType; -import org.virtualbox_4_2.IMachine; -import org.virtualbox_4_2.IProgress; -import org.virtualbox_4_2.ISession; -import org.virtualbox_4_2.SessionState; -import org.virtualbox_4_2.VBoxException; -import org.virtualbox_4_2.VirtualBoxManager; - -import com.google.common.base.Function; - -/** - * Starts a machine using launchMachine() with the provided type and - * environment. - * <p/> - * Note that launchMachine() may throw VBoxException with the following error - * codes: - * <p/> - * VBOX_E_UNEXPECTED: Virtual machine not registered. VBOX_E_INVALIDARG: Invalid - * session type type. VBOX_E_OBJECT_NOT_FOUND: No machine matching machineId - * found. VBOX_E_INVALID_OBJECT_STATE: Session already open or being opened. - * VBOX_E_IPRT_ERROR: Launching process for machine failed. VBOX_E_VM_ERROR: - * Failed to assign machine to session. - * - * @see ErrorCode - */ -public class LaunchMachineIfNotAlreadyRunning implements Function<IMachine, ISession> { - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final VirtualBoxManager manager; - private final ExecutionType type; - private final String environment; - - public LaunchMachineIfNotAlreadyRunning(VirtualBoxManager manager, ExecutionType type, String environment) { - this.manager = manager; - this.type = type; - this.environment = environment; - } - - @Override - public ISession apply(IMachine machine) { - ISession session = manager.getSessionObject(); - try { - final IProgress progress = machine - .launchVMProcess(session, type.stringValue(), environment); - progress.waitForCompletion(-1); - } catch (VBoxException e) { - ErrorCode errorCode = ErrorCode.valueOf(e); - switch (errorCode) { - case VBOX_E_INVALID_OBJECT_STATE: - logger.warn(e, "Could not start machine. Got error code %s from launchMachine(). " - + "The machine might already be running.", errorCode); - break; - default: - propagate(e); - } - } finally { - if (session.getState() == SessionState.Locked) { - // Remove session lock taken by launchVmProcess() - session.unlockMachine(); - // TODO this unlock is not IMMEDIATELY visible outside (vbox doc) - } - } - return session; - } -}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MacAddressToBSD.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MacAddressToBSD.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MacAddressToBSD.java deleted file mode 100644 index e058848..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MacAddressToBSD.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - -import static com.google.common.base.Preconditions.checkArgument; - -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; - -public enum MacAddressToBSD implements Function<String, String> { - - INSTANCE; - - @Override - public String apply(String macAddress) { - checkArgument(macAddress.length() == 17); - return Joiner.on(":").join( - Iterables.transform(Splitter.on(":").split(macAddress), - new Function<String, String>() { - @Override - public String apply(String addressPart) { - if (addressPart.equals("00")) - return "0"; - if (addressPart.startsWith("0")) - return addressPart.substring(1); - - return addressPart; - } - })); - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MastersLoadingCache.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MastersLoadingCache.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MastersLoadingCache.java deleted file mode 100644 index 658429a..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MastersLoadingCache.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot; -import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_DEFAULT_DIR; -import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX; -import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_NAME_SEPARATOR; -import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL; -import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR; -import static org.jclouds.virtualbox.util.MachineUtils.machineNotFoundException; - -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.ExecutionException; - -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.compute.callables.RunScriptOnNode.Factory; -import org.jclouds.compute.domain.ExecResponse; -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.domain.LoginCredentials; -import org.jclouds.location.Provider; -import org.jclouds.logging.Logger; -import org.jclouds.rest.annotations.BuildVersion; -import org.jclouds.scriptbuilder.domain.Statement; -import org.jclouds.scriptbuilder.domain.StatementList; -import org.jclouds.scriptbuilder.domain.Statements; -import org.jclouds.virtualbox.domain.HardDisk; -import org.jclouds.virtualbox.domain.IsoSpec; -import org.jclouds.virtualbox.domain.Master; -import org.jclouds.virtualbox.domain.MasterSpec; -import org.jclouds.virtualbox.domain.NetworkAdapter; -import org.jclouds.virtualbox.domain.NetworkInterfaceCard; -import org.jclouds.virtualbox.domain.NetworkSpec; -import org.jclouds.virtualbox.domain.StorageController; -import org.jclouds.virtualbox.domain.VmSpec; -import org.jclouds.virtualbox.domain.YamlImage; -import org.jclouds.virtualbox.functions.admin.PreseedCfgServer; -import org.jclouds.virtualbox.predicates.RetryIfSocketNotYetOpen; -import org.jclouds.virtualbox.statements.Md5; -import org.jclouds.virtualbox.util.NetworkUtils; -import org.virtualbox_4_2.CleanupMode; -import org.virtualbox_4_2.IMachine; -import org.virtualbox_4_2.NetworkAttachmentType; -import org.virtualbox_4_2.StorageBus; -import org.virtualbox_4_2.VBoxException; -import org.virtualbox_4_2.VirtualBoxManager; - -import com.google.common.base.CaseFormat; -import com.google.common.base.Function; -import com.google.common.base.Splitter; -import com.google.common.base.Supplier; -import com.google.common.cache.AbstractLoadingCache; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.net.HostAndPort; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; - -/** - * A {@link LoadingCache} for masters. If the requested master has been - * previously created this returns it, if not it coordinates its creation - * including downloading isos and creating cache/config directories. This also - * implements {@link Supplier} in order to provide jetty with the current image - * (only one master can be created at a time). - */ -@Singleton -public class MastersLoadingCache extends AbstractLoadingCache<Image, Master> { - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final Map<String, Master> masters = Maps.newHashMap(); - private final Function<MasterSpec, IMachine> masterCreatorAndInstaller; - private final Map<String, YamlImage> imageMapping; - private final String workingDir; - private final String isosDir; - private final Supplier<VirtualBoxManager> manager; - private final String version; - private final String preconfigurationUrl; - - private final Factory runScriptOnNodeFactory; - private final RetryIfSocketNotYetOpen socketTester; - private final Supplier<NodeMetadata> host; - private final Supplier<URI> providerSupplier; - private final HardcodedHostToHostNodeMetadata hardcodedHostToHostNodeMetadata; - - @Inject - public MastersLoadingCache(@BuildVersion String version, - @Named(VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl, - @Named(VIRTUALBOX_WORKINGDIR) String workingDir, Function<MasterSpec, IMachine> masterLoader, - Supplier<Map<Image, YamlImage>> yamlMapper, Supplier<VirtualBoxManager> manager, - Factory runScriptOnNodeFactory, RetryIfSocketNotYetOpen socketTester, Supplier<NodeMetadata> host, - @Provider Supplier<URI> providerSupplier, HardcodedHostToHostNodeMetadata hardcodedHostToHostNodeMetadata) { - this.manager = checkNotNull(manager, "vboxmanager can't be null"); - this.masterCreatorAndInstaller = masterLoader; - this.workingDir = workingDir == null ? VIRTUALBOX_DEFAULT_DIR : workingDir; - this.isosDir = workingDir + File.separator + "isos"; - this.imageMapping = Maps.newLinkedHashMap(); - for (Entry<Image, YamlImage> entry : yamlMapper.get().entrySet()) { - this.imageMapping.put(entry.getKey().getId(), entry.getValue()); - } - this.version = Iterables.get(Splitter.on('r').split(checkNotNull(version, "version")), 0); - this.preconfigurationUrl = preconfigurationUrl; - - this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory"); - this.socketTester = checkNotNull(socketTester, "socketTester"); - this.socketTester.seconds(3L); - this.host = checkNotNull(host, "host"); - this.providerSupplier = checkNotNull(providerSupplier, "endpoint to virtualbox websrvd is needed"); - this.hardcodedHostToHostNodeMetadata = hardcodedHostToHostNodeMetadata; - } - - @PostConstruct - public void createCacheDirStructure() { - if (!new File(workingDir).exists()) { - new File(workingDir, "isos").mkdirs(); - } - } - - @Override - public synchronized Master get(Image key) throws ExecutionException { - // check if we have loaded this machine before - if (masters.containsKey(key.getId())) { - return masters.get(key.getId()); - } - checkState(!key.getId().contains(VIRTUALBOX_NODE_NAME_SEPARATOR), "master image names cannot contain \"" - + VIRTUALBOX_NODE_NAME_SEPARATOR + "\""); - String vmName = VIRTUALBOX_IMAGE_PREFIX + key.getId(); - IMachine masterMachine; - Master master; - // ready the preseed file server - PreseedCfgServer server = new PreseedCfgServer(); - try { - // try and find a master machine in vbox - masterMachine = manager.get().getVBox().findMachine(vmName); - master = Master.builder().machine(masterMachine).build(); - } catch (VBoxException e) { - if (machineNotFoundException(e)) { - // machine was not found try to build one from a yaml file - YamlImage currentImage = checkNotNull(imageMapping.get(key.getId()), "currentImage"); - URI preseedServer; - try { - preseedServer = new URI(preconfigurationUrl); - if (!socketTester.apply(HostAndPort.fromParts(preseedServer.getHost(), preseedServer.getPort()))) { - server.start(preconfigurationUrl, currentImage.preseed_cfg); - } - } catch (URISyntaxException e1) { - logger.error("Cannot start the preseed server", e); - throw e; - } - - MasterSpec masterSpec = buildMasterSpecFromYaml(currentImage, vmName); - masterMachine = masterCreatorAndInstaller.apply(masterSpec); - master = Master.builder().machine(masterMachine).spec(masterSpec).build(); - } else { - logger.error("Problem during master creation", e); - throw e; - } - } finally { - server.stop(); - } - - masters.put(key.getId(), master); - return master; - } - - private MasterSpec buildMasterSpecFromYaml(YamlImage currentImage, String vmName) throws ExecutionException { - String guestAdditionsFileName = String.format("VBoxGuestAdditions_%s.iso", version); - String guestAdditionsIso = String.format("%s/%s", isosDir, guestAdditionsFileName); - String guestAdditionsUri = "http://download.virtualbox.org/virtualbox/" + version + "/" + guestAdditionsFileName; - if (!new File(guestAdditionsIso).exists()) { - getFilePathOrDownload(guestAdditionsUri, null); - } - // check if the iso is here, download if not - String localIsoUrl = checkNotNull(getFilePathOrDownload(currentImage.iso, currentImage.iso_md5), "distro iso"); - String adminDisk = workingDir + File.separator + vmName + ".vdi"; - HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk).autoDelete(true).controllerPort(0).deviceSlot(1) - .build(); - - StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE) - .attachISO(0, 0, localIsoUrl).attachHardDisk(hardDisk).build(); - - VmSpec vmSpecification = VmSpec.builder().id(currentImage.id).name(vmName).memoryMB(512) - .osTypeId(getOsTypeId(currentImage.os_family, currentImage.os_64bit)).controller(ideController) - .forceOverwrite(true).guestUser(currentImage.username).guestPassword(currentImage.credential) - .cleanUpMode(CleanupMode.Full).build(); - - NetworkAdapter networkAdapter = NetworkAdapter.builder().networkAttachmentType(NetworkAttachmentType.NAT) - .tcpRedirectRule(providerSupplier.get().getHost(), NetworkUtils.MASTER_PORT, "", 22).build(); - - NetworkInterfaceCard networkInterfaceCard = NetworkInterfaceCard.builder().addNetworkAdapter(networkAdapter) - .slot(0L).build(); - - NetworkSpec networkSpec = NetworkSpec.builder().addNIC(networkInterfaceCard).build(); - - String installationSequence = currentImage.keystroke_sequence.replace("HOSTNAME", vmSpecification.getVmName()); - return MasterSpec.builder() - .vm(vmSpecification) - .iso(IsoSpec.builder() - .sourcePath(localIsoUrl) - .installationScript(installationSequence) - .build()) - .network(networkSpec) - .credentials(LoginCredentials.builder() - .user(currentImage.username) - .password(currentImage.credential) - .authenticateSudo(true) - .build()) - .build(); - } - - @Override - public synchronized Master getIfPresent(Object key) { - checkArgument(key instanceof Image, "this cache is for entries who's keys are Images"); - Image image = Image.class.cast(key); - if (masters.containsKey(image.getId())) { - return masters.get(image.getId()); - } - return null; - } - - private String getFilePathOrDownload(String httpUrl, String expectedMd5) throws ExecutionException { - String fileName = httpUrl.substring(httpUrl.lastIndexOf('/') + 1, httpUrl.length()); - URI provider = providerSupplier.get(); - if (!socketTester.apply(HostAndPort.fromParts(provider.getHost(), provider.getPort()))) { - throw new RuntimeException("could not connect to virtualbox"); - } - File file = new File(isosDir, fileName); - List<Statement> statements = new ImmutableList.Builder<Statement>().add( - Statements.saveHttpResponseTo(URI.create(httpUrl), isosDir, fileName)).build(); - StatementList statementList = new StatementList(statements); - NodeMetadata hostNode = checkNotNull(hardcodedHostToHostNodeMetadata.apply(host.get()), "hostNode"); - ListenableFuture<ExecResponse> future = runScriptOnNodeFactory.submit(hostNode, statementList, - runAsRoot(false)); - Futures.getUnchecked(future); - - if (expectedMd5 != null) { - String filePath = isosDir + File.separator + fileName; - ListenableFuture<ExecResponse> md5future = runScriptOnNodeFactory.submit(hostNode, new Md5(filePath), - runAsRoot(false)); - - ExecResponse responseMd5 = Futures.getUnchecked(md5future); - assert responseMd5.getExitStatus() == 0 : hostNode.getId() + ": " + responseMd5; - checkNotNull(responseMd5.getOutput(), "iso_md5 missing"); - String actualMd5 = responseMd5.getOutput().trim(); - checkState(actualMd5.equals(expectedMd5), "md5 of %s is %s but expected %s", filePath, actualMd5, expectedMd5); - } - return file.getAbsolutePath(); - } - - private String getOsTypeId(String os_family, boolean os_64bit) { - String osFamily = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, os_family); - return os_64bit ? osFamily + "_64" : osFamily; - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/NodeCreator.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/NodeCreator.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/NodeCreator.java deleted file mode 100644 index 739c197..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/NodeCreator.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - - import com.google.common.base.Charsets; - import com.google.common.base.Function; - import com.google.common.base.Optional; - import com.google.common.base.Predicate; - import com.google.common.base.Supplier; - import com.google.common.collect.ImmutableSet; - import com.google.common.collect.Iterables; - import com.google.common.io.Files; - import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials; - import org.jclouds.compute.domain.NodeMetadata; - import org.jclouds.compute.domain.NodeMetadataBuilder; - import org.jclouds.compute.options.RunScriptOptions; - import org.jclouds.compute.reference.ComputeServiceConstants; - import org.jclouds.domain.LoginCredentials; - import org.jclouds.logging.Logger; - import org.jclouds.util.Strings2; - import org.jclouds.virtualbox.config.VirtualBoxComputeServiceContextModule; - import org.jclouds.virtualbox.domain.CloneSpec; - import org.jclouds.virtualbox.domain.Master; - import org.jclouds.virtualbox.domain.NetworkInterfaceCard; - import org.jclouds.virtualbox.domain.NetworkSpec; - import org.jclouds.virtualbox.domain.NodeSpec; - import org.jclouds.virtualbox.domain.VmSpec; - import org.jclouds.virtualbox.statements.DeleteGShadowLock; - import org.jclouds.virtualbox.statements.PasswordlessSudo; - import org.jclouds.virtualbox.util.MachineController; - import org.jclouds.virtualbox.util.MachineUtils; - import org.jclouds.virtualbox.util.NetworkUtils; - import org.virtualbox_4_2.CleanupMode; - import org.virtualbox_4_2.IMachine; - import org.virtualbox_4_2.IProgress; - import org.virtualbox_4_2.ISession; - import org.virtualbox_4_2.LockType; - import org.virtualbox_4_2.NetworkAttachmentType; - import org.virtualbox_4_2.VirtualBoxManager; - import com.google.common.collect.ImmutableList; - - import javax.annotation.Resource; - import javax.inject.Inject; - import javax.inject.Named; - import javax.inject.Singleton; - - import java.io.File; - import java.io.IOException; - - import static com.google.common.base.Preconditions.checkNotNull; - import static com.google.common.base.Preconditions.checkState; - import static org.jclouds.virtualbox.config.VirtualBoxConstants.GUEST_OS_PASSWORD; - import static org.jclouds.virtualbox.config.VirtualBoxConstants.GUEST_OS_USER; - import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_GUEST_MEMORY; - import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX; - import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_NAME_SEPARATOR; - import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_NODE_PREFIX; - import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR; - -/** - * Creates nodes, by cloning a master vm and based on the provided {@link NodeSpec}. Must be - * synchronized mainly because of snapshot creation (must be synchronized on a per-master-basis). - */ -@Singleton -public class NodeCreator implements Function<NodeSpec, NodeAndInitialCredentials<IMachine>> { - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final Supplier<VirtualBoxManager> manager; - private final Function<CloneSpec, IMachine> cloner; - private final MachineUtils machineUtils; - private final MachineController machineController; - private final NetworkUtils networkUtils; - private final int ram; - private final String workingDir; - - @Inject - public NodeCreator(Supplier<VirtualBoxManager> manager, Function<CloneSpec, IMachine> cloner, - MachineUtils machineUtils, MachineController machineController, - NetworkUtils networkUtils, - @Named(VIRTUALBOX_GUEST_MEMORY) String ram, - @Named(VIRTUALBOX_WORKINGDIR) String workingDir) { - this.manager = checkNotNull(manager, "manager"); - this.cloner = checkNotNull(cloner, "cloner"); - this.networkUtils = checkNotNull(networkUtils, "networkUtils"); - this.machineUtils = checkNotNull(machineUtils, "machineUtils"); - this.machineController = checkNotNull(machineController, "machineController"); - this.ram = checkNotNull(Integer.valueOf(ram), "ram"); - this.workingDir = checkNotNull(workingDir, "workingDir"); - } - - @Override - public synchronized NodeAndInitialCredentials<IMachine> apply(NodeSpec nodeSpec) { - checkNotNull(nodeSpec, "NodeSpec"); - Master master = checkNotNull(nodeSpec.getMaster(), "Master"); - IMachine masterMachine = master.getMachine(); - String guestOsUser = masterMachine.getExtraData(GUEST_OS_USER); - String guestOsPassword = masterMachine.getExtraData(GUEST_OS_PASSWORD); - - cleanUpMaster(master); - CloneSpec cloneSpec = configureCloneSpec(nodeSpec, guestOsUser, guestOsPassword); - IMachine clone = cloner.apply(cloneSpec); - String cloneName = cloneSpec.getVmSpec().getVmName(); - logger.debug("<< cloned a vm(%s) from master(%s)", cloneName, nodeSpec.getMaster().getMachine().getName()); - machineController.ensureMachineIsLaunched(cloneName); - logger.debug("<< cloned vm(%s) is up and running", cloneName); - - reconfigureNetworkInterfaces(masterMachine, guestOsUser, guestOsPassword, cloneSpec.getNetworkSpec(), clone); - - postConfigurations(clone, guestOsUser, guestOsPassword); - - LoginCredentials credentials = LoginCredentials.builder() - .user(guestOsUser) - .password(guestOsPassword) - .authenticateSudo(true) - .build(); - return new NodeAndInitialCredentials<IMachine>(clone, cloneName, credentials); - } - - private void reconfigureNetworkInterfaces(IMachine masterMachine, String guestOsUser, String guestOsPassword, NetworkSpec networkSpec, IMachine clone) { - reconfigureHostOnlyInterfaceIfNeeded(guestOsUser, guestOsPassword, clone.getName(), masterMachine.getOSTypeId()); - logger.debug("<< reconfigured hostOnly interface of node(%s)", clone.getName()); - reconfigureNatInterfaceIfNeeded(guestOsUser, guestOsPassword, clone.getOSTypeId(), clone, networkSpec); - logger.debug("<< reconfigured NAT interface of node(%s)", clone.getName()); - } - - /** - * {@see DeleteGShadowLock} and {@see PasswordlessSudo} for a detailed explanation - * - * @param clone the target machine - * @param guestOsUser the user to access the target machine - * @param guestOsPassword the password to access the target machine - */ - private void postConfigurations(IMachine clone, String guestOsUser, String guestOsPassword) { - NodeMetadata partialNodeMetadata = buildPartialNodeMetadata(clone, guestOsUser, guestOsPassword); - machineUtils.runScriptOnNode(partialNodeMetadata, new DeleteGShadowLock(), RunScriptOptions.NONE); - machineUtils.runScriptOnNode(partialNodeMetadata, new PasswordlessSudo(partialNodeMetadata.getCredentials().identity), RunScriptOptions.Builder.runAsRoot(true)); - } - - private CloneSpec configureCloneSpec( - NodeSpec nodeSpec, String guestOsUser, String guestOsPassword) { - - String cloneName = generateCloneName(nodeSpec); - - VmSpec cloneVmSpec = VmSpec.builder() - .id(cloneName) - .name(cloneName) - .memoryMB(ram) - .osTypeId(nodeSpec.getMaster().getMachine().getOSTypeId()) - .guestUser(guestOsUser) - .guestPassword(guestOsPassword) - .cleanUpMode(CleanupMode.Full) - .forceOverwrite(true) - .build(); - - // case 'vbox host is localhost': NAT + HOST-ONLY - NetworkSpec networkSpec = networkUtils.createNetworkSpecWhenVboxIsLocalhost(); - - return CloneSpec.builder() - .linked(true) - .master(nodeSpec.getMaster().getMachine()) - .network(networkSpec) - .vm(cloneVmSpec).build(); - } - - private void cleanUpMaster(Master master) { - deleteExistingSnapshot(master); - } - - private void reconfigureHostOnlyInterfaceIfNeeded(final String username, final String password, - String vmName, String osTypeId) { - final String scriptName = "hostOnly"; - if (osTypeId.contains("RedHat")) { - File scriptFile = copyScriptToWorkingDir("redHatAndDerivatives", scriptName); - copyToNodeAndExecScript(username, password, vmName, scriptFile); - } - } - - private void reconfigureNatInterfaceIfNeeded(final String guestOsUser, final String guestOsPassword, - String osTypeId, IMachine clone, NetworkSpec networkSpec) { - - final String scriptName = "nat"; - final String folder = "redHatAndDerivatives"; - if (osTypeId.contains("RedHat")) { - File scriptFile = copyScriptToWorkingDir(folder, scriptName); - copyToNodeAndExecScript(guestOsUser, guestOsPassword, clone.getName(), scriptFile); - } else if (osTypeId.contains("Ubuntu") || osTypeId.contains("Debian")) { - NodeMetadata partialNodeMetadata = buildPartialNodeMetadata(clone, guestOsUser, guestOsPassword); - - Optional<NetworkInterfaceCard> optionalNatIfaceCard = Iterables.tryFind( - networkSpec.getNetworkInterfaceCards(), - new Predicate<NetworkInterfaceCard>() { - - @Override - public boolean apply(NetworkInterfaceCard nic) { - return nic.getNetworkAdapter().getNetworkAttachmentType() - .equals(NetworkAttachmentType.NAT); - } - }); - - checkState(networkUtils.enableNetworkInterface(partialNodeMetadata, optionalNatIfaceCard.get()), - "cannot enable NAT Interface on vm(%s)", clone.getName()); - } - } - - private File copyScriptToWorkingDir(String folder, String scriptName) { - File scriptFile = new File(workingDir + "/conf/" + "/" + folder + "/" + scriptName); - scriptFile.getParentFile().mkdirs(); - if (!scriptFile.exists()) { - try { - Files.write(Strings2.toStringAndClose(getClass().getResourceAsStream("/" + folder + "/" + scriptName)), scriptFile, Charsets.UTF_8); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - return scriptFile; - } - - private void copyToNodeAndExecScript(final String username, final String password, - String vmName, final File scriptFile) { - machineUtils.sharedLockMachineAndApplyToSession(vmName, new Function<ISession, Void>() { - - @Override - public Void apply(ISession session) { - String scriptName = scriptFile.getName(); - - manager.get().getSessionObject().getConsole().getGuest() - .createSession(username, password, null, null) - .copyTo(scriptFile.getAbsolutePath(), "/tmp/" + scriptName, null); - - manager.get().getSessionObject().getConsole().getGuest() - .createSession(username, password, null, null) - .processCreate("/bin/chmod", ImmutableList.of("777", "/tmp/" + scriptName), null, null, 5 * 1000l); - - manager.get().getSessionObject().getConsole().getGuest() - .createSession(username, password, null, null) - .processCreate("/bin/sh", ImmutableList.of("/tmp/" + scriptName), null, null, 5 * 1000l); - return null; - } - }); - } - - private String generateCloneName(NodeSpec nodeSpec) { - String masterNameWithoutPrefix = nodeSpec.getMaster().getMachine().getName().replace(VIRTUALBOX_IMAGE_PREFIX, ""); - return VIRTUALBOX_NODE_PREFIX + masterNameWithoutPrefix + VIRTUALBOX_NODE_NAME_SEPARATOR - + nodeSpec.getTag() + VIRTUALBOX_NODE_NAME_SEPARATOR + nodeSpec.getName(); - } - - private void deleteExistingSnapshot(Master master) { - if (master.getMachine().getCurrentSnapshot() != null) { - ISession session; - try { - session = manager.get().getSessionObject(); - master.getMachine().lockMachine(session, LockType.Write); - IProgress progress = session.getConsole().deleteSnapshot(master.getMachine().getCurrentSnapshot().getId()); - progress.waitForCompletion(-1); - session.unlockMachine(); - } catch (Exception e) { - throw new RuntimeException("error opening vbox machine session: " + e.getMessage(), e); - } - logger.debug("<< deleted an existing snapshot of vm(%s)", master.getMachine().getName()); - } - } - - private NodeMetadata buildPartialNodeMetadata(IMachine clone, String guestOsUser, String guestOsPassword) { - NodeMetadataBuilder nodeMetadataBuilder = new NodeMetadataBuilder(); - nodeMetadataBuilder.id(clone.getName()); - nodeMetadataBuilder.status(VirtualBoxComputeServiceContextModule.toPortableNodeStatus.get(clone.getState())); - nodeMetadataBuilder.publicAddresses(ImmutableSet.of(networkUtils.getValidHostOnlyIpFromVm(clone.getName()))); - nodeMetadataBuilder.credentials(LoginCredentials.builder() - .user(guestOsUser) - .password(guestOsPassword) - .authenticateSudo(true).build()); - return nodeMetadataBuilder.build(); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfaces.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfaces.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfaces.java deleted file mode 100644 index 8c076c2..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfaces.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.filter; -import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot; - -import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.regex.Pattern; - -import javax.annotation.Resource; - -import org.jclouds.compute.callables.RunScriptOnNode.Factory; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.logging.Logger; -import org.jclouds.scriptbuilder.domain.Statement; -import org.jclouds.scriptbuilder.domain.Statements; -import org.jclouds.virtualbox.domain.BridgedIf; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Splitter; -import com.google.common.base.Throwables; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.inject.Inject; -import com.google.inject.name.Named; - -public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, List<BridgedIf>> { - -@Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final Factory runScriptOnNodeFactory; - - @Inject - public RetrieveActiveBridgedInterfaces(Factory runScriptOnNodeFactory) { - this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory"); - } - - @Override - public List<BridgedIf> apply(NodeMetadata host) { - // Bridged Network - Statement command = Statements.exec("VBoxManage list bridgedifs"); - String bridgedIfBlocks = runScriptOnNodeFactory.create(host, command, runAsRoot(false).wrapInInitScript(false)) - .init().call().getOutput(); - - List<BridgedIf> bridgedInterfaces = retrieveBridgedInterfaceNames(bridgedIfBlocks); - checkNotNull(bridgedInterfaces); - - // union of bridgedNetwork with inet up and !loopback - List<BridgedIf> activeNetworkInterfaces = Lists.newArrayList(); - try { - Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces(); - for (NetworkInterface inet : Collections.list(nets)) { - Iterable<BridgedIf> filteredBridgedInterface = filter(bridgedInterfaces, new IsActiveBridgedInterface(inet)); - Iterables.addAll(activeNetworkInterfaces, filteredBridgedInterface); - } - } catch (SocketException e) { - logger.error(e, "Problem in listing network interfaces."); - throw Throwables.propagate(e); - } - return activeNetworkInterfaces; - } - - protected static List<BridgedIf> retrieveBridgedInterfaceNames(String bridgedIfBlocks) { - List<BridgedIf> bridgedInterfaces = Lists.newArrayList(); - // separate the different bridge block - for (String bridgedIfBlock : Splitter.on(Pattern.compile("(?m)^[ \t]*\r?\n")).split(bridgedIfBlocks)) { - if (!bridgedIfBlock.isEmpty()) - bridgedInterfaces.add(new BridgedIfStringToBridgedIf().apply(bridgedIfBlock)); - } - return bridgedInterfaces; - } - - private class IsActiveBridgedInterface implements Predicate<BridgedIf> { - - private NetworkInterface networkInterface; - - public IsActiveBridgedInterface(NetworkInterface networkInterface) { - this.networkInterface = networkInterface; - } - - @Override - public boolean apply(BridgedIf bridgedInterface) { - try { - return bridgedInterface.getName().startsWith(networkInterface.getDisplayName()) && - bridgedInterface.getStatus().equals("Up") && - networkInterface.isUp() && - !networkInterface.isLoopback(); - } catch (SocketException e) { - logger.error(e, "Problem in listing network interfaces."); - throw Throwables.propagate(e); - } - } - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/SendScancodes.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/SendScancodes.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/SendScancodes.java deleted file mode 100644 index e5929c6..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/SendScancodes.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - -import static com.google.common.base.Predicates.in; -import static com.google.common.collect.Iterables.any; -import static com.google.common.collect.Lists.partition; -import static org.jclouds.compute.reference.ComputeServiceConstants.COMPUTE_LOGGER; -import static org.jclouds.virtualbox.settings.KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP_LIST; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.annotation.Resource; -import javax.inject.Named; - -import org.jclouds.logging.Logger; -import org.virtualbox_4_2.ISession; - -import com.google.common.base.Function; -import com.google.common.util.concurrent.Uninterruptibles; - -class SendScancodes implements Function<ISession, Void> { - - @Resource - @Named(COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private static final int MAX_SIZE = 30; - - private final List<Integer> scancodes; - - public SendScancodes(List<Integer> scancodes) { - this.scancodes = scancodes; - } - - @Override - public Void apply(ISession iSession) { - for (List<Integer> maxOrLess : partition(scancodes, MAX_SIZE)) { - long codesSent = iSession.getConsole().getKeyboard().putScancodes(maxOrLess); - logger.debug("List of scancodes sent: ", maxOrLess); - assert codesSent == maxOrLess.size(); - if (any(maxOrLess, in(SPECIAL_KEYBOARD_BUTTON_MAP_LIST.values()))) { - // in case of special keystroke we assume more time needed than normal (page refresh) - Uninterruptibles.sleepUninterruptibly(500, TimeUnit.MILLISECONDS); - } else { - Uninterruptibles.sleepUninterruptibly(250, TimeUnit.MILLISECONDS); - } - } - return null; - } - - @Override - public String toString() { - return "sendScancodes(" + scancodes + ")"; - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/StringToKeyCode.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/StringToKeyCode.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/StringToKeyCode.java deleted file mode 100644 index 3c9af94..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/StringToKeyCode.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - -import java.util.Collection; -import java.util.List; - -import org.jclouds.virtualbox.settings.KeyboardScancodes; - -import com.google.common.base.Function; -import com.google.common.base.Splitter; -import com.google.common.collect.Lists; - -public class StringToKeyCode implements Function<String, List<Integer>> { - - @Override - public List<Integer> apply(String subsequence) { - return stringToKeycode(subsequence); - } - - private List<Integer> stringToKeycode(String s) { - if (containsSpecialCharacter(s)) { - return transformSpecialCharIntoKeycodes(s); - } else { - return transformStandardCharacterIntoKeycodes(s); - } - } - - private List<Integer> transformStandardCharacterIntoKeycodes(String s) { - List<Integer> values = Lists.newArrayList(); - for (String digit : Splitter.fixedLength(1).split(s)) { - Collection<Integer> hex = KeyboardScancodes.NORMAL_KEYBOARD_BUTTON_MAP_LIST.get(digit); - if (hex != null) - values.addAll(hex); - } - values.addAll(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP_LIST.get("<Spacebar>")); - return values; - } - - private List<Integer> transformSpecialCharIntoKeycodes(String s) { - List<Integer> values = Lists.newArrayList(); - for (String special : s.split("<")) { - Collection<Integer> value = KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP_LIST.get("<" + special); - if (value != null) - values.addAll(value); - } - return values; - } - - private boolean containsSpecialCharacter(String s) { - return s.startsWith("<"); - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttached.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttached.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttached.java deleted file mode 100644 index e7dad2b..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttached.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - -import java.util.concurrent.TimeUnit; - -import org.jclouds.logging.Logger; -import org.virtualbox_4_2.IMachine; -import org.virtualbox_4_2.IProgress; -import org.virtualbox_4_2.ISession; -import org.virtualbox_4_2.ISnapshot; -import org.virtualbox_4_2.MachineState; -import org.virtualbox_4_2.VirtualBoxManager; - -import com.google.common.base.Function; -import com.google.common.base.Supplier; -import com.google.common.base.Throwables; -import com.google.common.util.concurrent.Uninterruptibles; - -public class TakeSnapshotIfNotAlreadyAttached implements Function<IMachine, ISnapshot> { - - private Supplier<VirtualBoxManager> manager; - private String snapshotName; - private String snapshotDesc; - private Logger logger; - - public TakeSnapshotIfNotAlreadyAttached(Supplier<VirtualBoxManager> manager, String snapshotName, - String snapshotDesc, Logger logger) { - this.manager = manager; - this.snapshotName = snapshotName; - this.snapshotDesc = snapshotDesc; - this.logger = logger; - } - - @Override - public ISnapshot apply(IMachine machine) { - // Snapshot a machine - ISession session = null; - ISnapshot snap = machine.getCurrentSnapshot(); - - if (snap == null) { - try { - session = manager.get().openMachineSession(machine); - int retries = 10; - while (true) { - try { - - // running machines need to be pause before a snapshot can be taken - // due to a vbox bug see https://www.virtualbox.org/ticket/9255 - boolean paused = false; - if (machine.getState() == MachineState.Running) { - session.getConsole().pause(); - paused = true; - } - - IProgress progress = session.getConsole().takeSnapshot(snapshotName, snapshotDesc); - progress.waitForCompletion(-1); - - if (paused) { - session.getConsole().resume(); - } - - snap = machine.getCurrentSnapshot(); - logger.debug("<< snapshot(%s) with description(%s) taken from master(%s)", snapshotName, snapshotDesc, - machine.getName()); - break; - } catch (Exception e) { - if (e.getMessage().contains("VirtualBox error: The object is not ready") - || e.getMessage().contains("This machine does not have any snapshots")) { - retries--; - if (retries == 0) { - logger.error(e, - "Problem creating snapshot (too many retries) %s (description: %s) from machine %s", - snapshotName, snapshotDesc, machine.getName()); - throw Throwables.propagate(e); - } - Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); - continue; - } - logger.error(e, "Problem creating snapshot %s (description: %s) from machine %s", snapshotName, - snapshotDesc, machine.getName()); - throw Throwables.propagate(e); - } - } - } catch (Exception e) { - Throwables.propagate(e); - } finally { - if (session != null) { - manager.get().closeMachineSession(session); - } - } - - } - return snap; - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/YamlImagesFromFileConfig.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/YamlImagesFromFileConfig.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/YamlImagesFromFileConfig.java deleted file mode 100644 index 0415ad9..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/YamlImagesFromFileConfig.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.File; -import java.io.IOException; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.jclouds.util.Strings2; -import org.jclouds.virtualbox.config.VirtualBoxConstants; - -import com.google.common.base.Charsets; -import com.google.common.base.Supplier; -import com.google.common.io.Files; - -/** - * A supplier for vbox yaml config that reads a yaml whose path is stored under - * VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR. - */ -public class YamlImagesFromFileConfig implements Supplier<String> { - - private String yamlFilePath; - - @Inject - public YamlImagesFromFileConfig(@Named(VirtualBoxConstants.VIRTUALBOX_IMAGES_DESCRIPTOR) String yamlFilePath) { - this.yamlFilePath = yamlFilePath; - } - - @Override - public String get() { - try { - File yamlFile = new File(yamlFilePath); - String yamlDesc = null; - // if the yaml file does not exist just use default-images.yaml - if (!yamlFile.exists()) { - yamlDesc = Strings2.toStringAndClose(getClass().getResourceAsStream("/default-images.yaml")); - } else { - yamlDesc = Files.toString(yamlFile, Charsets.UTF_8); - } - checkNotNull(yamlDesc, "yaml descriptor"); - return yamlDesc; - } catch (IOException e) { - throw new RuntimeException("error reading yaml file"); - } - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/FileDownloadFromURI.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/FileDownloadFromURI.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/FileDownloadFromURI.java deleted file mode 100644 index f9b8a14..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/FileDownloadFromURI.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions.admin; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.util.Closeables2.closeQuietly; -import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; - -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; - -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.logging.Logger; -import org.jclouds.rest.HttpClient; - -import com.google.common.base.Function; -import com.google.common.base.Throwables; -import com.google.common.io.Files; - -public class FileDownloadFromURI implements Function<URI, File> { - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final HttpClient client; - private final String isosDir; - - @Inject - public FileDownloadFromURI(HttpClient client, @Named(VIRTUALBOX_WORKINGDIR) String workingDir) { - this.client = client; - this.isosDir = workingDir + File.separator + "isos"; - } - - @Override - public File apply(@Nullable URI input) { - final File file = new File(isosDir, new File(input.getPath()).getName()); - try { - if (!file.exists()) { - final InputStream inputStream = client.get(input); - checkNotNull(inputStream, "%s not found", input); - try { - Files.asByteSink(file).writeFrom(inputStream); - return file; - } catch (FileNotFoundException e) { - logger.error(e, "File %s could not be found", file.getPath()); - } catch (IOException e) { - logger.error(e, "Error when downloading file %s", input.toString()); - } finally { - closeQuietly(inputStream); - } - return null; - } else { - logger.debug("File %s already exists. Skipping download", file.getPath()); - return file; - } - } catch (Exception e) { - throw Throwables.propagate(e); - } - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/ImagesToYamlImagesFromYamlDescriptor.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/ImagesToYamlImagesFromYamlDescriptor.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/ImagesToYamlImagesFromYamlDescriptor.java deleted file mode 100644 index 5159f24..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/ImagesToYamlImagesFromYamlDescriptor.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions.admin; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import org.jclouds.compute.domain.Image; -import org.jclouds.virtualbox.domain.YamlImage; -import org.jclouds.virtualbox.functions.YamlImagesFromFileConfig; -import org.yaml.snakeyaml.Loader; -import org.yaml.snakeyaml.TypeDescription; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; - -import com.google.common.base.Supplier; -import com.google.common.collect.Maps; - -@Singleton -public class ImagesToYamlImagesFromYamlDescriptor implements Supplier<Map<Image, YamlImage>> { - - private String yamlDescriptor; - - @Inject - public ImagesToYamlImagesFromYamlDescriptor(YamlImagesFromFileConfig yamlDescriptorSupplier) { - this.yamlDescriptor = yamlDescriptorSupplier.get(); - checkNotNull(yamlDescriptor, "yaml descriptor"); - checkState(!yamlDescriptor.equals(""), "yaml descriptor is empty"); - } - - /** - * Type-safe config class for YAML - * - */ - public static class Config { - public List<YamlImage> images; - } - - @Override - public Map<Image, YamlImage> get() { - - Constructor constructor = new Constructor(Config.class); - - TypeDescription imageDesc = new TypeDescription(YamlImage.class); - imageDesc.putListPropertyType("images", String.class); - constructor.addTypeDescription(imageDesc); - - // Issue 855: testng is rev-locking us to snakeyaml 1.6 - // we have to use old constructor until this is fixed - Yaml yaml = new Yaml(new Loader(constructor)); - Config config = (Config) yaml.load(yamlDescriptor); - checkState(config != null, "missing config: class"); - checkState(config.images != null, "missing images: collection"); - - Map<Image, YamlImage> backingMap = Maps.newLinkedHashMap(); - for (YamlImage yamlImage : config.images) { - backingMap.put(YamlImage.toImage.apply(yamlImage), yamlImage); - } - return backingMap; - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/PreseedCfgServer.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/PreseedCfgServer.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/PreseedCfgServer.java deleted file mode 100644 index 4f5d410..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/PreseedCfgServer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions.admin; - -import java.io.IOException; -import java.net.URI; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.AbstractHandler; - -import com.google.common.base.Throwables; - -/** - * Sets up jetty so that it can serve the preseed.cfg file to automate master creation. - */ -public class PreseedCfgServer { - - private Server jetty; - - public void start(String preconfigurationUrl, final String preseedCfg) { - this.jetty = new Server(URI.create(preconfigurationUrl).getPort()); - try { - // since we're only serving the preseed.cfg file respond to all requests with it - jetty.setHandler(new AbstractHandler() { - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - response.setContentType("text/plain;charset=utf-8"); - response.setStatus(HttpServletResponse.SC_OK); - baseRequest.setHandled(true); - response.getWriter().println(preseedCfg); - } - }); - jetty.start(); - } catch (Exception e) { - throw Throwables.propagate(e); - } - } - - public void stop() { - try { - if (jetty != null) { - jetty.stop(); - } - } catch (Exception e) { - throw Throwables.propagate(e); - } - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunning.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunning.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunning.java deleted file mode 100644 index 8324838..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunning.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions.admin; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot; -import static org.jclouds.scriptbuilder.domain.Statements.exec; -import static org.jclouds.scriptbuilder.domain.Statements.findPid; -import static org.jclouds.scriptbuilder.domain.Statements.kill; - -import java.net.URI; -import java.util.List; - -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.compute.callables.RunScriptOnNode.Factory; -import org.jclouds.compute.domain.ExecResponse; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.location.Provider; -import org.jclouds.logging.Logger; -import org.jclouds.scriptbuilder.domain.Statement; -import org.jclouds.scriptbuilder.domain.StatementList; -import org.jclouds.virtualbox.functions.HardcodedHostToHostNodeMetadata; -import org.jclouds.virtualbox.predicates.RetryIfSocketNotYetOpen; -import org.virtualbox_4_2.SessionState; -import org.virtualbox_4_2.VirtualBoxManager; - -import com.google.common.base.Function; -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableList; -import com.google.common.net.HostAndPort; -import com.google.common.util.concurrent.UncheckedTimeoutException; - -@Singleton -public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager> { - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final Factory runScriptOnNodeFactory; - private final RetryIfSocketNotYetOpen socketTester; - private final Supplier<NodeMetadata> host; - private final Supplier<URI> providerSupplier; - private final Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode; - private transient VirtualBoxManager manager; - private final HardcodedHostToHostNodeMetadata hardcodedHostToHostNodeMetadata; - - // the functions and suppliers here are to ensure we don't do heavy i/o in injection - @Inject - public StartVBoxIfNotAlreadyRunning(Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode, - Factory runScriptOnNodeFactory, RetryIfSocketNotYetOpen socketTester, Supplier<NodeMetadata> host, - @Provider Supplier<URI> providerSupplier, HardcodedHostToHostNodeMetadata hardcodedHostToHostNodeMetadata) { - this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory"); - this.socketTester = checkNotNull(socketTester, "socketTester"); - this.socketTester.seconds(3L); - this.host = checkNotNull(host, "host"); - this.providerSupplier = checkNotNull(providerSupplier, "endpoint to virtualbox websrvd is needed"); - this.managerForNode = checkNotNull(managerForNode, "managerForNode"); - this.hardcodedHostToHostNodeMetadata = hardcodedHostToHostNodeMetadata; - } - - @PostConstruct - public void start() { - URI provider = providerSupplier.get(); - NodeMetadata hostNodeMetadata = hardcodedHostToHostNodeMetadata.apply(host.get()); - - if (!socketTester.apply(HostAndPort.fromParts(provider.getHost(), provider.getPort()))) { - logger.debug("disabling password access"); - runScriptOnNodeFactory - .create(hostNodeMetadata, exec("VBoxManage setproperty websrvauthlibrary null"), - runAsRoot(false).wrapInInitScript(false)).init().call(); - - logger.debug(">> starting vboxwebsrv"); - String vboxwebsrv = "vboxwebsrv -t0 -v -b -H " + providerSupplier.get().getHost(); - runScriptOnNodeFactory - .create(hostNodeMetadata, exec(vboxwebsrv), - runAsRoot(false).wrapInInitScript(false).blockOnComplete(false).nameTask("vboxwebsrv")).init() - .call(); - - if (!socketTester.apply(HostAndPort.fromParts(provider.getHost(), provider.getPort()))) { - throw new UncheckedTimeoutException(String.format("could not connect to virtualbox at %s", provider)); - } - } - - manager = managerForNode.apply(host); - manager.connect(provider.toASCIIString(), "", ""); - if (logger.isDebugEnabled()) - if (manager.getSessionObject().getState() != SessionState.Unlocked) - logger.warn("manager is not in unlocked state " + manager.getSessionObject().getState()); - - } - - public void cleanUpHost() { - // kill previously started vboxwebsrv (possibly dirty session) - URI provider = providerSupplier.get(); - NodeMetadata hostNodeMetadata = hardcodedHostToHostNodeMetadata.apply(host.get()); - List<Statement> statements = new ImmutableList.Builder<Statement>() - .add(findPid("vboxwebsrv")) - .add(kill()).build(); - StatementList statementList = new StatementList(statements); - - if (socketTester.apply(HostAndPort.fromParts(provider.getHost(), provider.getPort()))) { - logger.debug(String.format("shutting down previously started vboxwewbsrv at %s", provider)); - ExecResponse execResponse = runScriptOnNodeFactory.create(hostNodeMetadata, statementList, runAsRoot(false)) - .init().call(); - if (execResponse.getExitStatus() != 0) - throw new RuntimeException(String.format("Cannot shutdown a running vboxwebsrv at %s. ExecResponse: %s", provider, execResponse)); - } - } - - @Override - public VirtualBoxManager get() { - checkState(manager != null, "VirtualBoxManager is not initialised"); - return manager; - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMedia.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMedia.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMedia.java deleted file mode 100644 index 4437c79..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMedia.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions.admin; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.filter; -import static com.google.common.collect.Iterables.transform; - -import java.util.List; - -import javax.annotation.Resource; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.logging.Logger; -import org.jclouds.virtualbox.domain.ErrorCode; -import org.jclouds.virtualbox.domain.StorageController; -import org.jclouds.virtualbox.domain.VmSpec; -import org.virtualbox_4_2.DeviceType; -import org.virtualbox_4_2.IMachine; -import org.virtualbox_4_2.IMedium; -import org.virtualbox_4_2.IProgress; -import org.virtualbox_4_2.VBoxException; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; - -@Singleton -public class UnregisterMachineIfExistsAndDeleteItsMedia implements Function<IMachine, Void> { - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final VmSpec vmSpec; - - public UnregisterMachineIfExistsAndDeleteItsMedia(VmSpec vmSpec) { - this.vmSpec = vmSpec; - } - - @Override - public Void apply(IMachine machine) { - List<IMedium> mediaToBeDeleted = ImmutableList.of(); - try { - mediaToBeDeleted = machine.unregister(vmSpec.getCleanupMode()); - } catch (VBoxException e) { - ErrorCode errorCode = ErrorCode.valueOf(e); - switch (errorCode) { - case VBOX_E_OBJECT_NOT_FOUND: - logger.debug("Machine %s does not exists, cannot unregister", vmSpec.getVmName()); - break; - default: - throw e; - } - } - - List<IMedium> filteredMediaToBeDeleted = Lists.newArrayList(transform( - filter(mediaToBeDeleted, new AutoDeleteHardDiskPredicate(vmSpec)), new DeleteChildrenOfMedium())); - - if (!filteredMediaToBeDeleted.isEmpty()) { - try { - IProgress deletion = machine.delete(filteredMediaToBeDeleted); - deletion.waitForCompletion(-1); - } catch (Exception e) { - logger.error(e, "Problem in deleting the media attached to %s", machine.getName()); - Throwables.propagate(e); - } - } - - return null; - } - - private static class AutoDeleteHardDiskPredicate implements Predicate<IMedium> { - - private VmSpec vmSpec; - - public AutoDeleteHardDiskPredicate(VmSpec vmSpec) { - this.vmSpec = vmSpec; - } - - @Override - public boolean apply(IMedium medium) { - for (StorageController controller : vmSpec.getControllers()) { - if (controller.getHardDisk(medium.getName()).isAutoDelete()) - return true; - } - return false; - } - - }; - - private static class DeleteChildrenOfMedium implements Function<IMedium, IMedium> { - @Override - public IMedium apply(IMedium medium) { - checkNotNull(medium.getChildren()); - if (medium.getDeviceType().equals(DeviceType.HardDisk)) { - for (IMedium child : medium.getChildren()) { - IProgress deletion = child.deleteStorage(); - deletion.waitForCompletion(-1); - } - } - return medium; - } - - }; - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndForceDeleteItsMedia.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndForceDeleteItsMedia.java b/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndForceDeleteItsMedia.java deleted file mode 100644 index 487bd9e..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndForceDeleteItsMedia.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.functions.admin; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.transform; - -import java.util.List; - -import javax.annotation.Resource; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.logging.Logger; -import org.jclouds.virtualbox.domain.ErrorCode; -import org.virtualbox_4_2.CleanupMode; -import org.virtualbox_4_2.DeviceType; -import org.virtualbox_4_2.IMachine; -import org.virtualbox_4_2.IMedium; -import org.virtualbox_4_2.IProgress; -import org.virtualbox_4_2.VBoxException; - -import com.google.common.base.Function; -import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; - -@Singleton -public class UnregisterMachineIfExistsAndForceDeleteItsMedia implements Function<IMachine, Void> { - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - @Override - public Void apply(IMachine machine) { - List<IMedium> mediaToBeDeleted = ImmutableList.of(); - try { - mediaToBeDeleted = machine.unregister(CleanupMode.Full); - } catch (VBoxException e) { - ErrorCode errorCode = ErrorCode.valueOf(e); - switch (errorCode) { - case VBOX_E_OBJECT_NOT_FOUND: - logger.debug("Machine %s does not exists, cannot unregister", machine.getName()); - break; - default: - throw e; - } - } - - List<IMedium> filteredMediaToBeDeleted = Lists.newArrayList(transform(mediaToBeDeleted, - new DeleteChildrenOfMedium())); - if (!filteredMediaToBeDeleted.isEmpty()) { - try { - IProgress deletion = machine.delete(filteredMediaToBeDeleted); - deletion.waitForCompletion(100); - } catch (Exception e) { - logger.error(e, "Problem in deleting the media attached to %s", machine.getName()); - Throwables.propagate(e); - } - } - - return null; - } - - private class DeleteChildrenOfMedium implements Function<IMedium, IMedium> { - @Override - public IMedium apply(IMedium medium) { - checkNotNull(medium.getChildren()); - if (medium.getDeviceType().equals(DeviceType.HardDisk)) { - for (IMedium child : medium.getChildren()) { - try { - IProgress deletion = child.deleteStorage(); - deletion.waitForCompletion(-1); - } catch (Exception e) { - // work around media that are still attached to other vm's. this can happen when a - // running node is used to create a new image and then an attempt at deleting it - // is made - if (e.getMessage().contains("is still attached to the following")) { - logger.warn("Media could not be deleted. Ignoring... [Message %s]", e.getMessage()); - } - } - } - } - return medium; - } - - }; - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/75178c77/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/IMachinePredicates.java ---------------------------------------------------------------------- diff --git a/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/IMachinePredicates.java b/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/IMachinePredicates.java deleted file mode 100644 index 3db5121..0000000 --- a/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/IMachinePredicates.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.jclouds.virtualbox.predicates; - -import static com.google.common.base.Predicates.and; -import static com.google.common.collect.Iterables.any; -import static com.google.common.collect.Iterables.transform; -import static org.jclouds.virtualbox.predicates.IMediumPredicates.deviceTypeEquals; -import static org.jclouds.virtualbox.predicates.IMediumPredicates.hasParent; -import static org.jclouds.virtualbox.predicates.IMediumPredicates.machineIdsContain; -import static org.jclouds.virtualbox.util.IMediumAttachments.toMedium; -import static org.virtualbox_4_2.DeviceType.HardDisk; - -import org.virtualbox_4_2.IMachine; -import org.virtualbox_4_2.IMedium; - -import com.google.common.base.Predicate; - -public class IMachinePredicates { - /** - * TODO: andrea please explain - * - */ - static enum IsLinkedClone implements Predicate<IMachine> { - INSTANCE; - - @SuppressWarnings("unchecked") - @Override - public boolean apply(IMachine machine) { - Iterable<IMedium> mediumsOnMachine = transform(machine.getMediumAttachments(), toMedium()); - // TODO: previous impl walked the parent medium back to the child - // before checking machine ids. Determine if that extra walk was really - // necessary - return any(mediumsOnMachine, and(deviceTypeEquals(HardDisk), hasParent(), machineIdsContain(machine.getId()))); - } - - @Override - public String toString() { - return "isLinkedClone()"; - } - } - - public static Predicate<IMachine> isLinkedClone() { - return IsLinkedClone.INSTANCE; - } -}
