Skip to content

Commit b52d281

Browse files
Add package cli command
1 parent c595549 commit b52d281

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

cmd/kro/commands/package.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package commands
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"time"
7+
8+
"github.com/google/go-containerregistry/pkg/name"
9+
v1 "github.com/google/go-containerregistry/pkg/v1"
10+
"github.com/google/go-containerregistry/pkg/v1/empty"
11+
"github.com/google/go-containerregistry/pkg/v1/mutate"
12+
"github.com/google/go-containerregistry/pkg/v1/static"
13+
"github.com/google/go-containerregistry/pkg/v1/tarball"
14+
"github.com/google/go-containerregistry/pkg/v1/types"
15+
"github.com/spf13/cobra"
16+
"sigs.k8s.io/yaml"
17+
18+
"github.com/kro-run/kro/api/v1alpha1"
19+
)
20+
21+
type PackageConfig struct {
22+
resourceGraphDefinitionFile string
23+
outputFile string
24+
}
25+
26+
var packageConfig = &PackageConfig{}
27+
28+
func init() {
29+
packageRGDCmd.PersistentFlags().StringVarP(&packageConfig.resourceGraphDefinitionFile, "file", "f", "",
30+
"Path to the ResourceGraphDefinition file")
31+
packageRGDCmd.PersistentFlags().StringVarP(&packageConfig.outputFile, "output", "o", "",
32+
"Output file name for the OCI image tarball")
33+
}
34+
35+
var packageRGDCmd = &cobra.Command{
36+
Use: "package",
37+
Short: "Package ResourceGraphDefinition file into an OCI image",
38+
Long: "Package command packages the ResourceGraphDefinition file into an OCI image, which can be used for distribution and deployment.",
39+
RunE: func(cmd *cobra.Command, args []string) error {
40+
if packageConfig.resourceGraphDefinitionFile == "" {
41+
return fmt.Errorf("ResourceGraphDefinition file is required")
42+
}
43+
44+
if packageConfig.outputFile == "" {
45+
return fmt.Errorf("output file name is required")
46+
}
47+
48+
data, err := os.ReadFile(packageConfig.resourceGraphDefinitionFile)
49+
if err != nil {
50+
return fmt.Errorf("failed to read ResourceGraphDefinition file: %w", err)
51+
}
52+
53+
var rgd v1alpha1.ResourceGraphDefinition
54+
if err := yaml.Unmarshal(data, &rgd); err != nil {
55+
return fmt.Errorf("failed to unmarshal ResourceGraphDefinition: %w", err)
56+
}
57+
58+
fmt.Fprintf(os.Stderr, "Packaging ResourceGraphDefinition into %s...\n",
59+
packageConfig.outputFile)
60+
61+
if err = packageRGD(data, &rgd); err != nil {
62+
return fmt.Errorf("failed to package ResourceGraphDefinition: %w", err)
63+
}
64+
65+
fmt.Fprintf(os.Stderr, "Successfully packaged ResourceGraphDefinition to %s\n",
66+
packageConfig.outputFile)
67+
68+
return nil
69+
},
70+
}
71+
72+
func packageRGD(data []byte, rgd *v1alpha1.ResourceGraphDefinition) error {
73+
layer := static.NewLayer(data, types.MediaType("application/vnd.kro.resourcegraphdefinition.v1alpha1+yaml"))
74+
75+
img := empty.Image
76+
77+
img, err := mutate.AppendLayers(img, layer)
78+
79+
if err != nil {
80+
return fmt.Errorf("failed to append layer: %w", err)
81+
}
82+
83+
configFile, err := img.ConfigFile()
84+
if err != nil {
85+
return fmt.Errorf("failed to get config file: %w", err)
86+
}
87+
88+
now := time.Now()
89+
configFile.Created = v1.Time{Time: now}
90+
91+
configFile.Config.Labels = map[string]string{
92+
"kro.run/type": "resourcegraphdefinition",
93+
"kro.run/name": rgd.Name,
94+
}
95+
96+
img, err = mutate.ConfigFile(img, configFile)
97+
if err != nil {
98+
return fmt.Errorf("failed to update image config: %w", err)
99+
}
100+
101+
ref, err := name.ParseReference(fmt.Sprintf("kro.run/rgd/%s:latest", rgd.Name))
102+
if err != nil {
103+
return fmt.Errorf("failed to parse image reference: %w", err)
104+
}
105+
106+
if err := tarball.WriteToFile(packageConfig.outputFile, ref, img); err != nil {
107+
return fmt.Errorf("failed to write image to file: %w", err)
108+
}
109+
110+
return nil
111+
}
112+
113+
func AddPackageCommand(rootCmd *cobra.Command) {
114+
rootCmd.AddCommand(packageRGDCmd)
115+
}

cmd/kro/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,6 @@ func NewRootCommand() *cobra.Command {
6363
// TODO: Command groups
6464
commands.AddValidateCommands(cmd)
6565
commands.AddGenerateCommands(cmd)
66+
commands.AddPackageCommand(cmd)
6667
return cmd
6768
}

0 commit comments

Comments
 (0)