Skip to content

Commit fd74895

Browse files
New feature: Reconcile commands (CopyCommand, MigrateCommand, MigrateVolumeCommand) (#10514)
1 parent d7d9d13 commit fd74895

File tree

70 files changed

+3769
-90
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+3769
-90
lines changed

agent/src/main/java/com/cloud/agent/Agent.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,9 @@ protected void processRequest(final Request request, final Link link) {
800800
}
801801
commandsInProgress.incrementAndGet();
802802
try {
803+
if (cmd.isReconcile()) {
804+
cmd.setRequestSequence(request.getSequence());
805+
}
803806
answer = serverResource.executeRequest(cmd);
804807
} finally {
805808
commandsInProgress.decrementAndGet();
@@ -1021,6 +1024,8 @@ private void processPingAnswer(final PingAnswer answer) {
10211024
if ((answer.isSendStartup()) && reconnectAllowed) {
10221025
logger.info("Management server requested startup command to reinitialize the agent");
10231026
sendStartup(link);
1027+
} else {
1028+
serverResource.processPingAnswer((PingAnswer) answer);
10241029
}
10251030
shell.setAvoidHosts(answer.getAvoidMsList());
10261031
}
@@ -1087,6 +1092,9 @@ public void processOtherTask(final Task task) {
10871092
Answer answer = null;
10881093
commandsInProgress.incrementAndGet();
10891094
try {
1095+
if (command.isReconcile()) {
1096+
command.setRequestSequence(req.getSequence());
1097+
}
10901098
answer = serverResource.executeRequest(command);
10911099
} finally {
10921100
commandsInProgress.decrementAndGet();

api/src/main/java/com/cloud/agent/api/Command.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,31 @@ public static enum OnError {
3535
Continue, Stop
3636
}
3737

38+
public enum State {
39+
CREATED, // Command is created by management server
40+
STARTED, // Command is started by agent
41+
PROCESSING, // Processing by agent
42+
PROCESSING_IN_BACKEND, // Processing in backend by agent
43+
COMPLETED, // Operation succeeds by agent or management server
44+
FAILED, // Operation fails by agent
45+
RECONCILE_RETRY, // Ready for retry of reconciliation
46+
RECONCILING, // Being reconciled by management server
47+
RECONCILED, // Reconciled by management server
48+
RECONCILE_SKIPPED, // Skip the reconciliation as the resource state is inconsistent with the command
49+
RECONCILE_FAILED, // Fail to reconcile by management server
50+
TIMED_OUT, // Timed out on management server or agent
51+
INTERRUPTED, // Interrupted by management server or agent (for example agent is restarted),
52+
DANGLED_IN_BACKEND // Backend process which cannot be processed normally (for example agent is restarted)
53+
}
54+
3855
public static final String HYPERVISOR_TYPE = "hypervisorType";
3956

4057
// allow command to carry over hypervisor or other environment related context info
4158
@LogLevel(Log4jLevel.Trace)
4259
protected Map<String, String> contextMap = new HashMap<String, String>();
4360
private int wait; //in second
4461
private boolean bypassHostMaintenance = false;
62+
private transient long requestSequence = 0L;
4563

4664
protected Command() {
4765
this.wait = 0;
@@ -82,6 +100,10 @@ public String getContextParam(String name) {
82100
return contextMap.get(name);
83101
}
84102

103+
public Map<String, String> getContextMap() {
104+
return contextMap;
105+
}
106+
85107
public boolean allowCaching() {
86108
return true;
87109
}
@@ -94,6 +116,18 @@ public void setBypassHostMaintenance(boolean bypassHostMaintenance) {
94116
this.bypassHostMaintenance = bypassHostMaintenance;
95117
}
96118

119+
public boolean isReconcile() {
120+
return false;
121+
}
122+
123+
public long getRequestSequence() {
124+
return requestSequence;
125+
}
126+
127+
public void setRequestSequence(long requestSequence) {
128+
this.requestSequence = requestSequence;
129+
}
130+
97131
@Override
98132
public boolean equals(Object o) {
99133
if (this == o) return true;

api/src/main/java/com/cloud/agent/api/to/DiskTO.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class DiskTO {
4646
private Long diskSeq;
4747
private String path;
4848
private Volume.Type type;
49-
private Map<String, String> _details;
49+
private Map<String, String> details;
5050

5151
public DiskTO() {
5252

@@ -92,10 +92,10 @@ public void setType(Volume.Type type) {
9292
}
9393

9494
public void setDetails(Map<String, String> details) {
95-
_details = details;
95+
this.details = details;
9696
}
9797

9898
public Map<String, String> getDetails() {
99-
return _details;
99+
return details;
100100
}
101101
}

api/src/main/java/com/cloud/agent/api/to/NetworkTO.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class NetworkTO {
3636
protected TrafficType type;
3737
protected URI broadcastUri;
3838
protected URI isolationUri;
39-
protected boolean isSecurityGroupEnabled;
39+
protected boolean securityGroupEnabled;
4040
protected String name;
4141
protected String ip6address;
4242
protected String ip6gateway;
@@ -112,7 +112,7 @@ public String getName() {
112112
}
113113

114114
public void setSecurityGroupEnabled(boolean enabled) {
115-
this.isSecurityGroupEnabled = enabled;
115+
this.securityGroupEnabled = enabled;
116116
}
117117

118118
/**
@@ -221,7 +221,7 @@ public void setIsolationuri(URI isolationUri) {
221221
}
222222

223223
public boolean isSecurityGroupEnabled() {
224-
return this.isSecurityGroupEnabled;
224+
return this.securityGroupEnabled;
225225
}
226226

227227
public void setIp6Dns1(String ip6Dns1) {

api/src/main/java/com/cloud/agent/api/to/NicTO.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ public void setUuid(String uuid) {
8686
this.nicUuid = uuid;
8787
}
8888

89+
public String getNicUuid() {
90+
return nicUuid;
91+
}
92+
93+
public void setNicUuid(String nicUuid) {
94+
this.nicUuid = nicUuid;
95+
}
96+
8997
@Override
9098
public String toString() {
9199
return new StringBuilder("[Nic:").append(type).append("-").append(ip).append("-").append(broadcastUri).append("]").toString();

api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class VirtualMachineTO {
6161
@LogLevel(LogLevel.Log4jLevel.Off)
6262
String vncPassword;
6363
String vncAddr;
64-
Map<String, String> params;
64+
Map<String, String> details;
6565
String uuid;
6666
String bootType;
6767
String bootMode;
@@ -191,7 +191,11 @@ public Integer getMaxSpeed() {
191191
return maxSpeed;
192192
}
193193

194-
public boolean getLimitCpuUse() {
194+
public boolean isEnableHA() {
195+
return enableHA;
196+
}
197+
198+
public boolean isLimitCpuUse() {
195199
return limitCpuUse;
196200
}
197201

@@ -289,11 +293,11 @@ public void setVncAddr(String vncAddr) {
289293
}
290294

291295
public Map<String, String> getDetails() {
292-
return params;
296+
return details;
293297
}
294298

295299
public void setDetails(Map<String, String> params) {
296-
this.params = params;
300+
this.details = params;
297301
}
298302

299303
public String getUuid() {
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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.command;
18+
19+
20+
import com.cloud.agent.api.Answer;
21+
import com.cloud.agent.api.Command;
22+
import com.cloud.hypervisor.Hypervisor;
23+
import org.apache.cloudstack.api.ApiCommandResourceType;
24+
import org.apache.cloudstack.framework.config.ConfigKey;
25+
26+
import java.util.Arrays;
27+
import java.util.List;
28+
29+
public interface ReconcileCommandService {
30+
31+
ConfigKey<Boolean> ReconcileCommandsEnabled = new ConfigKey<>("Advanced", Boolean.class,
32+
"reconcile.commands.enabled", "false",
33+
"Indicates whether the background task to reconcile the commands is enabled or not",
34+
false);
35+
36+
ConfigKey<Integer> ReconcileCommandsInterval = new ConfigKey<>("Advanced", Integer.class,
37+
"reconcile.commands.interval", "60",
38+
"Interval (in seconds) for the background task to reconcile the commands",
39+
false);
40+
ConfigKey<Integer> ReconcileCommandsMaxAttempts = new ConfigKey<>("Advanced", Integer.class,
41+
"reconcile.commands.max.attempts", "30",
42+
"The maximum number of attempts to reconcile the commands",
43+
true);
44+
45+
ConfigKey<Integer> ReconcileCommandsWorkers = new ConfigKey<>("Advanced", Integer.class,
46+
"reconcile.commands.workers", "100",
47+
"The Number of worker threads to reconcile the commands",
48+
false);
49+
50+
List<Hypervisor.HypervisorType> SupportedHypervisorTypes = Arrays.asList(Hypervisor.HypervisorType.KVM);
51+
52+
void persistReconcileCommands(Long hostId, Long requestSequence, Command[] cmd);
53+
54+
boolean updateReconcileCommand(long requestSeq, Command command, Answer answer, Command.State newStateByManagement, Command.State newStateByAgent);
55+
56+
void processCommand(Command pingCommand, Answer pingAnswer);
57+
58+
void processAnswers(long requestSeq, Command[] commands, Answer[] answers);
59+
60+
void updateReconcileCommandToInterruptedByManagementServerId(long managementServerId);
61+
62+
void updateReconcileCommandToInterruptedByHostId(long hostId);
63+
64+
boolean isReconcileResourceNeeded(long resourceId, ApiCommandResourceType resourceType);
65+
}

core/src/main/java/com/cloud/agent/api/MigrateCommand.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929

3030
public class MigrateCommand extends Command {
3131
private String vmName;
32-
private String destIp;
32+
private String destinationIp;
3333
private Map<String, MigrateDiskInfo> migrateStorage;
3434
private boolean migrateStorageManaged;
3535
private boolean migrateNonSharedInc;
3636
private boolean autoConvergence;
3737
private String hostGuid;
38-
private boolean isWindows;
39-
private VirtualMachineTO vmTO;
38+
private boolean windows;
39+
private VirtualMachineTO virtualMachine;
4040
private boolean executeInSequence = false;
4141
private List<MigrateDiskInfo> migrateDiskInfoList = new ArrayList<>();
4242
private Map<String, DpdkTO> dpdkInterfaceMapping = new HashMap<>();
@@ -64,11 +64,11 @@ public void setVlanToPersistenceMap(Map<String, Boolean> vlanToPersistenceMap) {
6464
protected MigrateCommand() {
6565
}
6666

67-
public MigrateCommand(String vmName, String destIp, boolean isWindows, VirtualMachineTO vmTO, boolean executeInSequence) {
67+
public MigrateCommand(String vmName, String destinationIp, boolean windows, VirtualMachineTO virtualMachine, boolean executeInSequence) {
6868
this.vmName = vmName;
69-
this.destIp = destIp;
70-
this.isWindows = isWindows;
71-
this.vmTO = vmTO;
69+
this.destinationIp = destinationIp;
70+
this.windows = windows;
71+
this.virtualMachine = virtualMachine;
7272
this.executeInSequence = executeInSequence;
7373
}
7474

@@ -105,15 +105,15 @@ public boolean isAutoConvergence() {
105105
}
106106

107107
public boolean isWindows() {
108-
return isWindows;
108+
return windows;
109109
}
110110

111111
public VirtualMachineTO getVirtualMachine() {
112-
return vmTO;
112+
return virtualMachine;
113113
}
114114

115115
public String getDestinationIp() {
116-
return destIp;
116+
return destinationIp;
117117
}
118118

119119
public String getVmName() {
@@ -233,4 +233,9 @@ public void setSourceDiskOnStorageFileSystem(boolean isDiskOnFileSystemStorage)
233233
this.isSourceDiskOnStorageFileSystem = isDiskOnFileSystemStorage;
234234
}
235235
}
236+
237+
@Override
238+
public boolean isReconcile() {
239+
return true;
240+
}
236241
}

core/src/main/java/com/cloud/agent/api/PingAnswer.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package com.cloud.agent.api;
2121

22+
import java.util.ArrayList;
2223
import java.util.List;
2324

2425
public class PingAnswer extends Answer {
@@ -27,6 +28,8 @@ public class PingAnswer extends Answer {
2728
private boolean sendStartup = false;
2829
private List<String> avoidMsList;
2930

31+
private List<String> reconcileCommands = new ArrayList<>();
32+
3033
protected PingAnswer() {
3134
}
3235

@@ -49,6 +52,18 @@ public void setSendStartup(boolean sendStartup) {
4952
this.sendStartup = sendStartup;
5053
}
5154

55+
public List<String> getReconcileCommands() {
56+
return reconcileCommands;
57+
}
58+
59+
public void setReconcileCommands(List<String> reconcileCommands) {
60+
this.reconcileCommands = reconcileCommands;
61+
}
62+
63+
public void addReconcileCommand(String reconcileCommand) {
64+
this.reconcileCommands.add(reconcileCommand);
65+
}
66+
5267
public List<String> getAvoidMsList() {
5368
return avoidMsList;
5469
}

core/src/main/java/com/cloud/agent/api/PingCommand.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
package com.cloud.agent.api;
2121

2222
import com.cloud.host.Host;
23+
import org.apache.cloudstack.command.CommandInfo;
2324

2425
public class PingCommand extends Command {
2526
Host.Type hostType;
2627
long hostId;
2728
boolean outOfBand;
29+
@LogLevel(LogLevel.Log4jLevel.Trace)
30+
private CommandInfo[] commandInfos = new CommandInfo[] {};
2831

2932
protected PingCommand() {
3033
}
@@ -78,4 +81,12 @@ public int hashCode() {
7881
result = 31 * result + (int) (hostId ^ (hostId >>> 32));
7982
return result;
8083
}
84+
85+
public CommandInfo[] getCommandInfos() {
86+
return commandInfos;
87+
}
88+
89+
public void setCommandInfos(CommandInfo[] commandInfos) {
90+
this.commandInfos = commandInfos;
91+
}
8192
}

0 commit comments

Comments
 (0)