feat: make storage:mount upsert the existing attachment
Re-running `storage:mount <app> <entry> --container-dir <path>` against an existing `(entry, container_dir, process_type)` tuple now updates the attachment's mount-time fields in place instead of erroring with `already mounted`. Declarative tooling that wants to change `--volume-options`, `--volume-chown`, `--phase`, `--volume-subpath`, or `--volume-readonly` on an existing mount no longer has to unmount-then-remount, which briefly dropped the volume from `storage:report` and raced against any deploy that fired in the window. The legacy `host:container[:opts]` form keeps its strict `Mount path already exists.` failure.
This commit is contained in:
@@ -193,7 +193,21 @@ func CommandMount(input CommandMountInput) error {
|
||||
VolumeChown: input.VolumeChown,
|
||||
}
|
||||
|
||||
return AddAttachment(input.AppName, attachment)
|
||||
// Idempotent contract: same (entry, container_dir, process_type)
|
||||
// tuple updates the mount-time fields in place rather than appending
|
||||
// a duplicate attachment. Lets declarative tooling change
|
||||
// --volume-options / --volume-chown / --phase / etc. without an
|
||||
// unmount-then-remount dance that briefly drops the volume.
|
||||
created, err := UpsertAttachment(input.AppName, attachment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if created {
|
||||
common.LogInfo1(fmt.Sprintf("Storage entry %s mounted at %s on %s", entry.Name, input.ContainerDir, input.AppName))
|
||||
} else {
|
||||
common.LogInfo1(fmt.Sprintf("Storage entry %s mount at %s on %s updated", entry.Name, input.ContainerDir, input.AppName))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommandUnmountInput captures the flags accepted by storage:unmount when
|
||||
|
||||
Reference in New Issue
Block a user