Skip to content

Commit

Permalink
test: Add e2e tests for image bundle serve and push (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmidyson authored Sep 14, 2022
1 parent 80f7e5b commit 20cebe7
Show file tree
Hide file tree
Showing 15 changed files with 700 additions and 27 deletions.
51 changes: 40 additions & 11 deletions cmd/mindthegap/push/imagebundle/image_bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"fmt"
"os"
"path/filepath"

"github.com/spf13/cobra"

Expand All @@ -22,12 +23,13 @@ import (

func NewCommand(out output.Output) *cobra.Command {
var (
imageBundleFiles []string
destRegistry string
destRegistrySkipTLSVerify bool
destRegistryUsername string
destRegistryPassword string
ecrLifecyclePolicy string
imageBundleFiles []string
destRegistry string
destRegistryCACertificateFile string
destRegistrySkipTLSVerify bool
destRegistryUsername string
destRegistryPassword string
ecrLifecyclePolicy string
)

cmd := &cobra.Command{
Expand Down Expand Up @@ -113,6 +115,7 @@ func NewCommand(out output.Output) *cobra.Command {
reg.Address(),
destRegistry,
skopeoOpts,
destRegistryCACertificateFile,
destRegistrySkipTLSVerify,
out,
skopeoRunner,
Expand All @@ -126,8 +129,14 @@ func NewCommand(out output.Output) *cobra.Command {
_ = cmd.MarkFlagRequired("image-bundle")
cmd.Flags().StringVar(&destRegistry, "to-registry", "", "Registry to push images to")
_ = cmd.MarkFlagRequired("to-registry")
cmd.Flags().StringVar(&destRegistryCACertificateFile, "to-registry-ca-cert-file", "",
"CA certificate file used to verify TLS verification of registry to push images to (use for http registries)")
cmd.Flags().BoolVar(&destRegistrySkipTLSVerify, "to-registry-insecure-skip-tls-verify", false,
"Skip TLS verification of registry to push images to (use for http registries)")
"Skip TLS verification of registry to push images to (use for non-TLS http registries)")
cmd.MarkFlagsMutuallyExclusive(
"to-registry-ca-cert-file",
"to-registry-insecure-skip-tls-verify",
)
cmd.Flags().StringVar(&destRegistryUsername, "to-registry-username", "",
"Username to use to log in to destination registry")
cmd.Flags().StringVar(&destRegistryPassword, "to-registry-password", "",
Expand All @@ -145,6 +154,7 @@ func pushImages(
cfg config.ImagesConfig,
sourceRegistry, destRegistry string,
skopeoOpts []skopeo.SkopeoOption,
destRegistryCACertificateFile string,
destRegistrySkipTLSVerify bool,
out output.Output,
skopeoRunner *skopeo.Runner,
Expand All @@ -153,12 +163,31 @@ func pushImages(
// Sort registries for deterministic ordering.
regNames := cfg.SortedRegistryNames()

if destRegistryCACertificateFile != "" {
tmpDir, err := os.MkdirTemp("", ".skopeo-certs-*")
if err != nil {
return fmt.Errorf(
"failed to create temporary directory for destination registry certificates: %w",
err,
)
}
defer os.RemoveAll(tmpDir)

if err := utils.CopyFile(destRegistryCACertificateFile, filepath.Join(tmpDir, "ca.crt")); err != nil {
return err
}

skopeoOpts = append(skopeoOpts, skopeo.DestCertDir(tmpDir))
}

skopeoOpts = append(skopeoOpts, skopeo.DisableSrcTLSVerify())

if destRegistrySkipTLSVerify {
skopeoOpts = append(skopeoOpts, skopeo.DisableDestTLSVerify())
}

for _, registryName := range regNames {
registryConfig := cfg[registryName]
skopeoOpts = append(skopeoOpts, skopeo.DisableSrcTLSVerify())
if destRegistrySkipTLSVerify {
skopeoOpts = append(skopeoOpts, skopeo.DisableDestTLSVerify())
}

// Sort images for deterministic ordering.
imageNames := registryConfig.SortedImageNames()
Expand Down
25 changes: 16 additions & 9 deletions cmd/mindthegap/serve/imagebundle/image_bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package imagebundle

import (
"fmt"
"net/http"
"os"
"path/filepath"

Expand All @@ -18,7 +19,7 @@ import (
"github.com/mesosphere/mindthegap/docker/registry"
)

func NewCommand(out output.Output) *cobra.Command {
func NewCommand(out output.Output) (cmd *cobra.Command, stopCh chan struct{}) {
var (
imageBundleFiles []string
listenAddress string
Expand All @@ -27,7 +28,9 @@ func NewCommand(out output.Output) *cobra.Command {
tlsKey string
)

cmd := &cobra.Command{
stopCh = make(chan struct{})

cmd = &cobra.Command{
Use: "image-bundle",
Short: "Serve an OCI registry from image bundles",
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -74,23 +77,27 @@ func NewCommand(out output.Output) *cobra.Command {
}
out.EndOperation(true)
out.Infof("Listening on %s\n", reg.Address())
if err := reg.ListenAndServe(); err != nil {
out.Error(err, "error serving Docker registry")
os.Exit(2)
}

go func() {
if err := reg.ListenAndServe(); err != nil && err != http.ErrServerClosed {
out.Error(err, "error serving Docker registry")
os.Exit(2)
}
}()
<-stopCh

return nil
},
}

cmd.Flags().StringSliceVar(&imageBundleFiles, "images-bundle", nil,
cmd.Flags().StringSliceVar(&imageBundleFiles, "image-bundle", nil,
"Tarball of images to serve. Can also be a glob pattern.")
_ = cmd.MarkFlagRequired("images-bundle")
_ = cmd.MarkFlagRequired("image-bundle")
cmd.Flags().StringVar(&listenAddress, "listen-address", "localhost", "Address to listen on")
cmd.Flags().
Uint16Var(&listenPort, "listen-port", 0, "Port to listen on (0 means use any free port)")
cmd.Flags().StringVar(&tlsCertificate, "tls-cert-file", "", "TLS certificate file")
cmd.Flags().StringVar(&tlsKey, "tls-private-key-file", "", "TLS private key file")

return cmd
return cmd, stopCh
}
3 changes: 2 additions & 1 deletion cmd/mindthegap/serve/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ func NewCommand(out output.Output) *cobra.Command {
Short: "Serve image or Helm chart bundles from an OCI registry",
}

cmd.AddCommand(imagebundle.NewCommand(out))
imageBundleCmd, _ := imagebundle.NewCommand(out)
cmd.AddCommand(imageBundleCmd)

helmBundleCmd, _ := helmbundle.NewCommand(out)
cmd.AddCommand(helmBundleCmd)
Expand Down
37 changes: 37 additions & 0 deletions cmd/mindthegap/utils/copy_file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2021 D2iQ, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package utils

import (
"fmt"
"io"
"os"
)

func CopyFile(src, dst string) error {
s, err := os.Open(src)
if err != nil {
return fmt.Errorf("failed to open source file: %w", err)
}
defer s.Close()

d, err := os.Create(dst)
if err != nil {
return fmt.Errorf("failed to create destination file: %w", err)
}
defer d.Close()

// Copy the contents of the source file into the destination file
_, err = io.Copy(d, s)
if err != nil {
return fmt.Errorf("failed to copy file contents file: %w", err)
}

// Return any errors that result from closing the destination file
// Will return nil if no errors occurred
if err := d.Close(); err != nil {
return fmt.Errorf("failed to close destination file: %w", err)
}
return nil
}
2 changes: 1 addition & 1 deletion config/images_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func ParseImagesConfigFile(configFile string) (ImagesConfig, error) {
}
named, nameErr := reference.ParseNamed(trimmedLine)
if nameErr != nil {
return ImagesConfig{}, fmt.Errorf("failed to parse config file: %w", yamlParseErr)
return ImagesConfig{}, fmt.Errorf("failed to parse config file: %w", nameErr)
}
namedTagged, ok := named.(reference.NamedTagged)
if !ok {
Expand Down
3 changes: 2 additions & 1 deletion make/go.mk
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ E2E_FLAKE_ATTEMPTS ?= 1

.PHONY: e2e-test
e2e-test: ## Runs e2e tests
e2e-test: install-tool.golang install-tool.ginkgo skopeo.build; $(info $(M) running e2e tests$(if $(E2E_FOCUS), matching "$(E2E_FOCUS)"))
e2e-test: install-tool.golang install-tool.ginkgo skopeo.build
$(info $(M) running e2e tests$(if $(E2E_LABEL), labelled "$(E2E_LABEL)")$(if $(E2E_FOCUS), matching "$(E2E_FOCUS)"))
ginkgo run \
--r \
--race \
Expand Down
2 changes: 1 addition & 1 deletion make/skopeo.mk
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ skopeo.build.all:
$(MAKE) --no-print-directory GOOS=windows GOARCH=arm64 skopeo.build

.PHONY: skopeo/static/skopeo-$(GOOS)-$(GOARCH)$(if $(filter $(GOOS),windows),.exe)
skopeo/static/skopeo-$(GOOS)-$(GOARCH)$(if $(filter $(GOOS),windows),.exe): ; $(info $(M) Building skopeo for $(GOOS)/$(GOARCH))
skopeo/static/skopeo-$(GOOS)-$(GOARCH)$(if $(filter $(GOOS),windows),.exe): ; $(info $(M) building skopeo for $(GOOS)/$(GOARCH))
mkdir -p $(dir $@)
rm -f $(REPO_ROOT)/$@
cd skopeo-static && \
Expand Down
18 changes: 18 additions & 0 deletions skopeo/skopeo.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,30 @@ func DisableSrcTLSVerify() SkopeoOption {
}
}

func DisableTLSVerify() SkopeoOption {
return func() string {
return "--tls-verify=false"
}
}

func CertDir(dir string) SkopeoOption {
return func() string {
return fmt.Sprintf("--cert-dir=%s", dir)
}
}

func DisableDestTLSVerify() SkopeoOption {
return func() string {
return "--dest-tls-verify=false"
}
}

func DestCertDir(dir string) SkopeoOption {
return func() string {
return fmt.Sprintf("--dest-cert-dir=%s", dir)
}
}

func AllImages() SkopeoOption {
return func() string {
return "--all"
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/helmbundle/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func ValidateChartIsAvailable(
d, err := h.GetChartFromRepo(
helmTmpDir,
"",
fmt.Sprintf("%s://%s:%v/charts/%s", helm.OCIScheme, addr, port, chartName),
fmt.Sprintf("%s://%s:%d/charts/%s", helm.OCIScheme, addr, port, chartName),
chartVersion,
[]helm.ConfigOpt{helm.RegistryClientConfigOpt()},
pullOpts...,
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/helmbundle/push_bundle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ var _ = Describe("Push Bundle", func() {

cmd.SetArgs([]string{
"--helm-bundle", bundleFile,
"--to-registry", fmt.Sprintf("localhost:%v/charts", port),
"--to-registry", fmt.Sprintf("localhost:%d/charts", port),
"--to-registry-insecure-skip-tls-verify",
})

Expand Down Expand Up @@ -127,7 +127,7 @@ var _ = Describe("Push Bundle", func() {

cmd.SetArgs([]string{
"--helm-bundle", bundleFile,
"--to-registry", fmt.Sprintf("%s:%v/charts", ipAddr, port),
"--to-registry", fmt.Sprintf("%s:%d/charts", ipAddr, port),
"--to-registry-insecure-skip-tls-verify",
})

Expand Down
Loading

0 comments on commit 20cebe7

Please sign in to comment.