Skip to content

Commit 29b0f3e

Browse files
committed
Add tag command
1 parent 4f21b69 commit 29b0f3e

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

cmd/root.go

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"kitops/pkg/cmd/pull"
1919
"kitops/pkg/cmd/push"
2020
"kitops/pkg/cmd/remove"
21+
"kitops/pkg/cmd/tag"
2122
"kitops/pkg/cmd/version"
2223
"kitops/pkg/lib/constants"
2324
"kitops/pkg/output"
@@ -75,6 +76,7 @@ func addSubcommands(rootCmd *cobra.Command) {
7576
rootCmd.AddCommand(export.ExportCommand())
7677
rootCmd.AddCommand(remove.RemoveCommand())
7778
rootCmd.AddCommand(version.VersionCommand())
79+
rootCmd.AddCommand(tag.TagCommand())
7880
}
7981

8082
// Execute adds all child commands to the root command and sets flags appropriately.

pkg/cmd/tag/cmd.go

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package tag
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"kitops/pkg/lib/constants"
7+
"kitops/pkg/lib/repo"
8+
"kitops/pkg/output"
9+
10+
"github.com/spf13/cobra"
11+
"oras.land/oras-go/v2/registry"
12+
)
13+
14+
var (
15+
shortDesc = "Tag a modelkit"
16+
longDesc = `Tag a modelkit with a new tag.`
17+
)
18+
19+
type tagOptions struct {
20+
configHome string
21+
sourceRef *registry.Reference
22+
targetRef *registry.Reference
23+
}
24+
25+
func (opts *tagOptions) complete(ctx context.Context, args []string) error {
26+
27+
configHome, ok := ctx.Value(constants.ConfigKey{}).(string)
28+
if !ok {
29+
return fmt.Errorf("default config path not set on command context")
30+
}
31+
opts.configHome = configHome
32+
modelRef, _, err := repo.ParseReference(args[0])
33+
if err != nil {
34+
return fmt.Errorf("failed to parse reference %s: %w", opts.sourceRef, err)
35+
}
36+
opts.sourceRef = modelRef
37+
modelRef, _, err = repo.ParseReference(args[1])
38+
if err != nil {
39+
return fmt.Errorf("failed to parse reference %s: %w", opts.targetRef, err)
40+
}
41+
opts.targetRef = modelRef
42+
return nil
43+
}
44+
45+
func TagCommand() *cobra.Command {
46+
47+
cmd := &cobra.Command{
48+
Use: "tag SOURCE_MODELKIT[:TAG] TARGET_MODELKIT[:TAG]",
49+
Short: shortDesc,
50+
Long: longDesc,
51+
Example: `kit tag myregistry.com/myrepo/mykit:latest myregistry.com/myrepo/mykit:v1.0.0`,
52+
Run: runCommand(&tagOptions{}),
53+
}
54+
55+
cmd.Args = cobra.ExactArgs(2)
56+
return cmd
57+
}
58+
59+
func runCommand(opts *tagOptions) func(cmd *cobra.Command, args []string) {
60+
return func(cmd *cobra.Command, args []string) {
61+
if err := opts.complete(cmd.Context(), args); err != nil {
62+
output.Fatalf("Failed to parse argument: %s", err)
63+
}
64+
65+
err := RunTag(cmd.Context(), opts)
66+
if err != nil {
67+
output.Fatalf("Failed to tag modelkit: %s", err)
68+
}
69+
output.Infof("Modelkit %s tagged as %s", opts.sourceRef, opts.targetRef)
70+
}
71+
}

pkg/cmd/tag/tag.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package tag
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"kitops/pkg/lib/constants"
7+
"kitops/pkg/lib/repo"
8+
9+
"oras.land/oras-go/v2"
10+
"oras.land/oras-go/v2/errdef"
11+
)
12+
13+
func RunTag(ctx context.Context, options *tagOptions) error {
14+
storageHome := constants.StoragePath(options.configHome)
15+
sourceStore, err := repo.NewLocalStore(storageHome, options.sourceRef)
16+
if err != nil {
17+
return fmt.Errorf("failed to open local storage: %w", err)
18+
}
19+
descriptor, err := oras.Resolve(ctx, sourceStore, options.sourceRef.Reference, oras.ResolveOptions{})
20+
if err != nil {
21+
if err == errdef.ErrNotFound {
22+
return fmt.Errorf("model %s not found", options.sourceRef.String())
23+
}
24+
return fmt.Errorf("error resolving model: %s", err)
25+
}
26+
if options.sourceRef.Registry == options.targetRef.Registry && options.sourceRef.Repository == options.targetRef.Repository {
27+
err = sourceStore.Tag(ctx, descriptor, options.targetRef.Reference)
28+
if err != nil {
29+
return fmt.Errorf("failed to tag reference %s: %w", options.targetRef, err)
30+
}
31+
return nil
32+
}
33+
// model kit is on a different registry and/or repo, copy the model to the target store
34+
targetStore, err := repo.NewLocalStore(storageHome, options.targetRef)
35+
if err != nil {
36+
return fmt.Errorf("failed to open local storage: %w", err)
37+
}
38+
_, err = oras.Copy(ctx, sourceStore, options.sourceRef.Reference, targetStore, options.targetRef.Reference, oras.CopyOptions{})
39+
if err != nil {
40+
return fmt.Errorf("failed to tag model: %w", err)
41+
}
42+
return nil
43+
}

0 commit comments

Comments
 (0)