package pubshards import ( "fmt" "io" "os" "strconv" "strings" "github.com/spf13/cobra" cliapi "gitlink.org.cn/cloudream/jcs-pub/client/sdk/api/v1" jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types" "gitlink.org.cn/cloudream/jcs-pub/jcsctl/cmd" ) func init() { var opt exportOption c := &cobra.Command{ Use: "export ", Short: "export package object metadata as a file", Args: cobra.ExactArgs(1), RunE: func(c *cobra.Command, args []string) error { ctx := cmd.GetCmdCtx(c) return export(c, ctx, opt, args) }, } PubShardsCmd.AddCommand(c) c.Flags().BoolVarP(&opt.UseID, "id", "i", false, "treat first argumnet as package ID instead of package path") c.Flags().StringArrayVarP(&opt.PubShardsNames, "pubshards", "p", nil, "pub shards name") c.Flags().StringVarP(&opt.OutputPath, "output", "o", "", "output file path") } type exportOption struct { UseID bool PubShardsNames []string OutputPath string } func export(c *cobra.Command, ctx *cmd.CommandContext, opt exportOption, args []string) error { if len(opt.PubShardsNames) == 0 { return fmt.Errorf("you must specify at least one userspace name") } var pkgID jcstypes.PackageID if opt.UseID { id, err := strconv.ParseInt(args[0], 10, 64) if err != nil { return fmt.Errorf("invalid package ID: %s", args[0]) } pkgID = jcstypes.PackageID(id) } else { comps := strings.Split(args[0], "/") if len(comps) != 2 { return fmt.Errorf("invalid package path: %s", args[0]) } resp, err := ctx.Client.Package().GetByFullName(cliapi.PackageGetByFullName{ BucketName: comps[0], PackageName: comps[1], }) if err != nil { return fmt.Errorf("get package by full name: %w", err) } pkgID = resp.Package.PackageID } _, err := ctx.Client.Package().Pin(cliapi.PackagePin{ PackageID: pkgID, Pin: true, }) if err != nil { return fmt.Errorf("pin package: %w", err) } var pubIDs []jcstypes.PubShardsID for _, name := range opt.PubShardsNames { resp, err := ctx.Client.PubShards().Get(cliapi.PubShardsGet{ Name: name, }) if err != nil { return fmt.Errorf("get user space %v by name: %w", name, err) } pubIDs = append(pubIDs, resp.PubShards.PubShardsID) } resp, err := ctx.Client.PubShards().ExportPackage(cliapi.PubShardsExportPackage{ PackageID: pkgID, AvailablePubShards: pubIDs, }) if err != nil { return fmt.Errorf("export package: %w", err) } outputPath := opt.OutputPath if outputPath == "" { outputPath = resp.FileName } outputFile, err := os.Create(outputPath) if err != nil { return fmt.Errorf("create output file: %w", err) } defer outputFile.Close() _, err = io.Copy(outputFile, resp.PackFile) if err != nil { return fmt.Errorf("write output file: %w", err) } fmt.Printf("Package %v exported to %v, which also set pinned to true\n", pkgID, outputPath) return nil }