Skip to content

Commit

Permalink
+
Browse files Browse the repository at this point in the history
Signed-off-by: Denis Romanenko <[email protected]>
  • Loading branch information
RomanenkoDenys committed Jun 3, 2024
1 parent 77d1fd3 commit 893d8f0
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 54 deletions.
12 changes: 10 additions & 2 deletions internal/dhctl/cmd/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,17 @@ func parseAndValidateParameters(cmd *cobra.Command, args []string) error {
}

func bootstrap(cmd *cobra.Command, args []string) error {
ctx := buildInstallerContext()
return image.PullInstallerImage(ctx)
img := image.NewImage(buildContext(), TempDir, ImageTag, os.Args[1:], getDhctlEnvs())
err := img.Pull()
if err != nil {
return err
}
err = img.Run()
if err != nil {
return err
}

return nil
}

func cleanup(cmd *cobra.Command, args []string) error {
Expand Down
7 changes: 4 additions & 3 deletions internal/dhctl/cmd/dhctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ valid license for any commercial version of the Deckhouse Kubernetes Platform.

func NewCommand() *cobra.Command {
dhctlCmd := &cobra.Command{
Use: "i",
Short: "run Deckhouse installer tool",
Long: "Run Deckhouse installer tool.\n" + licenceNote,
Use: "i",
Aliases: []string{"dhctl"},
Short: "run Deckhouse installer tool",
Long: "Run Deckhouse installer tool.\n" + licenceNote,
}

dhctlCmd.AddCommand(
Expand Down
37 changes: 0 additions & 37 deletions internal/dhctl/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ import (
"os"
"path/filepath"

"github.com/google/go-containerregistry/pkg/authn"
"github.com/spf13/pflag"

"github.com/deckhouse/deckhouse-cli/internal/dhctl/cmd/app"
"github.com/deckhouse/deckhouse-cli/internal/dhctl/image"
"github.com/deckhouse/deckhouse-cli/internal/mirror/contexts"
)

const (
Expand Down Expand Up @@ -101,37 +98,3 @@ func addRegistryFlags(flagSet *pflag.FlagSet) {
"Interact with registries over HTTP.",
)
}

func getSourceRegistryAuthProvider() authn.Authenticator {
if RegistryLogin != "" {
return authn.FromConfig(authn.AuthConfig{
Username: RegistryLogin,
Password: RegistryPassword,
})
}

if LicenseToken != "" {
return authn.FromConfig(authn.AuthConfig{
Username: "license-token",
Password: LicenseToken,
})
}

return authn.Anonymous
}

func buildInstallerContext() *image.InstallerContext {
ctx := &image.InstallerContext{
BaseContext: contexts.BaseContext{
Insecure: Insecure,
SkipTLSVerification: TLSSkipVerify,
DeckhouseRegistryRepo: RegistryRepo,
RegistryAuth: getSourceRegistryAuthProvider(),
UnpackedImagesPath: TempDir,
},
Args: os.Args[1:],
ImageTag: ImageTag,
TempDir: TempDir,
}
return ctx
}
63 changes: 63 additions & 0 deletions internal/dhctl/cmd/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2024 Flant JSC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dhctl

import (
"os"
"strings"

"github.com/google/go-containerregistry/pkg/authn"

"github.com/deckhouse/deckhouse-cli/internal/mirror/contexts"
)

func getSourceRegistryAuthProvider() authn.Authenticator {
if RegistryLogin != "" {
return authn.FromConfig(authn.AuthConfig{
Username: RegistryLogin,
Password: RegistryPassword,
})
}

if LicenseToken != "" {
return authn.FromConfig(authn.AuthConfig{
Username: "license-token",
Password: LicenseToken,
})
}
return authn.Anonymous
}

func buildContext() *contexts.BaseContext {
ctx := &contexts.BaseContext{
Insecure: Insecure,
SkipTLSVerification: TLSSkipVerify,
DeckhouseRegistryRepo: RegistryRepo,
RegistryAuth: getSourceRegistryAuthProvider(),
UnpackedImagesPath: TempDir,
}
return ctx
}

func getDhctlEnvs() map[string]string {
ret := make(map[string]string)
for _, s := range os.Environ() {
pair := strings.SplitN(s, "=", 2)
if strings.HasPrefix(pair[0], "DHCTL_") {
ret[pair[0]] = pair[1]
}
}
return ret
}
76 changes: 64 additions & 12 deletions internal/dhctl/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"slices"
"syscall"

"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
Expand All @@ -32,32 +34,42 @@ import (
"github.com/deckhouse/deckhouse-cli/internal/mirror/util/log"
)

// InstallerContext holds data related to pending mirroring-from-registry operation.
type InstallerContext struct {
contexts.BaseContext
Args []string
ImageTag string
TempDir string
type Image struct {
ctx *contexts.BaseContext
args []string
imageTag string
tempDir string
envs map[string]string
}

func PullInstallerImage(ctx *InstallerContext) error {
nameOpts, remoteOpts := auth.MakeRemoteRegistryRequestOptions(ctx.RegistryAuth, ctx.Insecure, ctx.SkipTLSVerification)
imageRef := fmt.Sprintf("%s/%s:%s", ctx.DeckhouseRegistryRepo, "install", ctx.ImageTag)
func NewImage(ctx *contexts.BaseContext, tempDir string, imageTag string, args []string, envs map[string]string) *Image {
return &Image{
ctx: ctx,
tempDir: tempDir,
imageTag: imageTag,
args: args,
envs: envs,
}
}

func (img *Image) Pull() error {
nameOpts, remoteOpts := auth.MakeRemoteRegistryRequestOptions(img.ctx.RegistryAuth, img.ctx.Insecure, img.ctx.SkipTLSVerification)
imageRef := fmt.Sprintf("%s/%s:%s", img.ctx.DeckhouseRegistryRepo, "install", img.imageTag)
ref, err := name.ParseReference(imageRef, nameOpts...)
if err != nil {
return err
}

log.InfoF("Pulling %s...\n", imageRef)
img, err := remote.Image(ref, remoteOpts...)
image, err := remote.Image(ref, remoteOpts...)
if err != nil {
if errorutil.IsImageNotFoundError(err) {
return fmt.Errorf("⚠️ %s Not found in registry", imageRef)
}

return fmt.Errorf("pull image %s metadata: %w", imageRef, err)
}
layers, err := img.Layers()
layers, err := image.Layers()
if err != nil {
return err
}
Expand All @@ -75,7 +87,7 @@ func PullInstallerImage(ctx *InstallerContext) error {
return err
}

err = writeAndUnpackLayer(r, ctx.TempDir, digest.String())
err = writeAndUnpackLayer(r, img.tempDir, digest.String())
if err != nil {
return err
}
Expand Down Expand Up @@ -122,3 +134,43 @@ func writeAndUnpackLayer(r io.ReadCloser, targetDir, filename string) error {
}
return nil
}

func (img *Image) Run() error {
log.InfoF("Running %s...\n", img.tempDir)
//Hold onto old root
oldrootHandle, err := os.Open("/")
if err != nil {
panic(err)
}
defer oldrootHandle.Close()

cmd := exec.Command(img.args[0], img.args[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

//New Root time
err = syscall.Chdir(img.tempDir)
if err != nil {
return err
}

err = syscall.Chroot(img.tempDir)
if err != nil {
return err
}

err = cmd.Run()
if err != nil {
return err
}

//Go back to old root
//So that we can clean up the temp dir
err = syscall.Fchdir(int(oldrootHandle.Fd()))
if err != nil {
return err
}

return syscall.Chroot(".")
}

0 comments on commit 893d8f0

Please sign in to comment.