/* * Copyright 2026 Oleg Borodin * * This work is published and licensed under a Creative Commons * Attribution-NonCommercial-NoDerivatives 4.0 International License. * * Distribution of this work is permitted, but commercial use and * modifications are strictly prohibited. */ package main import ( "context" "net/url" "path" "strings" "time" "mstore/pkg/client" "github.com/spf13/cobra" ) func packUserinfo(resurseuri, username, password string) (string, error) { var err error var res string if !strings.Contains(resurseuri, "://") { resurseuri = "https://" + resurseuri } uri, err := url.Parse(resurseuri) if err != nil { return res, err } uri.Path = path.Clean(uri.Path) if username != "" && password != "" { uri.User = url.UserPassword(username, password) } res = uri.String() return res, err } func (util *ImageUtil) CreateImageCmds() *cobra.Command { const defaultTimeout uint64 = 30 // Second var subCmd = &cobra.Command{ Use: "image", Short: "Image operation", } // PushImage var pushImageCmd = &cobra.Command{ Use: "push", Short: "Pull container image into local file", Run: util.PushImage, } pushImageCmd.Flags().StringVarP(&util.pushImageParams.Username, "user", "u", "", "Username") pushImageCmd.Flags().StringVarP(&util.pushImageParams.Password, "pass", "p", "", "Password") pushImageCmd.Flags().StringVarP(&util.pushImageParams.Imagepath, "image", "i", "", "Remote image path") pushImageCmd.Flags().StringVarP(&util.pushImageParams.Filepath, "file", "f", "", "Local file path") pushImageCmd.Flags().Uint64VarP(&util.pushImageParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") pushImageCmd.MarkFlagRequired("image") pushImageCmd.MarkFlagRequired("file") pushImageCmd.MarkFlagsRequiredTogether("user", "pass") subCmd.AddCommand(pushImageCmd) // ImageInfo var imageInfoCmd = &cobra.Command{ Use: "info", Short: "Show container image info", Run: util.ImageInfo, } imageInfoCmd.Flags().StringVarP(&util.imageInfoParams.Username, "user", "u", "", "Username") imageInfoCmd.Flags().StringVarP(&util.imageInfoParams.Password, "pass", "p", "", "Password") imageInfoCmd.Flags().StringVarP(&util.imageInfoParams.Imagepath, "image", "i", "", "Remote image path") imageInfoCmd.Flags().Uint64VarP(&util.imageInfoParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") imageInfoCmd.MarkFlagRequired("image") imageInfoCmd.MarkFlagsRequiredTogether("user", "pass") subCmd.AddCommand(imageInfoCmd) // PullImage var pullImageCmd = &cobra.Command{ Use: "pull", Short: "Pull container image into local file", Run: util.PullImage, } pullImageCmd.Flags().StringVarP(&util.pullImageParams.Username, "user", "u", "", "Username") pullImageCmd.Flags().StringVarP(&util.pullImageParams.Password, "pass", "p", "", "Password") pullImageCmd.Flags().StringVarP(&util.pullImageParams.Imagepath, "image", "i", "", "Remote image path") pullImageCmd.Flags().StringVarP(&util.pullImageParams.Filepath, "file", "f", "", "Local file path") pullImageCmd.Flags().Uint64VarP(&util.pullImageParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") pullImageCmd.MarkFlagRequired("image") pullImageCmd.MarkFlagRequired("file") pullImageCmd.MarkFlagsRequiredTogether("user", "pass") subCmd.AddCommand(pullImageCmd) // DeleteImage var deleteImageCmd = &cobra.Command{ Use: "info", Short: "Show container image info", Run: util.DeleteImage, } deleteImageCmd.Flags().StringVarP(&util.deleteImageParams.Username, "user", "u", "", "Username") deleteImageCmd.Flags().StringVarP(&util.deleteImageParams.Password, "pass", "p", "", "Password") deleteImageCmd.Flags().StringVarP(&util.deleteImageParams.Imagepath, "image", "i", "", "Remote image path") deleteImageCmd.Flags().Uint64VarP(&util.deleteImageParams.Timeout, "timeout", "t", defaultTimeout, "Operation timeout") deleteImageCmd.MarkFlagRequired("image") deleteImageCmd.MarkFlagsRequiredTogether("user", "pass") subCmd.AddCommand(imageInfoCmd) return subCmd } type ImageUtil struct { imageInfoParams ImageInfoParams pullImageParams PullImageParams pushImageParams PushImageParams deleteImageParams DeleteImageParams } // PushImage type PushImageParams struct { Imagepath string Filepath string Timeout uint64 Username string Password string } type PushImageResult struct{} func (util *ImageUtil) PushImage(cmd *cobra.Command, args []string) { res, err := util.pushImage(&util.pushImageParams) printResponse(res, err) } func (util *ImageUtil) pushImage(params *PushImageParams) (*PushImageResult, error) { var err error ctx := context.Background() res := &PushImageResult{} cli := client.NewClient() timeout := time.Duration(params.Timeout) * time.Second params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password) if err != nil { return res, err } ctx, _ = context.WithTimeout(ctx, timeout) err = cli.PushImage(ctx, params.Filepath, params.Imagepath) if err != nil { return res, err } return res, err } // ImageInfo type ImageInfoParams struct { Imagepath string Timeout uint64 Username string Password string } type ImageInfoResult struct { ImageInfo *client.ImageDescr `json:"imageInfo"` } func (util *ImageUtil) ImageInfo(cmd *cobra.Command, args []string) { res, err := util.imageInfo(&util.imageInfoParams) printResponse(res, err) } func (util *ImageUtil) imageInfo(params *ImageInfoParams) (*ImageInfoResult, error) { var err error res := &ImageInfoResult{} ctx := context.Background() cli := client.NewClient() timeout := time.Duration(params.Timeout) * time.Second params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password) if err != nil { return res, err } ctx, _ = context.WithTimeout(ctx, timeout) opres, err := cli.ImageInfo(ctx, params.Imagepath) if err != nil { return res, err } res.ImageInfo = opres return res, err } // PullImage type PullImageParams struct { Imagepath string Filepath string Timeout uint64 Username string Password string } type PullImageResult struct{} func (util *ImageUtil) PullImage(cmd *cobra.Command, args []string) { res, err := util.pullImage(&util.pullImageParams) printResponse(res, err) } func (util *ImageUtil) pullImage(params *PullImageParams) (*PullImageResult, error) { var err error ctx := context.Background() res := &PullImageResult{} cli := client.NewClient() timeout := time.Duration(params.Timeout) * time.Second params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password) if err != nil { return res, err } ctx, _ = context.WithTimeout(ctx, timeout) err = cli.PullImage(ctx, params.Imagepath, params.Filepath) if err != nil { return res, err } return res, err } // DeleteImage type DeleteImageParams struct { Imagepath string Timeout uint64 Username string Password string } type DeleteImageResult struct { } func (util *ImageUtil) DeleteImage(cmd *cobra.Command, args []string) { res, err := util.deleteImage(&util.deleteImageParams) printResponse(res, err) } func (util *ImageUtil) deleteImage(params *DeleteImageParams) (*DeleteImageResult, error) { var err error res := &DeleteImageResult{} ctx := context.Background() cli := client.NewClient() timeout := time.Duration(params.Timeout) * time.Second params.Imagepath, err = packUserinfo(params.Imagepath, params.Username, params.Password) if err != nil { return res, err } ctx, _ = context.WithTimeout(ctx, timeout) err = cli.DeleteImage(ctx, params.Imagepath) if err != nil { return res, err } return res, err }