Skip to content

Commit cb25a92

Browse files
zhong.zhoucursoragent
andcommitted
feat(storage): local primary LUKS qcow2 creation only
Keep KVM LUKS agent params on InstantiateVolumeMsg / InstantiateVolumeOnPrimaryStorageMsg (VolumeLuksAgentSpec), premium pre-instantiate DEK path, and LocalStorageKvmBackend wiring. Shared MergeSnapshotCmd encrypt fields removed; helper script commit-push-three-repos.sh at repo root. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 2b8fcfc commit cb25a92

9 files changed

Lines changed: 265 additions & 10 deletions

File tree

commit-push-three-repos.sh

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#!/usr/bin/env bash
2+
# Run from zstack repo root. For each repo: git add -A, then amend HEAD when index non-empty
3+
# (git commit --amend), then git push --force-with-lease origin <current-branch>.
4+
#
5+
# Repositories:
6+
# 1) zstack (directory containing this script)
7+
# 2) ../zstack-utility (sibling directory)
8+
# 3) ./premium (nested repo)
9+
#
10+
# Usage:
11+
# ./commit-push-three-repos.sh [--dry-run] # amend --no-edit (keep message)
12+
# ./commit-push-three-repos.sh [--dry-run] "new subject" # amend -m "..."
13+
# COMMIT_MSG="msg" ./commit-push-three-repos.sh [--dry-run]
14+
#
15+
set -euo pipefail
16+
17+
ZSTACK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18+
19+
DRY_RUN=0
20+
COMMIT_MSG="${COMMIT_MSG:-}"
21+
22+
while [[ $# -gt 0 ]]; do
23+
case "$1" in
24+
-n|--dry-run)
25+
DRY_RUN=1
26+
shift
27+
;;
28+
-h|--help)
29+
sed -n '2,16p' "$0"
30+
exit 0
31+
;;
32+
*)
33+
if [[ -z "${COMMIT_MSG}" ]]; then
34+
COMMIT_MSG="$1"
35+
else
36+
COMMIT_MSG+=" $1"
37+
fi
38+
shift
39+
;;
40+
esac
41+
done
42+
43+
UTILITY_ROOT=""
44+
if [[ -d "${ZSTACK_ROOT}/../zstack-utility" ]]; then
45+
UTILITY_ROOT="$(cd "${ZSTACK_ROOT}/../zstack-utility" && pwd)"
46+
fi
47+
PREMIUM_ROOT="${ZSTACK_ROOT}/premium"
48+
49+
is_git_repo() {
50+
local d="$1"
51+
[[ -d "${d}/.git" || -f "${d}/.git" ]]
52+
}
53+
54+
commit_and_push() {
55+
local name="$1"
56+
local dir="$2"
57+
58+
if [[ ! -d "${dir}" ]]; then
59+
echo "skip ${name}: directory missing (${dir})"
60+
return 0
61+
fi
62+
63+
if ! is_git_repo "${dir}"; then
64+
echo "skip ${name}: not a git repo (${dir})"
65+
return 0
66+
fi
67+
68+
echo "=== ${name}: ${dir} ==="
69+
70+
local branch
71+
branch="$(git -C "${dir}" rev-parse --abbrev-ref HEAD)"
72+
73+
if [[ "${DRY_RUN}" -eq 1 ]]; then
74+
echo "[dry-run] git -C ${dir} add -A"
75+
if [[ -n "${COMMIT_MSG}" ]]; then
76+
echo "[dry-run] git -C ${dir} commit --amend -m \"${COMMIT_MSG}\" # only if index non-empty"
77+
else
78+
echo "[dry-run] git -C ${dir} commit --amend --no-edit # only if index non-empty"
79+
fi
80+
echo "[dry-run] git -C ${dir} push --force-with-lease origin ${branch}"
81+
echo
82+
return 0
83+
fi
84+
85+
git -C "${dir}" add -A
86+
87+
if git -C "${dir}" diff --cached --quiet; then
88+
echo "nothing staged after add -A; skip amend"
89+
else
90+
if [[ -n "${COMMIT_MSG}" ]]; then
91+
git -C "${dir}" commit --amend -m "${COMMIT_MSG}"
92+
else
93+
git -C "${dir}" commit --amend --no-edit
94+
fi
95+
fi
96+
97+
git -C "${dir}" push --force-with-lease origin "${branch}"
98+
echo "pushed origin/${branch}"
99+
echo
100+
}
101+
102+
commit_and_push "zstack" "${ZSTACK_ROOT}"
103+
104+
if [[ -n "${UTILITY_ROOT}" ]]; then
105+
commit_and_push "zstack-utility" "${UTILITY_ROOT}"
106+
else
107+
echo "skip zstack-utility: ../zstack-utility not found"
108+
fi
109+
110+
commit_and_push "premium" "${PREMIUM_ROOT}"
111+
112+
echo "done."

header/src/main/java/org/zstack/header/storage/primary/InstantiateVolumeOnPrimaryStorageMsg.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import org.zstack.header.message.NeedReplyMessage;
55
import org.zstack.header.message.ReplayableMessage;
66
import org.zstack.header.volume.VolumeInventory;
7+
import org.zstack.header.volume.VolumeLuksAgentSpec;
78

89
public class InstantiateVolumeOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage, ReplayableMessage {
910
private HostInventory destHost;
1011
private VolumeInventory volume;
1112
private String primaryStorageUuid;
1213
private boolean skipIfExisting;
1314
private String allocatedInstallUrl;
15+
private VolumeLuksAgentSpec volumeLuksAgentSpec;
1416

1517
public String getAllocatedInstallUrl() {
1618
return allocatedInstallUrl;
@@ -53,6 +55,14 @@ public void setSkipIfExisting(boolean skipIfExisting) {
5355
this.skipIfExisting = skipIfExisting;
5456
}
5557

58+
public VolumeLuksAgentSpec getVolumeLuksAgentSpec() {
59+
return volumeLuksAgentSpec;
60+
}
61+
62+
public void setVolumeLuksAgentSpec(VolumeLuksAgentSpec volumeLuksAgentSpec) {
63+
this.volumeLuksAgentSpec = volumeLuksAgentSpec;
64+
}
65+
5666
@Override
5767
public String getResourceUuid() {
5868
return volume.getUuid();

header/src/main/java/org/zstack/header/volume/InstantiateVolumeMsg.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class InstantiateVolumeMsg extends NeedReplyMessage implements VolumeMess
1212
private boolean primaryStorageAllocated;
1313
private boolean skipIfExisting;
1414
private String allocatedInstallUrl;
15+
/** Present only for this instantiate RPC chain; not stored as system tags */
16+
private VolumeLuksAgentSpec volumeLuksAgentSpec;
1517

1618
public String getAllocatedInstallUrl() {
1719
return allocatedInstallUrl;
@@ -61,4 +63,12 @@ public boolean isSkipIfExisting() {
6163
public void setSkipIfExisting(boolean skipIfExisting) {
6264
this.skipIfExisting = skipIfExisting;
6365
}
66+
67+
public VolumeLuksAgentSpec getVolumeLuksAgentSpec() {
68+
return volumeLuksAgentSpec;
69+
}
70+
71+
public void setVolumeLuksAgentSpec(VolumeLuksAgentSpec volumeLuksAgentSpec) {
72+
this.volumeLuksAgentSpec = volumeLuksAgentSpec;
73+
}
6474
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.zstack.header.volume;
2+
3+
import java.io.Serializable;
4+
5+
/**
6+
* QEMU qcow2 LUKS parameters passed with volume instantiation messages to kvmagent (not persisted as system tags).
7+
*/
8+
public class VolumeLuksAgentSpec implements Serializable {
9+
private static final long serialVersionUID = 1L;
10+
11+
private String encryptSecretUuid;
12+
private String encryptPassphraseBase64;
13+
/** e.g. {@code luks}; defaults via {@link #getEncryptFormat()} when unset */
14+
private String encryptFormat;
15+
16+
public boolean isComplete() {
17+
return encryptSecretUuid != null && !encryptSecretUuid.isEmpty()
18+
&& encryptPassphraseBase64 != null && !encryptPassphraseBase64.isEmpty();
19+
}
20+
21+
public String getEncryptSecretUuid() {
22+
return encryptSecretUuid;
23+
}
24+
25+
public void setEncryptSecretUuid(String encryptSecretUuid) {
26+
this.encryptSecretUuid = encryptSecretUuid;
27+
}
28+
29+
public String getEncryptPassphraseBase64() {
30+
return encryptPassphraseBase64;
31+
}
32+
33+
public void setEncryptPassphraseBase64(String encryptPassphraseBase64) {
34+
this.encryptPassphraseBase64 = encryptPassphraseBase64;
35+
}
36+
37+
public String getEncryptFormat() {
38+
return encryptFormat != null && !encryptFormat.isEmpty() ? encryptFormat : "luks";
39+
}
40+
41+
public void setEncryptFormat(String encryptFormat) {
42+
this.encryptFormat = encryptFormat;
43+
}
44+
}

plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,7 @@ public void instantiateDataVolumeOnCreation(InstantiateVolumeMsg msg, VolumeInve
10791079

10801080
imsg.setVolume(volume);
10811081
imsg.setPrimaryStorageUuid(msg.getPrimaryStorageUuid());
1082+
imsg.setVolumeLuksAgentSpec(msg.getVolumeLuksAgentSpec());
10821083
imsg.setDestHost(HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class)));
10831084
bus.makeTargetServiceIdByResourceUuid(imsg, PrimaryStorageConstant.SERVICE_ID, msg.getPrimaryStorageUuid());
10841085
bus.send(imsg, new CloudBusCallBack(completion) {

plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHypervisorBackend.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,8 @@ public LocalStorageHypervisorBackend(PrimaryStorageVO self) {
108108

109109
abstract void deleteBits(String path, String hostUuid, Completion completion);
110110

111-
abstract void createEmptyVolume(VolumeInventory volume, String hostUuid, ReturnValueCompletion<VolumeStats> completion);
112-
113-
abstract void createEmptyVolumeWithBackingFile(VolumeInventory volume, String hostUuid, String backingFile, ReturnValueCompletion<VolumeStats> completion);
111+
abstract void createEmptyVolume(VolumeInventory volume, String hostUuid, String backingFile,
112+
VolumeLuksAgentSpec volumeLuksAgentSpec, ReturnValueCompletion<VolumeStats> completion);
114113

115114
abstract void checkHostAttachedPSMountPath(String hostUuid, ReturnValueCompletion<LocalStorageKvmBackend.CheckInitializedFileRsp> completion);
116115

plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ public static class CreateEmptyVolumeCmd extends AgentCommand {
205205
private String volumeUuid;
206206
private String backingFile;
207207
private String volumeFormat;
208+
private String encryptFormat;
209+
private String encryptPassphraseBase64;
210+
private String encryptSecretUuid;
208211

209212
public String getBackingFile() {
210213
return backingFile;
@@ -222,6 +225,30 @@ public void setVolumeFormat(String volumeFormat) {
222225
this.volumeFormat = volumeFormat;
223226
}
224227

228+
public String getEncryptFormat() {
229+
return encryptFormat;
230+
}
231+
232+
public void setEncryptFormat(String encryptFormat) {
233+
this.encryptFormat = encryptFormat;
234+
}
235+
236+
public String getEncryptPassphraseBase64() {
237+
return encryptPassphraseBase64;
238+
}
239+
240+
public void setEncryptPassphraseBase64(String encryptPassphraseBase64) {
241+
this.encryptPassphraseBase64 = encryptPassphraseBase64;
242+
}
243+
244+
public String getEncryptSecretUuid() {
245+
return encryptSecretUuid;
246+
}
247+
248+
public void setEncryptSecretUuid(String encryptSecretUuid) {
249+
this.encryptSecretUuid = encryptSecretUuid;
250+
}
251+
225252
public String getInstallUrl() {
226253
return installUrl;
227254
}
@@ -317,6 +344,34 @@ public long getVirtualSize() {
317344
public void setVirtualSize(long virtualSize) {
318345
this.virtualSize = virtualSize;
319346
}
347+
348+
private String encryptFormat;
349+
private String encryptPassphraseBase64;
350+
private String encryptSecretUuid;
351+
352+
public String getEncryptFormat() {
353+
return encryptFormat;
354+
}
355+
356+
public void setEncryptFormat(String encryptFormat) {
357+
this.encryptFormat = encryptFormat;
358+
}
359+
360+
public String getEncryptPassphraseBase64() {
361+
return encryptPassphraseBase64;
362+
}
363+
364+
public void setEncryptPassphraseBase64(String encryptPassphraseBase64) {
365+
this.encryptPassphraseBase64 = encryptPassphraseBase64;
366+
}
367+
368+
public String getEncryptSecretUuid() {
369+
return encryptSecretUuid;
370+
}
371+
372+
public void setEncryptSecretUuid(String encryptSecretUuid) {
373+
this.encryptSecretUuid = encryptSecretUuid;
374+
}
320375
}
321376

322377
public static class CreateVolumeFromCacheRsp extends AgentResponse {
@@ -329,6 +384,9 @@ public static class CreateVolumeWithBackingCmd extends AgentCommand {
329384
public String installPath;
330385
public String volumeUuid;
331386
public long virtualSize;
387+
public String encryptFormat;
388+
public String encryptPassphraseBase64;
389+
public String encryptSecretUuid;
332390
}
333391

334392
public static class CreateVolumeWithBackingRsp extends AgentResponse {
@@ -1309,7 +1367,7 @@ private void createTemporaryEmptyVolume(InstantiateTemporaryVolumeOnPrimaryStora
13091367
}
13101368

13111369
private void createEmptyVolume(InstantiateVolumeOnPrimaryStorageMsg msg, ReturnValueCompletion<InstantiateVolumeOnPrimaryStorageReply> completion) {
1312-
createEmptyVolume(msg.getVolume(), msg.getDestHost().getUuid(), new ReturnValueCompletion<VolumeStats>(completion) {
1370+
createEmptyVolume(msg.getVolume(), msg.getDestHost().getUuid(), null, msg.getVolumeLuksAgentSpec(), new ReturnValueCompletion<VolumeStats>(completion) {
13131371
@Override
13141372
public void success(VolumeStats returnValue) {
13151373
InstantiateVolumeOnPrimaryStorageReply r = new InstantiateVolumeOnPrimaryStorageReply();
@@ -1332,11 +1390,27 @@ public void fail(ErrorCode errorCode) {
13321390
});
13331391
}
13341392

1335-
public void createEmptyVolume(final VolumeInventory volume, final String hostUuid, final ReturnValueCompletion<VolumeStats> completion) {
1336-
createEmptyVolumeWithBackingFile(volume, hostUuid, null, completion);
1393+
private static void applyVolumeLuksAgentSpec(CreateEmptyVolumeCmd cmd, VolumeLuksAgentSpec spec) {
1394+
if (spec == null || !spec.isComplete()) {
1395+
return;
1396+
}
1397+
cmd.setEncryptFormat(spec.getEncryptFormat());
1398+
cmd.setEncryptPassphraseBase64(spec.getEncryptPassphraseBase64());
1399+
cmd.setEncryptSecretUuid(spec.getEncryptSecretUuid());
1400+
}
1401+
1402+
private static void applyVolumeLuksAgentSpec(CreateVolumeFromCacheCmd cmd, VolumeLuksAgentSpec spec) {
1403+
if (spec == null || !spec.isComplete()) {
1404+
return;
1405+
}
1406+
cmd.setEncryptFormat(spec.getEncryptFormat());
1407+
cmd.setEncryptPassphraseBase64(spec.getEncryptPassphraseBase64());
1408+
cmd.setEncryptSecretUuid(spec.getEncryptSecretUuid());
13371409
}
13381410

1339-
public void createEmptyVolumeWithBackingFile(final VolumeInventory volume, final String hostUuid, final String backingFile, final ReturnValueCompletion<VolumeStats> completion) {
1411+
@Override
1412+
public void createEmptyVolume(final VolumeInventory volume, final String hostUuid, final String backingFile,
1413+
final VolumeLuksAgentSpec volumeLuksAgentSpec, final ReturnValueCompletion<VolumeStats> completion) {
13401414
final CreateEmptyVolumeCmd cmd = new CreateEmptyVolumeCmd();
13411415
cmd.setAccountUuid(acntMgr.getOwnerAccountUuidOfResource(volume.getUuid()));
13421416
if (volume.getInstallPath() != null && !volume.getInstallPath().equals("")) {
@@ -1359,6 +1433,8 @@ public void createEmptyVolumeWithBackingFile(final VolumeInventory volume, final
13591433
cmd.setVolumeUuid(volume.getUuid());
13601434
cmd.setBackingFile(backingFile);
13611435

1436+
applyVolumeLuksAgentSpec(cmd, volumeLuksAgentSpec);
1437+
13621438
httpCall(CREATE_EMPTY_VOLUME_PATH, hostUuid, cmd, CreateEmptyVolumeRsp.class, new ReturnValueCompletion<CreateEmptyVolumeRsp>(completion) {
13631439
@Override
13641440
public void success(CreateEmptyVolumeRsp returnValue) {
@@ -1707,7 +1783,7 @@ private void createRootVolume(final InstantiateRootVolumeFromTemplateOnPrimarySt
17071783
final ImageInventory image = ispec.getInventory();
17081784

17091785
if (!ImageMediaType.RootVolumeTemplate.toString().equals(image.getMediaType())) {
1710-
createEmptyVolume(msg.getVolume(), msg.getDestHost().getUuid(), new ReturnValueCompletion<VolumeStats>(completion) {
1786+
createEmptyVolume(msg.getVolume(), msg.getDestHost().getUuid(), null, msg.getVolumeLuksAgentSpec(), new ReturnValueCompletion<VolumeStats>(completion) {
17111787
@Override
17121788
public void success(VolumeStats returnValue) {
17131789
InstantiateVolumeOnPrimaryStorageReply r = new InstantiateVolumeOnPrimaryStorageReply();
@@ -1778,6 +1854,8 @@ public void run(final FlowTrigger trigger, Map data) {
17781854
cmd.setVirtualSize(volume.getSize());
17791855
}
17801856

1857+
applyVolumeLuksAgentSpec(cmd, msg.getVolumeLuksAgentSpec());
1858+
17811859
httpCall(CREATE_VOLUME_FROM_CACHE_PATH, hostUuid, cmd, CreateVolumeFromCacheRsp.class, new ReturnValueCompletion<CreateVolumeFromCacheRsp>(trigger) {
17821860
@Override
17831861
public void success(CreateVolumeFromCacheRsp returnValue) {
@@ -2359,7 +2437,7 @@ public void run(MessageReply reply) {
23592437

23602438
@Override
23612439
void handle(LocalStorageCreateEmptyVolumeMsg msg, final ReturnValueCompletion<LocalStorageCreateEmptyVolumeReply> completion) {
2362-
createEmptyVolumeWithBackingFile(msg.getVolume(), msg.getHostUuid(), msg.getBackingFile(), new ReturnValueCompletion<VolumeStats>(completion) {
2440+
createEmptyVolume(msg.getVolume(), msg.getHostUuid(), msg.getBackingFile(), null, new ReturnValueCompletion<VolumeStats>(completion) {
23632441
@Override
23642442
public void success(VolumeStats returnValue) {
23652443
LocalStorageCreateEmptyVolumeReply reply = new LocalStorageCreateEmptyVolumeReply();

0 commit comments

Comments
 (0)