Repository: jclouds-labs Updated Branches: refs/heads/2.0.x a5a4f30b1 -> e4c809dbd
Load existing machines info on startup * Lets jclouds manage vagrant machines from previous runs. * Update README, removing fixed limitations - vagrant user no longer shared with other providers. * Remove null checks in guice managed constructors Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/e4c809db Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/e4c809db Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/e4c809db Branch: refs/heads/2.0.x Commit: e4c809dbd60eedec509610eac759b2c3400b2a9e Parents: a5a4f30 Author: Svetoslav Neykov <[email protected]> Authored: Sun Jan 29 19:13:52 2017 +0200 Committer: Ignasi Barrera <[email protected]> Committed: Wed Feb 1 12:01:44 2017 +0100 ---------------------------------------------------------------------- vagrant/README.md | 1 - .../jclouds/vagrant/api/VagrantApiFacade.java | 9 +- .../vagrant/api/VagrantBoxApiFacade.java | 28 ++++ .../compute/VagrantComputeServiceAdapter.java | 82 ++++------ .../config/PersistVagrantCredentialsModule.java | 8 +- .../VagrantComputeServiceContextModule.java | 28 +++- .../org/jclouds/vagrant/domain/VagrantNode.java | 4 + .../jclouds/vagrant/functions/BoxToImage.java | 4 +- .../functions/MachineToNodeMetadata.java | 47 +----- .../jclouds/vagrant/internal/ImageSupplier.java | 55 +++++++ .../jclouds/vagrant/internal/MachineConfig.java | 9 +- .../vagrant/internal/VagrantCliFacade.java | 18 ++- .../internal/VagrantExistingMachines.java | 155 +++++++++++++++++++ .../vagrant/internal/VagrantNodeRegistry.java | 41 ++++- .../VagrantDefaultImageCredentials.java | 5 +- .../functions/MachineToNodeMetadataTest.java | 79 +--------- .../vagrant/internal/VagrantNodeLoaderTest.java | 116 ++++++++++++++ .../internal/VagrantNodeRegistryTest.java | 12 +- 18 files changed, 489 insertions(+), 212 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/README.md ---------------------------------------------------------------------- diff --git a/vagrant/README.md b/vagrant/README.md index 3fa71a3..36194dd 100644 --- a/vagrant/README.md +++ b/vagrant/README.md @@ -119,4 +119,3 @@ Limitations ----------- * Machines are created sequentially, no support for parallel execution from virtualbox provider -* Something prevents using vagrant at the same time with other jclouds providers - they try to login with vagrant user. http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantApiFacade.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantApiFacade.java b/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantApiFacade.java index c3bccfd..d87cedb 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantApiFacade.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantApiFacade.java @@ -17,13 +17,12 @@ package org.jclouds.vagrant.api; import java.io.File; -import java.util.Collection; import org.jclouds.domain.LoginCredentials; -public interface VagrantApiFacade<B> { - interface Factory<B> { - VagrantApiFacade<B> create(File path); +public interface VagrantApiFacade { + interface Factory { + VagrantApiFacade create(File path); } /** @@ -35,8 +34,6 @@ public interface VagrantApiFacade<B> { void halt(String machineName); void destroy(String machineName); LoginCredentials sshConfig(String machineName); - Collection<B> listBoxes(); - B getBox(String boxName); void haltForced(String name); boolean exists(); } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantBoxApiFacade.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantBoxApiFacade.java b/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantBoxApiFacade.java new file mode 100644 index 0000000..90844ce --- /dev/null +++ b/vagrant/src/main/java/org/jclouds/vagrant/api/VagrantBoxApiFacade.java @@ -0,0 +1,28 @@ +/* + * 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.vagrant.api; + +import java.util.Collection; + +public interface VagrantBoxApiFacade<B> { + interface Factory<B> { + VagrantBoxApiFacade<B> create(); + } + + Collection<B> listBoxes(); + B getBox(String boxName); +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/compute/VagrantComputeServiceAdapter.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/compute/VagrantComputeServiceAdapter.java b/vagrant/src/main/java/org/jclouds/vagrant/compute/VagrantComputeServiceAdapter.java index 665504f..2f19b3e 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/compute/VagrantComputeServiceAdapter.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/compute/VagrantComputeServiceAdapter.java @@ -16,12 +16,9 @@ */ package org.jclouds.vagrant.compute; -import static com.google.common.base.Preconditions.checkNotNull; - import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -59,12 +56,11 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.base.Throwables; -import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; -public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<VagrantNode, Hardware, B, Location> { +public class VagrantComputeServiceAdapter implements ComputeServiceAdapter<VagrantNode, Hardware, Image, Location> { private static final Pattern PATTERN_IP_ADDR = Pattern.compile("inet ([0-9\\.]+)/(\\d+)"); private static final Pattern PATTERN_IPCONFIG = Pattern.compile("IPv4 Address[ .]+: ([0-9\\.]+)"); @@ -75,25 +71,28 @@ public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<Va private final JustProvider locationSupplier; private final VagrantNodeRegistry nodeRegistry; private final MachineConfig.Factory machineConfigFactory; - private final Function<Collection<B>, Collection<B>> outdatedBoxesFilter; - private final VagrantApiFacade.Factory<B> cliFactory; + private final VagrantApiFacade.Factory cliFactory; private final Supplier<? extends Map<String, Hardware>> hardwareSupplier; + private final Supplier<Collection<Image>> imageListSupplier; + private final Function<String, Image> imageIdToImage; @Inject VagrantComputeServiceAdapter(@Named(VagrantConstants.JCLOUDS_VAGRANT_HOME) String home, JustProvider locationSupplier, VagrantNodeRegistry nodeRegistry, MachineConfig.Factory machineConfigFactory, - Function<Collection<B>, Collection<B>> outdatedBoxesFilter, - VagrantApiFacade.Factory<B> cliFactory, - Supplier<? extends Map<String, Hardware>> hardwareSupplier) { - this.home = new File(checkNotNull(home, "home")); - this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier"); - this.nodeRegistry = checkNotNull(nodeRegistry, "nodeRegistry"); - this.machineConfigFactory = checkNotNull(machineConfigFactory, "machineConfigFactory"); - this.outdatedBoxesFilter = checkNotNull(outdatedBoxesFilter, "outdatedBoxesFilter"); - this.cliFactory = checkNotNull(cliFactory, "cliFactory"); - this.hardwareSupplier = checkNotNull(hardwareSupplier, "hardwareSupplier"); + VagrantApiFacade.Factory cliFactory, + Supplier<? extends Map<String, Hardware>> hardwareSupplier, + Supplier<Collection<Image>> imageListSupplier, + Function<String, Image> imageIdToImage) { + this.home = new File(home); + this.locationSupplier = locationSupplier; + this.nodeRegistry = nodeRegistry; + this.machineConfigFactory = machineConfigFactory; + this.cliFactory = cliFactory; + this.hardwareSupplier = hardwareSupplier; + this.imageListSupplier = imageListSupplier; + this.imageIdToImage = imageIdToImage; this.home.mkdirs(); } @@ -104,14 +103,15 @@ public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<Va init(nodePath, machineName, template); - NodeAndInitialCredentials<VagrantNode> node = startMachine(nodePath, group, machineName, template.getImage()); + NodeAndInitialCredentials<VagrantNode> node = startMachine(nodePath, group, machineName, + template.getImage(), template.getHardware()); nodeRegistry.add(node.getNode()); return node; } - private NodeAndInitialCredentials<VagrantNode> startMachine(File path, String group, String name, Image image) { + private NodeAndInitialCredentials<VagrantNode> startMachine(File path, String group, String name, Image image, Hardware hardware) { - VagrantApiFacade<B> vagrant = cliFactory.create(path); + VagrantApiFacade vagrant = cliFactory.create(path); String rawOutput = vagrant.up(name); String output = normalizeOutput(name, rawOutput); @@ -123,6 +123,7 @@ public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<Va .setGroup(group) .setName(name) .setImage(image) + .setHardware(hardware) .setNetworks(getNetworks(output, getOsInterfacePattern(osFamily))) .setHostname(getHostname(output)) .build(); @@ -250,14 +251,13 @@ public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<Va } @Override - public Iterable<B> listImages() { - Collection<B> allBoxes = cliFactory.create(new File(".")).listBoxes(); - return outdatedBoxesFilter.apply(allBoxes); + public Iterable<Image> listImages() { + return imageListSupplier.get(); } @Override - public B getImage(String id) { - return cliFactory.create(new File(".")).getBox(id); + public Image getImage(String id) { + return imageIdToImage.apply(id); } @Override @@ -309,14 +309,14 @@ public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<Va VagrantNode node = nodeRegistry.get(id); String name = node.name(); - VagrantApiFacade<B> vagrant = getMachine(node); + VagrantApiFacade vagrant = getMachine(node); vagrant.up(name); } private void halt(String id) { VagrantNode node = nodeRegistry.get(id); String name = node.name(); - VagrantApiFacade<B> vagrant = getMachine(node); + VagrantApiFacade vagrant = getMachine(node); try { vagrant.halt(name); @@ -330,7 +330,7 @@ public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<Va public void resumeNode(String id) { VagrantNode node = nodeRegistry.get(id); String name = node.name(); - VagrantApiFacade<B> vagrant = getMachine(node); + VagrantApiFacade vagrant = getMachine(node); vagrant.up(name); node.setMachineState(Status.RUNNING); } @@ -344,29 +344,7 @@ public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<Va @Override public Iterable<VagrantNode> listNodes() { - return FluentIterable.from(Arrays.asList(home.listFiles())) - .transformAndConcat(new Function<File, Collection<VagrantNode>>() { - @Override - public Collection<VagrantNode> apply(File input) { - File machines = new File(input, VagrantConstants.MACHINES_CONFIG_SUBFOLDER); - VagrantApiFacade<B> vagrant = cliFactory.create(input); - if (input.isDirectory() && machines.exists() && vagrant.exists()) { - Collection<VagrantNode> nodes = new ArrayList<VagrantNode>(); - for (File machine : machines.listFiles()) { - if (machine.getName().endsWith(VagrantConstants.MACHINES_CONFIG_EXTENSION)) { - String id = input.getName() + "/" + machine.getName().replace(VagrantConstants.MACHINES_CONFIG_EXTENSION, ""); - VagrantNode n = nodeRegistry.get(id); - if (n != null) { - nodes.add(n); - } - } - } - return nodes; - } else { - return ImmutableList.of(); - } - } - }); + return nodeRegistry.list(); } @Override @@ -379,7 +357,7 @@ public class VagrantComputeServiceAdapter<B> implements ComputeServiceAdapter<Va }); } - private VagrantApiFacade<B> getMachine(VagrantNode node) { + private VagrantApiFacade getMachine(VagrantNode node) { File nodePath = node.path(); return cliFactory.create(nodePath); } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/config/PersistVagrantCredentialsModule.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/config/PersistVagrantCredentialsModule.java b/vagrant/src/main/java/org/jclouds/vagrant/config/PersistVagrantCredentialsModule.java index d140b76..cd79882 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/config/PersistVagrantCredentialsModule.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/config/PersistVagrantCredentialsModule.java @@ -16,8 +16,6 @@ */ package org.jclouds.vagrant.config; -import static com.google.common.base.Preconditions.checkNotNull; - import java.io.File; import java.io.IOException; import java.util.Map; @@ -59,10 +57,10 @@ public class PersistVagrantCredentialsModule extends AbstractModule { Map<String, Credentials> credentialStore, @Nullable @Assisted Statement statement, MachineConfig.Factory machineConfigFactory) { - this.vagrantNodeRegistry = checkNotNull(vagrantNodeRegistry, "vagrantNodeRegistry"); - this.credentialStore = checkNotNull(credentialStore, "credentialStore"); + this.vagrantNodeRegistry = vagrantNodeRegistry; + this.credentialStore = credentialStore; this.statement = statement; - this.machineConfigFactory = checkNotNull(machineConfigFactory, "machineConfigFactory"); + this.machineConfigFactory = machineConfigFactory; } @Override http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/config/VagrantComputeServiceContextModule.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/config/VagrantComputeServiceContextModule.java b/vagrant/src/main/java/org/jclouds/vagrant/config/VagrantComputeServiceContextModule.java index 61f30fd..bb122e4 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/config/VagrantComputeServiceContextModule.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/config/VagrantComputeServiceContextModule.java @@ -32,12 +32,15 @@ import org.jclouds.date.TimeStamp; import org.jclouds.domain.Location; import org.jclouds.functions.IdentityFunction; import org.jclouds.vagrant.api.VagrantApiFacade; +import org.jclouds.vagrant.api.VagrantBoxApiFacade; import org.jclouds.vagrant.compute.VagrantComputeServiceAdapter; import org.jclouds.vagrant.domain.VagrantNode; import org.jclouds.vagrant.functions.BoxToImage; import org.jclouds.vagrant.functions.MachineToNodeMetadata; import org.jclouds.vagrant.functions.OutdatedBoxesFilter; +import org.jclouds.vagrant.internal.ImageSupplier; import org.jclouds.vagrant.internal.VagrantCliFacade; +import org.jclouds.vagrant.internal.VagrantExistingMachines; import org.jclouds.vagrant.internal.VagrantWireLogger; import org.jclouds.vagrant.strategy.VagrantDefaultImageCredentials; import org.jclouds.vagrant.suppliers.VagrantHardwareSupplier; @@ -53,28 +56,39 @@ import com.google.inject.assistedinject.FactoryModuleBuilder; import vagrant.api.CommandIOListener; import vagrant.api.domain.Box; -public class VagrantComputeServiceContextModule extends ComputeServiceAdapterContextModule<VagrantNode, Hardware, Box, Location> { +public class VagrantComputeServiceContextModule extends ComputeServiceAdapterContextModule<VagrantNode, Hardware, Image, Location> { @Override protected void configure() { super.configure(); - bind(new TypeLiteral<ComputeServiceAdapter<VagrantNode, Hardware, Box, Location>>() { - }).to(new TypeLiteral<VagrantComputeServiceAdapter<Box>>() {}); + bind(new TypeLiteral<ComputeServiceAdapter<VagrantNode, Hardware, Image, Location>>() { + }).to(VagrantComputeServiceAdapter.class); bind(new TypeLiteral<Function<VagrantNode, NodeMetadata>>() { }).to(MachineToNodeMetadata.class); bind(new TypeLiteral<Function<Box, Image>>() { }).to(BoxToImage.class); bind(new TypeLiteral<Supplier<? extends Map<String, Hardware>>>() { }).to(VagrantHardwareSupplier.class).in(Singleton.class); + bind(new TypeLiteral<Function<Collection<Box>, Collection<Box>>>() { + }).to(OutdatedBoxesFilter.class); bind(new TypeLiteral<Function<Hardware, Hardware>>() { }).to(this.<Hardware>castIdentityFunction()); bind(new TypeLiteral<Function<Location, Location>>() { }).to(this.<Location>castIdentityFunction()); - bind(new TypeLiteral<Function<Collection<Box>, Collection<Box>>>() { - }).to(OutdatedBoxesFilter.class); + bind(new TypeLiteral<Function<Image, Image>>() { + }).to(this.<Image>castIdentityFunction()); + bind(new TypeLiteral<Supplier<Collection<Image>>>() { + }).to(new TypeLiteral<ImageSupplier<Box>>() {}); + bind(new TypeLiteral<Function<String, Image>>() { + }).to(new TypeLiteral<ImageSupplier<Box>>() {}); + bind(new TypeLiteral<Supplier<Collection<VagrantNode>>>() { + }).to(VagrantExistingMachines.class); + install(new FactoryModuleBuilder() + .implement(VagrantApiFacade.class, VagrantCliFacade.class) + .build(VagrantApiFacade.Factory.class)); install(new FactoryModuleBuilder() - .implement(new TypeLiteral<VagrantApiFacade<Box>>() {}, VagrantCliFacade.class) - .build(new TypeLiteral<VagrantApiFacade.Factory<Box>>() {})); + .implement(new TypeLiteral<VagrantBoxApiFacade<Box>>() {}, VagrantCliFacade.class) + .build(new TypeLiteral<VagrantBoxApiFacade.Factory<Box>>() {})); bind(PopulateDefaultLoginCredentialsForImageStrategy.class).to(VagrantDefaultImageCredentials.class); bind(TemplateBuilderImpl.class).to(ArbitraryCpuRamTemplateBuilderImpl.class); bind(CommandIOListener.class).to(VagrantWireLogger.class).in(Singleton.class); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/domain/VagrantNode.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/domain/VagrantNode.java b/vagrant/src/main/java/org/jclouds/vagrant/domain/VagrantNode.java index cfb02ca..66ef095 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/domain/VagrantNode.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/domain/VagrantNode.java @@ -19,6 +19,7 @@ package org.jclouds.vagrant.domain; import java.io.File; import java.util.Collection; +import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata.Status; @@ -39,6 +40,8 @@ public abstract class VagrantNode { public abstract Image image(); + public abstract Hardware hardware(); + public abstract Collection<String> networks(); public abstract String hostname(); @@ -54,6 +57,7 @@ public abstract class VagrantNode { public abstract Builder setGroup(String group); public abstract Builder setName(String name); public abstract Builder setImage(Image image); + public abstract Builder setHardware(Hardware hardware); public abstract Builder setNetworks(Collection<String> networks); public abstract Builder setHostname(String hostname); public abstract VagrantNode build(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/functions/BoxToImage.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/functions/BoxToImage.java b/vagrant/src/main/java/org/jclouds/vagrant/functions/BoxToImage.java index 1fd77fa..bf0f155 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/functions/BoxToImage.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/functions/BoxToImage.java @@ -16,8 +16,6 @@ */ package org.jclouds.vagrant.functions; -import static com.google.common.base.Preconditions.checkNotNull; - import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image.Status; import org.jclouds.compute.domain.ImageBuilder; @@ -38,7 +36,7 @@ public class BoxToImage implements Function<Box, Image> { @Inject BoxToImage(BoxConfig.Factory boxConfigFactory) { - this.boxConfigFactory = checkNotNull(boxConfigFactory, "boxConfigFactory"); + this.boxConfigFactory = boxConfigFactory; } @Override http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/functions/MachineToNodeMetadata.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/functions/MachineToNodeMetadata.java b/vagrant/src/main/java/org/jclouds/vagrant/functions/MachineToNodeMetadata.java index 298b7cc..755bc50 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/functions/MachineToNodeMetadata.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/functions/MachineToNodeMetadata.java @@ -16,28 +16,19 @@ */ package org.jclouds.vagrant.functions; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; import java.util.Set; import org.jclouds.collect.Memoized; -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.HardwareBuilder; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Processor; -import org.jclouds.compute.util.AutomaticHardwareIdSpec; import org.jclouds.domain.Location; import org.jclouds.vagrant.domain.VagrantNode; import org.jclouds.vagrant.internal.BoxConfig; -import org.jclouds.vagrant.internal.MachineConfig; import org.jclouds.vagrant.reference.VagrantConstants; import com.google.common.base.Function; -import com.google.common.base.Optional; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -46,19 +37,13 @@ import com.google.inject.Inject; public class MachineToNodeMetadata implements Function<VagrantNode, NodeMetadata> { private final Location location; private final BoxConfig.Factory boxConfigFactory; - private final MachineConfig.Factory machineConfigFactory; - private final Supplier<? extends Map<String, Hardware>> hardwareSupplier; @Inject MachineToNodeMetadata( @Memoized Supplier<Set<? extends Location>> locations, - BoxConfig.Factory boxConfigFactory, - MachineConfig.Factory machineConfigFactory, - Supplier<? extends Map<String, Hardware>> hardwareSupplier) { - this.location = Iterables.getOnlyElement(checkNotNull(locations, "locations").get()); - this.boxConfigFactory = checkNotNull(boxConfigFactory, "boxConfigFactory"); - this.machineConfigFactory = checkNotNull(machineConfigFactory, "machineConfigFactory"); - this.hardwareSupplier = checkNotNull(hardwareSupplier, "hardwareSupplier"); + BoxConfig.Factory boxConfigFactory) { + this.location = Iterables.getOnlyElement(locations.get()); + this.boxConfigFactory = boxConfigFactory; } @Override @@ -69,7 +54,7 @@ public class MachineToNodeMetadata implements Function<VagrantNode, NodeMetadata .group(node.group()) .imageId(node.image().getId()) .location(location) - .hardware(getHardware(node)) + .hardware(node.hardware()) .operatingSystem(node.image().getOperatingSystem()) .hostname(node.name()) .status(node.machineState()) @@ -82,30 +67,6 @@ public class MachineToNodeMetadata implements Function<VagrantNode, NodeMetadata return nodeMetadataBuilder.build(); } - private Hardware getHardware(VagrantNode node) { - MachineConfig machineConfig = machineConfigFactory.newInstance(node); - - Map<String, Object> config = machineConfig.load(); - String hardwareId = config.get(VagrantConstants.CONFIG_HARDWARE_ID).toString(); - if (hardwareId.equals(VagrantConstants.MACHINES_AUTO_HARDWARE)) { - double cpus = Double.parseDouble(config.get(VagrantConstants.CONFIG_CPUS).toString()); - int memory = Integer.parseInt(config.get(VagrantConstants.CONFIG_MEMORY).toString()); - AutomaticHardwareIdSpec hardwareSpec = AutomaticHardwareIdSpec.automaticHardwareIdSpecBuilder(cpus, memory, Optional.<Float>absent()); - return new HardwareBuilder() - .id(hardwareSpec.toString()) - .providerId(hardwareSpec.toString()) - .processor(new Processor(cpus, 1.0)) - .ram(memory) - .build(); - } else { - Hardware hardware = hardwareSupplier.get().get(hardwareId); - if (hardware == null) { - throw new IllegalStateException("Unsupported hardwareId " + hardwareId + " for machine " + node.id()); - } - return hardware; - } - } - private int getLoginPort(Image image) { BoxConfig config = boxConfigFactory.newInstance(image); String port; http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/internal/ImageSupplier.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/internal/ImageSupplier.java b/vagrant/src/main/java/org/jclouds/vagrant/internal/ImageSupplier.java new file mode 100644 index 0000000..fc1c823 --- /dev/null +++ b/vagrant/src/main/java/org/jclouds/vagrant/internal/ImageSupplier.java @@ -0,0 +1,55 @@ +/* + * 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.vagrant.internal; + +import java.util.Collection; + +import org.jclouds.compute.domain.Image; +import org.jclouds.vagrant.api.VagrantBoxApiFacade; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.collect.Collections2; +import com.google.inject.Inject; + +public class ImageSupplier<B> implements Supplier<Collection<Image>>, Function<String, Image> { + private final Function<Collection<B>, Collection<B>> outdatedBoxesFilter; + private final VagrantBoxApiFacade.Factory<B> cliFactory; + private final Function<B, Image> boxToImage; + + @Inject + ImageSupplier(Function<Collection<B>, Collection<B>> outdatedBoxesFilter, + VagrantBoxApiFacade.Factory<B> cliFactory, + Function<B, Image> boxToImage) { + this.outdatedBoxesFilter = outdatedBoxesFilter; + this.cliFactory = cliFactory; + this.boxToImage = boxToImage; + } + + @Override + public Collection<Image> get() { + Collection<B> boxes = outdatedBoxesFilter.apply(cliFactory.create().listBoxes()); + return Collections2.transform(boxes, boxToImage); + } + + @Override + public Image apply(String id) { + B box = cliFactory.create().getBox(id); + return boxToImage.apply(box); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/internal/MachineConfig.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/internal/MachineConfig.java b/vagrant/src/main/java/org/jclouds/vagrant/internal/MachineConfig.java index 8f23d87..fdf9c02 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/internal/MachineConfig.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/internal/MachineConfig.java @@ -41,8 +41,8 @@ import com.google.common.collect.Maps; public class MachineConfig { public static class Factory { - public MachineConfig newInstance(File path, String name) { - return new MachineConfig(path, name); + public MachineConfig newInstance(File group, String machineName) { + return new MachineConfig(group, machineName); } public MachineConfig newInstance(VagrantNode node) { @@ -52,8 +52,9 @@ public class MachineConfig { private File configPath; - protected MachineConfig(File path, String name) { - this.configPath = new File(new File(path, VagrantConstants.MACHINES_CONFIG_SUBFOLDER), name + ".yaml"); + protected MachineConfig(File group, String machineName) { + this.configPath = new File(new File(group, VagrantConstants.MACHINES_CONFIG_SUBFOLDER), + machineName + VagrantConstants.MACHINES_CONFIG_EXTENSION); } public Map<String, Object> load() { http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantCliFacade.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantCliFacade.java b/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantCliFacade.java index 26d592f..8c32e43 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantCliFacade.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantCliFacade.java @@ -16,22 +16,20 @@ */ package org.jclouds.vagrant.internal; -import static com.google.common.base.Preconditions.checkNotNull; - import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.Collection; -import javax.inject.Inject; - import org.jclouds.domain.LoginCredentials; import org.jclouds.vagrant.api.VagrantApiFacade; +import org.jclouds.vagrant.api.VagrantBoxApiFacade; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.io.Files; import com.google.inject.assistedinject.Assisted; +import com.google.inject.assistedinject.AssistedInject; import vagrant.Vagrant; import vagrant.api.CommandIOListener; @@ -39,16 +37,22 @@ import vagrant.api.VagrantApi; import vagrant.api.domain.Box; import vagrant.api.domain.SshConfig; -public class VagrantCliFacade implements VagrantApiFacade<Box> { +public class VagrantCliFacade implements VagrantApiFacade, VagrantBoxApiFacade<Box> { private final VagrantApi vagrant; private final VagrantOutputRecorder outputRecorder; - @Inject + @AssistedInject VagrantCliFacade(CommandIOListener wireLogger, @Assisted File path) { - this.outputRecorder = new VagrantOutputRecorder(checkNotNull(wireLogger, "wireLogger")); + this.outputRecorder = new VagrantOutputRecorder(wireLogger); this.vagrant = Vagrant.forPath(path, outputRecorder); } + @AssistedInject + VagrantCliFacade(CommandIOListener wireLogger) { + this.outputRecorder = new VagrantOutputRecorder(wireLogger); + this.vagrant = Vagrant.forPath(new File("."), outputRecorder); + } + @Override public String up(String machineName) { outputRecorder.record(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantExistingMachines.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantExistingMachines.java b/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantExistingMachines.java new file mode 100644 index 0000000..d8c9604 --- /dev/null +++ b/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantExistingMachines.java @@ -0,0 +1,155 @@ +/* + * 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.vagrant.internal; + +import java.io.File; +import java.util.Collection; +import java.util.Map; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; + +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.NodeMetadata.Status; +import org.jclouds.compute.util.AutomaticHardwareIdSpec; +import org.jclouds.logging.Logger; +import org.jclouds.vagrant.domain.VagrantNode; +import org.jclouds.vagrant.reference.VagrantConstants; + +import com.google.common.base.Optional; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +public class VagrantExistingMachines implements Supplier<Collection<VagrantNode>> { + @Resource + protected Logger logger = Logger.NULL; + + private final File home; + private final MachineConfig.Factory machineConfigFactory; + private final Supplier<Collection<Image>> imageLister; + private final Supplier<? extends Map<String, Hardware>> hardwareSupplier; + + @Inject + VagrantExistingMachines(@Named(VagrantConstants.JCLOUDS_VAGRANT_HOME) String home, + MachineConfig.Factory machineConfigFactory, + Supplier<Collection<Image>> imageLister, + Supplier<? extends Map<String, Hardware>> hardwareSupplier) { + this.home = new File(home); + this.machineConfigFactory = machineConfigFactory; + this.imageLister = imageLister; + this.hardwareSupplier = hardwareSupplier; + } + + @Override + public Collection<VagrantNode> get() { + File[] groups = home.listFiles(); + if (groups == null) return ImmutableList.of(); + Map<String, Image> images = getImages(); + Collection<VagrantNode> nodes = Lists.newArrayList(); + for (File group : groups) { + File[] machines = new File(group, VagrantConstants.MACHINES_CONFIG_SUBFOLDER).listFiles(); + if (machines == null) continue; + for (File machine : machines) { + if (machine.getName().endsWith(VagrantConstants.MACHINES_CONFIG_EXTENSION)) { + try { + VagrantNode node = createMachine(group, machine, images); + if (node != null) { + nodes.add(node); + } + } catch (RuntimeException e) { + // Skip image, something is broken about it. + // Most probable cause is that another process just deleted it. + logger.debug("Failed loading machine " + machine.getAbsolutePath() + ". Skipping.", e); + } + } + } + } + return nodes; + } + + private Map<String, Image> getImages() { + Collection<Image> images = imageLister.get(); + Map<String, Image> imageMap = Maps.newHashMap(); + for (Image image : images) { + imageMap.put(image.getId(), image); + } + return imageMap; + } + + // Build minimum viable VagrantNode. Just enough to allow users to halt the machine. + // If this is found to be inadequate need to keep the missing information in the config + // file as we can't always fetch it at this point (machine is halted or Windows). + private VagrantNode createMachine(File group, File machine, Map<String, Image> images) { + String machineName = machine.getName().replace(VagrantConstants.MACHINES_CONFIG_EXTENSION, ""); + String id = group.getName() + "/" + machineName; + Map<String, Object> config = machineConfigFactory.newInstance(group, machineName).load(); + String imageName = (String) config.get(VagrantConstants.CONFIG_BOX); + Image image = images.get(imageName); + if (image == null) { + // Machine is unusable if its image is not available, can't be running or started. + logger.debug("Skipping machine " + machine.getAbsolutePath() + + " because image " + imageName + " no longer available."); + return null; + } + Hardware hardware = getHardware(id, config); + // We've got the latest image. Depending on whether the machine is running + // or halted it could be using an older image or switch to the latest on UP correspondingly. + // Ubuntu for example will change passwords between image versions so we might need to fix + // the image version used in future, so it doesn't change and we know which one is used. + VagrantNode node = VagrantNode.builder() + .setPath(group) + .setId(id) + .setGroup(group.getName()) + .setName(machineName) + .setImage(image) + .setHardware(hardware) + .setNetworks(ImmutableList.<String>of()) + .setHostname("unknown") + .build(); + // Don't bother asking Vagrant for the status as it could take quite a while for all the running machines + node.setMachineState(Status.UNRECOGNIZED); + return node; + } + + private Hardware getHardware(String id, Map<String, ?> config) { + String hardwareId = config.get(VagrantConstants.CONFIG_HARDWARE_ID).toString(); + if (hardwareId.equals(VagrantConstants.MACHINES_AUTO_HARDWARE)) { + double cpus = Double.parseDouble(config.get(VagrantConstants.CONFIG_CPUS).toString()); + int memory = Integer.parseInt(config.get(VagrantConstants.CONFIG_MEMORY).toString()); + AutomaticHardwareIdSpec hardwareSpec = AutomaticHardwareIdSpec.automaticHardwareIdSpecBuilder(cpus, memory, Optional.<Float>absent()); + return new HardwareBuilder() + .id(hardwareSpec.toString()) + .providerId(hardwareSpec.toString()) + .processor(new Processor(cpus, 1.0)) + .ram(memory) + .build(); + } else { + Hardware hardware = hardwareSupplier.get().get(hardwareId); + if (hardware == null) { + throw new IllegalStateException("Unsupported hardwareId " + hardwareId + " for machine " + id); + } + return hardware; + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantNodeRegistry.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantNodeRegistry.java b/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantNodeRegistry.java index e4121fd..8355b2d 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantNodeRegistry.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/internal/VagrantNodeRegistry.java @@ -16,6 +16,7 @@ */ package org.jclouds.vagrant.internal; +import java.util.Collection; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.DelayQueue; @@ -26,6 +27,7 @@ import org.jclouds.date.TimeStamp; import org.jclouds.vagrant.domain.VagrantNode; import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -34,6 +36,24 @@ public class VagrantNodeRegistry { private static final long TERMINATED_NODES_EXPIRY_MS = TimeUnit.MINUTES.toMillis(5); private static final long VACUUM_PERIOD_MS = TimeUnit.SECONDS.toMillis(15); + private static class ConcurrentWrapperSupplier implements Supplier<Map<String, VagrantNode>> { + private Supplier<Collection<VagrantNode>> existingMachines; + + public ConcurrentWrapperSupplier(Supplier<Collection<VagrantNode>> existingMachines) { + this.existingMachines = existingMachines; + } + + @Override + public Map<String, VagrantNode> get() { + Map<String, VagrantNode> nodes = new ConcurrentHashMap<String, VagrantNode>(); + for (VagrantNode node : existingMachines.get()) { + nodes.put(node.id(), node); + } + return nodes; + } + + } + private static class TerminatedNode implements Delayed { Supplier<Long> timeSupplier; long expiryTime; @@ -73,21 +93,22 @@ public class VagrantNodeRegistry { return unit.convert(expiryTime - timeSupplier.get(), TimeUnit.MILLISECONDS); } } - private Map<String, VagrantNode> nodes = new ConcurrentHashMap<String, VagrantNode>(); - private DelayQueue<TerminatedNode> terminatedNodes = new DelayQueue<TerminatedNode>(); + + private final DelayQueue<TerminatedNode> terminatedNodes = new DelayQueue<TerminatedNode>(); + private final Supplier<Map<String, VagrantNode>> nodes; private volatile long lastVacuumMs; - private Supplier<Long> timeSupplier; + private final Supplier<Long> timeSupplier; @Inject - VagrantNodeRegistry(@TimeStamp Supplier<Long> timeSupplier) { + VagrantNodeRegistry(@TimeStamp Supplier<Long> timeSupplier, Supplier<Collection<VagrantNode>> existingMachines) { this.timeSupplier = timeSupplier; + this.nodes = Suppliers.memoize(new ConcurrentWrapperSupplier(existingMachines)); } - public VagrantNode get(String id) { vacuum(); - return nodes.get(id); + return nodes.get().get(id); } protected void vacuum() { @@ -95,14 +116,18 @@ public class VagrantNodeRegistry { if (timeSupplier.get() - lastVacuumMs > VACUUM_PERIOD_MS) { TerminatedNode terminated; while ((terminated = terminatedNodes.poll()) != null) { - nodes.remove(terminated.node.id()); + nodes.get().remove(terminated.node.id()); } lastVacuumMs = timeSupplier.get(); } } public void add(VagrantNode node) { - nodes.put(node.id(), node); + nodes.get().put(node.id(), node); + } + + public Collection<VagrantNode> list() { + return nodes.get().values(); } public void onTerminated(VagrantNode node) { http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/main/java/org/jclouds/vagrant/strategy/VagrantDefaultImageCredentials.java ---------------------------------------------------------------------- diff --git a/vagrant/src/main/java/org/jclouds/vagrant/strategy/VagrantDefaultImageCredentials.java b/vagrant/src/main/java/org/jclouds/vagrant/strategy/VagrantDefaultImageCredentials.java index 97667cf..fa2f2bb 100644 --- a/vagrant/src/main/java/org/jclouds/vagrant/strategy/VagrantDefaultImageCredentials.java +++ b/vagrant/src/main/java/org/jclouds/vagrant/strategy/VagrantDefaultImageCredentials.java @@ -16,7 +16,6 @@ */ package org.jclouds.vagrant.strategy; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import java.io.File; @@ -59,8 +58,8 @@ public class VagrantDefaultImageCredentials implements PopulateDefaultLoginCrede Map<String, Credentials> credentialStore, BoxConfig.Factory boxConfigFactory) { this.creds = creds; - this.credentialStore = checkNotNull(credentialStore, "credentialStore"); - this.boxConfigFactory = checkNotNull(boxConfigFactory, "boxConfigFactory"); + this.credentialStore = credentialStore; + this.boxConfigFactory = boxConfigFactory; } @Override http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/test/java/org/jclouds/vagrant/functions/MachineToNodeMetadataTest.java ---------------------------------------------------------------------- diff --git a/vagrant/src/test/java/org/jclouds/vagrant/functions/MachineToNodeMetadataTest.java b/vagrant/src/test/java/org/jclouds/vagrant/functions/MachineToNodeMetadataTest.java index 7f5f5f2..ea02d22 100644 --- a/vagrant/src/test/java/org/jclouds/vagrant/functions/MachineToNodeMetadataTest.java +++ b/vagrant/src/test/java/org/jclouds/vagrant/functions/MachineToNodeMetadataTest.java @@ -19,7 +19,6 @@ package org.jclouds.vagrant.functions; import static org.testng.Assert.assertEquals; import java.io.File; -import java.util.Map; import java.util.Set; import org.easymock.EasyMock; @@ -36,7 +35,6 @@ import org.jclouds.compute.domain.Processor; import org.jclouds.domain.Location; import org.jclouds.vagrant.domain.VagrantNode; import org.jclouds.vagrant.internal.BoxConfig; -import org.jclouds.vagrant.internal.MachineConfig; import org.jclouds.vagrant.reference.VagrantConstants; import org.testng.annotations.Test; @@ -44,7 +42,6 @@ import com.google.common.base.Optional; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import vagrant.api.domain.Box; @@ -59,14 +56,16 @@ public class MachineToNodeMetadataTest { .operatingSystem(os) .status(org.jclouds.compute.domain.Image.Status.AVAILABLE) .build(); - + Hardware hardware = new HardwareBuilder().ids("mini").ram(100).processor(new Processor(1.0, 1)).build(); ImmutableList<String> networks = ImmutableList.of("172.28.128.3"); + VagrantNode node = VagrantNode.builder() .setPath(new File("/path/to/machine")) .setId("vagrant/node") .setGroup("vagrant") .setName("node") .setImage(image) + .setHardware(hardware) .setNetworks(networks) .setHostname("vagrant-node") .build(); @@ -81,26 +80,14 @@ public class MachineToNodeMetadataTest { BoxConfig.Factory boxConfigFactory = EasyMock.createMock(BoxConfig.Factory.class); EasyMock.expect(boxConfigFactory.newInstance((Image)EasyMock.<Box>anyObject())).andReturn(boxConfig); - MachineConfig machineConfig = EasyMock.createMock(MachineConfig.class); - EasyMock.expect(machineConfig.load()).andReturn(getMachineConfig()); - - MachineConfig.Factory machineConfigFactory = EasyMock.createMock(MachineConfig.Factory.class); - EasyMock.expect(machineConfigFactory.newInstance(node)).andReturn(machineConfig); - - Hardware hardware = new HardwareBuilder().ids(getHardwareId()).ram(100).processor(new Processor(1.0, 1)).build(); - Supplier<? extends Map<String, Hardware>> hardwareSupplier = Suppliers.ofInstance(ImmutableMap.of(getHardwareId(), hardware)); - - EasyMock.replay(location, boxConfig, boxConfigFactory, - machineConfig, machineConfigFactory); + EasyMock.replay(location, boxConfig, boxConfigFactory); @SuppressWarnings({ "unchecked", "rawtypes" }) Supplier<Set<? extends Location>> locations = (Supplier<Set<? extends Location>>)(Supplier)Suppliers.ofInstance(ImmutableSet.of(location)); MachineToNodeMetadata machineToNodeMetadata = new MachineToNodeMetadata( locations, - boxConfigFactory, - machineConfigFactory, - hardwareSupplier); + boxConfigFactory); NodeMetadata nodeMetadataActual = machineToNodeMetadata.apply(node); @@ -122,12 +109,7 @@ public class MachineToNodeMetadataTest { assertEquals(nodeMetadataActual.toString(), nodeMetadataExpected.toString()); } - protected Map<String, Object> getMachineConfig() { - return ImmutableMap.<String, Object>of(VagrantConstants.CONFIG_HARDWARE_ID, getHardwareId()); - } - protected abstract void customizeBuilder(NodeMetadataBuilder nodeMetadataBuilder); - protected abstract String getHardwareId(); protected abstract OsFamily getOsFamily(); protected abstract void expectBoxConfig(BoxConfig boxConfig); } @@ -139,10 +121,6 @@ public class MachineToNodeMetadataTest { nodeMetadataBuilder.loginPort(2222); } - protected String getHardwareId() { - return "mini"; - } - protected OsFamily getOsFamily() { return OsFamily.LINUX; } @@ -169,10 +147,6 @@ public class MachineToNodeMetadataTest { protected void customizeBuilder(NodeMetadataBuilder nodeMetadataBuilder) { nodeMetadataBuilder.loginPort(22); } - - protected String getHardwareId() { - return "mini"; - } } new MachineToNodeMetadataLinuxMini().doTest(); } @@ -189,25 +163,9 @@ public class MachineToNodeMetadataTest { } protected void customizeBuilder(NodeMetadataBuilder nodeMetadataBuilder) { - nodeMetadataBuilder.loginPort(2222) - .hardware(new HardwareBuilder() - .ids("automatic:cores=2.0;ram=1000") - .processor(new Processor(2.0, 1)) - .ram(1000) - .build()); - } - - @Override - protected Map<String, Object> getMachineConfig() { - return ImmutableMap.<String, Object>of( - VagrantConstants.CONFIG_HARDWARE_ID, getHardwareId(), - VagrantConstants.CONFIG_CPUS, "2.0", - VagrantConstants.CONFIG_MEMORY, "1000"); + nodeMetadataBuilder.loginPort(2222); } - protected String getHardwareId() { - return "automatic"; - } } new MachineToNodeMetadataLinuxMini().doTest(); } @@ -219,10 +177,6 @@ public class MachineToNodeMetadataTest { nodeMetadataBuilder.loginPort(8899); } - protected String getHardwareId() { - return "mini"; - } - protected OsFamily getOsFamily() { return OsFamily.WINDOWS; } @@ -250,9 +204,6 @@ public class MachineToNodeMetadataTest { nodeMetadataBuilder.loginPort(5985); } - protected String getHardwareId() { - return "mini"; - } } new MachineToNodeMetadataLinuxMini().doTest(); } @@ -269,25 +220,9 @@ public class MachineToNodeMetadataTest { } protected void customizeBuilder(NodeMetadataBuilder nodeMetadataBuilder) { - nodeMetadataBuilder.loginPort(8899) - .hardware(new HardwareBuilder() - .ids("automatic:cores=2.0;ram=1000") - .processor(new Processor(2.0, 1)) - .ram(1000) - .build()); - } - - @Override - protected Map<String, Object> getMachineConfig() { - return ImmutableMap.<String, Object>of( - VagrantConstants.CONFIG_HARDWARE_ID, getHardwareId(), - VagrantConstants.CONFIG_CPUS, "2.0", - VagrantConstants.CONFIG_MEMORY, "1000"); + nodeMetadataBuilder.loginPort(8899); } - protected String getHardwareId() { - return "automatic"; - } } new MachineToNodeMetadataLinuxMini().doTest(); } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeLoaderTest.java ---------------------------------------------------------------------- diff --git a/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeLoaderTest.java b/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeLoaderTest.java new file mode 100644 index 0000000..2eeed6a --- /dev/null +++ b/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeLoaderTest.java @@ -0,0 +1,116 @@ +/* + * 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.vagrant.internal; + +import static org.testng.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Map; + +import org.easymock.EasyMock; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.Processor; +import org.jclouds.vagrant.domain.VagrantNode; +import org.jclouds.vagrant.reference.VagrantConstants; +import org.jclouds.vagrant.util.VagrantUtils; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.io.Files; + +public class VagrantNodeLoaderTest { + @Test + public void testAutoMachine() throws Exception { + ImmutableMap<String, Object> hardwareConfig = ImmutableMap.<String, Object>of( + VagrantConstants.CONFIG_HARDWARE_ID, VagrantConstants.MACHINES_AUTO_HARDWARE, + VagrantConstants.CONFIG_CPUS, "2", + VagrantConstants.CONFIG_MEMORY, "1024"); + Hardware expectedHardware = new HardwareBuilder().ids("automatic:cores=2.0;ram=1024").ram(1024).processor(new Processor(2.0, 1)).build(); + + doTest(hardwareConfig, expectedHardware); + } + + @Test + public void testSmallMachine() throws Exception { + ImmutableMap<String, Object> hardwareConfig = ImmutableMap.<String, Object>of( + VagrantConstants.CONFIG_HARDWARE_ID, "small"); + Hardware expectedHardware = new HardwareBuilder().ids("small").ram(1024).processor(new Processor(1.0, 1)).build(); + + doTest(hardwareConfig, expectedHardware); + } + + protected void doTest(ImmutableMap<String, Object> hardwareConfig, Hardware expectedHardware) throws IOException { + String groupName = "groupId"; + String machineName = "machineId"; + + File home = Files.createTempDir(); + File group = new File(home, groupName); + File machines = new File(group, VagrantConstants.MACHINES_CONFIG_SUBFOLDER); + machines.mkdirs(); + File machine = new File(machines, machineName + VagrantConstants.MACHINES_CONFIG_EXTENSION); + Files.write("dummy", machine, Charsets.UTF_8); + + MachineConfig config = EasyMock.createMock(MachineConfig.class); + String imageId = "centos/7"; + EasyMock.expect(config.load()).andReturn(ImmutableMap.<String, Object>builder() + .put(VagrantConstants.CONFIG_BOX, imageId) + .putAll(hardwareConfig) + .build()); + MachineConfig.Factory factory = EasyMock.createMock(MachineConfig.Factory.class); + EasyMock.expect(factory.newInstance(group, machineName)).andReturn(config); + + Image image = EasyMock.createMock(Image.class); + EasyMock.expect(image.getId()).andReturn(imageId); + + @SuppressWarnings("unchecked") + Supplier<Collection<Image>> imageSupplier = EasyMock.createMock(Supplier.class); + EasyMock.expect(imageSupplier.get()).andReturn(ImmutableList.<Image>of(image)); + + @SuppressWarnings("unchecked") + Supplier<Map<String, Hardware>> hardwareSupplier = EasyMock.createMock(Supplier.class); + EasyMock.expect(hardwareSupplier.get()).andReturn(ImmutableMap.<String, Hardware>of( + "small", new HardwareBuilder().ids("small").ram(1024).processor(new Processor(1.0, 1)).build())); + + EasyMock.replay(config, factory, imageSupplier, image, hardwareSupplier); + + VagrantExistingMachines nodeLoader = new VagrantExistingMachines(home.getAbsolutePath(), factory, imageSupplier, hardwareSupplier); + Collection<VagrantNode> nodes = nodeLoader.get(); + + VagrantNode actualNode = Iterables.getOnlyElement(nodes); + VagrantNode expectedNode = VagrantNode.builder() + .setPath(group) + .setId(group.getName() + "/" + machineName) + .setGroup(group.getName()) + .setName(machineName) + .setImage(image) + .setHardware(expectedHardware) + .setNetworks(ImmutableList.<String>of()) + .setHostname("unknown") + .build(); + assertEquals(actualNode, expectedNode); + VagrantUtils.deleteFolder(home); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/e4c809db/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeRegistryTest.java ---------------------------------------------------------------------- diff --git a/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeRegistryTest.java b/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeRegistryTest.java index fb4950c..4ad492a 100644 --- a/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeRegistryTest.java +++ b/vagrant/src/test/java/org/jclouds/vagrant/internal/VagrantNodeRegistryTest.java @@ -22,10 +22,14 @@ import static org.testng.Assert.assertNull; import java.io.File; import java.util.concurrent.TimeUnit; +import org.easymock.EasyMock; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.Processor; import org.jclouds.vagrant.domain.VagrantNode; import org.testng.annotations.Test; @@ -49,14 +53,19 @@ public class VagrantNodeRegistryTest { @Test public void testNodeRegistry() { + VagrantExistingMachines loader = EasyMock.createMock(VagrantExistingMachines.class); + EasyMock.expect(loader.get()).andReturn(ImmutableList.<VagrantNode>of()); + EasyMock.replay(loader); + TestTimeSupplier timeSupplier = new TestTimeSupplier(); - VagrantNodeRegistry registry = new VagrantNodeRegistry(timeSupplier); + VagrantNodeRegistry registry = new VagrantNodeRegistry(timeSupplier, loader); OperatingSystem os = new OperatingSystem(OsFamily.UNRECOGNIZED, "Jclouds OS", "10", "x64", "Jclouds Test Image", true); Image image = new ImageBuilder() .ids("jclouds/box") .operatingSystem(os) .status(Image.Status.AVAILABLE) .build(); + Hardware hardware = new HardwareBuilder().ids("mini").ram(100).processor(new Processor(1.0, 1)).build(); ImmutableList<String> networks = ImmutableList.of("172.28.128.3"); VagrantNode node = VagrantNode.builder() @@ -66,6 +75,7 @@ public class VagrantNodeRegistryTest { .setName("node") .setImage(image) .setNetworks(networks) + .setHardware(hardware) .setHostname("vagrant-node") .build();
