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 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
- const pullResult = await ssh2.exec(pullCommand, {
3636
- ignoreExitCode: true,
3637
- silent: true
3638
- });
3639
- if (pullResult.code !== 0) {
3640
- return failedCommand(
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-ENWMSERJ.js.map
5797
+ //# sourceMappingURL=chunk-D4CS2GCH.js.map