@@ -20,6 +20,7 @@ var imageCmd = cli.Command{
2020 & imageCreateCmd ,
2121 & imageListCmd ,
2222 & imageGetCmd ,
23+ & imageTagCmd ,
2324 & imageDeleteCmd ,
2425 },
2526 HideHelpCommand : true ,
@@ -60,6 +61,14 @@ var imageGetCmd = cli.Command{
6061 HideHelpCommand : true ,
6162}
6263
64+ var imageTagCmd = cli.Command {
65+ Name : "tag" ,
66+ Usage : "Tag an existing local image without pulling or converting" ,
67+ ArgsUsage : "<source> <target>" ,
68+ Action : handleImageTag ,
69+ HideHelpCommand : true ,
70+ }
71+
6372var imageDeleteCmd = cli.Command {
6473 Name : "delete" ,
6574 Aliases : []string {"rm" },
@@ -255,6 +264,49 @@ func handleImageGet(ctx context.Context, cmd *cli.Command) error {
255264 return ShowJSON (os .Stdout , "image get" , obj , format , transform )
256265}
257266
267+ // imageTagBody is the POST /images/{name}/tag request body, defined locally
268+ // until the generated SDK gains a typed method for the endpoint.
269+ type imageTagBody struct {
270+ Name string `json:"name"`
271+ }
272+
273+ func handleImageTag (ctx context.Context , cmd * cli.Command ) error {
274+ args := cmd .Args ().Slice ()
275+ if len (args ) < 2 {
276+ return fmt .Errorf ("source and target required\n Usage: hypeman image tag <source> <target>" )
277+ }
278+ source , target := args [0 ], args [1 ]
279+
280+ client := hypeman .NewClient (getDefaultRequestOptions (cmd )... )
281+
282+ var opts []option.RequestOption
283+ if cmd .Root ().Bool ("debug" ) {
284+ opts = append (opts , debugMiddlewareOption )
285+ }
286+
287+ path := fmt .Sprintf ("images/%s/tag" , url .PathEscape (source ))
288+ body := imageTagBody {Name : target }
289+
290+ format := cmd .Root ().String ("format" )
291+ transform := cmd .Root ().String ("transform" )
292+
293+ if format != "auto" {
294+ var res []byte
295+ opts = append (opts , option .WithResponseBodyInto (& res ))
296+ if err := client .Post (ctx , path , body , nil , opts ... ); err != nil {
297+ return err
298+ }
299+ return ShowJSON (os .Stdout , "image tag" , gjson .ParseBytes (res ), format , transform )
300+ }
301+
302+ var img hypeman.Image
303+ if err := client .Post (ctx , path , body , & img , opts ... ); err != nil {
304+ return err
305+ }
306+ fmt .Println (img .Name )
307+ return nil
308+ }
309+
258310func handleImageDelete (ctx context.Context , cmd * cli.Command ) error {
259311 args := cmd .Args ().Slice ()
260312 if len (args ) < 1 {
0 commit comments