paratix 0.6.0 → 0.7.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 +1 -1
- package/dist/{chunk-ENWMSERJ.js → chunk-D4CS2GCH.js} +73 -21
- package/dist/chunk-D4CS2GCH.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/modules/index.d.ts +2 -2
- package/dist/modules/index.js +1 -1
- package/dist/{types-BPzPHfax.d.ts → types-Cl2Muw1x.d.ts} +2 -0
- package/dist/{user-CiAMlpWO.d.ts → user-BJMqDePy.d.ts} +1 -1
- package/llm-guide.md +1 -1
- package/package.json +1 -1
- package/dist/chunk-ENWMSERJ.js.map +0 -1
package/README.md
CHANGED
|
@@ -104,7 +104,7 @@ Signals are deferred side effects such as `service.reload(...)` or `service.rest
|
|
|
104
104
|
|
|
105
105
|
For Podman-native services, Paratix now also includes `quadlet.container(...)`. It writes a `.container` file under `/etc/containers/systemd`, reloads systemd when the content changes, and works cleanly with `service.enabled(...)` and `service.running(...)` for the generated service.
|
|
106
106
|
|
|
107
|
-
When you need a targeted image refresh outside the normal deploy flow, `quadlet.updateImage(...)` pulls exactly one image, reuses existing Podman registry auth on the host, optionally supports `authFile`, and only restarts the generated service when the pull actually downloaded a newer image.
|
|
107
|
+
When you need a targeted image refresh outside the normal deploy flow, `quadlet.updateImage(...)` pulls exactly one image, reuses existing Podman registry auth on the host, optionally supports `authFile`, and only restarts the generated service when the pull actually downloaded a newer image. Changed runs now also print the new image ID in parentheses in the CLI output.
|
|
108
108
|
|
|
109
109
|
### Guards
|
|
110
110
|
|
|
@@ -3522,6 +3522,12 @@ function buildQuadletImagePullCommand(options) {
|
|
|
3522
3522
|
const authFileFlag = options.authFile == null ? "" : ` --authfile ${shellQuoteForQuadlet(options.authFile)}`;
|
|
3523
3523
|
return `podman pull${authFileFlag} ${shellQuoteForQuadlet(options.image)} 2>&1`;
|
|
3524
3524
|
}
|
|
3525
|
+
function buildQuadletImageInspectCommand(image) {
|
|
3526
|
+
return `podman image inspect --format '{{.Id}}' ${shellQuoteForQuadlet(image)}`;
|
|
3527
|
+
}
|
|
3528
|
+
function formatQuadletImageIdDetail(imageId) {
|
|
3529
|
+
return `(${imageId})`;
|
|
3530
|
+
}
|
|
3525
3531
|
function getQuadletContainerFilePath(name) {
|
|
3526
3532
|
return `${CONTAINERS_SYSTEMD_DIRECTORY}/${name}.container`;
|
|
3527
3533
|
}
|
|
@@ -3531,6 +3537,13 @@ function getQuadletContainerServiceName(options) {
|
|
|
3531
3537
|
function quadletPullOutputIndicatesChange(output) {
|
|
3532
3538
|
return QUADLET_PULL_CHANGED_OUTPUT_PATTERNS.some((pattern) => output.includes(pattern));
|
|
3533
3539
|
}
|
|
3540
|
+
function readQuadletImageIdFromInspectOutput(output) {
|
|
3541
|
+
for (const line of output.split("\n")) {
|
|
3542
|
+
const trimmed = line.trim();
|
|
3543
|
+
if (trimmed.length > 0) return trimmed;
|
|
3544
|
+
}
|
|
3545
|
+
return null;
|
|
3546
|
+
}
|
|
3534
3547
|
var UNIT_NAME_PATTERN2 = new RegExp("^[\\w@.\\-]+$", "v");
|
|
3535
3548
|
function validateQuadletName(name) {
|
|
3536
3549
|
if (!UNIT_NAME_PATTERN2.test(name)) {
|
|
@@ -3588,6 +3601,58 @@ async function checkQuadletFile(parameters) {
|
|
|
3588
3601
|
const remoteContent = await parameters.ssh.readFile(parameters.filePath);
|
|
3589
3602
|
return remoteContent.trim() === parameters.content.trim() ? "ok" : NEEDS_APPLY;
|
|
3590
3603
|
}
|
|
3604
|
+
async function inspectQuadletImageId(parameters) {
|
|
3605
|
+
const inspectResult = await parameters.ssh.exec(parameters.inspectCommand, {
|
|
3606
|
+
ignoreExitCode: true,
|
|
3607
|
+
silent: true
|
|
3608
|
+
});
|
|
3609
|
+
if (inspectResult.code !== 0) {
|
|
3610
|
+
return failedCommand(
|
|
3611
|
+
`[quadlet.updateImage: ${parameters.name}] podman image inspect failed`,
|
|
3612
|
+
inspectResult
|
|
3613
|
+
);
|
|
3614
|
+
}
|
|
3615
|
+
const imageId = readQuadletImageIdFromInspectOutput(inspectResult.stdout);
|
|
3616
|
+
if (imageId == null) {
|
|
3617
|
+
return failed(
|
|
3618
|
+
`[quadlet.updateImage: ${parameters.name}] podman image inspect returned no image ID`
|
|
3619
|
+
);
|
|
3620
|
+
}
|
|
3621
|
+
return imageId;
|
|
3622
|
+
}
|
|
3623
|
+
async function restartQuadletService(parameters) {
|
|
3624
|
+
const restartResult = await parameters.ssh.exec(
|
|
3625
|
+
`${SYSTEMCTL} restart ${shellQuote(parameters.serviceName)}`,
|
|
3626
|
+
{
|
|
3627
|
+
ignoreExitCode: true,
|
|
3628
|
+
silent: true
|
|
3629
|
+
}
|
|
3630
|
+
);
|
|
3631
|
+
return restartResult.code === 0 ? { detail: formatQuadletImageIdDetail(parameters.imageId), status: "changed" } : failedCommand(
|
|
3632
|
+
`[quadlet.updateImage: ${parameters.name}] systemctl restart failed`,
|
|
3633
|
+
restartResult
|
|
3634
|
+
);
|
|
3635
|
+
}
|
|
3636
|
+
async function applyQuadletImageUpdate(parameters) {
|
|
3637
|
+
const pullResult = await parameters.ssh.exec(parameters.pullCommand, {
|
|
3638
|
+
ignoreExitCode: true,
|
|
3639
|
+
silent: true
|
|
3640
|
+
});
|
|
3641
|
+
if (pullResult.code !== 0) {
|
|
3642
|
+
return failedCommand(`[quadlet.updateImage: ${parameters.name}] podman pull failed`, pullResult);
|
|
3643
|
+
}
|
|
3644
|
+
if (!quadletPullOutputIndicatesChange(pullResult.stdout)) {
|
|
3645
|
+
return { status: "ok" };
|
|
3646
|
+
}
|
|
3647
|
+
const imageId = await inspectQuadletImageId(parameters);
|
|
3648
|
+
if (typeof imageId !== "string") return imageId;
|
|
3649
|
+
return restartQuadletService({
|
|
3650
|
+
imageId,
|
|
3651
|
+
name: parameters.name,
|
|
3652
|
+
serviceName: parameters.serviceName,
|
|
3653
|
+
ssh: parameters.ssh
|
|
3654
|
+
});
|
|
3655
|
+
}
|
|
3591
3656
|
var quadlet = {
|
|
3592
3657
|
/**
|
|
3593
3658
|
* Write a Podman Quadlet `.container` definition and reload systemd when it changes.
|
|
@@ -3628,31 +3693,18 @@ var quadlet = {
|
|
|
3628
3693
|
validateQuadletName(options.name);
|
|
3629
3694
|
if (options.serviceName != null) validateQuadletName(options.serviceName);
|
|
3630
3695
|
const pullCommand = buildQuadletImagePullCommand(options);
|
|
3696
|
+
const inspectCommand = buildQuadletImageInspectCommand(options.image);
|
|
3631
3697
|
const serviceName = getQuadletContainerServiceName(options);
|
|
3632
3698
|
return {
|
|
3633
3699
|
async apply(ssh2) {
|
|
3634
3700
|
if (!ssh2) return failed(`[quadlet.updateImage: ${options.name}] SSH connection is required`);
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
`[quadlet.updateImage: ${options.name}] podman pull failed`,
|
|
3642
|
-
pullResult
|
|
3643
|
-
);
|
|
3644
|
-
}
|
|
3645
|
-
if (!quadletPullOutputIndicatesChange(pullResult.stdout)) {
|
|
3646
|
-
return { status: "ok" };
|
|
3647
|
-
}
|
|
3648
|
-
const restartResult = await ssh2.exec(`${SYSTEMCTL} restart ${shellQuote(serviceName)}`, {
|
|
3649
|
-
ignoreExitCode: true,
|
|
3650
|
-
silent: true
|
|
3701
|
+
return applyQuadletImageUpdate({
|
|
3702
|
+
inspectCommand,
|
|
3703
|
+
name: options.name,
|
|
3704
|
+
pullCommand,
|
|
3705
|
+
serviceName,
|
|
3706
|
+
ssh: ssh2
|
|
3651
3707
|
});
|
|
3652
|
-
return restartResult.code === 0 ? { status: "changed" } : failedCommand(
|
|
3653
|
-
`[quadlet.updateImage: ${options.name}] systemctl restart failed`,
|
|
3654
|
-
restartResult
|
|
3655
|
-
);
|
|
3656
3708
|
},
|
|
3657
3709
|
// eslint-disable-next-line @typescript-eslint/require-await -- Signal-style module
|
|
3658
3710
|
async check() {
|
|
@@ -5742,4 +5794,4 @@ export {
|
|
|
5742
5794
|
ufw,
|
|
5743
5795
|
user
|
|
5744
5796
|
};
|
|
5745
|
-
//# sourceMappingURL=chunk-
|
|
5797
|
+
//# sourceMappingURL=chunk-D4CS2GCH.js.map
|