@le-space/rootfs 0.1.52 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/index.d.ts +6 -1
- package/index.js +71 -31
- package/le-space-rootfs-0.3.0.tgz +0 -0
- package/package.json +1 -1
- package/reference/orbitdb-relay-pinner/contract.json +70 -0
- package/reference/orbitdb-relay-pinner/rootfs/Dockerfile.rootfs +19 -0
- package/reference/orbitdb-relay-pinner/rootfs/build-rootfs-image.sh +335 -0
- package/reference/orbitdb-relay-pinner/rootfs/build-rootfs.sh +521 -0
- package/reference/orbitdb-relay-pinner/rootfs/orbitdb-relay-pinner-autotls-refresh.py +224 -0
- package/reference/orbitdb-relay-pinner/rootfs/orbitdb-relay-pinner-autotls-refresh.service +24 -0
- package/reference/orbitdb-relay-pinner/rootfs/orbitdb-relay-pinner-bootstrap.conf +2 -0
- package/reference/orbitdb-relay-pinner/rootfs/orbitdb-relay-pinner-bootstrap.service +21 -0
- package/reference/orbitdb-relay-pinner/rootfs/orbitdb-relay-pinner-bootstrap.sh +121 -0
- package/reference/orbitdb-relay-pinner/rootfs/orbitdb-relay-pinner-configure.sh +240 -0
- package/reference/orbitdb-relay-pinner/rootfs/orbitdb-relay-pinner-describe.py +165 -0
- package/reference/orbitdb-relay-pinner/rootfs/orbitdb-relay-pinner-setup-server.py +237 -0
- package/reference/orbitdb-relay-pinner/rootfs/read-rootfs-contract.py +72 -0
package/README.md
CHANGED
|
@@ -7,10 +7,14 @@ Shared rootfs contract parsing, reference profile assets, and build helpers.
|
|
|
7
7
|
- typed parsing and validation of rootfs contract JSON
|
|
8
8
|
- shell-env mapping compatible with the existing UC rootfs builder
|
|
9
9
|
- copied `uc-go-peer` reference contract and guest asset set
|
|
10
|
+
- copied `orbitdb-relay-pinner` reference contract and guest asset set,
|
|
11
|
+
including the delayed first-start, setup endpoint, Caddy, and AutoTLS flow
|
|
10
12
|
|
|
11
13
|
## Reference assets
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
Current shared reference profiles live under:
|
|
14
16
|
|
|
15
17
|
- `reference/uc-go-peer/contract.json`
|
|
16
18
|
- `reference/uc-go-peer/rootfs/*`
|
|
19
|
+
- `reference/orbitdb-relay-pinner/contract.json`
|
|
20
|
+
- `reference/orbitdb-relay-pinner/rootfs/*`
|
package/index.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ declare function referenceProfileRootfsDir(profile: string): string;
|
|
|
51
51
|
type RootfsBuildDriver = 'auto' | 'host' | 'docker';
|
|
52
52
|
interface RootfsBuildOptions {
|
|
53
53
|
projectDir: string;
|
|
54
|
+
orbitdbRelayPinnerDir?: string;
|
|
54
55
|
alephDir?: string;
|
|
55
56
|
outDir?: string;
|
|
56
57
|
contractPath?: string;
|
|
@@ -77,6 +78,7 @@ interface RootfsBuildPlan {
|
|
|
77
78
|
contract: RootfsContract;
|
|
78
79
|
contractPath: string;
|
|
79
80
|
projectDir: string;
|
|
81
|
+
orbitdbRelayPinnerDir?: string;
|
|
80
82
|
alephDir: string;
|
|
81
83
|
outDir: string;
|
|
82
84
|
driver: RootfsBuildDriver;
|
|
@@ -102,7 +104,9 @@ interface RootfsBuildPlan {
|
|
|
102
104
|
baseImagePath: string;
|
|
103
105
|
binaryPath: string;
|
|
104
106
|
}
|
|
105
|
-
declare function deriveRootfsVersion(options?: Pick<RootfsBuildOptions, 'rootfsVersion' | 'gitShortSha' | 'now'>
|
|
107
|
+
declare function deriveRootfsVersion(options?: Pick<RootfsBuildOptions, 'rootfsVersion' | 'gitShortSha' | 'now'> & {
|
|
108
|
+
defaultId?: string;
|
|
109
|
+
}): string;
|
|
106
110
|
declare function createRootfsBuildPlan(contract: RootfsContract, options: RootfsBuildOptions): RootfsBuildPlan;
|
|
107
111
|
declare function rootfsBuildShellEnv(plan: RootfsBuildPlan): Record<string, string>;
|
|
108
112
|
|
|
@@ -166,6 +170,7 @@ interface RootfsExecutionPlanOptions {
|
|
|
166
170
|
referenceRootfsDir?: string;
|
|
167
171
|
projectMountPath?: string;
|
|
168
172
|
rootfsMountPath?: string;
|
|
173
|
+
orbitdbRelayPinnerMountPath?: string;
|
|
169
174
|
dockerImageTag?: string;
|
|
170
175
|
}
|
|
171
176
|
declare function createHostRootfsExecutionPlan(plan: RootfsBuildPlan, options?: RootfsExecutionPlanOptions): RootfsExecutionPlan;
|
package/index.js
CHANGED
|
@@ -165,21 +165,44 @@ function deriveRootfsVersion(options = {}) {
|
|
|
165
165
|
if (options.rootfsVersion && options.rootfsVersion.trim()) {
|
|
166
166
|
return options.rootfsVersion.trim();
|
|
167
167
|
}
|
|
168
|
+
const defaultId = options.defaultId?.trim() || "uc-go-peer";
|
|
168
169
|
if (options.gitShortSha && options.gitShortSha.trim()) {
|
|
169
170
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
170
171
|
const yyyy = String(now.getUTCFullYear());
|
|
171
172
|
const mm = String(now.getUTCMonth() + 1).padStart(2, "0");
|
|
172
173
|
const dd = String(now.getUTCDate()).padStart(2, "0");
|
|
173
|
-
return
|
|
174
|
+
return `${defaultId}-git-${yyyy}${mm}${dd}-${options.gitShortSha.trim()}`;
|
|
174
175
|
}
|
|
175
|
-
return
|
|
176
|
+
return `${defaultId}-v0.1.0`;
|
|
177
|
+
}
|
|
178
|
+
function defaultRootfsVersionId(contract) {
|
|
179
|
+
return contract.id.trim() || contract.rootfs.profile.trim() || "rootfs";
|
|
180
|
+
}
|
|
181
|
+
function defaultRootfsImageBasename(contract) {
|
|
182
|
+
return `aleph-${contract.rootfs.profile}.qcow2`;
|
|
183
|
+
}
|
|
184
|
+
function sourceSubdirectory(contract) {
|
|
185
|
+
const value = contract.source?.subdirectory?.trim();
|
|
186
|
+
return value && value !== "." ? value : null;
|
|
176
187
|
}
|
|
177
188
|
function createRootfsBuildPlan(contract, options) {
|
|
178
189
|
const projectDir = path.resolve(options.projectDir);
|
|
179
|
-
const
|
|
190
|
+
const orbitdbRelayPinnerDir = options.orbitdbRelayPinnerDir?.trim() ? path.resolve(options.orbitdbRelayPinnerDir) : void 0;
|
|
191
|
+
const subdirectory = sourceSubdirectory(contract);
|
|
192
|
+
const defaultAlephDir = subdirectory ? path.join(projectDir, subdirectory, "aleph") : projectDir;
|
|
193
|
+
const alephDir = path.resolve(options.alephDir ?? defaultAlephDir);
|
|
180
194
|
const outDir = path.resolve(options.outDir ?? path.join(alephDir, "dist-rootfs"));
|
|
181
|
-
const
|
|
182
|
-
const
|
|
195
|
+
const defaultContractDir = subdirectory ? path.join(alephDir, "root-profiles") : path.join(projectDir, "root-profiles");
|
|
196
|
+
const contractPath = path.resolve(options.contractPath ?? path.join(defaultContractDir, `${contract.id}.json`));
|
|
197
|
+
const versionId = defaultRootfsVersionId(contract);
|
|
198
|
+
const rootfsVersion = deriveRootfsVersion({
|
|
199
|
+
...options,
|
|
200
|
+
defaultId: versionId,
|
|
201
|
+
rootfsVersion: options.rootfsVersion?.trim() || void 0,
|
|
202
|
+
gitShortSha: options.gitShortSha,
|
|
203
|
+
now: options.now
|
|
204
|
+
});
|
|
205
|
+
const imageBasename = defaultRootfsImageBasename(contract);
|
|
183
206
|
const copyTarget = contract.manifest.copyTarget?.trim() ?? "";
|
|
184
207
|
const latestManifestPath = copyTarget ? path.resolve(copyTarget.startsWith("/") ? copyTarget : path.join(projectDir, copyTarget)) : null;
|
|
185
208
|
const versionedManifestPath = latestManifestPath ? path.join(path.dirname(latestManifestPath), `${rootfsVersion}.json`) : null;
|
|
@@ -187,6 +210,7 @@ function createRootfsBuildPlan(contract, options) {
|
|
|
187
210
|
contract,
|
|
188
211
|
contractPath,
|
|
189
212
|
projectDir,
|
|
213
|
+
orbitdbRelayPinnerDir,
|
|
190
214
|
alephDir,
|
|
191
215
|
outDir,
|
|
192
216
|
driver: options.driver ?? "auto",
|
|
@@ -208,13 +232,13 @@ function createRootfsBuildPlan(contract, options) {
|
|
|
208
232
|
manifestPath: path.join(outDir, "rootfs-manifest.json"),
|
|
209
233
|
latestManifestPath,
|
|
210
234
|
versionedManifestPath,
|
|
211
|
-
imagePath: path.join(outDir,
|
|
235
|
+
imagePath: path.join(outDir, imageBasename),
|
|
212
236
|
baseImagePath: path.join(outDir, "debian-12-genericcloud-amd64.qcow2"),
|
|
213
|
-
binaryPath: path.join(outDir, "
|
|
237
|
+
binaryPath: path.join(outDir, path.basename(contract.rootfs.binaryPath || "artifact"))
|
|
214
238
|
};
|
|
215
239
|
}
|
|
216
240
|
function rootfsBuildShellEnv(plan) {
|
|
217
|
-
|
|
241
|
+
const env = {
|
|
218
242
|
PROJECT_DIR: plan.projectDir,
|
|
219
243
|
OUT_DIR: plan.outDir,
|
|
220
244
|
ROOTFS_CONTRACT_FILE: plan.contractPath,
|
|
@@ -235,6 +259,10 @@ function rootfsBuildShellEnv(plan) {
|
|
|
235
259
|
IPFS_GATEWAY_WAIT_ATTEMPTS: String(plan.ipfsGatewayWaitAttempts),
|
|
236
260
|
IPFS_GATEWAY_WAIT_DELAY_SECONDS: String(plan.ipfsGatewayWaitDelaySeconds)
|
|
237
261
|
};
|
|
262
|
+
if (plan.orbitdbRelayPinnerDir) {
|
|
263
|
+
env.ORBITDB_RELAY_PINNER_DIR = plan.orbitdbRelayPinnerDir;
|
|
264
|
+
}
|
|
265
|
+
return env;
|
|
238
266
|
}
|
|
239
267
|
|
|
240
268
|
// src/manifest.ts
|
|
@@ -360,6 +388,14 @@ function containerPathForProjectFile(hostPath, projectDir, mountPath, label) {
|
|
|
360
388
|
const relative = ensurePathWithin(projectDir, hostPath, label);
|
|
361
389
|
return path2.posix.join(mountPath, relative.split(path2.sep).join("/"));
|
|
362
390
|
}
|
|
391
|
+
function containerContractPathForFile(hostPath, projectDir, projectMountPath) {
|
|
392
|
+
const relative = path2.relative(projectDir, hostPath);
|
|
393
|
+
if (!relative.startsWith("..") && !path2.isAbsolute(relative)) {
|
|
394
|
+
return path2.posix.join(projectMountPath, relative.split(path2.sep).join("/"));
|
|
395
|
+
}
|
|
396
|
+
const basename = path2.posix.basename(hostPath);
|
|
397
|
+
return path2.posix.join("/workspace/shared-contracts", basename);
|
|
398
|
+
}
|
|
363
399
|
function resolveReferenceRootfsDir(contract, override) {
|
|
364
400
|
if (override) {
|
|
365
401
|
return path2.resolve(override);
|
|
@@ -376,12 +412,7 @@ function createHostRootfsExecutionPlan(plan, options = {}) {
|
|
|
376
412
|
command: "/bin/bash",
|
|
377
413
|
args: [path2.join(referenceRootfsDir, "build-rootfs-image.sh")],
|
|
378
414
|
workdir: referenceRootfsDir,
|
|
379
|
-
env:
|
|
380
|
-
PROJECT_DIR: plan.projectDir,
|
|
381
|
-
OUT_DIR: plan.outDir,
|
|
382
|
-
ROOTFS_CONTRACT_FILE: plan.contractPath,
|
|
383
|
-
ROOTFS_IMAGE_SIZE: plan.rootfsImageSize
|
|
384
|
-
}
|
|
415
|
+
env: rootfsBuildShellEnv(plan)
|
|
385
416
|
}
|
|
386
417
|
};
|
|
387
418
|
}
|
|
@@ -389,12 +420,35 @@ function createDockerRootfsExecutionPlan(plan, options = {}) {
|
|
|
389
420
|
const referenceRootfsDir = resolveReferenceRootfsDir(plan.contract, options.referenceRootfsDir);
|
|
390
421
|
const projectMountPath = options.projectMountPath ?? "/workspace/project";
|
|
391
422
|
const rootfsMountPath = options.rootfsMountPath ?? "/workspace/shared-rootfs";
|
|
423
|
+
const orbitdbRelayPinnerMountPath = options.orbitdbRelayPinnerMountPath ?? "/workspace-orbitdb-relay-pinner";
|
|
392
424
|
const dockerImageTag = options.dockerImageTag ?? `${plan.contract.id}-rootfs-builder:local`;
|
|
393
425
|
const containerProjectDir = projectMountPath;
|
|
394
|
-
const containerContractPath =
|
|
426
|
+
const containerContractPath = containerContractPathForFile(plan.contractPath, plan.projectDir, projectMountPath);
|
|
395
427
|
const containerOutDir = containerPathForProjectFile(plan.outDir, plan.projectDir, projectMountPath, "outDir");
|
|
396
428
|
const hostUid = typeof process.getuid === "function" ? String(process.getuid()) : "1000";
|
|
397
429
|
const hostGid = typeof process.getgid === "function" ? String(process.getgid()) : "1000";
|
|
430
|
+
const runEnv = {
|
|
431
|
+
...rootfsBuildShellEnv(plan),
|
|
432
|
+
PROJECT_DIR: containerProjectDir,
|
|
433
|
+
OUT_DIR: containerOutDir,
|
|
434
|
+
ROOTFS_CONTRACT_FILE: containerContractPath,
|
|
435
|
+
HOST_UID: hostUid,
|
|
436
|
+
HOST_GID: hostGid
|
|
437
|
+
};
|
|
438
|
+
const volumeMounts = [
|
|
439
|
+
"-v",
|
|
440
|
+
`${plan.projectDir}:${projectMountPath}`,
|
|
441
|
+
"-v",
|
|
442
|
+
`${referenceRootfsDir}:${rootfsMountPath}`
|
|
443
|
+
];
|
|
444
|
+
const contractRelative = path2.relative(plan.projectDir, plan.contractPath);
|
|
445
|
+
if (contractRelative.startsWith("..") || path2.isAbsolute(contractRelative)) {
|
|
446
|
+
volumeMounts.push("-v", `${plan.contractPath}:${containerContractPath}:ro`);
|
|
447
|
+
}
|
|
448
|
+
if (plan.orbitdbRelayPinnerDir) {
|
|
449
|
+
runEnv.ORBITDB_RELAY_PINNER_DIR = orbitdbRelayPinnerMountPath;
|
|
450
|
+
volumeMounts.push("-v", `${plan.orbitdbRelayPinnerDir}:${orbitdbRelayPinnerMountPath}:ro`);
|
|
451
|
+
}
|
|
398
452
|
return {
|
|
399
453
|
mode: "docker",
|
|
400
454
|
reason: "Using Dockerized Debian/libguestfs builder.",
|
|
@@ -422,22 +476,8 @@ function createDockerRootfsExecutionPlan(plan, options = {}) {
|
|
|
422
476
|
"linux/amd64",
|
|
423
477
|
"-e",
|
|
424
478
|
"LIBGUESTFS_BACKEND=direct",
|
|
425
|
-
"-e",
|
|
426
|
-
|
|
427
|
-
"-e",
|
|
428
|
-
`OUT_DIR=${containerOutDir}`,
|
|
429
|
-
"-e",
|
|
430
|
-
`ROOTFS_IMAGE_SIZE=${plan.rootfsImageSize}`,
|
|
431
|
-
"-e",
|
|
432
|
-
`PROJECT_DIR=${containerProjectDir}`,
|
|
433
|
-
"-e",
|
|
434
|
-
`HOST_UID=${hostUid}`,
|
|
435
|
-
"-e",
|
|
436
|
-
`HOST_GID=${hostGid}`,
|
|
437
|
-
"-v",
|
|
438
|
-
`${plan.projectDir}:${projectMountPath}`,
|
|
439
|
-
"-v",
|
|
440
|
-
`${referenceRootfsDir}:${rootfsMountPath}`,
|
|
479
|
+
...Object.entries(runEnv).flatMap(([key, value]) => ["-e", `${key}=${value}`]),
|
|
480
|
+
...volumeMounts,
|
|
441
481
|
"-w",
|
|
442
482
|
rootfsMountPath,
|
|
443
483
|
dockerImageTag,
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "orbitdb-relay-pinner",
|
|
4
|
+
"displayName": "OrbitDB Relay Pinner",
|
|
5
|
+
"source": {
|
|
6
|
+
"repository": "external",
|
|
7
|
+
"subdirectory": "."
|
|
8
|
+
},
|
|
9
|
+
"rootfs": {
|
|
10
|
+
"profile": "orbitdb-relay-pinner",
|
|
11
|
+
"installMode": "prebaked",
|
|
12
|
+
"installDir": "/opt/orbitdb-relay-pinner",
|
|
13
|
+
"binaryPath": "/usr/local/bin/orbitdb-relay-pinner",
|
|
14
|
+
"dataDir": "/var/lib/orbitdb-relay-pinner",
|
|
15
|
+
"envFile": "/etc/default/orbitdb-relay-pinner"
|
|
16
|
+
},
|
|
17
|
+
"services": {
|
|
18
|
+
"bootstrap": "orbitdb-relay-pinner-bootstrap.service",
|
|
19
|
+
"main": "orbitdb-relay-pinner.service",
|
|
20
|
+
"autotlsRefresh": "orbitdb-relay-pinner-autotls-refresh.service"
|
|
21
|
+
},
|
|
22
|
+
"ports": [
|
|
23
|
+
{
|
|
24
|
+
"port": 22,
|
|
25
|
+
"tcp": true,
|
|
26
|
+
"udp": false,
|
|
27
|
+
"purpose": "SSH"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"port": 80,
|
|
31
|
+
"tcp": true,
|
|
32
|
+
"udp": false,
|
|
33
|
+
"purpose": "Temporary setup endpoint"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"port": 9090,
|
|
37
|
+
"tcp": true,
|
|
38
|
+
"udp": false,
|
|
39
|
+
"purpose": "Metrics and health API"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"port": 9091,
|
|
43
|
+
"tcp": true,
|
|
44
|
+
"udp": false,
|
|
45
|
+
"purpose": "libp2p TCP"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"port": 443,
|
|
49
|
+
"tcp": true,
|
|
50
|
+
"udp": false,
|
|
51
|
+
"purpose": "Caddy HTTPS and WSS proxy"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"port": 9093,
|
|
55
|
+
"tcp": false,
|
|
56
|
+
"udp": true,
|
|
57
|
+
"purpose": "WebRTC direct"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"port": 9094,
|
|
61
|
+
"tcp": false,
|
|
62
|
+
"udp": true,
|
|
63
|
+
"purpose": "QUIC"
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"manifest": {
|
|
67
|
+
"copyTarget": "public/rootfs-manifest.json",
|
|
68
|
+
"notes": "The OrbitDB relay image prebakes Node.js, production dependencies, and Caddy into the qcow2, delays first relay start until Aleph host port mappings are known, exposes a temporary setup endpoint on port 80, and uses Caddy on port 443 to front both HTTPS helper routes and secure libp2p WSS transport for the configured proxy hostname."
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
FROM --platform=linux/amd64 debian:12
|
|
2
|
+
|
|
3
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
4
|
+
ENV LIBGUESTFS_BACKEND=direct
|
|
5
|
+
|
|
6
|
+
RUN apt-get update \
|
|
7
|
+
&& apt-get install -y --no-install-recommends \
|
|
8
|
+
ca-certificates \
|
|
9
|
+
curl \
|
|
10
|
+
jq \
|
|
11
|
+
libguestfs-tools \
|
|
12
|
+
linux-image-amd64 \
|
|
13
|
+
python3 \
|
|
14
|
+
qemu-system-x86 \
|
|
15
|
+
qemu-utils \
|
|
16
|
+
tar \
|
|
17
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
18
|
+
|
|
19
|
+
WORKDIR /workspace/relay-deployer-pwa
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
APP_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
6
|
+
REPO_DIR="$(cd "${APP_DIR}/.." && pwd)"
|
|
7
|
+
ROOTFS_CONTRACT_FILE="${ROOTFS_CONTRACT_FILE:-}"
|
|
8
|
+
ROOTFS_PROFILE="${ROOTFS_PROFILE:-}"
|
|
9
|
+
ROOTFS_INSTALL_MODE="${ROOTFS_INSTALL_MODE:-}"
|
|
10
|
+
PY_LIBP2P_DIR="${PY_LIBP2P_DIR:-${REPO_DIR}/py-libp2p}"
|
|
11
|
+
ORBITDB_RELAY_PINNER_DIR="${ORBITDB_RELAY_PINNER_DIR:-}"
|
|
12
|
+
UNIVERSAL_CONNECTIVITY_DIR="${UNIVERSAL_CONNECTIVITY_DIR:-}"
|
|
13
|
+
OUT_DIR="${OUT_DIR:-${APP_DIR}/dist-rootfs}"
|
|
14
|
+
BASE_URL="${BASE_URL:-https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2}"
|
|
15
|
+
BASE_IMAGE="${OUT_DIR}/debian-12-genericcloud-amd64.qcow2"
|
|
16
|
+
IMAGE_SIZE="${IMAGE_SIZE:-${ROOTFS_IMAGE_SIZE:-20G}}"
|
|
17
|
+
ROOTFS_SPARSIFY="${ROOTFS_SPARSIFY:-1}"
|
|
18
|
+
|
|
19
|
+
require() {
|
|
20
|
+
command -v "$1" >/dev/null 2>&1 || {
|
|
21
|
+
echo "Missing required command: $1" >&2
|
|
22
|
+
exit 1
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
require curl
|
|
27
|
+
require qemu-img
|
|
28
|
+
require virt-customize
|
|
29
|
+
require tar
|
|
30
|
+
|
|
31
|
+
load_rootfs_contract() {
|
|
32
|
+
[ -n "${ROOTFS_CONTRACT_FILE}" ] || return 0
|
|
33
|
+
require python3
|
|
34
|
+
[ -f "${ROOTFS_CONTRACT_FILE}" ] || {
|
|
35
|
+
echo "Rootfs contract does not exist: ${ROOTFS_CONTRACT_FILE}" >&2
|
|
36
|
+
exit 1
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
eval "$(python3 "${SCRIPT_DIR}/read-rootfs-contract.py" "${ROOTFS_CONTRACT_FILE}")"
|
|
40
|
+
|
|
41
|
+
if [ -n "${ROOTFS_PROFILE}" ] && [ "${ROOTFS_PROFILE}" != "${ROOTFS_CONTRACT_PROFILE}" ]; then
|
|
42
|
+
echo "ROOTFS_PROFILE=${ROOTFS_PROFILE} conflicts with contract profile ${ROOTFS_CONTRACT_PROFILE}" >&2
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
if [ -n "${ROOTFS_INSTALL_MODE}" ] && [ "${ROOTFS_INSTALL_MODE}" != "${ROOTFS_CONTRACT_INSTALL_MODE}" ]; then
|
|
46
|
+
echo "ROOTFS_INSTALL_MODE=${ROOTFS_INSTALL_MODE} conflicts with contract install mode ${ROOTFS_CONTRACT_INSTALL_MODE}" >&2
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
ROOTFS_PROFILE="${ROOTFS_CONTRACT_PROFILE}"
|
|
51
|
+
ROOTFS_INSTALL_MODE="${ROOTFS_INSTALL_MODE:-${ROOTFS_CONTRACT_INSTALL_MODE}}"
|
|
52
|
+
echo "Loaded rootfs contract: ${ROOTFS_CONTRACT_PATH}"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
load_rootfs_contract
|
|
56
|
+
ROOTFS_PROFILE="${ROOTFS_PROFILE:-py-libp2p}"
|
|
57
|
+
ROOTFS_CONTRACT_INSTALL_DIR="${ROOTFS_CONTRACT_INSTALL_DIR:-/opt/go-peer}"
|
|
58
|
+
ROOTFS_CONTRACT_DATA_DIR="${ROOTFS_CONTRACT_DATA_DIR:-/var/lib/uc-go-peer}"
|
|
59
|
+
ROOTFS_CONTRACT_ENV_FILE="${ROOTFS_CONTRACT_ENV_FILE:-/etc/default/uc-go-peer}"
|
|
60
|
+
ROOTFS_CONTRACT_BOOTSTRAP_SERVICE="${ROOTFS_CONTRACT_BOOTSTRAP_SERVICE:-uc-go-peer-bootstrap.service}"
|
|
61
|
+
ROOTFS_CONTRACT_MAIN_SERVICE="${ROOTFS_CONTRACT_MAIN_SERVICE:-uc-go-peer.service}"
|
|
62
|
+
ROOTFS_CONTRACT_AUTOTLS_SERVICE="${ROOTFS_CONTRACT_AUTOTLS_SERVICE:-uc-go-peer-autotls-refresh.service}"
|
|
63
|
+
ROOTFS_CONTRACT_BINARY_PATH="${ROOTFS_CONTRACT_BINARY_PATH:-/usr/local/bin/universal-chat-go}"
|
|
64
|
+
ROOTFS_CONTRACT_BINARY_DIR="$(dirname "${ROOTFS_CONTRACT_BINARY_PATH}")"
|
|
65
|
+
|
|
66
|
+
case "${ROOTFS_PROFILE}" in
|
|
67
|
+
py-libp2p)
|
|
68
|
+
IMAGE="${OUT_DIR}/aleph-py-libp2p-relay.qcow2"
|
|
69
|
+
APP_TAR="${OUT_DIR}/py-libp2p.tar"
|
|
70
|
+
if [ -z "${ROOTFS_INSTALL_MODE}" ]; then
|
|
71
|
+
ROOTFS_INSTALL_MODE="thin"
|
|
72
|
+
fi
|
|
73
|
+
if [ ! -d "${PY_LIBP2P_DIR}" ]; then
|
|
74
|
+
echo "Missing py-libp2p directory: ${PY_LIBP2P_DIR}" >&2
|
|
75
|
+
exit 1
|
|
76
|
+
fi
|
|
77
|
+
;;
|
|
78
|
+
orbitdb-relay-pinner)
|
|
79
|
+
IMAGE="${OUT_DIR}/aleph-orbitdb-relay-pinner.qcow2"
|
|
80
|
+
APP_TAR="${OUT_DIR}/orbitdb-relay-pinner.tar"
|
|
81
|
+
if [ -z "${ROOTFS_INSTALL_MODE}" ]; then
|
|
82
|
+
ROOTFS_INSTALL_MODE="prebaked"
|
|
83
|
+
fi
|
|
84
|
+
if [ -z "${ORBITDB_RELAY_PINNER_DIR}" ]; then
|
|
85
|
+
echo "ROOTFS_PROFILE=orbitdb-relay-pinner requires ORBITDB_RELAY_PINNER_DIR=/path/to/orbitdb-relay-pinner" >&2
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
if [ ! -d "${ORBITDB_RELAY_PINNER_DIR}" ]; then
|
|
89
|
+
echo "Missing orbitdb-relay-pinner directory: ${ORBITDB_RELAY_PINNER_DIR}" >&2
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
if [ ! -d "${ORBITDB_RELAY_PINNER_DIR}/dist" ]; then
|
|
93
|
+
echo "Missing orbitdb-relay-pinner dist directory: ${ORBITDB_RELAY_PINNER_DIR}/dist" >&2
|
|
94
|
+
echo "Build orbitdb-relay-pinner before creating this rootfs image." >&2
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
if [ "${ROOTFS_INSTALL_MODE}" = "thin" ]; then
|
|
98
|
+
echo "ROOTFS_PROFILE=orbitdb-relay-pinner now requires ROOTFS_INSTALL_MODE=prebaked." >&2
|
|
99
|
+
echo "The runtime is installed into the image, then configured with mapped ports before first start." >&2
|
|
100
|
+
exit 1
|
|
101
|
+
fi
|
|
102
|
+
;;
|
|
103
|
+
uc-go-peer)
|
|
104
|
+
IMAGE="${OUT_DIR}/aleph-uc-go-peer.qcow2"
|
|
105
|
+
APP_TAR="${OUT_DIR}/uc-go-peer.tar"
|
|
106
|
+
if [ -z "${ROOTFS_INSTALL_MODE}" ]; then
|
|
107
|
+
ROOTFS_INSTALL_MODE="prebaked"
|
|
108
|
+
fi
|
|
109
|
+
if [ -z "${UNIVERSAL_CONNECTIVITY_DIR}" ]; then
|
|
110
|
+
echo "ROOTFS_PROFILE=uc-go-peer requires UNIVERSAL_CONNECTIVITY_DIR=/path/to/universal-connectivity" >&2
|
|
111
|
+
exit 1
|
|
112
|
+
fi
|
|
113
|
+
if [ ! -d "${UNIVERSAL_CONNECTIVITY_DIR}/go-peer" ]; then
|
|
114
|
+
echo "Missing go-peer directory: ${UNIVERSAL_CONNECTIVITY_DIR}/go-peer" >&2
|
|
115
|
+
exit 1
|
|
116
|
+
fi
|
|
117
|
+
if [ "${ROOTFS_INSTALL_MODE}" = "thin" ]; then
|
|
118
|
+
echo "ROOTFS_PROFILE=uc-go-peer requires ROOTFS_INSTALL_MODE=prebaked." >&2
|
|
119
|
+
echo "The Go binary is built into the image, then configured with mapped ports before first start." >&2
|
|
120
|
+
exit 1
|
|
121
|
+
fi
|
|
122
|
+
;;
|
|
123
|
+
uc-rust-peer)
|
|
124
|
+
IMAGE="${OUT_DIR}/aleph-uc-rust-peer.qcow2"
|
|
125
|
+
APP_TAR="${OUT_DIR}/uc-rust-peer.tar"
|
|
126
|
+
if [ -z "${ROOTFS_INSTALL_MODE}" ]; then
|
|
127
|
+
ROOTFS_INSTALL_MODE="prebaked"
|
|
128
|
+
fi
|
|
129
|
+
if [ -z "${UNIVERSAL_CONNECTIVITY_DIR}" ]; then
|
|
130
|
+
echo "ROOTFS_PROFILE=uc-rust-peer requires UNIVERSAL_CONNECTIVITY_DIR=/path/to/universal-connectivity" >&2
|
|
131
|
+
exit 1
|
|
132
|
+
fi
|
|
133
|
+
if [ ! -d "${UNIVERSAL_CONNECTIVITY_DIR}/rust-peer" ]; then
|
|
134
|
+
echo "Missing rust-peer directory: ${UNIVERSAL_CONNECTIVITY_DIR}/rust-peer" >&2
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
if [ "${ROOTFS_INSTALL_MODE}" = "thin" ]; then
|
|
138
|
+
echo "ROOTFS_PROFILE=uc-rust-peer requires ROOTFS_INSTALL_MODE=prebaked." >&2
|
|
139
|
+
echo "The Rust binary and websocket bridge are built into the image, then configured with mapped ports before first start." >&2
|
|
140
|
+
exit 1
|
|
141
|
+
fi
|
|
142
|
+
;;
|
|
143
|
+
*)
|
|
144
|
+
echo "Unsupported ROOTFS_PROFILE: ${ROOTFS_PROFILE}" >&2
|
|
145
|
+
echo "Expected one of: py-libp2p, orbitdb-relay-pinner, uc-go-peer, uc-rust-peer" >&2
|
|
146
|
+
exit 1
|
|
147
|
+
;;
|
|
148
|
+
esac
|
|
149
|
+
|
|
150
|
+
case "${ROOTFS_INSTALL_MODE}" in
|
|
151
|
+
thin|prebaked)
|
|
152
|
+
;;
|
|
153
|
+
*)
|
|
154
|
+
echo "Unsupported ROOTFS_INSTALL_MODE: ${ROOTFS_INSTALL_MODE}" >&2
|
|
155
|
+
echo "Expected one of: thin, prebaked" >&2
|
|
156
|
+
exit 1
|
|
157
|
+
;;
|
|
158
|
+
esac
|
|
159
|
+
|
|
160
|
+
mkdir -p "${OUT_DIR}"
|
|
161
|
+
|
|
162
|
+
echo "Building ${ROOTFS_PROFILE} image in ${ROOTFS_INSTALL_MODE} mode"
|
|
163
|
+
|
|
164
|
+
if [ ! -f "${BASE_IMAGE}" ]; then
|
|
165
|
+
curl -L "${BASE_URL}" -o "${BASE_IMAGE}"
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
cp "${BASE_IMAGE}" "${IMAGE}"
|
|
169
|
+
qemu-img resize "${IMAGE}" "${IMAGE_SIZE}"
|
|
170
|
+
|
|
171
|
+
case "${ROOTFS_PROFILE}" in
|
|
172
|
+
py-libp2p)
|
|
173
|
+
tar \
|
|
174
|
+
--exclude ".git" \
|
|
175
|
+
--exclude ".venv" \
|
|
176
|
+
--exclude "__pycache__" \
|
|
177
|
+
-C "$(dirname "${PY_LIBP2P_DIR}")" \
|
|
178
|
+
-cf "${APP_TAR}" \
|
|
179
|
+
"$(basename "${PY_LIBP2P_DIR}")"
|
|
180
|
+
|
|
181
|
+
py_customize_args=(
|
|
182
|
+
-a "${IMAGE}"
|
|
183
|
+
--mkdir /opt/py-libp2p
|
|
184
|
+
--mkdir /var/lib/py-libp2p-relay
|
|
185
|
+
--copy-in "${APP_TAR}:/opt"
|
|
186
|
+
--copy-in "${SCRIPT_DIR}/relay-bootstrap.sh:/usr/local/sbin"
|
|
187
|
+
--copy-in "${SCRIPT_DIR}/py-libp2p-relay.service:/etc/systemd/system"
|
|
188
|
+
--copy-in "${SCRIPT_DIR}/py-libp2p-relay-bootstrap.service:/etc/systemd/system"
|
|
189
|
+
--run-command "tar -xf /opt/$(basename "${APP_TAR}") -C /opt/py-libp2p --strip-components=1"
|
|
190
|
+
--run-command "chmod 0755 /usr/local/sbin/relay-bootstrap.sh"
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
if [ "${ROOTFS_INSTALL_MODE}" = "prebaked" ]; then
|
|
194
|
+
py_customize_args+=(
|
|
195
|
+
--run-command "BOOTSTRAP_STAMP=/var/lib/py-libp2p-relay/bootstrap-complete RELAY_PORT=4001 /usr/local/sbin/relay-bootstrap.sh"
|
|
196
|
+
)
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
py_customize_args+=(
|
|
200
|
+
--run-command "systemctl enable py-libp2p-relay.service"
|
|
201
|
+
--run-command "rm -f /opt/$(basename "${APP_TAR}")"
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
virt-customize "${py_customize_args[@]}"
|
|
205
|
+
;;
|
|
206
|
+
orbitdb-relay-pinner)
|
|
207
|
+
tar \
|
|
208
|
+
-C "${ORBITDB_RELAY_PINNER_DIR}" \
|
|
209
|
+
-cf "${APP_TAR}" \
|
|
210
|
+
dist \
|
|
211
|
+
deploy \
|
|
212
|
+
package.json \
|
|
213
|
+
pnpm-lock.yaml \
|
|
214
|
+
pnpm-workspace.yaml \
|
|
215
|
+
README.md \
|
|
216
|
+
LICENSE \
|
|
217
|
+
.env.example
|
|
218
|
+
|
|
219
|
+
orbitdb_customize_args=(
|
|
220
|
+
-a "${IMAGE}"
|
|
221
|
+
--mkdir /opt/orbitdb-relay-pinner
|
|
222
|
+
--mkdir /var/lib/orbitdb-relay-pinner
|
|
223
|
+
--mkdir /etc/systemd/system/orbitdb-relay-pinner.service.d
|
|
224
|
+
--copy-in "${APP_TAR}:/opt"
|
|
225
|
+
--copy-in "${SCRIPT_DIR}/orbitdb-relay-pinner-bootstrap.sh:/usr/local/sbin"
|
|
226
|
+
--copy-in "${SCRIPT_DIR}/orbitdb-relay-pinner-configure.sh:/usr/local/sbin"
|
|
227
|
+
--copy-in "${SCRIPT_DIR}/orbitdb-relay-pinner-autotls-refresh.py:/usr/local/sbin"
|
|
228
|
+
--copy-in "${SCRIPT_DIR}/orbitdb-relay-pinner-setup-server.py:/usr/local/sbin"
|
|
229
|
+
--copy-in "${SCRIPT_DIR}/orbitdb-relay-pinner-describe.py:/usr/local/sbin"
|
|
230
|
+
--copy-in "${SCRIPT_DIR}/orbitdb-relay-pinner-bootstrap.service:/etc/systemd/system"
|
|
231
|
+
--copy-in "${SCRIPT_DIR}/orbitdb-relay-pinner-autotls-refresh.service:/etc/systemd/system"
|
|
232
|
+
--copy-in "${SCRIPT_DIR}/orbitdb-relay-pinner-bootstrap.conf:/etc/systemd/system/orbitdb-relay-pinner.service.d"
|
|
233
|
+
--run-command "tar -xf /opt/$(basename "${APP_TAR}") -C /opt/orbitdb-relay-pinner"
|
|
234
|
+
--run-command "chmod 0755 /usr/local/sbin/orbitdb-relay-pinner-bootstrap.sh"
|
|
235
|
+
--run-command "chmod 0755 /usr/local/sbin/orbitdb-relay-pinner-configure.sh"
|
|
236
|
+
--run-command "chmod 0755 /usr/local/sbin/orbitdb-relay-pinner-autotls-refresh.py"
|
|
237
|
+
--run-command "chmod 0755 /usr/local/sbin/orbitdb-relay-pinner-setup-server.py"
|
|
238
|
+
--run-command "chmod 0755 /usr/local/sbin/orbitdb-relay-pinner-describe.py"
|
|
239
|
+
--run-command "cp /opt/orbitdb-relay-pinner/deploy/orbitdb-relay-pinner.service /etc/systemd/system/orbitdb-relay-pinner.service"
|
|
240
|
+
--run-command "INSTALL_DIR=/opt/orbitdb-relay-pinner DATA_DIR=/var/lib/orbitdb-relay-pinner ENV_FILE=/etc/default/orbitdb-relay-pinner SERVICE_USER=orbitdb-relay /usr/local/sbin/orbitdb-relay-pinner-bootstrap.sh"
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
orbitdb_customize_args+=(
|
|
244
|
+
--run-command "systemctl enable orbitdb-relay-pinner-bootstrap.service"
|
|
245
|
+
--run-command "systemctl enable orbitdb-relay-pinner.service"
|
|
246
|
+
--run-command "rm -f /opt/$(basename "${APP_TAR}")"
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
virt-customize "${orbitdb_customize_args[@]}"
|
|
250
|
+
;;
|
|
251
|
+
uc-go-peer)
|
|
252
|
+
tar \
|
|
253
|
+
--exclude ".git" \
|
|
254
|
+
-C "${UNIVERSAL_CONNECTIVITY_DIR}" \
|
|
255
|
+
-cf "${APP_TAR}" \
|
|
256
|
+
go-peer
|
|
257
|
+
|
|
258
|
+
uc_go_customize_args=(
|
|
259
|
+
-a "${IMAGE}"
|
|
260
|
+
--mkdir "${ROOTFS_CONTRACT_INSTALL_DIR}"
|
|
261
|
+
--mkdir "${ROOTFS_CONTRACT_DATA_DIR}"
|
|
262
|
+
--mkdir "${ROOTFS_CONTRACT_BINARY_DIR}"
|
|
263
|
+
--copy-in "${APP_TAR}:/opt"
|
|
264
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap.sh:/usr/local/sbin"
|
|
265
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-configure.sh:/usr/local/sbin"
|
|
266
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-autotls-refresh.py:/usr/local/sbin"
|
|
267
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-setup-server.py:/usr/local/sbin"
|
|
268
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-describe.py:/usr/local/sbin"
|
|
269
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-bootstrap.service:/etc/systemd/system"
|
|
270
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer-autotls-refresh.service:/etc/systemd/system"
|
|
271
|
+
--copy-in "${SCRIPT_DIR}/uc-go-peer.service:/etc/systemd/system"
|
|
272
|
+
--run-command "tar -xf /opt/$(basename "${APP_TAR}") -C /opt"
|
|
273
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-bootstrap.sh"
|
|
274
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-configure.sh"
|
|
275
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-autotls-refresh.py"
|
|
276
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-setup-server.py"
|
|
277
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-go-peer-describe.py"
|
|
278
|
+
--run-command "INSTALL_DIR=${ROOTFS_CONTRACT_INSTALL_DIR} APP_BINARY=${ROOTFS_CONTRACT_BINARY_PATH} DATA_DIR=${ROOTFS_CONTRACT_DATA_DIR} ENV_FILE=${ROOTFS_CONTRACT_ENV_FILE} SERVICE_USER=uc-go-peer /usr/local/sbin/uc-go-peer-bootstrap.sh base"
|
|
279
|
+
--run-command "INSTALL_DIR=${ROOTFS_CONTRACT_INSTALL_DIR} APP_BINARY=${ROOTFS_CONTRACT_BINARY_PATH} DATA_DIR=${ROOTFS_CONTRACT_DATA_DIR} ENV_FILE=${ROOTFS_CONTRACT_ENV_FILE} SERVICE_USER=uc-go-peer /usr/local/sbin/uc-go-peer-bootstrap.sh build"
|
|
280
|
+
--run-command "INSTALL_DIR=${ROOTFS_CONTRACT_INSTALL_DIR} APP_BINARY=${ROOTFS_CONTRACT_BINARY_PATH} DATA_DIR=${ROOTFS_CONTRACT_DATA_DIR} ENV_FILE=${ROOTFS_CONTRACT_ENV_FILE} SERVICE_USER=uc-go-peer /usr/local/sbin/uc-go-peer-bootstrap.sh finalize"
|
|
281
|
+
--run-command "systemctl enable ${ROOTFS_CONTRACT_BOOTSTRAP_SERVICE}"
|
|
282
|
+
--run-command "systemctl enable ${ROOTFS_CONTRACT_AUTOTLS_SERVICE}"
|
|
283
|
+
--run-command "systemctl enable ${ROOTFS_CONTRACT_MAIN_SERVICE}"
|
|
284
|
+
--run-command "rm -f /opt/$(basename "${APP_TAR}")"
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
virt-customize "${uc_go_customize_args[@]}"
|
|
288
|
+
;;
|
|
289
|
+
uc-rust-peer)
|
|
290
|
+
tar \
|
|
291
|
+
--exclude "target" \
|
|
292
|
+
--exclude ".git" \
|
|
293
|
+
-C "${UNIVERSAL_CONNECTIVITY_DIR}" \
|
|
294
|
+
-cf "${APP_TAR}" \
|
|
295
|
+
rust-peer
|
|
296
|
+
|
|
297
|
+
uc_rust_customize_args=(
|
|
298
|
+
-a "${IMAGE}"
|
|
299
|
+
--mkdir /opt/rust-peer
|
|
300
|
+
--mkdir /var/lib/uc-rust-peer
|
|
301
|
+
--copy-in "${APP_TAR}:/opt"
|
|
302
|
+
--copy-in "${SCRIPT_DIR}/uc-rust-peer-bootstrap.sh:/usr/local/sbin"
|
|
303
|
+
--copy-in "${SCRIPT_DIR}/uc-rust-peer-configure.sh:/usr/local/sbin"
|
|
304
|
+
--copy-in "${SCRIPT_DIR}/uc-rust-peer-setup-server.py:/usr/local/sbin"
|
|
305
|
+
--copy-in "${SCRIPT_DIR}/uc-rust-peer-ws-bridge.py:/usr/local/sbin"
|
|
306
|
+
--copy-in "${SCRIPT_DIR}/uc-rust-peer-run.sh:/usr/local/sbin"
|
|
307
|
+
--copy-in "${SCRIPT_DIR}/uc-rust-peer-bootstrap.service:/etc/systemd/system"
|
|
308
|
+
--copy-in "${SCRIPT_DIR}/uc-rust-peer.service:/etc/systemd/system"
|
|
309
|
+
--copy-in "${SCRIPT_DIR}/uc-rust-peer-ws-bridge.service:/etc/systemd/system"
|
|
310
|
+
--run-command "tar -xf /opt/$(basename "${APP_TAR}") -C /opt"
|
|
311
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-rust-peer-bootstrap.sh"
|
|
312
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-rust-peer-configure.sh"
|
|
313
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-rust-peer-setup-server.py"
|
|
314
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-rust-peer-ws-bridge.py"
|
|
315
|
+
--run-command "chmod 0755 /usr/local/sbin/uc-rust-peer-run.sh"
|
|
316
|
+
--run-command "INSTALL_DIR=/opt/rust-peer DATA_DIR=/var/lib/uc-rust-peer ENV_FILE=/etc/default/uc-rust-peer SERVICE_USER=uc-rust-peer /usr/local/sbin/uc-rust-peer-bootstrap.sh"
|
|
317
|
+
--run-command "systemctl enable uc-rust-peer-bootstrap.service"
|
|
318
|
+
--run-command "systemctl enable uc-rust-peer.service"
|
|
319
|
+
--run-command "systemctl enable uc-rust-peer-ws-bridge.service"
|
|
320
|
+
--run-command "rm -f /opt/$(basename "${APP_TAR}")"
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
virt-customize "${uc_rust_customize_args[@]}"
|
|
324
|
+
;;
|
|
325
|
+
esac
|
|
326
|
+
|
|
327
|
+
if [ "${ROOTFS_SPARSIFY}" = "1" ] && command -v virt-sparsify >/dev/null 2>&1; then
|
|
328
|
+
SPARSE_IMAGE="${IMAGE%.qcow2}.sparse.qcow2"
|
|
329
|
+
rm -f "${SPARSE_IMAGE}"
|
|
330
|
+
echo "Sparsifying and compressing ${IMAGE}..."
|
|
331
|
+
virt-sparsify --compress "${IMAGE}" "${SPARSE_IMAGE}"
|
|
332
|
+
mv "${SPARSE_IMAGE}" "${IMAGE}"
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
echo "Rootfs image ready at ${IMAGE}"
|