Skip to content

Commit 78dcb2e

Browse files
committed
bx 백업 개발
1 parent 130286a commit 78dcb2e

20 files changed

Lines changed: 1613 additions & 4 deletions

File tree

api/src/main/java/com/cloud/vm/UserVmService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.apache.cloudstack.api.command.user.vm.AddNicToVMCmd;
3232
import org.apache.cloudstack.api.command.user.vm.CloneVMCmd;
3333
import org.apache.cloudstack.api.command.user.vm.CreateVMFromBackupCmd;
34+
import org.apache.cloudstack.api.command.user.vm.CreateVMFromBxBackupCmd;
3435
import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
3536
import org.apache.cloudstack.api.command.user.vm.DestroyVMCmd;
3637
import org.apache.cloudstack.api.command.user.vm.DeployVMVolumeCmd;
@@ -575,4 +576,6 @@ UserVm importVM(final DataCenter zone, final Host host, final VirtualMachineTemp
575576
UserVm allocateVMFromBackup(CreateVMFromBackupCmd cmd) throws InsufficientCapacityException, ResourceAllocationException, ResourceUnavailableException;
576577

577578
UserVm restoreVMFromBackup(CreateVMFromBackupCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;
579+
580+
Pair<Boolean, String> restoreVMFromBxBackup(CreateVMFromBxBackupCmd createVMFromBxBackupCmd) throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;
578581
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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+
package org.apache.cloudstack.api.command.user.vm;
18+
19+
import org.apache.cloudstack.acl.RoleType;
20+
import org.apache.cloudstack.api.ACL;
21+
import org.apache.cloudstack.api.APICommand;
22+
import org.apache.cloudstack.api.ApiArgValidator;
23+
import org.apache.cloudstack.api.ApiConstants;
24+
import org.apache.cloudstack.api.ApiErrorCode;
25+
import org.apache.cloudstack.api.BaseCmd;
26+
import org.apache.cloudstack.api.Parameter;
27+
import org.apache.cloudstack.api.ResponseObject;
28+
import org.apache.cloudstack.api.ServerApiException;
29+
import org.apache.cloudstack.api.response.BackupResponse;
30+
import org.apache.cloudstack.api.response.DomainResponse;
31+
import org.apache.cloudstack.api.response.ProjectResponse;
32+
import org.apache.cloudstack.api.response.ServiceOfferingResponse;
33+
import org.apache.cloudstack.api.response.SuccessResponse;
34+
import org.apache.cloudstack.api.response.TemplateResponse;
35+
import org.apache.cloudstack.context.CallContext;
36+
37+
import com.cloud.exception.ConcurrentOperationException;
38+
import com.cloud.exception.InsufficientCapacityException;
39+
import com.cloud.exception.InsufficientServerCapacityException;
40+
import com.cloud.exception.ResourceAllocationException;
41+
import com.cloud.exception.ResourceUnavailableException;
42+
import com.cloud.utils.Pair;
43+
import com.cloud.vm.VirtualMachine;
44+
45+
@APICommand(name = "createVMFromBxBackup",
46+
description = "Creates and automatically starts a VM from a backup.",
47+
responseObject = SuccessResponse.class,
48+
responseView = ResponseObject.ResponseView.Restricted,
49+
entityType = {VirtualMachine.class},
50+
requestHasSensitiveInfo = false, responseHasSensitiveInfo = true,
51+
since = "4.21.0",
52+
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
53+
public class CreateVMFromBxBackupCmd extends BaseCmd {
54+
55+
/////////////////////////////////////////////////////
56+
//////////////// API parameters /////////////////////
57+
/////////////////////////////////////////////////////
58+
59+
@Parameter(name = ApiConstants.BACKUP_ID,
60+
type = CommandType.UUID,
61+
entityType = BackupResponse.class,
62+
required = true,
63+
description = "backup ID to create the VM from")
64+
private Long backupId;
65+
66+
@ACL
67+
@Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, description = "the ID of the service offering for the virtual machine")
68+
private Long serviceOfferingId;
69+
70+
@ACL
71+
@Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "the ID of the template for the virtual machine")
72+
private Long templateId;
73+
74+
@Parameter(name = ApiConstants.PRESERVE_IP, type = CommandType.BOOLEAN, description = "Use the same IP/MAC addresses as stored in the backup metadata. Works only if the original Instance is deleted and the IP/MAC address is available.")
75+
private Boolean preserveIp;
76+
77+
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "host name for the virtual machine", validations = {ApiArgValidator.RFCComplianceDomainName})
78+
private String name;
79+
80+
/////////////////////////////////////////////////////
81+
/////////////////// Accessors ///////////////////////
82+
/////////////////////////////////////////////////////
83+
84+
public Long getBackupId() {
85+
return backupId;
86+
}
87+
88+
public Long getServiceOfferingId() {
89+
return serviceOfferingId;
90+
}
91+
92+
public Long getTemplateId() {
93+
return templateId;
94+
}
95+
96+
public boolean getPreserveIp() {
97+
return (preserveIp != null) ? preserveIp : false;
98+
}
99+
100+
public String getName() {
101+
return name;
102+
}
103+
104+
//Owner information
105+
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "an optional account for the virtual machine. Must be used with domainId.")
106+
private String accountName;
107+
108+
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "an optional domainId for the virtual machine. If the account parameter is used, domainId must also be used. If account is NOT provided then virtual machine will be assigned to the caller account and domain.")
109+
private Long domainId;
110+
111+
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class, description = "Deploy vm for the project")
112+
private Long projectId;
113+
114+
public void execute () {
115+
Pair<Boolean, String> result = null;
116+
try {
117+
result = _userVmService.restoreVMFromBxBackup(this);
118+
} catch (ResourceUnavailableException ex) {
119+
logger.warn("Exception: ", ex);
120+
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
121+
} catch (ResourceAllocationException ex) {
122+
logger.warn("Exception: ", ex);
123+
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
124+
} catch (ConcurrentOperationException ex) {
125+
logger.warn("Exception: ", ex);
126+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
127+
} catch (InsufficientCapacityException ex) {
128+
StringBuilder message = new StringBuilder(ex.getMessage());
129+
if (ex instanceof InsufficientServerCapacityException) {
130+
if (((InsufficientServerCapacityException)ex).isAffinityApplied()) {
131+
message.append(", Please check the affinity groups provided, there may not be sufficient capacity to follow them");
132+
}
133+
}
134+
logger.info("{}: {}", message.toString(), ex.getLocalizedMessage());
135+
logger.debug(message.toString(), ex);
136+
throw new ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, message.toString());
137+
}
138+
139+
if (result != null && Boolean.TRUE.equals(result.first())) {
140+
SuccessResponse response = new SuccessResponse(getCommandName());
141+
response.setResponseName(getCommandName());
142+
setResponseObject(response);
143+
// UserVmResponse response = _responseGenerator.createUserVmResponse(getResponseView(), "virtualmachine", vm).get(0);
144+
// response.setResponseName(getCommandName());
145+
// setResponseObject(response);
146+
} else {
147+
String message = result != null ? result.second() : null;
148+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
149+
message != null ? message : "Failed to create VM from BX backup");
150+
}
151+
}
152+
153+
@Override
154+
public long getEntityOwnerId() {
155+
Long accountId = _accountService.finalizeAccountId(accountName, domainId, projectId, true);
156+
if (accountId == null) {
157+
return CallContext.current().getCallingAccount().getId();
158+
}
159+
160+
return accountId;
161+
}
162+
}

api/src/main/java/org/apache/cloudstack/backup/BackupManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
5757
ConfigKey<String> BackupProviderPlugin = new ValidatedConfigKey<>("Advanced", String.class,
5858
"backup.framework.provider.plugin",
5959
"dummy",
60-
"The backup and recovery provider plugin. Valid plugin values: dummy, veeam, networker and nas",
60+
"The backup and recovery provider plugin. Valid plugin values: dummy, veeam, networker, bx and nas",
6161
true, ConfigKey.Scope.Zone, BackupFrameworkEnabled.key(), value -> validateBackupProviderConfig((String)value));
6262

6363
ConfigKey<Long> BackupSyncPollingInterval = new ConfigKey<>("Advanced", Long.class,
@@ -257,7 +257,7 @@ static void validateBackupProviderConfig(String value) {
257257
if (value != null && (value.contains(",") || value.trim().contains(" "))) {
258258
throw new IllegalArgumentException("Multiple backup provider plugins are not supported. Please provide a single plugin value.");
259259
}
260-
List<String> validPlugins = List.of("dummy", "veeam", "networker", "nas");
260+
List<String> validPlugins = List.of("dummy", "veeam", "networker", "nas", "bx");
261261
if (value != null && !validPlugins.contains(value)) {
262262
throw new IllegalArgumentException("Invalid backup provider plugin: " + value + ". Valid plugin values are: " + String.join(", ", validPlugins));
263263
}

api/src/main/java/org/apache/cloudstack/backup/BackupProvider.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ public interface BackupProvider {
8989

9090
Pair<Boolean, String> restoreBackupToVM(VirtualMachine vm, Backup backup, String hostIp, String dataStoreUuid);
9191

92+
/**
93+
* Restore VM from BX backup
94+
*/
95+
Pair<Boolean, String> restoreBackupToVM(Long backupId, String vmName);
96+
9297
/**
9398
* Restore VM from backup
9499
*/

plugins/backup/bx/pom.xml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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+
16+
KIND, either express or implied. See the License for the
17+
specific language governing permissions and limitations
18+
under the License.
19+
-->
20+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
21+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
22+
<modelVersion>4.0.0</modelVersion>
23+
<artifactId>cloud-plugin-backup-bx</artifactId>
24+
<name>Apache CloudStack Plugin - KVM BK Backup and Recovery Plugin</name>
25+
<parent>
26+
<artifactId>cloudstack-plugins</artifactId>
27+
<groupId>org.apache.cloudstack</groupId>
28+
<version>4.22.0.0-SNAPSHOT</version>
29+
<relativePath>../../pom.xml</relativePath>
30+
</parent>
31+
<dependencies>
32+
<dependency>
33+
<groupId>org.apache.cloudstack</groupId>
34+
<artifactId>cloud-plugin-hypervisor-kvm</artifactId>
35+
<version>${project.version}</version>
36+
</dependency>
37+
<dependency>
38+
<groupId>org.apache.commons</groupId>
39+
<artifactId>commons-lang3</artifactId>
40+
<version>${cs.commons-lang3.version}</version>
41+
</dependency>
42+
<dependency>
43+
<groupId>com.fasterxml.jackson.core</groupId>
44+
<artifactId>jackson-databind</artifactId>
45+
<version>${cs.jackson.version}</version>
46+
</dependency>
47+
<dependency>
48+
<groupId>com.github.tomakehurst</groupId>
49+
<artifactId>wiremock-standalone</artifactId>
50+
<version>${cs.wiremock.version}</version>
51+
<scope>test</scope>
52+
</dependency>
53+
</dependencies>
54+
</project>

0 commit comments

Comments
 (0)