1
0
mirror of synced 2025-12-19 18:05:53 -05:00

upgrading k-apis to v0.0.2

This commit is contained in:
Andriy Bulynko
2020-02-04 13:39:08 -05:00
committed by Sanat Nayar
parent 3ff45e47d7
commit 4b0543b7b0
10 changed files with 481 additions and 473 deletions

View File

@@ -1,27 +1,27 @@
package main
import (
"github.com/qlik-oss/sense-installer/pkg/qliksense"
"github.com/spf13/cobra"
)
func pullQliksenseImages(q *qliksense.Qliksense) *cobra.Command {
opts := &aboutCommandOptions{}
cmd := &cobra.Command{
Use: "pull",
Short: "Pull docke images for offline install",
Example: `qliksense pull`,
RunE: func(cmd *cobra.Command, args []string) error {
if gitRef, err := getAboutCommandGitRef(args); err != nil {
return err
} else if err = q.PullImages(gitRef, opts.Profile, false); err != nil {
return err
}
return nil
},
}
f := cmd.Flags()
f.StringVar(&opts.Profile, "profile", "", "Configuration profile")
return cmd
}
package main
import (
"github.com/qlik-oss/sense-installer/pkg/qliksense"
"github.com/spf13/cobra"
)
func pullQliksenseImages(q *qliksense.Qliksense) *cobra.Command {
opts := &aboutCommandOptions{}
cmd := &cobra.Command{
Use: "pull",
Short: "Pull docke images for offline install",
Example: `qliksense pull`,
RunE: func(cmd *cobra.Command, args []string) error {
if gitRef, err := getAboutCommandGitRef(args); err != nil {
return err
} else if err = q.PullImages(gitRef, opts.Profile, false); err != nil {
return err
}
return nil
},
}
f := cmd.Flags()
f.StringVar(&opts.Profile, "profile", "", "Configuration profile")
return cmd
}

2
go.mod
View File

@@ -52,7 +52,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0
github.com/morikuni/aec v1.0.0 // indirect
github.com/pkg/errors v0.8.1
github.com/qlik-oss/k-apis v0.0.1
github.com/qlik-oss/k-apis v0.0.2
github.com/spf13/cobra v0.0.5
github.com/spf13/viper v1.6.1
github.com/theupdateframework/notary v0.6.1 // indirect

6
go.sum
View File

@@ -482,6 +482,10 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-replayers/grpcreplay v0.1.0 h1:eNb1y9rZFmY4ax45uEEECSa8fsxGRU+8Bil52ASAwic=
github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
github.com/google/go-replayers/httpreplay v0.1.0 h1:AX7FUb4BjrrzNvblr/OlgwrmFiep6soj5K2QSDW7BGk=
@@ -898,6 +902,8 @@ github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qlik-oss/k-apis v0.0.1 h1:XgKSi2Lu/Jsc0XeBRCObw8urt9vVjtgr7INq6kjJpV0=
github.com/qlik-oss/k-apis v0.0.1/go.mod h1:FDHuThas5MNw192Sk2IGy9fv8S06BLiuz2vfskZ162Q=
github.com/qlik-oss/k-apis v0.0.2 h1:7Sdz7528of+34NijkhxSc964FTOl+RV3IMMJxiScmd0=
github.com/qlik-oss/k-apis v0.0.2/go.mod h1:KOFzKVIdRqp47ytnHg3+9zb8fTlnrQjO6aKiwcrCJUE=
github.com/qlik-oss/kustomize/api v0.3.3-0.20200129153315-09eb26c762c8 h1:WLVkArXf58T+3SHDvSddE8P6OjkeeUtGEgHk8LDdfeo=
github.com/qlik-oss/kustomize/api v0.3.3-0.20200129153315-09eb26c762c8/go.mod h1:OCt7FTrRVHj4kmR2xLJJUIqu00BTr6GeF09hSmM17Kw=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=

View File

@@ -1,6 +1,6 @@
package api
import "github.com/qlik-oss/k-apis/config"
import "github.com/qlik-oss/k-apis/pkg/config"
// CommonConfig is exported
type CommonConfig struct {

View File

@@ -10,7 +10,7 @@ import (
"reflect"
"sort"
kapis_git "github.com/qlik-oss/k-apis/git"
kapis_git "github.com/qlik-oss/k-apis/pkg/git"
"gopkg.in/yaml.v2"
)

View File

@@ -2,10 +2,11 @@ package qliksense
import (
"fmt"
"github.com/qlik-oss/k-apis"
"path/filepath"
"github.com/qlik-oss/k-apis/pkg/cr"
qapi "github.com/qlik-oss/sense-installer/pkg/api"
"gopkg.in/yaml.v2"
"path/filepath"
)
const (

View File

@@ -1,411 +1,411 @@
package qliksense
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"github.com/containers/image/v5/copy"
"github.com/containers/image/v5/signature"
"github.com/containers/image/v5/transports/alltransports"
imageTypes "github.com/containers/image/v5/types"
"github.com/docker/cli/cli/command"
cliflags "github.com/docker/cli/cli/flags"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/term"
"github.com/docker/docker/registry"
homedir "github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
"golang.org/x/net/context"
yaml "gopkg.in/yaml.v2"
)
// PullImages ...
func (p *Qliksense) PullImages(gitRef, profile string, engine bool) error {
var (
image, versionFile, imagesDir, homeDir string
err error
versionOut *VersionOutput
)
println("getting images list...")
// TODO: get getref and profile from config/cr for About function call
if versionOut, err = p.About(gitRef, profile); err != nil {
return err
}
if homeDir, err = homedir.Dir(); err != nil {
return err
}
imagesDir = filepath.Join(homeDir, ".qliksense", "images")
os.MkdirAll(imagesDir, os.ModePerm)
versionFile = filepath.Join(imagesDir, versionOut.QliksenseVersion)
if _, err = os.Stat(versionFile); err != nil {
if os.IsNotExist(err) {
if yamlVersion, err := yaml.Marshal(versionOut); err != nil {
return err
} else if err = ioutil.WriteFile(versionFile, yamlVersion, os.ModePerm); err != nil {
return err
}
} else {
return errors.Errorf("Unable to determine About file %v exists", versionFile)
}
}
for _, image = range versionOut.Images {
if _, err = p.PullImage(image, engine); err != nil {
fmt.Print(err)
}
println("---")
}
return nil
}
// PullImage ...
func (p *Qliksense) PullImage(imageName string, engine bool) (map[string]string, error) {
if engine {
return p.pullDockerImage(imageName)
}
return p.pullImage(imageName)
}
func (p *Qliksense) commandTimeoutContext(commandTimeout time.Duration) (context.Context, context.CancelFunc) {
ctx := context.Background()
var cancel context.CancelFunc = func() {}
if commandTimeout > 0 {
ctx, cancel = context.WithTimeout(ctx, commandTimeout)
}
return ctx, cancel
}
func (p *Qliksense) pullImage(imageName string) (map[string]string, error) {
var (
ctx context.Context
cancel context.CancelFunc
srcRef, destRef imageTypes.ImageReference
blobDir, targetDir, homeDir string
segments []string
nameTag []string
err error
policyContext *signature.PolicyContext
)
ctx, cancel = p.commandTimeoutContext(0)
defer cancel()
if srcRef, err = alltransports.ParseImageName("docker://" + imageName); err != nil {
return nil, err
}
segments = strings.Split(imageName, "/")
nameTag = strings.Split(segments[len(segments)-1], ":")
if len(nameTag) < 2 {
nameTag = append(nameTag, "latest")
}
if homeDir, err = homedir.Dir(); err != nil {
return nil, err
}
targetDir = filepath.Join(homeDir, ".qliksense", "images", nameTag[0], nameTag[1])
fmt.Printf("==> Pulling image %v:%v", nameTag[0], nameTag[1])
fmt.Println()
os.MkdirAll(targetDir, os.ModePerm)
blobDir = filepath.Join(homeDir, ".qliksense", "blobs")
os.MkdirAll(blobDir, os.ModePerm)
if destRef, err = alltransports.ParseImageName("oci:" + targetDir); err != nil {
return nil, err
}
if policyContext, err = signature.NewPolicyContext(&signature.Policy{Default: []signature.PolicyRequirement{signature.NewPRInsecureAcceptAnything()}}); err != nil {
return nil, err
}
defer policyContext.Destroy()
_, err = copy.Image(ctx, policyContext, destRef, srcRef, &copy.Options{
ReportWriter: os.Stdout,
SourceCtx: &imageTypes.SystemContext{
ArchitectureChoice: "amd64",
OSChoice: "linux",
},
DestinationCtx: &imageTypes.SystemContext{
OCISharedBlobDirPath: blobDir,
},
})
return nil, err
}
func (p *Qliksense) pullDockerImage(imageName string) (map[string]string, error) {
var (
cli *command.DockerCli
dockerOutput io.Writer
response io.ReadCloser
pullOptions types.ImagePullOptions
ctx context.Context
cancel context.CancelFunc
ref reference.Named
repoInfo *registry.RepositoryInfo
authConfig types.AuthConfig
encodedAuth string
termFd uintptr
err error
)
ctx, cancel = p.commandTimeoutContext(0)
defer cancel()
if cli, err = command.NewDockerCli(); err != nil {
return nil, err
}
if err = cli.Initialize(cliflags.NewClientOptions()); err != nil {
return nil, err
}
if ref, err = reference.ParseNormalizedNamed(imageName); err != nil {
return nil, err
}
if repoInfo, err = registry.ParseRepositoryInfo(ref); err != nil {
return nil, err
}
authConfig = command.ResolveAuthConfig(ctx, cli, repoInfo.Index)
if encodedAuth, err = command.EncodeAuthToBase64(authConfig); err != nil {
return nil, err
}
pullOptions = types.ImagePullOptions{
RegistryAuth: encodedAuth,
}
if response, err = cli.Client().ImagePull(ctx, imageName, pullOptions); err != nil {
return nil, err
}
defer response.Close()
dockerOutput = ioutil.Discard
// if b.IsVerbose() {
// dockerOutput = b.Out
// }
dockerOutput = os.Stdout
termFd, _ = term.GetFdInfo(dockerOutput)
// Setting this to false here because Moby os.Exit(1) all over the place and this fails on WSL (only)
// when Term is true.
isTerm := false
if err = jsonmessage.DisplayJSONMessagesStream(response, dockerOutput, termFd, isTerm, nil); err != nil {
return nil, err
}
inspectData, _, err := cli.Client().ImageInspectWithRaw(ctx, imageName)
if err != nil {
return nil, err
}
return inspectData.ContainerConfig.Labels, nil
}
//TagAndPushImages ...
func (p *Qliksense) TagAndPushImages(registry string, engine bool) error {
var (
image string
err error
yamlVersion string
images VersionOutput
)
if err = yaml.Unmarshal([]byte(yamlVersion), &images); err != nil {
return err
}
for _, image = range images.Images {
if err = p.TagAndPush(image, registry, engine); err != nil {
fmt.Print(err)
}
println("---")
}
return nil
}
func (p *Qliksense) directoryExists(path string) (exists bool, err error) {
if info, err := os.Stat(path); err != nil && os.IsNotExist(err) {
exists = false
err = nil
} else if err != nil && !os.IsNotExist(err) {
exists = false
} else if err == nil && info.IsDir() {
exists = true
} else if err == nil && !info.IsDir() {
exists = false
err = fmt.Errorf("path: %v is occupied by a file instead of a directory", path)
}
return exists, err
}
//TagAndPush ...
func (p *Qliksense) TagAndPush(image string, registryName string, engine bool) error {
if engine {
return p.tagAndDockerPush(image, registryName)
}
return p.tagAndPush(image, registryName)
}
func (p *Qliksense) tagAndPush(image string, registryName string) error {
var (
ctx context.Context
cancel context.CancelFunc
srcRef, destRef imageTypes.ImageReference
blobDir, srcDir, homeDir, newName string
segments []string
nameTag []string
err error
policyContext *signature.PolicyContext
srcExists bool
)
ctx, cancel = p.commandTimeoutContext(0)
defer cancel()
segments = strings.Split(image, "/")
nameTag = strings.Split(segments[len(segments)-1], ":")
if len(nameTag) < 2 {
nameTag = append(nameTag, "latest")
}
if homeDir, err = homedir.Dir(); err != nil {
return err
}
srcDir = filepath.Join(homeDir, ".qliksense", "images", nameTag[0], nameTag[1])
if srcExists, err = p.directoryExists(srcDir); err != nil {
return err
}
if !srcExists {
if _, err = p.PullImage(image, false); err != nil {
return err
}
}
if srcRef, err = alltransports.ParseImageName("oci:" + srcDir); err != nil {
return err
}
if segments[0] == "docker.io" {
image = strings.Join(segments[1:], "/")
}
newName = "//" + registryName + "/" + segments[len(segments)-1]
fmt.Printf("==> Tag and push image to %v", newName)
fmt.Println()
if destRef, err = alltransports.ParseImageName("docker:" + newName); err != nil {
return err
}
if policyContext, err = signature.NewPolicyContext(&signature.Policy{Default: []signature.PolicyRequirement{signature.NewPRInsecureAcceptAnything()}}); err != nil {
return err
}
defer policyContext.Destroy()
blobDir = filepath.Join(homeDir, ".qliksense", "blobs")
os.MkdirAll(blobDir, os.ModePerm)
_, err = copy.Image(ctx, policyContext, destRef, srcRef, &copy.Options{
ReportWriter: os.Stdout,
SourceCtx: &imageTypes.SystemContext{
OCISharedBlobDirPath: blobDir,
},
DestinationCtx: &imageTypes.SystemContext{
DockerDaemonInsecureSkipTLSVerify: true,
},
})
return err
}
// PullImage ...
func (p *Qliksense) tagAndDockerPush(image string, registryName string) error {
var (
cli *command.DockerCli
dockerOutput io.Writer
response io.ReadCloser
pushOptions types.ImagePushOptions
ctx context.Context
cancel context.CancelFunc
newName string
segments []string
imageList []types.ImageSummary
imageListOptions types.ImageListOptions
filterArgs filters.Args
ref reference.Named
repoInfo *registry.RepositoryInfo
authConfig types.AuthConfig
encodedAuth string
termFd uintptr
err error
)
// TODO: Create a real cli config context
ctx, cancel = p.commandTimeoutContext(0)
defer cancel()
if cli, err = command.NewDockerCli(); err != nil {
return err
}
if err = cli.Initialize(cliflags.NewClientOptions()); err != nil {
return err
}
segments = strings.Split(image, "/")
if segments[0] == "docker.io" {
image = strings.Join(segments[1:], "/")
}
newName = registryName + "/" + segments[len(segments)-1]
filterArgs = filters.NewArgs()
filterArgs.Add("reference", image)
imageListOptions = types.ImageListOptions{
Filters: filterArgs,
}
if imageList, err = cli.Client().ImageList(ctx, imageListOptions); err != nil {
return err
}
if imageList == nil || len(imageList) <= 0 {
fmt.Printf("Use `qliksense pull`, to pull %v for an air gap push", newName)
return nil
}
if err = cli.Client().ImageTag(ctx, image, newName); err != nil {
return err
}
if ref, err = reference.ParseNormalizedNamed(image); err != nil {
return err
}
if repoInfo, err = registry.ParseRepositoryInfo(ref); err != nil {
return err
}
authConfig = command.ResolveAuthConfig(ctx, cli, repoInfo.Index)
if encodedAuth, err = command.EncodeAuthToBase64(authConfig); err != nil {
return err
}
pushOptions = types.ImagePushOptions{
All: true,
RegistryAuth: encodedAuth,
}
if response, err = cli.Client().ImagePush(ctx, newName, pushOptions); err != nil {
return err
}
defer response.Close()
dockerOutput = ioutil.Discard
// if b.IsVerbose() {
// dockerOutput = b.Out
// }
dockerOutput = os.Stdout
termFd, _ = term.GetFdInfo(dockerOutput)
// Setting this to false here because Moby os.Exit(1) all over the place and this fails on WSL (only)
// when Term is true.
isTerm := false
if err = jsonmessage.DisplayJSONMessagesStream(response, dockerOutput, termFd, isTerm, nil); err != nil {
return err
}
return nil
}
package qliksense
import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"github.com/containers/image/v5/copy"
"github.com/containers/image/v5/signature"
"github.com/containers/image/v5/transports/alltransports"
imageTypes "github.com/containers/image/v5/types"
"github.com/docker/cli/cli/command"
cliflags "github.com/docker/cli/cli/flags"
"github.com/docker/distribution/reference"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/term"
"github.com/docker/docker/registry"
homedir "github.com/mitchellh/go-homedir"
"github.com/pkg/errors"
"golang.org/x/net/context"
yaml "gopkg.in/yaml.v2"
)
// PullImages ...
func (p *Qliksense) PullImages(gitRef, profile string, engine bool) error {
var (
image, versionFile, imagesDir, homeDir string
err error
versionOut *VersionOutput
)
println("getting images list...")
// TODO: get getref and profile from config/cr for About function call
if versionOut, err = p.About(gitRef, profile); err != nil {
return err
}
if homeDir, err = homedir.Dir(); err != nil {
return err
}
imagesDir = filepath.Join(homeDir, ".qliksense", "images")
os.MkdirAll(imagesDir, os.ModePerm)
versionFile = filepath.Join(imagesDir, versionOut.QliksenseVersion)
if _, err = os.Stat(versionFile); err != nil {
if os.IsNotExist(err) {
if yamlVersion, err := yaml.Marshal(versionOut); err != nil {
return err
} else if err = ioutil.WriteFile(versionFile, yamlVersion, os.ModePerm); err != nil {
return err
}
} else {
return errors.Errorf("Unable to determine About file %v exists", versionFile)
}
}
for _, image = range versionOut.Images {
if _, err = p.PullImage(image, engine); err != nil {
fmt.Print(err)
}
println("---")
}
return nil
}
// PullImage ...
func (p *Qliksense) PullImage(imageName string, engine bool) (map[string]string, error) {
if engine {
return p.pullDockerImage(imageName)
}
return p.pullImage(imageName)
}
func (p *Qliksense) commandTimeoutContext(commandTimeout time.Duration) (context.Context, context.CancelFunc) {
ctx := context.Background()
var cancel context.CancelFunc = func() {}
if commandTimeout > 0 {
ctx, cancel = context.WithTimeout(ctx, commandTimeout)
}
return ctx, cancel
}
func (p *Qliksense) pullImage(imageName string) (map[string]string, error) {
var (
ctx context.Context
cancel context.CancelFunc
srcRef, destRef imageTypes.ImageReference
blobDir, targetDir, homeDir string
segments []string
nameTag []string
err error
policyContext *signature.PolicyContext
)
ctx, cancel = p.commandTimeoutContext(0)
defer cancel()
if srcRef, err = alltransports.ParseImageName("docker://" + imageName); err != nil {
return nil, err
}
segments = strings.Split(imageName, "/")
nameTag = strings.Split(segments[len(segments)-1], ":")
if len(nameTag) < 2 {
nameTag = append(nameTag, "latest")
}
if homeDir, err = homedir.Dir(); err != nil {
return nil, err
}
targetDir = filepath.Join(homeDir, ".qliksense", "images", nameTag[0], nameTag[1])
fmt.Printf("==> Pulling image %v:%v", nameTag[0], nameTag[1])
fmt.Println()
os.MkdirAll(targetDir, os.ModePerm)
blobDir = filepath.Join(homeDir, ".qliksense", "blobs")
os.MkdirAll(blobDir, os.ModePerm)
if destRef, err = alltransports.ParseImageName("oci:" + targetDir); err != nil {
return nil, err
}
if policyContext, err = signature.NewPolicyContext(&signature.Policy{Default: []signature.PolicyRequirement{signature.NewPRInsecureAcceptAnything()}}); err != nil {
return nil, err
}
defer policyContext.Destroy()
_, err = copy.Image(ctx, policyContext, destRef, srcRef, &copy.Options{
ReportWriter: os.Stdout,
SourceCtx: &imageTypes.SystemContext{
ArchitectureChoice: "amd64",
OSChoice: "linux",
},
DestinationCtx: &imageTypes.SystemContext{
OCISharedBlobDirPath: blobDir,
},
})
return nil, err
}
func (p *Qliksense) pullDockerImage(imageName string) (map[string]string, error) {
var (
cli *command.DockerCli
dockerOutput io.Writer
response io.ReadCloser
pullOptions types.ImagePullOptions
ctx context.Context
cancel context.CancelFunc
ref reference.Named
repoInfo *registry.RepositoryInfo
authConfig types.AuthConfig
encodedAuth string
termFd uintptr
err error
)
ctx, cancel = p.commandTimeoutContext(0)
defer cancel()
if cli, err = command.NewDockerCli(); err != nil {
return nil, err
}
if err = cli.Initialize(cliflags.NewClientOptions()); err != nil {
return nil, err
}
if ref, err = reference.ParseNormalizedNamed(imageName); err != nil {
return nil, err
}
if repoInfo, err = registry.ParseRepositoryInfo(ref); err != nil {
return nil, err
}
authConfig = command.ResolveAuthConfig(ctx, cli, repoInfo.Index)
if encodedAuth, err = command.EncodeAuthToBase64(authConfig); err != nil {
return nil, err
}
pullOptions = types.ImagePullOptions{
RegistryAuth: encodedAuth,
}
if response, err = cli.Client().ImagePull(ctx, imageName, pullOptions); err != nil {
return nil, err
}
defer response.Close()
dockerOutput = ioutil.Discard
// if b.IsVerbose() {
// dockerOutput = b.Out
// }
dockerOutput = os.Stdout
termFd, _ = term.GetFdInfo(dockerOutput)
// Setting this to false here because Moby os.Exit(1) all over the place and this fails on WSL (only)
// when Term is true.
isTerm := false
if err = jsonmessage.DisplayJSONMessagesStream(response, dockerOutput, termFd, isTerm, nil); err != nil {
return nil, err
}
inspectData, _, err := cli.Client().ImageInspectWithRaw(ctx, imageName)
if err != nil {
return nil, err
}
return inspectData.ContainerConfig.Labels, nil
}
//TagAndPushImages ...
func (p *Qliksense) TagAndPushImages(registry string, engine bool) error {
var (
image string
err error
yamlVersion string
images VersionOutput
)
if err = yaml.Unmarshal([]byte(yamlVersion), &images); err != nil {
return err
}
for _, image = range images.Images {
if err = p.TagAndPush(image, registry, engine); err != nil {
fmt.Print(err)
}
println("---")
}
return nil
}
func (p *Qliksense) directoryExists(path string) (exists bool, err error) {
if info, err := os.Stat(path); err != nil && os.IsNotExist(err) {
exists = false
err = nil
} else if err != nil && !os.IsNotExist(err) {
exists = false
} else if err == nil && info.IsDir() {
exists = true
} else if err == nil && !info.IsDir() {
exists = false
err = fmt.Errorf("path: %v is occupied by a file instead of a directory", path)
}
return exists, err
}
//TagAndPush ...
func (p *Qliksense) TagAndPush(image string, registryName string, engine bool) error {
if engine {
return p.tagAndDockerPush(image, registryName)
}
return p.tagAndPush(image, registryName)
}
func (p *Qliksense) tagAndPush(image string, registryName string) error {
var (
ctx context.Context
cancel context.CancelFunc
srcRef, destRef imageTypes.ImageReference
blobDir, srcDir, homeDir, newName string
segments []string
nameTag []string
err error
policyContext *signature.PolicyContext
srcExists bool
)
ctx, cancel = p.commandTimeoutContext(0)
defer cancel()
segments = strings.Split(image, "/")
nameTag = strings.Split(segments[len(segments)-1], ":")
if len(nameTag) < 2 {
nameTag = append(nameTag, "latest")
}
if homeDir, err = homedir.Dir(); err != nil {
return err
}
srcDir = filepath.Join(homeDir, ".qliksense", "images", nameTag[0], nameTag[1])
if srcExists, err = p.directoryExists(srcDir); err != nil {
return err
}
if !srcExists {
if _, err = p.PullImage(image, false); err != nil {
return err
}
}
if srcRef, err = alltransports.ParseImageName("oci:" + srcDir); err != nil {
return err
}
if segments[0] == "docker.io" {
image = strings.Join(segments[1:], "/")
}
newName = "//" + registryName + "/" + segments[len(segments)-1]
fmt.Printf("==> Tag and push image to %v", newName)
fmt.Println()
if destRef, err = alltransports.ParseImageName("docker:" + newName); err != nil {
return err
}
if policyContext, err = signature.NewPolicyContext(&signature.Policy{Default: []signature.PolicyRequirement{signature.NewPRInsecureAcceptAnything()}}); err != nil {
return err
}
defer policyContext.Destroy()
blobDir = filepath.Join(homeDir, ".qliksense", "blobs")
os.MkdirAll(blobDir, os.ModePerm)
_, err = copy.Image(ctx, policyContext, destRef, srcRef, &copy.Options{
ReportWriter: os.Stdout,
SourceCtx: &imageTypes.SystemContext{
OCISharedBlobDirPath: blobDir,
},
DestinationCtx: &imageTypes.SystemContext{
DockerDaemonInsecureSkipTLSVerify: true,
},
})
return err
}
// PullImage ...
func (p *Qliksense) tagAndDockerPush(image string, registryName string) error {
var (
cli *command.DockerCli
dockerOutput io.Writer
response io.ReadCloser
pushOptions types.ImagePushOptions
ctx context.Context
cancel context.CancelFunc
newName string
segments []string
imageList []types.ImageSummary
imageListOptions types.ImageListOptions
filterArgs filters.Args
ref reference.Named
repoInfo *registry.RepositoryInfo
authConfig types.AuthConfig
encodedAuth string
termFd uintptr
err error
)
// TODO: Create a real cli config context
ctx, cancel = p.commandTimeoutContext(0)
defer cancel()
if cli, err = command.NewDockerCli(); err != nil {
return err
}
if err = cli.Initialize(cliflags.NewClientOptions()); err != nil {
return err
}
segments = strings.Split(image, "/")
if segments[0] == "docker.io" {
image = strings.Join(segments[1:], "/")
}
newName = registryName + "/" + segments[len(segments)-1]
filterArgs = filters.NewArgs()
filterArgs.Add("reference", image)
imageListOptions = types.ImageListOptions{
Filters: filterArgs,
}
if imageList, err = cli.Client().ImageList(ctx, imageListOptions); err != nil {
return err
}
if imageList == nil || len(imageList) <= 0 {
fmt.Printf("Use `qliksense pull`, to pull %v for an air gap push", newName)
return nil
}
if err = cli.Client().ImageTag(ctx, image, newName); err != nil {
return err
}
if ref, err = reference.ParseNormalizedNamed(image); err != nil {
return err
}
if repoInfo, err = registry.ParseRepositoryInfo(ref); err != nil {
return err
}
authConfig = command.ResolveAuthConfig(ctx, cli, repoInfo.Index)
if encodedAuth, err = command.EncodeAuthToBase64(authConfig); err != nil {
return err
}
pushOptions = types.ImagePushOptions{
All: true,
RegistryAuth: encodedAuth,
}
if response, err = cli.Client().ImagePush(ctx, newName, pushOptions); err != nil {
return err
}
defer response.Close()
dockerOutput = ioutil.Discard
// if b.IsVerbose() {
// dockerOutput = b.Out
// }
dockerOutput = os.Stdout
termFd, _ = term.GetFdInfo(dockerOutput)
// Setting this to false here because Moby os.Exit(1) all over the place and this fails on WSL (only)
// when Term is true.
isTerm := false
if err = jsonmessage.DisplayJSONMessagesStream(response, dockerOutput, termFd, isTerm, nil); err != nil {
return err
}
return nil
}

View File

@@ -1,11 +1,12 @@
package qliksense
import (
kapis_git "github.com/qlik-oss/k-apis/git"
"io/ioutil"
"os"
"path"
"testing"
kapis_git "github.com/qlik-oss/k-apis/pkg/git"
)
func Test_executeKustomizeBuild(t *testing.T) {
@@ -67,4 +68,4 @@ func Test_executeKustomizeBuild_onQlikConfig_DISABLED(t *testing.T) {
if _, err := executeKustomizeBuild(path.Join(configPath, "manifests", "base")); err != nil {
t.Fatalf("unexpected kustomize error: %v\n", err)
}
}
}

View File

@@ -1,20 +1,20 @@
//go:generate packr2
package qliksense
import (
"github.com/gobuffalo/packr/v2"
)
// Qliksense is the logic behind the qliksense client
type Qliksense struct {
QliksenseHome string
CrdBox *packr.Box
}
// New qliksense client, initialized with useful defaults.
func New(qliksenseHome string) *Qliksense {
return &Qliksense{
QliksenseHome: qliksenseHome,
CrdBox: packr.New("crds", "./crds"),
}
}
//go:generate packr2
package qliksense
import (
"github.com/gobuffalo/packr/v2"
)
// Qliksense is the logic behind the qliksense client
type Qliksense struct {
QliksenseHome string
CrdBox *packr.Box
}
// New qliksense client, initialized with useful defaults.
func New(qliksenseHome string) *Qliksense {
return &Qliksense{
QliksenseHome: qliksenseHome,
CrdBox: packr.New("crds", "./crds"),
}
}

View File

@@ -1,8 +1,8 @@
package pkg
// These are build-time values, set during an official release
var (
Commit string
Version string
CommitDate string
)
package pkg
// These are build-time values, set during an official release
var (
Commit string
Version string
CommitDate string
)