diff --git a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java b/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java index d847aa1d1d76..8d4d879c808d 100644 --- a/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java +++ b/engine/storage/configdrive/src/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilder.java @@ -51,6 +51,10 @@ public class ConfigDriveBuilder { public static final Logger LOG = Logger.getLogger(ConfigDriveBuilder.class); + public ConfigDriveBuilder() { + + } + private static void writeFile(final File folder, final String file, final String content) { if (folder == null || Strings.isNullOrEmpty(file)) { return; @@ -136,7 +140,18 @@ public static String buildConfigDrive(final List vmData, final String } File tmpIsoStore = new File(tempDirName, new File(isoFileName).getName()); - Script command = new Script("/usr/bin/genisoimage", Duration.standardSeconds(300), LOG); + File isoCreator = new File("/usr/bin/genisoimage"); + if (!isoCreator.exists()) { + isoCreator = new File("/usr/local/bin/mkisofs"); // are these all the paths we search? + if(!isoCreator.exists()) { + throw new CloudRuntimeException("cannot create iso for config drive using any know tool."); + } + } + if(!isoCreator.canExecute()) { + throw new CloudRuntimeException("cannot create iso for config drive using " + isoCreator.getCanonicalPath()); + } + + Script command = new Script(isoCreator.getCanonicalPath(), Duration.standardSeconds(300), LOG); command.add("-o", tmpIsoStore.getAbsolutePath()); command.add("-ldots"); command.add("-allow-lowercase"); @@ -219,4 +234,7 @@ private static JsonObject buildOpenStackMetaData(JsonObject metaData, String dat return metaData; } + public String build(final List vmData, final String driveLabel) { + return ConfigDriveBuilder.buildConfigDrive(vmData, ConfigDrive.CONFIGDRIVEFILENAME, driveLabel); + } } diff --git a/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java b/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java index 50a4384d5c8d..7e5a997a5a1d 100644 --- a/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java +++ b/engine/storage/configdrive/test/org/apache/cloudstack/storage/configdrive/ConfigDriveBuilderTest.java @@ -17,14 +17,8 @@ package org.apache.cloudstack.storage.configdrive; -import java.io.File; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.List; -import org.apache.commons.io.FileUtils; import org.junit.Assert; import org.junit.Test; @@ -35,31 +29,4 @@ public void testConfigDriveIsoPath() throws IOException { Assert.assertEquals(ConfigDrive.createConfigDrivePath("i-x-y"), "configdrive/i-x-y/configdrive.iso"); } - @Test - public void testConfigDriveBuild() throws IOException { - List actualVmData = Arrays.asList( - new String[]{"userdata", "user_data", "c29tZSB1c2VyIGRhdGE="}, - new String[]{"metadata", "service-offering", "offering"}, - new String[]{"metadata", "availability-zone", "zone1"}, - new String[]{"metadata", "local-hostname", "hostname"}, - new String[]{"metadata", "local-ipv4", "192.168.111.111"}, - new String[]{"metadata", "public-hostname", "7.7.7.7"}, - new String[]{"metadata", "public-ipv4", "7.7.7.7"}, - new String[]{"metadata", "vm-id", "uuid"}, - new String[]{"metadata", "instance-id", "i-x-y"}, - new String[]{"metadata", "public-keys", "ssh-rsa some-key"}, - new String[]{"metadata", "cloud-identifier", String.format("CloudStack-{%s}", "uuid")}, - new String[]{"password", "vm_password", "password123"} - ); - - final Path tempDir = Files.createTempDirectory(ConfigDrive.CONFIGDRIVEDIR); - final String isoData = ConfigDriveBuilder.buildConfigDrive(actualVmData, "i-x-y.iso", "config-2"); - final File isoFile = ConfigDriveBuilder.base64StringToFile(isoData, tempDir.toAbsolutePath().toString(), ConfigDrive.CONFIGDRIVEFILENAME); - - Assert.assertTrue(isoFile.exists()); - Assert.assertTrue(isoFile.isFile()); - Assert.assertTrue(isoFile.length() > 0L); - - FileUtils.deleteDirectory(tempDir.toFile()); - } -} \ No newline at end of file +} diff --git a/server/src/com/cloud/network/element/ConfigDriveNetworkElement.java b/server/src/com/cloud/network/element/ConfigDriveNetworkElement.java index dab4a14311c6..34187c174d19 100644 --- a/server/src/com/cloud/network/element/ConfigDriveNetworkElement.java +++ b/server/src/com/cloud/network/element/ConfigDriveNetworkElement.java @@ -114,6 +114,12 @@ public class ConfigDriveNetworkElement extends AdapterBase implements NetworkEle private final static Integer CONFIGDRIVEDISKSEQ = 4; + ConfigDriveBuilder configDriveBuilder; + + void setConfigDriveBuilder(ConfigDriveBuilder configDriveBuilder) { + this.configDriveBuilder = configDriveBuilder; + } + private boolean canHandle(TrafficType trafficType) { return trafficType.equals(TrafficType.Guest); } @@ -121,6 +127,7 @@ private boolean canHandle(TrafficType trafficType) { @Override public boolean start() { VirtualMachine.State.getStateMachine().registerListener(this); + setConfigDriveBuilder(new ConfigDriveBuilder()); return super.start(); } @@ -347,7 +354,7 @@ private boolean createConfigDriveIso(VirtualMachineProfile profile, DeployDestin LOG.debug("Creating config drive ISO for vm: " + profile.getInstanceName()); final String isoPath = ConfigDrive.createConfigDrivePath(profile.getInstanceName()); - final String isoData = ConfigDriveBuilder.buildConfigDrive(profile.getVmData(), ConfigDrive.CONFIGDRIVEFILENAME, profile.getConfigDriveLabel()); + final String isoData = getConfigDriveAsString(profile.getVmData(), profile.getConfigDriveLabel()); final HandleConfigDriveIsoCommand configDriveIsoCommand = new HandleConfigDriveIsoCommand(isoPath, isoData, dataStore.getTO(), true); final Answer answer = agentManager.easySend(agentId, configDriveIsoCommand); @@ -359,6 +366,10 @@ private boolean createConfigDriveIso(VirtualMachineProfile profile, DeployDestin return true; } + String getConfigDriveAsString(List profileData,String label) { + return configDriveBuilder.build(profileData, label); + } + private boolean deleteConfigDriveIso(final VirtualMachine vm) throws ResourceUnavailableException { DataStore dataStore = _dataStoreMgr.getImageStore(vm.getDataCenterId()); Long agentId = findAgentIdForImageStore(dataStore); diff --git a/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java b/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java index e964999ee9d6..8abfdea6ea41 100644 --- a/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java +++ b/server/test/com/cloud/network/element/ConfigDriveNetworkElementTest.java @@ -41,6 +41,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.configdrive.ConfigDrive; +import org.apache.cloudstack.storage.configdrive.ConfigDriveBuilder; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; @@ -137,6 +138,8 @@ public class ConfigDriveNetworkElementTest { @Mock private IPAddressVO publicIp; @Mock private AgentManager agentManager; + @Mock private ConfigDriveBuilder configDriveBuilder; + @InjectMocks private final ConfigDriveNetworkElement _configDrivesNetworkElement = new ConfigDriveNetworkElement(); @InjectMocks @Spy private NetworkModelImpl _networkModel = new NetworkModelImpl(); @@ -145,6 +148,7 @@ public void setUp() throws NoSuchFieldException, IllegalAccessException { MockitoAnnotations.initMocks(this); _configDrivesNetworkElement._networkModel = _networkModel; + _configDrivesNetworkElement.setConfigDriveBuilder(configDriveBuilder); when(_dataStoreMgr.getImageStore(DATACENTERID)).thenReturn(dataStore); @@ -257,6 +261,7 @@ public void testAddPasswordAndUserData() throws Exception { when(_ipAddressDao.findByAssociatedVmId(VMID)).thenReturn(publicIp); when(publicIp.getAddress()).thenReturn(new Ip("7.7.7.7")); + when(configDriveBuilder.build(any(), anyString())).thenReturn("an iso file"); Map parms = Maps.newHashMap(); parms.put(VirtualMachineProfile.Param.VmPassword, PASSWORD); parms.put(VirtualMachineProfile.Param.VmSshPubKey, PUBLIC_KEY);