Skip to content
This repository has been archived by the owner on Jun 13, 2021. It is now read-only.

Commit

Permalink
Add --label flag when running an application
Browse files Browse the repository at this point in the history
This will add the given labels to all the containers inside the
application (except for the invocation image). The labels are passed
over by file, this is to be able to easely add new parameters in the
future and limit the explosion of parameters we have in our bundle

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
  • Loading branch information
rumpl committed Oct 25, 2019
1 parent 0d08d65 commit b1d4b76
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 11 deletions.
26 changes: 26 additions & 0 deletions cmd/cnab-run/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ func installAction(instanceName string) error {
if err != nil {
return err
}
if err = addLabels(rendered); err != nil {
return err
}
addAppLabels(rendered, instanceName)

if err := os.Chdir(app.Path); err != nil {
return err
}
Expand Down Expand Up @@ -87,6 +91,28 @@ func getBundleImageMap() (map[string]bundle.Image, error) {
return result, nil
}

func addLabels(rendered *composetypes.Config) error {
args, err := ioutil.ReadFile(internal.DockerArgsPath)
if err != nil {
return err
}
a := packager.DockerAppArgs{}
err = json.Unmarshal(args, &a)
if err != nil {
return err
}
for k, v := range a.Labels {
for i, service := range rendered.Services {
if service.Labels == nil {
service.Labels = map[string]string{}
}
service.Labels[k] = v
rendered.Services[i] = service
}
}
return nil
}

func addAppLabels(rendered *composetypes.Config, instanceName string) {
for i, service := range rendered.Services {
if service.Labels == nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/image/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func printImageIDs(dockerCli command.Cli, refs []pkg) error {
}
fmt.Fprintln(&buf, stringid.TruncateID(id.String()))
}
fmt.Fprintf(dockerCli.Out(), buf.String())
fmt.Fprint(dockerCli.Out(), buf.String())
return nil
}

Expand Down
6 changes: 0 additions & 6 deletions internal/commands/image/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ import (
"github.com/docker/distribution/reference"
)

type mockRef string

func (ref mockRef) String() string {
return string(ref)
}

type bundleStoreStubForListCmd struct {
refMap map[reference.Reference]*bundle.Bundle
// in order to keep the reference in the same order between tests
Expand Down
18 changes: 18 additions & 0 deletions internal/commands/parameters.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package commands

import (
"encoding/json"
"fmt"
"io"
"os"
"strings"

"github.com/deislabs/cnab-go/bundle"
"github.com/docker/app/internal"
"github.com/docker/app/internal/packager"
"github.com/docker/app/internal/store"
"github.com/docker/app/types/parameters"
cliopts "github.com/docker/cli/opts"
Expand Down Expand Up @@ -45,6 +47,22 @@ func withCommandLineParameters(overrides []string) mergeBundleOpt {
}
}

func withLabels(labels []string) mergeBundleOpt {
return func(c *mergeBundleConfig) error {
l := packager.DockerAppArgs{
Labels: cliopts.ConvertKVStringsToMap(labels),
}
out, err := json.Marshal(l)
if err != nil {
return err
}
if _, ok := c.bundle.Parameters[internal.ParameterArgs]; ok {
c.params[internal.ParameterArgs] = string(out)
}
return nil
}
}

func withSendRegistryAuth(sendRegistryAuth bool) mergeBundleOpt {
return func(c *mergeBundleConfig) error {
if _, ok := c.bundle.Definitions[internal.ParameterShareRegistryCredsName]; ok {
Expand Down
11 changes: 7 additions & 4 deletions internal/commands/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type runOptions struct {
kubeNamespace string
stackName string
cnabBundle string
labels []string
}

const longDescription = `Run an App from an App image.`
Expand Down Expand Up @@ -59,10 +60,11 @@ func runCmd(dockerCli command.Cli) *cobra.Command {
}
opts.parametersOptions.addFlags(cmd.Flags())
opts.credentialOptions.addFlags(cmd.Flags())
cmd.Flags().StringVar(&opts.orchestrator, "orchestrator", "", "Orchestrator to run on (swarm, kubernetes)")
cmd.Flags().StringVar(&opts.kubeNamespace, "namespace", "default", "Kubernetes namespace in which to run the App")
cmd.Flags().StringVar(&opts.stackName, "name", "", "Name of the running App")
cmd.Flags().StringVar(&opts.cnabBundle, "cnab-bundle-json", "", "Run a CNAB bundle instead of a Docker App image")
cmd.Flags().StringVar(&opts.orchestrator, "orchestrator", "", "Orchestrator to install on (swarm, kubernetes)")
cmd.Flags().StringVar(&opts.kubeNamespace, "namespace", "default", "Kubernetes namespace to install into")
cmd.Flags().StringVar(&opts.stackName, "name", "", "Assign a name to the installation")
cmd.Flags().StringVar(&opts.cnabBundle, "cnab-bundle-json", "", "Run a CNAB bundle instead of a Docker App")
cmd.Flags().StringArrayVar(&opts.labels, "label", nil, "Label to add to services")

return cmd
}
Expand Down Expand Up @@ -130,6 +132,7 @@ func runBundle(dockerCli command.Cli, bndl *bundle.Bundle, opts runOptions, ref
if err := mergeBundleParameters(installation,
withFileParameters(opts.parametersFiles),
withCommandLineParameters(opts.overrides),
withLabels(opts.labels),
withOrchestratorParameters(opts.orchestrator, opts.kubeNamespace),
withSendRegistryAuth(opts.sendRegistryAuth),
); err != nil {
Expand Down
4 changes: 4 additions & 0 deletions internal/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ const (
ParameterRenderFormatName = Namespace + "render-format"
// ParameterInspectFormatName is the name of the parameter containing the inspect format
ParameterInspectFormatName = Namespace + "inspect-format"
// ParameterArgs is the name of the parameter containing labels to be applied to service containers
ParameterArgs = Namespace + "args"
// ParameterShareRegistryCredsName is the name of the parameter which indicates if credentials should be shared
ParameterShareRegistryCredsName = Namespace + "share-registry-creds"

Expand All @@ -68,6 +70,8 @@ const (
// the inspect output format.
DockerInspectFormatEnvVar = "DOCKER_INSPECT_FORMAT"

DockerArgsPath = "/cnab/app/args.json"

// CustomDockerAppName is the custom variable set by Docker App to
// save custom informations
CustomDockerAppName = "com.docker.app"
Expand Down
23 changes: 23 additions & 0 deletions internal/packager/cnab.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,24 @@ type DockerAppCustom struct {
Payload json.RawMessage `json:"payload,omitempty"`
}

// DockerAppArgs represent the object passed to the invocation image
// by Docker App.
type DockerAppArgs struct {
// Labels are the labels to add to containers on run
Labels map[string]string `json:"labels,omitempty"`
}

// ToCNAB creates a CNAB bundle from an app package
func ToCNAB(app *types.App, invocationImageName string) (*bundle.Bundle, error) {
mapping := ExtractCNABParameterMapping(app.Parameters())
flatParameters := app.Parameters().Flatten()
definitions := definition.Definitions{
internal.ParameterArgs: {
Type: "string",
Default: "",
Title: "Labels",
Description: "Labels to apply to service containers",
},
internal.ParameterOrchestratorName: {
Type: "string",
Enum: []interface{}{
Expand Down Expand Up @@ -73,6 +86,16 @@ func ToCNAB(app *types.App, invocationImageName string) (*bundle.Bundle, error)
},
}
parameters := map[string]bundle.Parameter{
internal.ParameterArgs: {
Destination: &bundle.Location{
Path: internal.DockerArgsPath,
},
ApplyTo: []string{
"install",
"upgrade",
},
Definition: internal.ParameterArgs,
},
internal.ParameterOrchestratorName: {
Destination: &bundle.Location{
EnvironmentVariable: internal.DockerStackOrchestratorEnvVar,
Expand Down

0 comments on commit b1d4b76

Please sign in to comment.