Skip to content

Commit

Permalink
Add package cleanup command. (#174)
Browse files Browse the repository at this point in the history
In some cases a YUM operation can leave things partially finished. i.e. doing a live update of the sansshell YUM package could result in a server restart before yum has completed.

Allow this to fix via Cleanup which for YUM implements yum-complete-transaction --cleanup-only

Add client support and tests
  • Loading branch information
sfc-gh-jchacon authored Oct 18, 2022
1 parent 19f7e07 commit 5b3121c
Show file tree
Hide file tree
Showing 9 changed files with 521 additions and 54 deletions.
54 changes: 54 additions & 0 deletions services/packages/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func setup(f *flag.FlagSet) *subcommands.Commander {
c.Register(&listCmd{}, "")
c.Register(&repoListCmd{}, "")
c.Register(&updateCmd{}, "")
c.Register(&cleanupCmd{}, "")
return c
}

Expand Down Expand Up @@ -369,3 +370,56 @@ func getStatus(s pb.RepoStatus) string {
}
return status
}

type cleanupCmd struct {
packageSystem string
}

func (*cleanupCmd) Name() string { return "cleanup" }
func (*cleanupCmd) Synopsis() string { return "Run cleanup on machine" }
func (*cleanupCmd) Usage() string {
return `cleanup [--package_system=P]:
Run cleanup on remote machine
`
}

func (r *cleanupCmd) SetFlags(f *flag.FlagSet) {
f.StringVar(&r.packageSystem, "package-system", "YUM", fmt.Sprintf("Package system to use(one of: [%s])", strings.Join(shortPackageSystemNames(), ",")))
}

func (r *cleanupCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
if f.NArg() != 0 {
fmt.Fprintln(os.Stderr, "All options are set via flags")
return subcommands.ExitFailure
}
ps, err := flagToType(r.packageSystem)
if err != nil {
fmt.Fprintf(os.Stderr, "Can't parse package system for --package-system: %s invalid\n", r.packageSystem)
return subcommands.ExitFailure
}

state := args[0].(*util.ExecuteState)
c := pb.NewPackagesClientProxy(state.Conn)

resp, err := c.CleanupOneMany(ctx, &pb.CleanupRequest{
PackageSystem: ps,
})
if err != nil {
// Emit this to every error file as it's not specific to a given target.
for _, e := range state.Err {
fmt.Fprintf(e, "All targets - Cleanup returned error: %v\n", err)
}
return subcommands.ExitFailure
}

retCode := subcommands.ExitSuccess
for s := range resp {
if s.Error != nil {
fmt.Fprintf(state.Err[s.Index], "Cleanup for target %s (%d) returned error: %v\n", s.Target, s.Index, s.Error)
retCode = subcommands.ExitFailure
continue
}
fmt.Fprintf(state.Out[s.Index], "%s", s.Resp.DebugOutput)
}
return retCode
}
231 changes: 183 additions & 48 deletions services/packages/packages.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions services/packages/packages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ service Packages {
rpc Update(UpdateRequest) returns (UpdateReply) {}
rpc ListInstalled(ListInstalledRequest) returns (ListInstalledReply) {}
rpc RepoList(RepoListRequest) returns (RepoListReply) {}
// Cleanup executes any package system specific cleanup such as
// yum-complete-transaction for YUM systems. If a given package system doesn't
// have this API this is a no-op.
rpc Cleanup(CleanupRequest) returns (CleanupResponse) {}
}

// Allow different package systems as future proofing.
Expand Down Expand Up @@ -92,3 +96,7 @@ message Repo {
}

message RepoListReply { repeated Repo repos = 1; }

message CleanupRequest { PackageSystem package_system = 1; }

message CleanupResponse { string debug_output = 1; }
Loading

0 comments on commit 5b3121c

Please sign in to comment.