Skip to content

Commit

Permalink
Code refactoring and cleaning up
Browse files Browse the repository at this point in the history
  • Loading branch information
mpermar committed Sep 21, 2023
1 parent 6b2af78 commit 47d064b
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 166 deletions.
87 changes: 0 additions & 87 deletions chartutils/carvel.go

This file was deleted.

168 changes: 168 additions & 0 deletions chartutils/carvel/carvel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// Package chartutils implements helper functions to manipulate helm Charts
package chartutils

import (
"fmt"
"io"
"os"
"strings"

"github.com/vmware-labs/distribution-tooling-for-helm/chartutils"
"github.com/vmware-labs/distribution-tooling-for-helm/imagelock"
"github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/lockconfig"

"gopkg.in/yaml.v3"
)

// Somehow there is no data structure for a bundle in Carvel. Copying some basics from the describe command.

// Author information from a Bundle
type Author struct {
Name string `json:"name,omitempty"`
Email string `json:"email,omitempty"`
}

// Website URL where more information of the Bundle can be found
type Website struct {
URL string `json:"url,omitempty"`
}

// Bundle Metadata
const (
BundleAPIVersion = "imgpkg.carvel.dev/v1alpha1"
BundleKind = "Bundle"
)

// BundleVersion with detailsa bout the Carvel bundle version
type BundleVersion struct {
APIVersion string `json:"apiVersion"` // This generated yaml, but due to lib we need to use `json`
Kind string `json:"kind"` // This generated yaml, but due to lib we need to use `json`
}

// Metadata for a Carvel bundle
type Metadata struct {
Version BundleVersion
Metadata map[string]string `json:"metadata,omitempty"`
Authors []Author `json:"authors,omitempty"`
Websites []Website `json:"websites,omitempty"`
}

// ToYAML serializes the Carvel bundle into YAML
func (il *Metadata) ToYAML(w io.Writer) error {
enc := yaml.NewEncoder(w)
enc.SetIndent(2)

return enc.Encode(il)
}

// CarvelBundleFromYAMLFile Deserializes a string into a Metadata struct
func CarvelBundleFromYAMLFile(file string) (*Metadata, error) {
fh, err := os.Open(file)
if err != nil {
return nil, fmt.Errorf("failed to open Images.lock file: %v", err)
}
defer fh.Close()
return CarvelBundleFromYAML(fh)
}

// CarvelBundleFromYAML reads a Carvel metadata bundled from the YAML read from r
func CarvelBundleFromYAML(r io.Reader) (*Metadata, error) {
metadata := &Metadata{
Version: BundleVersion{
APIVersion: BundleAPIVersion,
Kind: BundleKind,
},
Metadata: map[string]string{},
Authors: []Author{},
Websites: []Website{},
}
dec := yaml.NewDecoder(r)
if err := dec.Decode(metadata); err != nil {
return nil, fmt.Errorf("failed to load Carvel bundle: %v", err)
}

return metadata, nil
}

// NewCarvelBundle returns a new carvel bundle Metadata instance
func NewCarvelBundle() *Metadata {

return &Metadata{
Version: BundleVersion{
APIVersion: BundleAPIVersion,
Kind: BundleKind,
},
Metadata: map[string]string{},
Authors: []Author{},
Websites: []Website{},
}
}

// PrepareBundleMetadata builds and sets a new Carvel bundle struct
func PrepareBundleMetadata(chartPath string, lock *imagelock.ImagesLock) (*Metadata, error) {

bundleMetadata := NewCarvelBundle()

chart, err := chartutils.LoadChart(chartPath)
if err != nil {
return nil, fmt.Errorf("failed to load chart: %w", err)
}

for _, maintainer := range chart.Metadata.Maintainers {
author := Author{
Name: maintainer.Name,
}
if maintainer.Email != "" {
author.Email = maintainer.Email
}
bundleMetadata.Authors = append(bundleMetadata.Authors, author)
}
for _, source := range chart.Metadata.Sources {
website := Website{
URL: source,
}
bundleMetadata.Websites = append(bundleMetadata.Websites, website)
}

bundleMetadata.Metadata["name"] = lock.Chart.Name
for key, value := range chart.Metadata.Annotations {
if key != "images" {
bundleMetadata.Metadata[key] = value
}
}
return bundleMetadata, nil
}

// PrepareImagesLock builds and set a new Carvel images lock struct
func PrepareImagesLock(lock *imagelock.ImagesLock) (lockconfig.ImagesLock, error) {

imagesLock := lockconfig.ImagesLock{
LockVersion: lockconfig.LockVersion{
APIVersion: lockconfig.ImagesLockAPIVersion,
Kind: lockconfig.ImagesLockKind,
},
}
for _, img := range lock.Images {
// Carvel does not seem to support multi-arch. Grab amd64 digest
name := img.Image
i := strings.LastIndex(img.Image, ":")
if i > -1 {
name = img.Image[0:i]

}
for _, digest := range img.Digests {
if digest.Arch == "linux/amd64" {
name = name + "@" + digest.Digest.String()
break
}
}
imageRef := lockconfig.ImageRef{
Image: name,
Annotations: map[string]string{
"kbld.carvel.dev/id": img.Image,
},
}
imagesLock.AddImageRef(imageRef)
}
return imagesLock, nil
}
66 changes: 10 additions & 56 deletions cmd/dt/carvelize.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import (
"bytes"
"fmt"
"os"
"strings"

"github.com/spf13/cobra"
"github.com/vmware-labs/distribution-tooling-for-helm/chartutils"
carvel "github.com/vmware-labs/distribution-tooling-for-helm/chartutils/carvel"
"github.com/vmware-labs/distribution-tooling-for-helm/internal/log"
"github.com/vmware-labs/distribution-tooling-for-helm/utils"
"github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/lockconfig"
)

var carvelizeCmd = newCarvelizeCmd()
Expand Down Expand Up @@ -105,66 +104,21 @@ func generateCarvelBundle(chartPath string, opts ...chartutils.Option) error {
return fmt.Errorf("wrap file %q does not exist", chartPath)
}

bundleMetadata := chartutils.NewCarvelBundle()

chart, err := chartutils.LoadChart(chartPath)
bundleMetadata, err := carvel.PrepareBundleMetadata(chartPath, lock)
if err != nil {
return fmt.Errorf("failed to load chart: %w", err)
}

for _, maintainer := range chart.Metadata.Maintainers {
author := chartutils.Author{
Name: maintainer.Name,
}
if maintainer.Email != "" {
author.Email = maintainer.Email
}
bundleMetadata.Authors = append(bundleMetadata.Authors, author)
}
for _, source := range chart.Metadata.Sources {
website := chartutils.Website{
URL: source,
}
bundleMetadata.Websites = append(bundleMetadata.Websites, website)
}

bundleMetadata.Metadata["name"] = lock.Chart.Name
for key, value := range chart.Metadata.Annotations {
if key != "images" {
bundleMetadata.Metadata[key] = value
}
return fmt.Errorf("failed to prepare Carvel bundle: %w", err)
}

imagesLock := lockconfig.ImagesLock{
LockVersion: lockconfig.LockVersion{
APIVersion: lockconfig.ImagesLockAPIVersion,
Kind: lockconfig.ImagesLockKind,
},
imagesLock, err := carvel.PrepareImagesLock(lock)
if err != nil {
return fmt.Errorf("failed to prepare Carvel images lock: %w", err)
}
for _, img := range lock.Images {
// Carvel does not seem to support multi-arch. Grab amd64 digest
name := img.Image
i := strings.LastIndex(img.Image, ":")
if i > -1 {
name = img.Image[0:i]
l.Infof("Validating Carvel images lock")

}
for _, digest := range img.Digests {
if digest.Arch == "linux/amd64" {
name = name + "@" + digest.Digest.String()
break
}
}
imageRef := lockconfig.ImageRef{
Image: name,
Annotations: map[string]string{
"kbld.carvel.dev/id": img.Image,
},
}
imagesLock.AddImageRef(imageRef)
err = imagesLock.Validate()
if err != nil {
return fmt.Errorf("failed to validate Carvel images lock: %w", err)
}
l.Infof("Validating Carvel images lock")
imagesLock.Validate()

path := imgPkgPath + "/images.yml"
err = imagesLock.WriteToPath(path)
Expand Down
Loading

0 comments on commit 47d064b

Please sign in to comment.