Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support diff airgap bundles #4373

Merged
merged 4 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions cmd/kots/cli/admin-console-push-images.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import (
"github.com/replicatedhq/kots/pkg/docker/registry"
dockerregistry "github.com/replicatedhq/kots/pkg/docker/registry"
registrytypes "github.com/replicatedhq/kots/pkg/docker/registry/types"
"github.com/replicatedhq/kots/pkg/image"
imagetypes "github.com/replicatedhq/kots/pkg/image/types"
"github.com/replicatedhq/kots/pkg/k8sutil"
"github.com/replicatedhq/kots/pkg/kotsadm"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
"github.com/replicatedhq/kots/pkg/logger"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -53,7 +54,7 @@ func AdminPushImagesCmd() *cobra.Command {
}

if _, err := os.Stat(imageSource); err == nil {
err = kotsadm.PushImages(imageSource, *options)
err = image.PushImages(imageSource, *options)
if err != nil {
return errors.Wrap(err, "failed to push images")
}
Expand All @@ -75,7 +76,7 @@ func AdminPushImagesCmd() *cobra.Command {
return cmd
}

func genAndCheckPushOptions(endpoint string, namespace string, log *logger.CLILogger, v *viper.Viper) (*kotsadmtypes.PushImagesOptions, error) {
func genAndCheckPushOptions(endpoint string, namespace string, log *logger.CLILogger, v *viper.Viper) (*imagetypes.PushImagesOptions, error) {
host, err := getHostFromEndpoint(endpoint)
if err != nil {
return nil, errors.Wrap(err, "failed get host from endpoint")
Expand Down Expand Up @@ -114,7 +115,7 @@ func genAndCheckPushOptions(endpoint string, namespace string, log *logger.CLILo
log.FinishSpinner()
}

options := kotsadmtypes.PushImagesOptions{
options := imagetypes.PushImagesOptions{
KotsadmTag: v.GetString("kotsadm-tag"),
Registry: registrytypes.RegistryOptions{
Endpoint: endpoint,
Expand Down
3 changes: 2 additions & 1 deletion cmd/kots/cli/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
dockerregistry "github.com/replicatedhq/kots/pkg/docker/registry"
"github.com/replicatedhq/kots/pkg/handlers"
"github.com/replicatedhq/kots/pkg/identity"
"github.com/replicatedhq/kots/pkg/image"
"github.com/replicatedhq/kots/pkg/k8sutil"
k8sutiltypes "github.com/replicatedhq/kots/pkg/k8sutil/types"
"github.com/replicatedhq/kots/pkg/kotsadm"
Expand Down Expand Up @@ -332,7 +333,7 @@ func InstallCmd() *cobra.Command {
}
defer os.RemoveAll(airgapRootDir)

err = kotsadm.ExtractAppAirgapArchive(airgapArchive, airgapRootDir, v.GetBool("disable-image-push"), deployOptions.ProgressWriter)
err = image.ExtractAppAirgapArchive(airgapArchive, airgapRootDir, v.GetBool("disable-image-push"), deployOptions.ProgressWriter)
if err != nil {
return errors.Wrap(err, "failed to extract images")
}
Expand Down
28 changes: 23 additions & 5 deletions pkg/apparchive/helm-v1beta2.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package apparchive
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
Expand All @@ -13,9 +12,11 @@ import (
"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/base"
"github.com/replicatedhq/kots/pkg/docker/registry"
dockerregistrytypes "github.com/replicatedhq/kots/pkg/docker/registry/types"
"github.com/replicatedhq/kots/pkg/image"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/logger"
"github.com/replicatedhq/kots/pkg/midstream"
upstreamtypes "github.com/replicatedhq/kots/pkg/upstream/types"
"github.com/replicatedhq/kots/pkg/util"
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
Expand Down Expand Up @@ -168,7 +169,7 @@ func WriteV1Beta2HelmCharts(opts WriteV1Beta2HelmChartsOptions) error {
if len(checkedImages) > 0 {
opts.KotsKinds.Installation.Spec.KnownImages = append(opts.KotsKinds.Installation.Spec.KnownImages, checkedImages...)

if err := SaveInstallation(&opts.KotsKinds.Installation, opts.Upstream.GetUpstreamDir(opts.WriteUpstreamOptions)); err != nil {
if err := kotsutil.SaveInstallation(&opts.KotsKinds.Installation, opts.Upstream.GetUpstreamDir(opts.WriteUpstreamOptions)); err != nil {
return errors.Wrap(err, "failed to save installation")
}
}
Expand Down Expand Up @@ -278,7 +279,7 @@ func templateV1Beta2HelmChartWithValuesToDir(helmChart *kotsv1beta2.HelmChart, c
return nil
}

func processV1Beta2HelmChartImages(opts WriteV1Beta2HelmChartsOptions, helmChart *kotsv1beta2.HelmChart, chartDir string) (*image.RewriteImagesResult, error) {
func processV1Beta2HelmChartImages(opts WriteV1Beta2HelmChartsOptions, helmChart *kotsv1beta2.HelmChart, chartDir string) (*base.RewriteImagesResult, error) {
// template the chart with the builder values to a temp dir and then process images
tmpDir, err := os.MkdirTemp("", fmt.Sprintf("kots-images-%s", helmChart.GetDirName()))
if err != nil {
Expand All @@ -297,7 +298,7 @@ func processV1Beta2HelmChartImages(opts WriteV1Beta2HelmChartsOptions, helmChart
}

builderValuesPath := path.Join(tmpDir, "builder-values.yaml")
if err := ioutil.WriteFile(builderValuesPath, builderValuesContent, 0644); err != nil {
if err := os.WriteFile(builderValuesPath, builderValuesContent, 0644); err != nil {
return nil, errors.Wrap(err, "failed to write builder values file")
}

Expand All @@ -316,7 +317,24 @@ func processV1Beta2HelmChartImages(opts WriteV1Beta2HelmChartsOptions, helmChart
dockerHubRegistryCreds, _ = registry.GetCredentialsForRegistryFromConfigJSON(dockerhubSecret.Data[".dockerconfigjson"], registry.DockerHubRegistryName)
}

result, err := image.RewriteBaseImages(opts.ProcessImageOptions, templatedOutputDir, opts.KotsKinds, opts.KotsKinds.License, dockerHubRegistryCreds, opts.RenderOptions.Log)
destRegistry := &dockerregistrytypes.RegistryOptions{
Endpoint: opts.ProcessImageOptions.RegistrySettings.Hostname,
Namespace: opts.ProcessImageOptions.RegistrySettings.Namespace,
Username: opts.ProcessImageOptions.RegistrySettings.Username,
Password: opts.ProcessImageOptions.RegistrySettings.Password,
}

baseImages, err := image.FindImagesInDir(templatedOutputDir)
if err != nil {
return nil, errors.Wrap(err, "failed to find base images")
}

kotsKindsImages, err := kotsutil.GetImagesFromKotsKinds(opts.KotsKinds, destRegistry)
if err != nil {
return nil, errors.Wrap(err, "failed to get images from kots kinds")
}

result, err := midstream.RewriteBaseImages(opts.ProcessImageOptions, baseImages, kotsKindsImages, opts.KotsKinds, opts.KotsKinds.License, dockerHubRegistryCreds, opts.RenderOptions.Log)
if err != nil {
return nil, errors.Wrap(err, "failed to rewrite base images")
}
Expand Down
19 changes: 0 additions & 19 deletions pkg/apparchive/installation.go

This file was deleted.

95 changes: 95 additions & 0 deletions pkg/base/airgap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package base

import (
"io"

"github.com/pkg/errors"
registrytypes "github.com/replicatedhq/kots/pkg/docker/registry/types"
"github.com/replicatedhq/kots/pkg/image"
imagetypes "github.com/replicatedhq/kots/pkg/image/types"
"github.com/replicatedhq/kots/pkg/imageutil"
"github.com/replicatedhq/kots/pkg/kotsutil"
"github.com/replicatedhq/kots/pkg/logger"
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
kustomizetypes "sigs.k8s.io/kustomize/api/types"
)

type ProcessAirgapImagesOptions struct {
BaseImages []string
KotsKindsImages []string
RootDir string
AirgapRoot string
AirgapBundle string
CreateAppDir bool
PushImages bool
Log *logger.CLILogger
ReplicatedRegistry registrytypes.RegistryOptions
ReportWriter io.Writer
DestinationRegistry registrytypes.RegistryOptions
KotsKinds *kotsutil.KotsKinds
}

type ProcessAirgapImagesResult struct {
KustomizeImages []kustomizetypes.Image
KnownImages []kotsv1beta1.InstallationImage
}

func ProcessAirgapImages(opts ProcessAirgapImagesOptions) (*ProcessAirgapImagesResult, error) {
pushOpts := imagetypes.PushImagesOptions{
Registry: opts.DestinationRegistry,
Log: opts.Log,
ProgressWriter: opts.ReportWriter,
LogForUI: true,
}

if opts.PushImages {
if opts.AirgapBundle != "" {
err := image.TagAndPushAppImagesFromBundle(opts.AirgapBundle, pushOpts)
if err != nil {
return nil, errors.Wrap(err, "failed to push images from bundle")
}
} else {
err := image.TagAndPushAppImagesFromPath(opts.AirgapRoot, pushOpts)
if err != nil {
return nil, errors.Wrap(err, "failed to push images from dir")
}
}
}

rewrittenImages := []kustomizetypes.Image{}
for _, image := range append(opts.BaseImages, opts.KotsKindsImages...) {
rewrittenImage, err := imageutil.RewriteDockerRegistryImage(opts.DestinationRegistry, image)
if err != nil {
return nil, errors.Wrapf(err, "failed to rewrite image %s", image)
}
rewrittenImages = append(rewrittenImages, *rewrittenImage)
}

withAltNames := make([]kustomizetypes.Image, 0)
for _, i := range rewrittenImages {
altNames, err := imageutil.BuildImageAltNames(i)
if err != nil {
return nil, errors.Wrap(err, "failed to build image alt names")
}
withAltNames = append(withAltNames, altNames...)
}

result := &ProcessAirgapImagesResult{
KustomizeImages: withAltNames,
// This list is slightly different from the list we get from app specs because of alternative names,
// but it still works because after rewriting image names with private registry, the lists become the same.
KnownImages: installationImagesFromKustomizeImages(withAltNames),
}
return result, nil
}

func installationImagesFromKustomizeImages(images []kustomizetypes.Image) []kotsv1beta1.InstallationImage {
result := make([]kotsv1beta1.InstallationImage, 0)
for _, i := range images {
result = append(result, kotsv1beta1.InstallationImage{
Image: imageutil.SrcImageFromKustomizeImage(i),
IsPrivate: true,
})
}
return result
}
8 changes: 4 additions & 4 deletions pkg/upstream/push_images_test.go → pkg/base/airgap_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package upstream
package base

import (
"reflect"
Expand All @@ -8,7 +8,7 @@ import (
kustomizetypes "sigs.k8s.io/kustomize/api/types"
)

func Test_makeInstallationImages(t *testing.T) {
func Test_installationImagesFromKustomizeImages(t *testing.T) {
tests := []struct {
name string
images []kustomizetypes.Image
Expand Down Expand Up @@ -49,8 +49,8 @@ func Test_makeInstallationImages(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := makeInstallationImages(tt.images); !reflect.DeepEqual(got, tt.want) {
t.Errorf("makeInstallationImages() = %v, want %v", got, tt.want)
if got := installationImagesFromKustomizeImages(tt.images); !reflect.DeepEqual(got, tt.want) {
t.Errorf("installationImagesFromKustomizeImages() = %v, want %v", got, tt.want)
}
})
}
Expand Down
23 changes: 0 additions & 23 deletions pkg/base/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strconv"

"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/k8sdoc"
"github.com/replicatedhq/kots/pkg/kotsutil"
kotsscheme "github.com/replicatedhq/kotskinds/client/kotsclientset/scheme"
troubleshootscheme "github.com/replicatedhq/troubleshoot/pkg/client/troubleshootclientset/scheme"
Expand Down Expand Up @@ -285,28 +284,6 @@ func (b Base) ListErrorFiles() []BaseFile {
return files
}

func FindObjectsWithImages(b *Base) []k8sdoc.K8sDoc {
var objects []k8sdoc.K8sDoc
for _, file := range b.Files {
parsed, err := k8sdoc.ParseYAML(file.Content)
if err != nil {
continue
}

images := parsed.ListImages()
if len(images) > 0 {
objects = append(objects, parsed)
}
}

for _, subBase := range b.Bases {
subObjects := FindObjectsWithImages(&subBase)
objects = append(objects, subObjects...)
}

return objects
}

func PrependBaseFilesPath(files []BaseFile, prefix string) []BaseFile {
if prefix == "" {
return files
Expand Down
Loading
Loading