Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39d02db187 | ||
|
|
0393a431fb | ||
|
|
d1088e2635 | ||
|
|
dabaed4c07 | ||
|
|
54d0972e85 | ||
|
|
2839e5b77b | ||
|
|
3608f9693c | ||
|
|
60a328d69f | ||
|
|
ee02016f16 |
4
Makefile
4
Makefile
@@ -3,11 +3,12 @@ PKG = github.com/qlik-oss/sense-installer
|
||||
# --no-print-directory avoids verbose logging when invoking targets that utilize sub-makes
|
||||
MAKE_OPTS ?= --no-print-directory
|
||||
|
||||
LDFLAGS = -w -X $(PKG)/pkg.Version=$(VERSION) -X $(PKG)/pkg.Commit=$(COMMIT)
|
||||
LDFLAGS = -w -X $(PKG)/pkg.Version=$(VERSION) -X $(PKG)/pkg.Commit=$(COMMIT) -X "$(PKG)/pkg.CommitDate=$(COMMIT_DATE)"
|
||||
XBUILD = CGO_ENABLED=0 go build -a -tags netgo -ldflags '$(LDFLAGS)'
|
||||
BINDIR = bin
|
||||
|
||||
COMMIT ?= $(shell git rev-parse --short HEAD)
|
||||
COMMIT_DATE ?= $(shell git show --no-patch --no-notes --pretty='%cd' $(COMMIT) --date=iso)
|
||||
VERSION ?= $(shell git describe --tags 2> /dev/null || echo v0)
|
||||
PERMALINK ?= $(shell git describe --tags --exact-match &> /dev/null && echo latest || echo canary)
|
||||
|
||||
@@ -44,3 +45,4 @@ xbuild: $(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EX
|
||||
$(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EXT):
|
||||
mkdir -p $(dir $@)
|
||||
GOOS=$(CLIENT_PLATFORM) GOARCH=$(CLIENT_ARCH) $(XBUILD) -o $@ ./cmd/$(MIXIN)
|
||||
|
||||
|
||||
@@ -9,6 +9,13 @@ Download the appropriate executable for your platform from the [releases page](h
|
||||
To make sure everything is order, you can fetch the Qlik Sense bundle version and corresponding image list from:
|
||||
- `qliksense about --tag qlik/qliksense-cnab-bundle:latest `
|
||||
|
||||
## Running Preflight checks
|
||||
You can run preflight checks to ensure that the cluster is in a healthy state before installing Qliksense.
|
||||
- `qliksense preflight -c <credential_name> `
|
||||
|
||||
The above command runs the checks in the default namespace. If you want to specify the namespace to run preflight checks on:
|
||||
- `qliksense preflight --param namespace=<value> -c <credential_name> `
|
||||
|
||||
## Qliksense Packaging
|
||||
Packaging of Qlik Sense on Kubernetes is done through a [Porter](https://porter.sh/) definition in the [Qlik Sense on Kubernetes configuration repository](https://github.com/qlik-oss/qliksense-k8s/blob/master/porter.yaml), the resulting bundle published on DockerHub as a [Cloud Natvie Application Bundle](https://cnab.io/) called [qliksense-cnab-bundle](https://hub.docker.com/r/qlik/qliksense-cnab-bundle).
|
||||
### Versioning
|
||||
|
||||
@@ -1,245 +1,412 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/qlik-oss/sense-installer/pkg/qliksense"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func buildAliasCommands(porterCmd *cobra.Command, q *qliksense.Qliksense) []*cobra.Command {
|
||||
|
||||
return []*cobra.Command{
|
||||
buildBuildAlias(porterCmd),
|
||||
buildInstallAlias(porterCmd, q),
|
||||
buildAboutAlias(porterCmd),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func buildBuildAlias(porterCmd *cobra.Command) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
)
|
||||
c = &cobra.Command{
|
||||
Use: "build",
|
||||
Short: "Build a bundle",
|
||||
Long: "Builds the bundle in the current directory by generating a Dockerfile and a CNAB bundle.json, and then building the invocation image.",
|
||||
DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return porterCmd.RunE(porterCmd, append([]string{"build"}, args...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
type paramOptions struct {
|
||||
aboutOptions
|
||||
Params []string
|
||||
ParamFiles []string
|
||||
Name string
|
||||
InsecureRegistry bool
|
||||
|
||||
// CredentialIdentifiers is a list of credential names or paths to make available to the bundle.
|
||||
CredentialIdentifiers []string
|
||||
Driver string
|
||||
Force bool
|
||||
Insecure bool
|
||||
}
|
||||
|
||||
func buildInstallAlias(porterCmd *cobra.Command, q *qliksense.Qliksense) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
opts *paramOptions
|
||||
registry *string
|
||||
)
|
||||
|
||||
opts = ¶mOptions{}
|
||||
|
||||
c = &cobra.Command{
|
||||
Use: "install [INSTANCE]",
|
||||
Short: "Install qliksense",
|
||||
Long: `Install a new instance of a bundle.
|
||||
|
||||
The first argument is the bundle instance name to create for the installation. This defaults to the name of the bundle.
|
||||
|
||||
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
|
||||
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
|
||||
Example: ` qliksense install
|
||||
qliksense install --version v1.0.0
|
||||
qliksense install --insecure
|
||||
qliksense install qliksense --file qliksense/bundle.json
|
||||
qliksense install --param-file base-values.txt --param-file dev-values.txt --param test-mode=true --param header-color=blue
|
||||
qliksense install --cred kubernetes
|
||||
qliksense install --driver debug
|
||||
qliksense install MyAppFromTag --tag qlik/qliksense-cnab-bundle:v1.0.0
|
||||
`,
|
||||
//DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// Push images here.
|
||||
// TODO: Need to get the private reg from params
|
||||
args = append(os.Args[1:], opts.getTagDefaults(args)...)
|
||||
if registry = opts.findKey("dockerRegistry"); registry != nil {
|
||||
if len(*registry) > 0 {
|
||||
q.TagAndPushImages(*registry)
|
||||
}
|
||||
}
|
||||
return porterCmd.RunE(porterCmd, append([]string{"install"}, args...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
f := c.Flags()
|
||||
f.StringVarP(&opts.Version, "version", "v", "latest",
|
||||
"Version of Qlik Sense to install")
|
||||
f.BoolVar(&opts.Insecure, "insecure", true,
|
||||
"Allow working with untrusted bundles")
|
||||
f.StringVarP(&opts.File, "file", "f", "",
|
||||
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
|
||||
f.StringVar(&opts.CNABFile, "cnab-file", "",
|
||||
"Path to the CNAB bundle.json file.")
|
||||
f.StringSliceVar(&opts.ParamFiles, "param-file", nil,
|
||||
"Path to a parameters definition file for the bundle, each line in the form of NAME=VALUE. May be specified multiple times.")
|
||||
f.StringSliceVar(&opts.Params, "param", nil,
|
||||
"Define an individual parameter in the form NAME=VALUE. Overrides parameters set with the same name using --param-file. May be specified multiple times.")
|
||||
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
|
||||
"Credential to use when installing the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
|
||||
f.StringVarP(&opts.Driver, "driver", "d", "docker",
|
||||
"Specify a driver to use. Allowed values: docker, debug")
|
||||
f.StringVarP(&opts.Tag, "tag", "t", "",
|
||||
"Use a bundle in an OCI registry specified by the given tag")
|
||||
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false,
|
||||
"Don't require TLS for the registry")
|
||||
f.BoolVar(&opts.Force, "force", false,
|
||||
"Force a fresh pull of the bundle and all dependencies")
|
||||
return c
|
||||
}
|
||||
func (o *aboutOptions) getTagDefaults(args []string) []string {
|
||||
var err error
|
||||
if len(o.Tag) > 1 {
|
||||
args = append(args, []string{"--tag", o.Tag}...)
|
||||
}
|
||||
if len(o.Tag) <= 0 && len(o.File) <= 0 && len(o.CNABFile) <= 0 {
|
||||
if _, err = os.Stat("porter.yaml"); err != nil {
|
||||
args = append(args, []string{"--tag", "qlik/qliksense-cnab-bundle:" + o.Version}...)
|
||||
}
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
type aboutOptions struct {
|
||||
Version string
|
||||
Tag string
|
||||
File string
|
||||
CNABFile string
|
||||
}
|
||||
|
||||
func buildAboutAlias(porterCmd *cobra.Command) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
opts *aboutOptions
|
||||
)
|
||||
|
||||
opts = &aboutOptions{}
|
||||
|
||||
c = &cobra.Command{
|
||||
Use: "about",
|
||||
Short: "About Qlik Sense",
|
||||
Long: "Gives the verion of QLik Sense on Kuberntetes and versions of images.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
args = opts.getTagDefaults(args)
|
||||
return porterCmd.RunE(porterCmd, append([]string{"invoke", "--action", "about"}, args...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
f := c.Flags()
|
||||
f.StringVarP(&opts.Version, "version", "v", "latest",
|
||||
"Version of Qlik Sense to install")
|
||||
f.StringVarP(&opts.Tag, "tag", "t", "",
|
||||
"Use a bundle in an OCI registry specified by the given tag")
|
||||
f.StringVarP(&opts.File, "file", "f", "",
|
||||
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
|
||||
f.StringVar(&opts.CNABFile, "cnab-file", "",
|
||||
"Path to the CNAB bundle.json file.")
|
||||
return c
|
||||
}
|
||||
|
||||
func (o *paramOptions) findKey(param string) *string {
|
||||
var (
|
||||
value *string
|
||||
)
|
||||
if value = o.findParams(param); value != nil {
|
||||
return value
|
||||
}
|
||||
|
||||
if value = o.findParamFiles(param); value != nil {
|
||||
return value
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// parsedParams parses the variable assignments in Params.
|
||||
func (o *paramOptions) findParams(param string) *string {
|
||||
return o.findVariableKey(param, o.Params)
|
||||
}
|
||||
|
||||
// parseParamFiles parses the variable assignments in ParamFiles.
|
||||
func (o *paramOptions) findParamFiles(param string) *string {
|
||||
var (
|
||||
path string
|
||||
retStr *string
|
||||
)
|
||||
|
||||
for _, path = range o.ParamFiles {
|
||||
retStr = o.findParamFile(param, path)
|
||||
}
|
||||
|
||||
return retStr
|
||||
}
|
||||
|
||||
func (o *paramOptions) findParamFile(param string, path string) *string {
|
||||
var (
|
||||
f *os.File
|
||||
err error
|
||||
scanner *bufio.Scanner
|
||||
lines []string
|
||||
retStr *string
|
||||
)
|
||||
if f, err = os.Open(path); err == nil {
|
||||
defer f.Close()
|
||||
|
||||
scanner = bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Text())
|
||||
}
|
||||
|
||||
retStr = o.findVariableKey(param, lines)
|
||||
}
|
||||
return retStr
|
||||
}
|
||||
|
||||
func (o *paramOptions) findVariableKey(param string, params []string) *string {
|
||||
var (
|
||||
variable, value string
|
||||
)
|
||||
for _, p := range params {
|
||||
parts := strings.SplitN(p, "=", 2)
|
||||
if len(parts) >= 2 {
|
||||
variable = strings.TrimSpace(parts[0])
|
||||
if variable == param {
|
||||
value = strings.TrimSpace(parts[1])
|
||||
return &value
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/qlik-oss/sense-installer/pkg/qliksense"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func buildAliasCommands(porterCmd *cobra.Command, q *qliksense.Qliksense) []*cobra.Command {
|
||||
|
||||
return []*cobra.Command{
|
||||
buildBuildAlias(porterCmd),
|
||||
buildInstallAlias(porterCmd, q),
|
||||
buildUpgradeAlias(porterCmd, q),
|
||||
buildAboutAlias(porterCmd),
|
||||
buildPreflightAlias(porterCmd, q),
|
||||
buildUninstallAlias(porterCmd, q),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func buildBuildAlias(porterCmd *cobra.Command) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
)
|
||||
c = &cobra.Command{
|
||||
Use: "build",
|
||||
Short: "Build a bundle",
|
||||
Long: "Builds the bundle in the current directory by generating a Dockerfile and a CNAB bundle.json, and then building the invocation image.",
|
||||
DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return porterCmd.RunE(porterCmd, append([]string{"build"}, args...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
type paramOptions struct {
|
||||
aboutOptions
|
||||
Params []string
|
||||
ParamFiles []string
|
||||
Name string
|
||||
InsecureRegistry bool
|
||||
|
||||
// CredentialIdentifiers is a list of credential names or paths to make available to the bundle.
|
||||
CredentialIdentifiers []string
|
||||
Driver string
|
||||
Force bool
|
||||
Insecure bool
|
||||
}
|
||||
|
||||
func buildInstallAlias(porterCmd *cobra.Command, q *qliksense.Qliksense) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
opts *paramOptions
|
||||
registry *string
|
||||
)
|
||||
|
||||
opts = ¶mOptions{}
|
||||
|
||||
c = &cobra.Command{
|
||||
Use: "install [INSTANCE]",
|
||||
Short: "Install qliksense",
|
||||
Long: `Install a new instance of a bundle.
|
||||
|
||||
The first argument is the bundle instance name to create for the installation. This defaults to the name of the bundle.
|
||||
|
||||
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
|
||||
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
|
||||
Example: ` qliksense install
|
||||
qliksense install --version v1.0.0
|
||||
qliksense install --insecure
|
||||
qliksense install qliksense --file qliksense/bundle.json
|
||||
qliksense install --param-file base-values.txt --param-file dev-values.txt --param test-mode=true --param header-color=blue
|
||||
qliksense install --cred kubernetes
|
||||
qliksense install --driver debug
|
||||
qliksense install MyAppFromTag --tag qlik/qliksense-cnab-bundle:v1.0.0
|
||||
`,
|
||||
//DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// Push images here.
|
||||
// TODO: Need to get the private reg from params
|
||||
args = append(os.Args[2:], opts.getTagValue(args)...)
|
||||
if registry = opts.findKey("dockerRegistry"); registry != nil {
|
||||
if len(*registry) > 0 {
|
||||
q.TagAndPushImages(*registry)
|
||||
}
|
||||
}
|
||||
return porterCmd.RunE(porterCmd, append([]string{"install"}, args...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
f := c.Flags()
|
||||
f.StringVarP(&opts.Version, "version", "v", "latest",
|
||||
"Version of Qlik Sense to install")
|
||||
f.BoolVar(&opts.Insecure, "insecure", true,
|
||||
"Allow working with untrusted bundles")
|
||||
f.StringVarP(&opts.File, "file", "f", "",
|
||||
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
|
||||
f.StringVar(&opts.CNABFile, "cnab-file", "",
|
||||
"Path to the CNAB bundle.json file.")
|
||||
f.StringSliceVar(&opts.ParamFiles, "param-file", nil,
|
||||
"Path to a parameters definition file for the bundle, each line in the form of NAME=VALUE. May be specified multiple times.")
|
||||
f.StringSliceVar(&opts.Params, "param", nil,
|
||||
"Define an individual parameter in the form NAME=VALUE. Overrides parameters set with the same name using --param-file. May be specified multiple times.")
|
||||
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
|
||||
"Credential to use when installing the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
|
||||
f.StringVarP(&opts.Driver, "driver", "d", "docker",
|
||||
"Specify a driver to use. Allowed values: docker, debug")
|
||||
f.StringVarP(&opts.Tag, "tag", "t", "",
|
||||
"Use a bundle in an OCI registry specified by the given tag")
|
||||
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false,
|
||||
"Don't require TLS for the registry")
|
||||
f.BoolVar(&opts.Force, "force", false,
|
||||
"Force a fresh pull of the bundle and all dependencies")
|
||||
return c
|
||||
}
|
||||
|
||||
func buildUpgradeAlias(porterCmd *cobra.Command, q *qliksense.Qliksense) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
opts *paramOptions
|
||||
registry *string
|
||||
)
|
||||
|
||||
opts = ¶mOptions{}
|
||||
|
||||
c = &cobra.Command{
|
||||
Use: "upgrade [INSTANCE]",
|
||||
Short: "Upgrade qliksense",
|
||||
Long: `Upgrade to a new instance of a bundle.
|
||||
|
||||
The first argument is the bundle instance name to upgrade for the installation. This defaults to the name of the bundle.
|
||||
|
||||
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
|
||||
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
|
||||
Example: ` qliksense upgrade
|
||||
qliksense upgrade --version v1.0.0
|
||||
qliksense upgrade --insecure
|
||||
qliksense upgrade qliksense --file qliksense/bundle.json
|
||||
qliksense upgrade --param-file base-values.txt --param-file dev-values.txt --param test-mode=true --param header-color=blue
|
||||
qliksense upgrade --cred kubernetes
|
||||
qliksense upgrade --driver debug
|
||||
qliksense upgrade MyAppFromTag --tag qlik/qliksense-cnab-bundle:v1.0.0
|
||||
`,
|
||||
//DisableFlagParsing: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// Push images here.
|
||||
// TODO: Need to get the private reg from params
|
||||
args = append(os.Args[2:], opts.getTagValue(args)...)
|
||||
if registry = opts.findKey("dockerRegistry"); registry != nil {
|
||||
if len(*registry) > 0 {
|
||||
q.TagAndPushImages(*registry)
|
||||
}
|
||||
}
|
||||
return porterCmd.RunE(porterCmd, append([]string{"upgrade"}, args...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
f := c.Flags()
|
||||
f.StringVarP(&opts.Version, "version", "v", "latest",
|
||||
"Version of Qlik Sense to upgrade to")
|
||||
f.BoolVar(&opts.Insecure, "insecure", true,
|
||||
"Allow working with untrusted bundles")
|
||||
f.StringVarP(&opts.File, "file", "f", "",
|
||||
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
|
||||
f.StringVar(&opts.CNABFile, "cnab-file", "",
|
||||
"Path to the CNAB bundle.json file.")
|
||||
f.StringSliceVar(&opts.ParamFiles, "param-file", nil,
|
||||
"Path to a parameters definition file for the bundle, each line in the form of NAME=VALUE. May be specified multiple times.")
|
||||
f.StringSliceVar(&opts.Params, "param", nil,
|
||||
"Define an individual parameter in the form NAME=VALUE. Overrides parameters set with the same name using --param-file. May be specified multiple times.")
|
||||
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
|
||||
"Credential to use when installing the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
|
||||
f.StringVarP(&opts.Driver, "driver", "d", "docker",
|
||||
"Specify a driver to use. Allowed values: docker, debug")
|
||||
f.StringVarP(&opts.Tag, "tag", "t", "",
|
||||
"Use a bundle in an OCI registry specified by the given tag")
|
||||
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false,
|
||||
"Don't require TLS for the registry")
|
||||
f.BoolVar(&opts.Force, "force", false,
|
||||
"Force a fresh pull of the bundle and all dependencies")
|
||||
return c
|
||||
}
|
||||
|
||||
func buildUninstallAlias(porterCmd *cobra.Command, q *qliksense.Qliksense) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
opts *paramOptions
|
||||
)
|
||||
|
||||
opts = ¶mOptions{}
|
||||
|
||||
c = &cobra.Command{
|
||||
Use: "uninstall [INSTANCE]",
|
||||
Short: "Uninstall a bundle instance",
|
||||
Long: `Uninstall a bundle instance
|
||||
The first argument is the bundle instance name to uninstall. This defaults to the name of the bundle.
|
||||
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
|
||||
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
|
||||
Example: ` qliksense uninstall
|
||||
qliksense uninstall --insecure
|
||||
qliksense uninstall MyAppInDev --file myapp/bundle.json
|
||||
qliksense uninstall --param-file base-values.txt --param-file dev-values.txt --param test-mode=true --param header-color=blue
|
||||
qliksense uninstall --cred azure --cred kubernetes
|
||||
qliksense uninstall --driver debug
|
||||
qliksense uninstall MyAppFromTag --tag deislabs/porter-kube-bundle:v1.0
|
||||
`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return porterCmd.RunE(porterCmd, append([]string{"uninstall"}, os.Args[2:]...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
|
||||
f := c.Flags()
|
||||
f.BoolVar(&opts.Insecure, "insecure", true,
|
||||
"Allow working with untrusted bundles")
|
||||
f.StringVarP(&opts.File, "file", "f", "",
|
||||
"Path to the porter manifest file. Defaults to the bundle in the current directory. Optional unless a newer version of the bundle should be used to uninstall the bundle.")
|
||||
f.StringVar(&opts.CNABFile, "cnab-file", "",
|
||||
"Path to the CNAB bundle.json file.")
|
||||
f.StringSliceVar(&opts.ParamFiles, "param-file", nil,
|
||||
"Path to a parameters definition file for the bundle, each line in the form of NAME=VALUE. May be specified multiple times.")
|
||||
f.StringSliceVar(&opts.Params, "param", nil,
|
||||
"Define an individual parameter in the form NAME=VALUE. Overrides parameters set with the same name using --param-file. May be specified multiple times.")
|
||||
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
|
||||
"Credential to use when uninstalling the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
|
||||
f.StringVarP(&opts.Driver, "driver", "d", "docker",
|
||||
"Specify a driver to use. Allowed values: docker, debug")
|
||||
f.StringVarP(&opts.Tag, "tag", "t", "",
|
||||
"Use a bundle in an OCI registry specified by the given tag")
|
||||
f.BoolVar(&opts.InsecureRegistry, "insecure-registry", false,
|
||||
"Don't require TLS for the registry")
|
||||
f.BoolVar(&opts.Force, "force", false,
|
||||
"Force a fresh pull of the bundle and all dependencies")
|
||||
|
||||
return c
|
||||
}
|
||||
func (o *aboutOptions) getTagDefaults(args []string) []string {
|
||||
args = append(args, o.getTagValue(args)...)
|
||||
return args
|
||||
}
|
||||
|
||||
func (o *aboutOptions) getTagValue(args []string) []string {
|
||||
tagArr := []string{}
|
||||
if len(o.Tag) > 1 {
|
||||
tagArr = []string{"--tag", o.Tag}
|
||||
}
|
||||
if len(o.Tag) <= 0 && len(o.File) <= 0 && len(o.CNABFile) <= 0 {
|
||||
if _, err := os.Stat("porter.yaml"); err != nil {
|
||||
tagArr = []string{"--tag", "qlik/qliksense-cnab-bundle:" + o.Version}
|
||||
}
|
||||
}
|
||||
return tagArr
|
||||
}
|
||||
|
||||
type aboutOptions struct {
|
||||
Version string
|
||||
Tag string
|
||||
File string
|
||||
CNABFile string
|
||||
}
|
||||
|
||||
func buildAboutAlias(porterCmd *cobra.Command) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
opts *aboutOptions
|
||||
)
|
||||
|
||||
opts = &aboutOptions{}
|
||||
|
||||
c = &cobra.Command{
|
||||
Use: "about",
|
||||
Short: "About Qlik Sense",
|
||||
Long: "Gives the verion of QLik Sense on Kuberntetes and versions of images.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
args = opts.getTagDefaults(args)
|
||||
return porterCmd.RunE(porterCmd, append([]string{"invoke", "--action", "about"}, args...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
f := c.Flags()
|
||||
f.StringVarP(&opts.Version, "version", "v", "latest",
|
||||
"Version of Qlik Sense to install")
|
||||
f.StringVarP(&opts.Tag, "tag", "t", "",
|
||||
"Use a bundle in an OCI registry specified by the given tag")
|
||||
f.StringVarP(&opts.File, "file", "f", "",
|
||||
"Path to the porter manifest file. Defaults to the bundle in the current directory.")
|
||||
f.StringVar(&opts.CNABFile, "cnab-file", "",
|
||||
"Path to the CNAB bundle.json file.")
|
||||
return c
|
||||
}
|
||||
|
||||
func buildPreflightAlias(porterCmd *cobra.Command, q *qliksense.Qliksense) *cobra.Command {
|
||||
var (
|
||||
c *cobra.Command
|
||||
opts *paramOptions
|
||||
)
|
||||
|
||||
opts = ¶mOptions{}
|
||||
|
||||
c = &cobra.Command{
|
||||
Use: "preflight",
|
||||
Short: "Preflight Checks",
|
||||
Long: "Perform Preflight Checks",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
args = append(os.Args[1:], opts.getTagDefaults(args)...)
|
||||
return porterCmd.RunE(porterCmd, append([]string{"invoke", "--action", "preflight"}, args...))
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
"group": "alias",
|
||||
},
|
||||
}
|
||||
f := c.Flags()
|
||||
f.StringSliceVar(&opts.Params, "param", nil,
|
||||
"Define an individual parameter in the form NAME=VALUE. Overrides parameters set with the same name using --param-file. May be specified multiple times.")
|
||||
f.StringSliceVar(&opts.ParamFiles, "param-file", nil,
|
||||
"Path to a parameters definition file for the bundle, each line in the form of NAME=VALUE. May be specified multiple times.")
|
||||
f.StringVarP(&opts.Tag, "tag", "t", "",
|
||||
"Use a bundle in an OCI registry specified by the given tag")
|
||||
f.StringVarP(&opts.Version, "version", "v", "latest",
|
||||
"Version of Qlik Sense to install")
|
||||
f.StringSliceVarP(&opts.CredentialIdentifiers, "cred", "c", nil,
|
||||
"Credential to use when installing the bundle. May be either a named set of credentials or a filepath, and specified multiple times.")
|
||||
return c
|
||||
}
|
||||
|
||||
func (o *paramOptions) findKey(param string) *string {
|
||||
var (
|
||||
value *string
|
||||
)
|
||||
if value = o.findParams(param); value != nil {
|
||||
return value
|
||||
}
|
||||
|
||||
if value = o.findParamFiles(param); value != nil {
|
||||
return value
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// parsedParams parses the variable assignments in Params.
|
||||
func (o *paramOptions) findParams(param string) *string {
|
||||
return o.findVariableKey(param, o.Params)
|
||||
}
|
||||
|
||||
// parseParamFiles parses the variable assignments in ParamFiles.
|
||||
func (o *paramOptions) findParamFiles(param string) *string {
|
||||
var (
|
||||
path string
|
||||
retStr *string
|
||||
)
|
||||
|
||||
for _, path = range o.ParamFiles {
|
||||
retStr = o.findParamFile(param, path)
|
||||
}
|
||||
|
||||
return retStr
|
||||
}
|
||||
|
||||
func (o *paramOptions) findParamFile(param string, path string) *string {
|
||||
var (
|
||||
f *os.File
|
||||
err error
|
||||
scanner *bufio.Scanner
|
||||
lines []string
|
||||
retStr *string
|
||||
)
|
||||
if f, err = os.Open(path); err == nil {
|
||||
defer f.Close()
|
||||
|
||||
scanner = bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
lines = append(lines, scanner.Text())
|
||||
}
|
||||
|
||||
retStr = o.findVariableKey(param, lines)
|
||||
}
|
||||
return retStr
|
||||
}
|
||||
|
||||
func (o *paramOptions) findVariableKey(param string, params []string) *string {
|
||||
var (
|
||||
variable, value string
|
||||
)
|
||||
for _, p := range params {
|
||||
parts := strings.SplitN(p, "=", 2)
|
||||
if len(parts) >= 2 {
|
||||
variable = strings.TrimSpace(parts[0])
|
||||
if variable == param {
|
||||
value = strings.TrimSpace(parts[1])
|
||||
return &value
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func installPorter() (string, error) {
|
||||
destination, homeDir, mixin, mixinOpts, qlikSenseHome, porterExe, ext string
|
||||
mixinsVar = map[string]string{
|
||||
"kustomize": "-v 0.2-beta-3-0e19ca4 --url https://github.com/donmstewart/porter-kustomize/releases/download",
|
||||
"qliksense": "-v v0.11.0 --url https://github.com/qlik-oss/porter-qliksense/releases/download",
|
||||
"qliksense": "-v v0.14.0 --url https://github.com/qlik-oss/porter-qliksense/releases/download",
|
||||
"exec": "-v latest",
|
||||
"kubernetes": "-v latest",
|
||||
"helm": "-v latest",
|
||||
@@ -148,6 +148,15 @@ func installPorter() (string, error) {
|
||||
|
||||
}
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Print the version number of qliksense cli",
|
||||
Long: `All software has versions. This is Hugo's`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Printf("%s (%s, %s)\n", pkg.Version, pkg.Commit, pkg.CommitDate)
|
||||
},
|
||||
}
|
||||
|
||||
func rootCmd(p *qliksense.Qliksense) *cobra.Command {
|
||||
var (
|
||||
cmd, porterCmd, alias *cobra.Command
|
||||
@@ -174,7 +183,8 @@ func rootCmd(p *qliksense.Qliksense) *cobra.Command {
|
||||
for _, alias = range buildAliasCommands(porterCmd, p) {
|
||||
cmd.AddCommand(alias)
|
||||
}
|
||||
|
||||
// add version command
|
||||
cmd.AddCommand(versionCmd)
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
|
||||
return cmd
|
||||
|
||||
@@ -8,10 +8,12 @@ import (
|
||||
|
||||
"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"
|
||||
|
||||
"strings"
|
||||
|
||||
@@ -53,7 +55,6 @@ func (p *Qliksense) PullImages() error {
|
||||
if err = yaml.Unmarshal([]byte(yamlVersion), &images); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, image = range images.Images {
|
||||
if err = p.PullImage(image); err != nil {
|
||||
fmt.Print(err)
|
||||
@@ -72,12 +73,12 @@ func (p *Qliksense) PullImage(imageName string) error {
|
||||
response io.ReadCloser
|
||||
pullOptions types.ImagePullOptions
|
||||
ctx context.Context
|
||||
// ref reference.Named
|
||||
// repoInfo *registry.RepositoryInfo
|
||||
// authConfig types.AuthConfig
|
||||
// encodedAuth string
|
||||
termFd uintptr
|
||||
err error
|
||||
ref reference.Named
|
||||
repoInfo *registry.RepositoryInfo
|
||||
authConfig types.AuthConfig
|
||||
encodedAuth string
|
||||
termFd uintptr
|
||||
err error
|
||||
)
|
||||
// TODO: Create a real cli config context
|
||||
ctx = context.Background()
|
||||
@@ -85,24 +86,26 @@ func (p *Qliksense) PullImage(imageName string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// if ref, err = reference.ParseNormalizedNamed(imageName); 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
|
||||
// }
|
||||
pullOptions = types.ImagePullOptions{
|
||||
// RegistryAuth: encodedAuth,
|
||||
}
|
||||
|
||||
if err = cli.Initialize(cliflags.NewClientOptions()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ref, err = reference.ParseNormalizedNamed(imageName); 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
|
||||
}
|
||||
|
||||
pullOptions = types.ImagePullOptions{
|
||||
RegistryAuth: encodedAuth,
|
||||
}
|
||||
|
||||
if response, err = cli.Client().ImagePull(ctx, imageName, pullOptions); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -164,7 +167,7 @@ func (p *Qliksense) TagAndPushImages(registry string) error {
|
||||
}
|
||||
|
||||
// PullImage ...
|
||||
func (p *Qliksense) TagAndPush(image string, registry string) error {
|
||||
func (p *Qliksense) TagAndPush(image string, registryName string) error {
|
||||
var (
|
||||
cli *command.DockerCli
|
||||
dockerOutput io.Writer
|
||||
@@ -176,11 +179,12 @@ func (p *Qliksense) TagAndPush(image string, registry string) error {
|
||||
imageList []types.ImageSummary
|
||||
imageListOptions types.ImageListOptions
|
||||
filterArgs filters.Args
|
||||
// repoInfo *registry.RepositoryInfo
|
||||
// authConfig types.AuthConfig
|
||||
// encodedAuth string
|
||||
termFd uintptr
|
||||
err error
|
||||
ref reference.Named
|
||||
repoInfo *registry.RepositoryInfo
|
||||
authConfig types.AuthConfig
|
||||
encodedAuth string
|
||||
termFd uintptr
|
||||
err error
|
||||
)
|
||||
// TODO: Create a real cli config context
|
||||
ctx = context.Background()
|
||||
@@ -194,7 +198,7 @@ func (p *Qliksense) TagAndPush(image string, registry string) error {
|
||||
if segments[0] == "docker.io" {
|
||||
image = strings.Join(segments[1:], "/")
|
||||
}
|
||||
newName = registry + "/" + segments[len(segments)-1]
|
||||
newName = registryName + "/" + segments[len(segments)-1]
|
||||
|
||||
filterArgs = filters.NewArgs()
|
||||
filterArgs.Add("reference", image)
|
||||
@@ -213,20 +217,19 @@ func (p *Qliksense) TagAndPush(image string, registry string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// if ref, err = reference.ParseNormalizedNamed(imageName); 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
|
||||
// }
|
||||
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: "temp",
|
||||
// RegistryAuth: encodedAuth,
|
||||
RegistryAuth: encodedAuth,
|
||||
}
|
||||
|
||||
if response, err = cli.Client().ImagePush(ctx, newName, pushOptions); err != nil {
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
package qliksense
|
||||
|
||||
import (
|
||||
"io"
|
||||
"fmt"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// ProcessLine ...
|
||||
type ProcessLine func(string) *string
|
||||
|
||||
// CallPorter ...
|
||||
func (p *Qliksense) CallPorter(args []string, processor ProcessLine) (string,error) {
|
||||
func (p *Qliksense) CallPorter(args []string, processor ProcessLine) (string, error) {
|
||||
var (
|
||||
outText string
|
||||
cmd *exec.Cmd
|
||||
err error
|
||||
output io.ReadCloser
|
||||
scanner *bufio.Scanner
|
||||
done chan struct{}
|
||||
output io.ReadCloser
|
||||
scanner *bufio.Scanner
|
||||
done chan struct{}
|
||||
)
|
||||
cmd = exec.Command(p.porterExe,args[:]...)
|
||||
if output,err = cmd.StdoutPipe(); err !=nil {
|
||||
return "",err
|
||||
|
||||
cmd = exec.Command(p.porterExe, args[:]...)
|
||||
if output, err = cmd.StdoutPipe(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
|
||||
done = make(chan struct{})
|
||||
scanner = bufio.NewScanner(output)
|
||||
go func() {
|
||||
@@ -35,24 +38,23 @@ func (p *Qliksense) CallPorter(args []string, processor ProcessLine) (string,err
|
||||
if processor != nil {
|
||||
newText = processor(text)
|
||||
if newText != nil {
|
||||
outText = outText + fmt.Sprintln(*newText)
|
||||
outText = outText + fmt.Sprintln(*newText)
|
||||
}
|
||||
} else {
|
||||
outText = outText + fmt.Sprintln(text)
|
||||
outText = outText + fmt.Sprintln(text)
|
||||
}
|
||||
}
|
||||
done <- struct{}{}
|
||||
}()
|
||||
if err = cmd.Start(); err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
<-done
|
||||
if err = cmd.Wait(); err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
if err = scanner.Err(); err != nil {
|
||||
return "",err
|
||||
return "", err
|
||||
}
|
||||
|
||||
return outText,nil
|
||||
return outText, nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package pkg
|
||||
|
||||
// These are build-time values, set during an official release
|
||||
var (
|
||||
Commit string
|
||||
Version string
|
||||
Commit string
|
||||
Version string
|
||||
CommitDate string
|
||||
)
|
||||
|
||||
5
renovate.json
Normal file
5
renovate.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": [
|
||||
"config:base"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user