package cmd
import (
"cmp"
"context"
"flag"
"fmt"
"io"
"os"
"github.com/openeuler/Conch/internal/cli/client"
)
func PrintSnapshotHelp(out io.Writer) {
fmt.Fprintln(out, "Usage:")
fmt.Fprintln(out, " conch debug snapshot ls [options]")
fmt.Fprintln(out, " conch debug snapshot rm [options] <snapshot-key>")
fmt.Fprintln(out, "")
fmt.Fprintln(out, "Subcommands:")
fmt.Fprintln(out, " ls List EROFS snapshots from conchd/containerd.")
fmt.Fprintln(out, " rm Remove one EROFS snapshot from conchd/containerd.")
fmt.Fprintln(out, "")
fmt.Fprintln(out, "Common usage:")
fmt.Fprintln(out, " conch debug snapshot ls")
fmt.Fprintln(out, " conch debug snapshot rm <snapshot-key>")
}
func runSnapshot(ctx context.Context, args []string) error {
if len(args) == 0 || args[0] == "-h" || args[0] == "--help" {
PrintSnapshotHelp(os.Stdout)
return nil
}
switch args[0] {
case "ls":
return runSnapshotList(ctx, args[1:])
case "rm":
return runSnapshotRemove(ctx, args[1:])
default:
PrintSnapshotHelp(os.Stderr)
return fmt.Errorf("unknown debug snapshot command %q", args[0])
}
}
func runSnapshotList(ctx context.Context, args []string) error {
fs := flag.NewFlagSet("debug snapshot ls", flag.ContinueOnError)
fs.SetOutput(os.Stderr)
configPath := fs.String("config", "", "config file path")
var filters stringSliceFlag
fs.Var(&filters, "filter", "containerd snapshot filter")
if err := fs.Parse(args); err != nil {
return err
}
if fs.NArg() != 0 {
return fmt.Errorf("conch debug snapshot ls: unexpected positional arguments: %v", fs.Args())
}
conchClient, err := client.New(client.Options{ConfigPath: *configPath})
if err != nil {
return fmt.Errorf("conch debug snapshot ls: create API client: %w", err)
}
snapshots, err := conchClient.ListSnapshots(ctx, client.ListSnapshotsRequest{
Filters: filters,
})
if err != nil {
return fmt.Errorf("conch debug snapshot ls: %w", err)
}
fmt.Fprintf(os.Stdout, "%-12s %-64s %-64s\n", "KIND", "KEY", "PARENT")
for _, snapshot := range snapshots {
fmt.Fprintf(os.Stdout, "%-12s %-64s %-64s\n",
snapshot.Kind,
snapshot.Key,
cmp.Or(snapshot.Parent, "-"),
)
}
return nil
}
func runSnapshotRemove(ctx context.Context, args []string) error {
fs := flag.NewFlagSet("debug snapshot rm", flag.ContinueOnError)
fs.SetOutput(os.Stderr)
configPath := fs.String("config", "", "config file path")
if err := fs.Parse(args); err != nil {
return err
}
if fs.NArg() != 1 {
return fmt.Errorf("conch debug snapshot rm: exactly one snapshot key is required")
}
key := fs.Arg(0)
conchClient, err := client.New(client.Options{ConfigPath: *configPath})
if err != nil {
return fmt.Errorf("conch debug snapshot rm: create API client: %w", err)
}
if err := conchClient.RemoveSnapshot(ctx, client.RemoveSnapshotRequest{
Key: key,
}); err != nil {
return fmt.Errorf("conch debug snapshot rm: %w", err)
}
fmt.Fprintf(os.Stdout, "Removed snapshot: %s\n", key)
return nil
}