Hold an archive, a process's unit and a user found on an adopted node for an untaken module (hq ADR 0103)

This commit is contained in:
2026-09-22 18:32:20 +02:00
parent 491e04fb8f
commit aef4993d10
3 changed files with 134 additions and 2 deletions
+57
View File
@@ -72,6 +72,25 @@ func lookBefore(ctx context.Context, sys system.System, d *declaration.Declarati
if present(res.Path) && !recordedPath(known, res.Path) {
seen["path:"+res.Path] = true
}
case *declaration.Archive:
// Unpacking over it, and re-owning it recursively, would change the predecessor's
// files.
if present(res.Path) && !recordedPath(known, res.Path) {
seen["path:"+res.Path] = true
}
case *declaration.Process:
// Its unit would be written over and restarted.
if !known.Recorded(string(declaration.TypeProcess), res.Name) &&
present(filepath.Join(unitDir, res.Name+".service")) {
seen["unit-file:"+res.Name] = true
}
case *declaration.User:
// Its shell and groups would be changed.
if !known.Recorded(string(declaration.TypeUser), res.Name) {
if _, exists, err := system.LookUpUser(ctx, run, res.Name); err == nil && exists {
seen["user:"+res.Name] = true
}
}
case *declaration.Service:
if known.Recorded(string(declaration.TypeService), res.Unit) {
continue
@@ -239,6 +258,12 @@ func holdOnAdopted(ctx context.Context, sys system.System, r declaration.Resourc
}
case *declaration.Directory:
isFound = before["path:"+res.Path]
case *declaration.Archive:
isFound = before["path:"+res.Path]
case *declaration.Process:
isFound = before["unit-file:"+res.Name]
case *declaration.User:
isFound = before["user:"+res.Name]
case *declaration.Service:
isFound = before["unit:"+res.Unit]
}
@@ -396,6 +421,38 @@ func hold(ctx context.Context, sys system.System, r declaration.Resource, module
}
}
detail = "found on the machine; its mode, owner and contents kept until " + module + " is taken"
case *declaration.Archive:
if _, err := os.Lstat(res.Path); errors.Is(err, os.ErrNotExist) {
if !already {
return out, h, fmt.Errorf("%s was found and is gone before it could be held", res.Path)
}
changed = "gone"
} else if err != nil {
return out, h, err
}
detail = "something is already at " + res.Path + "; nothing unpacked over it or re-owned until " +
module + " is taken"
case *declaration.Process:
unit := filepath.Join(unitDir, res.Name+".service")
if !present(unit) {
if !already {
return out, h, fmt.Errorf("%s was found and is gone before it could be held", unit)
}
changed = "gone"
}
detail = "its unit " + unit + " was found on the machine; not written over or restarted until " +
module + " is taken"
case *declaration.User:
_, exists, err := system.LookUpUser(ctx, run, res.Name)
switch {
case err != nil:
return out, h, err
case !exists && !already:
return out, h, fmt.Errorf("the user %s was found and is gone before it could be held", res.Name)
case !exists:
changed = "gone"
}
detail = "the user was found on the machine; its shell and groups are kept until " + module + " is taken"
case *declaration.Service:
state, err := sys.ServiceState(ctx, run, res.Unit)
switch {