Compare commits

..

6 Commits

Author SHA1 Message Date
Foysal Iqbal
cb8c868121 add cache clean 2020-01-17 15:03:01 -05:00
Foysal Iqbal
8535e70dfa add cache clean 2020-01-17 14:58:42 -05:00
Foysal Iqbal
87ebd74daf fix image pull (#24) 2020-01-17 13:47:36 -05:00
Andriy Bulynko
39d02db187 patching Makefile 2020-01-16 13:23:28 -05:00
Andriy Bulynko
0393a431fb - proxy qliksense upgrade to porter upgrade (#21) 2020-01-15 16:47:53 -05:00
Foysal Iqbal
d1088e2635 add version command (#19) 2020-01-10 13:11:40 -05:00
7 changed files with 512 additions and 362 deletions

View File

@@ -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)

View File

@@ -20,3 +20,20 @@ The above command runs the checks in the default namespace. If you want to speci
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
A version of [qliksense-cnab-bundle](https://hub.docker.com/r/qlik/qliksense-cnab-bundle) is published corresponding to an edge release. To get the latest edge release simply specify `qliksense-cnab-bundle:latest`
## Known Issues
if you see the error message like this
```console
invoking custom action about on Qliksense...
Unable to find image 'qlik/qliksense-cnab-bundle@sha256:b41a3be13914daee9fb5b9b2d39e68aa99526600d9a99448b346992d6de48171' locally
Error: 1 error occurred:
* failed to invoke the bundle: Error response from daemon: manifest for qlik/qliksense-cnab-bundle@sha256:b41a3be13914daee9fb5b9b2d39e68aa99526600d9a99448b346992d6de48171 not found: manifest unknown: manifest unknown
```
please issue this command
```console
qliksense cache clear
```

View File

@@ -1,342 +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),
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 = &paramOptions{}
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 buildUninstallAlias(porterCmd *cobra.Command, q *qliksense.Qliksense) *cobra.Command {
var (
c *cobra.Command
opts *paramOptions
)
opts = &paramOptions{}
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 = &paramOptions{}
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
}
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 = &paramOptions{}
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 = &paramOptions{}
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 = &paramOptions{}
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 = &paramOptions{}
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
}

View File

@@ -7,16 +7,27 @@ import (
func pullQliksenseImages(q *qliksense.Qliksense) *cobra.Command {
var (
cmd *cobra.Command
cmd *cobra.Command
opts *aboutOptions
)
opts = &aboutOptions{}
cmd = &cobra.Command{
Use: "pull",
Short: "Pull docke images for offline install",
Example: ` qliksense pull`,
Example: `qliksense pull`,
RunE: func(cmd *cobra.Command, args []string) error {
return q.PullImages()
return q.PullImages(opts.getTagDefaults(args))
},
}
f := cmd.Flags()
f.StringVarP(&opts.Version, "version", "v", "latest",
"From version of Qlik Sense The images will be pulled")
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 cmd
}

View File

@@ -46,8 +46,8 @@ func installPorter() (string, error) {
var (
porterPermaLink = pkg.Version
//porterPermaLink = "v0.3.0"
destination, homeDir, mixin, mixinOpts, qlikSenseHome, porterExe, ext string
mixinsVar = map[string]string{
destination, 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.14.0 --url https://github.com/qlik-oss/porter-qliksense/releases/download",
"exec": "-v latest",
@@ -68,14 +68,8 @@ func installPorter() (string, error) {
if runtime.GOOS == "windows" {
porterExe = porterExe + ".exe"
}
if qlikSenseHome = os.Getenv(qlikSenseHomeVar); qlikSenseHome == "" {
if homeDir, err = homedir.Dir(); err != nil {
return "", err
}
if homeDir, err = homedir.Expand(homeDir); err != nil {
return "", err
}
qlikSenseHome = filepath.Join(homeDir, qlikSenseDirVar)
if qlikSenseHome, err = getQliksenseHomeDir(); err != nil {
return "", err
}
os.Setenv(porterHomeVar, qlikSenseHome)
//TODO: Check if porter version is one alreadu is one for this build
@@ -148,6 +142,39 @@ 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)
},
}
var cacheClearCmd = &cobra.Command{
Use: "clear",
Short: "Clear the qliksense loacal cache",
Long: `Remove the everything from ~/.qliksense/cache directory`,
Run: func(cmd *cobra.Command, args []string) {
qsHome, err := getQliksenseHomeDir()
if err != nil {
fmt.Println("Cannot find qliksense home diretory")
return
}
cacheDir := filepath.Join(qsHome, "cache")
if _, err = os.Stat(cacheDir); err != nil {
// cache directory not exist
fmt.Println("Cache Cleaned")
return
}
if err = os.RemoveAll(cacheDir); err != nil {
fmt.Println("cannot remove cache", err)
return
}
fmt.Println("Cache Cleaned")
},
}
func rootCmd(p *qliksense.Qliksense) *cobra.Command {
var (
cmd, porterCmd, alias *cobra.Command
@@ -174,6 +201,12 @@ func rootCmd(p *qliksense.Qliksense) *cobra.Command {
for _, alias = range buildAliasCommands(porterCmd, p) {
cmd.AddCommand(alias)
}
// add version command
cmd.AddCommand(versionCmd)
// add cache command
var cahcheCommand = &cobra.Command{Use: "cache", Short: "Perform operations on cache"}
cmd.AddCommand(cahcheCommand)
cahcheCommand.AddCommand(cacheClearCmd)
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
@@ -238,3 +271,19 @@ func copy(src, dst string) (int64, error) {
nBytes, err = io.Copy(destination, source)
return nBytes, err
}
func getQliksenseHomeDir() (string, error) {
var qlikSenseHome string
if qlikSenseHome = os.Getenv(qlikSenseHomeVar); qlikSenseHome == "" {
var homeDir string
var err error
if homeDir, err = homedir.Dir(); err != nil {
return "", err
}
if homeDir, err = homedir.Expand(homeDir); err != nil {
return "", err
}
qlikSenseHome = filepath.Join(homeDir, qlikSenseDirVar)
}
return qlikSenseHome, nil
}

View File

@@ -27,7 +27,7 @@ type Images struct {
}
// PullImages ...
func (p *Qliksense) PullImages() error {
func (p *Qliksense) PullImages(args []string) error {
var (
image string
err error
@@ -35,8 +35,8 @@ func (p *Qliksense) PullImages() error {
valid bool
images Images
)
if yamlVersion, err = p.CallPorter([]string{"invoke", "--action", "about"},
println("getting images list...")
if yamlVersion, err = p.CallPorter(append([]string{"invoke", "--action", "about"}, args...),
func(x string) (out *string) {
if strings.HasPrefix(x, "qlikSenseVersion") {
valid = true

View File

@@ -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
)