Skip to content

Commit acc5fdc

Browse files
authored
CLOUDSTACK-10290: allow config drives on primary storage for KVM (#2651)
This introduces a new global setting `vm.configdrive.primarypool.enabled` to toggle creation/hosting of config drive iso files on primary storage, the default will be false causing them to be hosted on secondary storage. The current support is limited from hypervisor resource side and in current implementation limited to `KVM` only. The next big change is that config drive is created at a temporary location by management server and shipped to either KVM or SSVM agent via cmd-answer pattern, the data of which is not logged in logs. This saves us from adding genisoimage dependency on cloudstack-agent pkg. The APIs to reset ssh public key, password and user-data (via update VM API) requires that VM should be shutdown. Therefore, in the refactoring I removed the case of updation of existing ISO. If there are objections I'll re-put the strategy to detach+attach new config iso as a way of updation. In the refactored implementation, the folder name is changed to lower-cased configdrive. And during VM start, migration or shutdown/removal if primary storage is enable for use, the KVM agent will handle cleanup tasks otherwise SSVM agent will handle them. Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
1 parent f23278a commit acc5fdc

21 files changed

Lines changed: 758 additions & 602 deletions

File tree

api/src/com/cloud/network/element/UserDataServiceProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import com.cloud.vm.VirtualMachineProfile;
2727

2828
public interface UserDataServiceProvider extends NetworkElement {
29-
public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
29+
boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context)
3030
throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException;
3131

3232
boolean savePassword(Network network, NicProfile nic, VirtualMachineProfile vm) throws ResourceUnavailableException;

client/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,11 @@
378378
<artifactId>cloud-engine-storage-cache</artifactId>
379379
<version>${project.version}</version>
380380
</dependency>
381+
<dependency>
382+
<groupId>org.apache.cloudstack</groupId>
383+
<artifactId>cloud-engine-storage-configdrive</artifactId>
384+
<version>${project.version}</version>
385+
</dependency>
381386
<dependency>
382387
<groupId>org.apache.cloudstack</groupId>
383388
<artifactId>cloud-controller-secondary-storage</artifactId>

core/src/com/cloud/agent/api/HandleConfigDriveIsoCommand.java

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,60 +19,42 @@
1919

2020
package com.cloud.agent.api;
2121

22-
import java.util.List;
23-
2422
import com.cloud.agent.api.to.DataStoreTO;
2523

2624
public class HandleConfigDriveIsoCommand extends Command {
2725

28-
String isoFile;
29-
List<String[]> vmData;
30-
String configDriveLabel;
31-
boolean create = false;
32-
private boolean update = false;
33-
private DataStoreTO destStore;
34-
35-
public HandleConfigDriveIsoCommand(List<String[]> vmData, String label, DataStoreTO destStore, String isoFile, boolean create, boolean update) {
36-
this.vmData = vmData;
37-
this.configDriveLabel = label;
38-
this.create = create;
39-
this.update = update;
40-
this.destStore = destStore;
26+
@LogLevel(LogLevel.Log4jLevel.Off)
27+
private String isoData;
4128

29+
private String isoFile;
30+
private boolean create = false;
31+
private DataStoreTO destStore;
4232

33+
public HandleConfigDriveIsoCommand(String isoFile, String isoData, DataStoreTO destStore, boolean create) {
4334
this.isoFile = isoFile;
35+
this.isoData = isoData;
36+
this.destStore = destStore;
37+
this.create = create;
4438
}
4539

4640
@Override
4741
public boolean executeInSequence() {
4842
return false;
4943
}
5044

51-
public List<String[]> getVmData() {
52-
return vmData;
53-
}
54-
55-
public void setVmData(List<String[]> vmData) {
56-
this.vmData = vmData;
45+
public String getIsoData() {
46+
return isoData;
5747
}
5848

5949
public boolean isCreate() {
6050
return create;
6151
}
6252

63-
public String getConfigDriveLabel() {
64-
return configDriveLabel;
65-
}
66-
6753
public DataStoreTO getDestStore() {
6854
return destStore;
6955
}
7056

7157
public String getIsoFile() {
7258
return isoFile;
7359
}
74-
75-
public boolean isUpdate() {
76-
return update;
77-
}
7860
}

engine/api/src/com/cloud/vm/VirtualMachineManager.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,17 @@
4949
*/
5050
public interface VirtualMachineManager extends Manager {
5151

52-
static final ConfigKey<Boolean> ExecuteInSequence = new ConfigKey<Boolean>("Advanced", Boolean.class, "execute.in.sequence.hypervisor.commands", "false",
52+
ConfigKey<Boolean> ExecuteInSequence = new ConfigKey<>("Advanced", Boolean.class, "execute.in.sequence.hypervisor.commands", "false",
5353
"If set to true, start, stop, reboot, copy and migrate commands will be serialized on the agent side. If set to false the commands are executed in parallel. Default value is false.", false);
5454

55-
static final ConfigKey<String> VmConfigDriveLabel = new ConfigKey<String>("Hidden", String.class, "vm.configdrive.label", "config-2",
55+
ConfigKey<String> VmConfigDriveLabel = new ConfigKey<>("Hidden", String.class, "vm.configdrive.label", "config-2",
5656
"The default label name for the config drive", false);
5757

58-
public interface Topics {
59-
public static final String VM_POWER_STATE = "vm.powerstate";
58+
ConfigKey<Boolean> VmConfigDriveOnPrimaryPool = new ConfigKey<>("Advanced", Boolean.class, "vm.configdrive.primarypool.enabled", "false",
59+
"If config drive need to be created and hosted on primary storage pool. Currently only supported for KVM.", true);
60+
61+
interface Topics {
62+
String VM_POWER_STATE = "vm.powerstate";
6063
}
6164

6265
/**

engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,10 +1108,11 @@ public void orchestrateStart(final String vmUuid, final Map<VirtualMachineProfil
11081108
}
11091109

11101110
try {
1111-
_networkMgr.prepare(vmProfile, new DeployDestination(dest.getDataCenter(), dest.getPod(), null, null), ctx);
1111+
_networkMgr.prepare(vmProfile, new DeployDestination(dest.getDataCenter(), dest.getPod(), null, null, dest.getStorageForDisks()), ctx);
11121112
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
11131113
volumeMgr.prepare(vmProfile, dest);
11141114
}
1115+
11151116
//since StorageMgr succeeded in volume creation, reuse Volume for further tries until current cluster has capacity
11161117
if (!reuseVolume) {
11171118
reuseVolume = true;
@@ -4018,7 +4019,7 @@ public String getConfigComponentName() {
40184019
public ConfigKey<?>[] getConfigKeys() {
40194020
return new ConfigKey<?>[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait,
40204021
VmOpLockStateRetry,
4021-
VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, HaVmRestartHostUp};
4022+
VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp};
40224023
}
40234024

40244025
public List<StoragePoolAllocator> getStoragePoolAllocators() {

engine/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<module>storage/datamotion</module>
5454
<module>storage/cache</module>
5555
<module>storage/snapshot</module>
56+
<module>storage/configdrive</module>
5657
<module>components-api</module>
5758
<module>network</module>
5859
<module>service</module>

engine/storage/configdrive/pom.xml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20+
<modelVersion>4.0.0</modelVersion>
21+
<artifactId>cloud-engine-storage-configdrive</artifactId>
22+
<name>Apache CloudStack Framework - Storage Config Drive Component</name>
23+
<parent>
24+
<groupId>org.apache.cloudstack</groupId>
25+
<artifactId>cloud-engine</artifactId>
26+
<version>4.11.1.0-SNAPSHOT</version>
27+
<relativePath>../../pom.xml</relativePath>
28+
</parent>
29+
30+
<dependencies>
31+
<dependency>
32+
<groupId>org.apache.cloudstack</groupId>
33+
<artifactId>cloud-api</artifactId>
34+
<version>${project.version}</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.apache.cloudstack</groupId>
38+
<artifactId>cloud-core</artifactId>
39+
<version>${project.version}</version>
40+
</dependency>
41+
</dependencies>
42+
43+
</project>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.storage.configdrive;
19+
20+
public class ConfigDrive {
21+
22+
public final static String CONFIGDRIVEFILENAME = "configdrive.iso";
23+
public final static String CONFIGDRIVEDIR = "configdrive";
24+
25+
public static final String cloudStackConfigDriveName = "/cloudstack/";
26+
public static final String openStackConfigDriveName = "/openstack/latest/";
27+
28+
/**
29+
* This is the path to iso file relative to mount point
30+
* @return config drive iso file path
31+
*/
32+
public static String createConfigDrivePath(final String instanceName) {
33+
return ConfigDrive.CONFIGDRIVEDIR + "/" + instanceName + "/" + ConfigDrive.CONFIGDRIVEFILENAME;
34+
}
35+
36+
}

0 commit comments

Comments
 (0)