Skip to content

Commit

Permalink
Rework label parsing
Browse files Browse the repository at this point in the history
We attempted to share all logic for parsing labels and
environment variables, which on the surface makes lots of sense
(both are formatted key=value so parsing logic should be
identical) but has begun to fall apart now that we have added
additional logic to environment variable handling. Environment
variables that are unset, for example, are looked up against
environment variables set for the process. We don't want this for
labels, so we have to split parsing logic.

Fixes containers#3854

Signed-off-by: Matthew Heon <matthew.heon@pm.me>
  • Loading branch information
mheon committed Feb 14, 2020
1 parent 97fdfd0 commit 71b4022
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 17 deletions.
3 changes: 2 additions & 1 deletion cmd/podman/pod_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/adapter"
"github.com/containers/libpod/pkg/errorhandling"
Expand Down Expand Up @@ -103,7 +104,7 @@ func podCreateCmd(c *cliconfig.PodCreateValues) error {
defer errorhandling.SyncQuiet(podIdFile)
}

labels, err := shared.GetAllLabels(c.LabelFile, c.Labels)
labels, err := parse.GetAllLabels(c.LabelFile, c.Labels)
if err != nil {
return errors.Wrapf(err, "unable to process labels")
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/podman/shared/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
}

// LABEL VARIABLES
labels, err := GetAllLabels(c.StringSlice("label-file"), c.StringArray("label"))
labels, err := parse.GetAllLabels(c.StringSlice("label-file"), c.StringArray("label"))
if err != nil {
return nil, errors.Wrapf(err, "unable to process labels")
}
Expand Down
11 changes: 0 additions & 11 deletions cmd/podman/shared/create_cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,13 @@ import (
"fmt"
"strings"

"github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/pkg/cgroups"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/sysinfo"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

// GetAllLabels ...
func GetAllLabels(labelFile, inputLabels []string) (map[string]string, error) {
labels := make(map[string]string)
labelErr := parse.ReadKVStrings(labels, labelFile, inputLabels)
if labelErr != nil {
return labels, errors.Wrapf(labelErr, "unable to process labels from --label and label-file")
}
return labels, nil
}

// validateSysctl validates a sysctl and returns it.
func validateSysctl(strSlice []string) (map[string]string, error) {
sysctl := make(map[string]string)
Expand Down
28 changes: 28 additions & 0 deletions cmd/podman/shared/parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,34 @@ func ValidateDomain(val string) (string, error) {
return "", fmt.Errorf("%s is not a valid domain", val)
}

// GetAllLabels retrieves all labels given a potential label file and a number
// of labels provided from the command line.
func GetAllLabels(labelFile, inputLabels []string) (map[string]string, error) {
labels := make(map[string]string)
for _, file := range labelFile {
// Use of parseEnvFile still seems safe, as it's missing the
// extra parsing logic of parseEnv.
// There's an argument that we SHOULD be doing that parsing for
// all environment variables, even those sourced from files, but
// that would require a substantial rework.
if err := parseEnvFile(labels, file); err != nil {
return nil, err
}
}
for _, label := range inputLabels {
split := strings.SplitN(label, "=", 2)
if split[0] == "" {
return nil, errors.Errorf("invalid label format: %q", label)
}
value := ""
if len(split) > 1 {
value = split[1]
}
labels[split[0]] = value
}
return labels, nil
}

// reads a file of line terminated key=value pairs, and overrides any keys
// present in the file with additional pairs specified in the override parameter
// for env-file and labels-file flags
Expand Down
6 changes: 3 additions & 3 deletions cmd/podman/volume_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"

"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/pkg/adapter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -51,12 +51,12 @@ func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error {
return errors.Errorf("too many arguments, create takes at most 1 argument")
}

labels, err := shared.GetAllLabels([]string{}, c.Label)
labels, err := parse.GetAllLabels([]string{}, c.Label)
if err != nil {
return errors.Wrapf(err, "unable to process labels")
}

opts, err := shared.GetAllLabels([]string{}, c.Opt)
opts, err := parse.GetAllLabels([]string{}, c.Opt)
if err != nil {
return errors.Wrapf(err, "unable to process options")
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/api/handlers/libpod/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
}

if len(input.Labels) > 0 {
if err := parse.ReadKVStrings(labels, []string{}, input.Labels); err != nil {
labels, err = parse.GetAllLabels([]string{}, input.Labels)
if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
}
Expand Down

0 comments on commit 71b4022

Please sign in to comment.