summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/network/create.go4
-rw-r--r--libpod/network/files.go30
-rw-r--r--libpod/network/netconflist.go80
-rw-r--r--libpod/runtime_pod_infra_linux.go67
4 files changed, 151 insertions, 30 deletions
diff --git a/libpod/network/create.go b/libpod/network/create.go
index 7e4fc574a..cac438963 100644
--- a/libpod/network/create.go
+++ b/libpod/network/create.go
@@ -169,7 +169,7 @@ func createBridge(name string, options entities.NetworkCreateOptions, runtimeCon
}
// create CNI plugin configuration
- ncList := NewNcList(name, version.Current())
+ ncList := NewNcList(name, version.Current(), options.Labels)
var plugins []CNIPlugins
// TODO need to iron out the role of isDefaultGW and IPMasq
bridge := NewHostLocalBridge(bridgeDeviceName, isGateway, false, ipMasq, ipamConfig)
@@ -223,7 +223,7 @@ func createMacVLAN(name string, options entities.NetworkCreateOptions, runtimeCo
return "", err
}
}
- ncList := NewNcList(name, version.Current())
+ ncList := NewNcList(name, version.Current(), options.Labels)
macvlan := NewMacVLANPlugin(options.MacVLAN)
plugins = append(plugins, macvlan)
ncList["plugins"] = plugins
diff --git a/libpod/network/files.go b/libpod/network/files.go
index 7f1e3ee18..83cb1c23a 100644
--- a/libpod/network/files.go
+++ b/libpod/network/files.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v2/libpod/define"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// ErrNoSuchNetworkInterface indicates that no network interface exists
@@ -89,6 +90,35 @@ func GetCNIPlugins(list *libcni.NetworkConfigList) string {
return strings.Join(plugins, ",")
}
+// GetNetworkLabels returns a list of labels as a string
+func GetNetworkLabels(list *libcni.NetworkConfigList) NcLabels {
+ cniJSON := make(map[string]interface{})
+ err := json.Unmarshal(list.Bytes, &cniJSON)
+ if err != nil {
+ logrus.Errorf("failed to unmarshal network config %v %v", cniJSON["name"], err)
+ return nil
+ }
+ if args, ok := cniJSON["args"]; ok {
+ if key, ok := args.(map[string]interface{}); ok {
+ if labels, ok := key[PodmanLabelKey]; ok {
+ if labels, ok := labels.(map[string]interface{}); ok {
+ result := make(NcLabels, len(labels))
+ for k, v := range labels {
+ if v, ok := v.(string); ok {
+ result[k] = v
+ } else {
+ logrus.Errorf("network config %v invalid label value type %T should be string", cniJSON["name"], labels)
+ }
+ }
+ return result
+ }
+ logrus.Errorf("network config %v invalid label type %T should be map[string]string", cniJSON["name"], labels)
+ }
+ }
+ }
+ return nil
+}
+
// GetNetworksFromFilesystem gets all the networks from the cni configuration
// files
func GetNetworksFromFilesystem(config *config.Config) ([]*allocator.Net, error) {
diff --git a/libpod/network/netconflist.go b/libpod/network/netconflist.go
index ee9adce14..3db38485b 100644
--- a/libpod/network/netconflist.go
+++ b/libpod/network/netconflist.go
@@ -4,6 +4,11 @@ import (
"net"
"os"
"path/filepath"
+ "strings"
+
+ "github.com/containernetworking/cni/libcni"
+ "github.com/containers/podman/v2/pkg/util"
+ "github.com/pkg/errors"
)
const (
@@ -14,12 +19,24 @@ const (
// NcList describes a generic map
type NcList map[string]interface{}
+// NcArgs describes the cni args field
+type NcArgs map[string]NcLabels
+
+// NcLabels describes the label map
+type NcLabels map[string]string
+
+// PodmanLabelKey key used to store the podman network label in a cni config
+const PodmanLabelKey = "podman_labels"
+
// NewNcList creates a generic map of values with string
// keys and adds in version and network name
-func NewNcList(name, version string) NcList {
+func NewNcList(name, version string, labels NcLabels) NcList {
n := NcList{}
n["cniVersion"] = version
n["name"] = name
+ if len(labels) > 0 {
+ n["args"] = NcArgs{PodmanLabelKey: labels}
+ }
return n
}
@@ -159,3 +176,64 @@ func NewMacVLANPlugin(device string) MacVLANConfig {
}
return m
}
+
+// IfPassesFilter filters NetworkListReport and returns true if the filter match the given config
+func IfPassesFilter(netconf *libcni.NetworkConfigList, filters map[string][]string) (bool, error) {
+ result := true
+ for key, filterValues := range filters {
+ result = false
+ switch strings.ToLower(key) {
+ case "name":
+ // matches one name, regex allowed
+ result = util.StringMatchRegexSlice(netconf.Name, filterValues)
+
+ case "plugin":
+ // match one plugin
+ plugins := GetCNIPlugins(netconf)
+ for _, val := range filterValues {
+ if strings.Contains(plugins, val) {
+ result = true
+ break
+ }
+ }
+
+ case "label":
+ // matches all labels
+ labels := GetNetworkLabels(netconf)
+ outer:
+ for _, filterValue := range filterValues {
+ filterArray := strings.SplitN(filterValue, "=", 2)
+ filterKey := filterArray[0]
+ if len(filterArray) > 1 {
+ filterValue = filterArray[1]
+ } else {
+ filterValue = ""
+ }
+ for labelKey, labelValue := range labels {
+ if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
+ result = true
+ continue outer
+ }
+ }
+ result = false
+ }
+
+ case "driver":
+ // matches only for the DefaultNetworkDriver
+ for _, filterValue := range filterValues {
+ plugins := GetCNIPlugins(netconf)
+ if filterValue == DefaultNetworkDriver &&
+ strings.Contains(plugins, DefaultNetworkDriver) {
+ result = true
+ }
+ }
+
+ // TODO: add dangling filter
+ // TODO TODO: add id filter if we support ids
+
+ default:
+ return false, errors.Errorf("invalid filter %q", key)
+ }
+ }
+ return result, nil
+}
diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go
index 76419587a..3e4185db1 100644
--- a/libpod/runtime_pod_infra_linux.go
+++ b/libpod/runtime_pod_infra_linux.go
@@ -34,40 +34,56 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
// Set Pod hostname
g.Config.Hostname = p.config.Hostname
+ var options []CtrCreateOption
+
+ // Command: If user-specified, use that preferentially.
+ // If not set and the config file is set, fall back to that.
+ var infraCtrCommand []string
+ if p.config.InfraContainer.InfraCommand != nil {
+ logrus.Debugf("User-specified infra container entrypoint %v", p.config.InfraContainer.InfraCommand)
+ infraCtrCommand = p.config.InfraContainer.InfraCommand
+ } else if r.config.Engine.InfraCommand != "" {
+ logrus.Debugf("Config-specified infra container entrypoint %s", r.config.Engine.InfraCommand)
+ infraCtrCommand = []string{r.config.Engine.InfraCommand}
+ }
+ // Only if set by the user or containers.conf, we set entrypoint for the
+ // infra container.
+ // This is only used by commit, so it shouldn't matter... But someone
+ // may eventually want to commit an infra container?
+ // TODO: Should we actually do this if set by containers.conf?
+ if infraCtrCommand != nil {
+ // Need to duplicate the array - we are going to add Cmd later
+ // so the current array will be changed.
+ newArr := make([]string, 0, len(infraCtrCommand))
+ newArr = append(newArr, infraCtrCommand...)
+ options = append(options, WithEntrypoint(newArr))
+ }
+
isRootless := rootless.IsRootless()
- entrypointSet := len(p.config.InfraContainer.InfraCommand) > 0
- entryPoint := p.config.InfraContainer.InfraCommand
- entryCmd := []string{}
- var options []CtrCreateOption
// I've seen circumstances where config is being passed as nil.
// Let's err on the side of safety and make sure it's safe to use.
if config != nil {
- // default to entrypoint in image if there is one
- if !entrypointSet {
- if len(config.Entrypoint) > 0 {
- entrypointSet = true
- entryPoint = config.Entrypoint
- entryCmd = config.Entrypoint
+ if infraCtrCommand == nil {
+ // If we have no entrypoint and command from the image,
+ // we can't go on - the infra container has no command.
+ if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
+ return nil, errors.Errorf("infra container has no command")
}
- } else { // so use the InfraCommand
- entrypointSet = true
- entryCmd = entryPoint
- }
-
- if len(config.Cmd) > 0 {
- // We can't use the default pause command, since we're
- // sourcing from the image. If we didn't already set an
- // entrypoint, set one now.
- if !entrypointSet {
+ if len(config.Entrypoint) > 0 {
+ infraCtrCommand = config.Entrypoint
+ } else {
// Use the Docker default "/bin/sh -c"
// entrypoint, as we're overriding command.
// If an image doesn't want this, it can
// override entrypoint too.
- entryCmd = []string{"/bin/sh", "-c"}
+ infraCtrCommand = []string{"/bin/sh", "-c"}
}
- entryCmd = append(entryCmd, config.Cmd...)
}
+ if len(config.Cmd) > 0 {
+ infraCtrCommand = append(infraCtrCommand, config.Cmd...)
+ }
+
if len(config.Env) > 0 {
for _, nameValPair := range config.Env {
nameValSlice := strings.Split(nameValPair, "=")
@@ -127,9 +143,9 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
}
g.SetRootReadonly(true)
- g.SetProcessArgs(entryCmd)
+ g.SetProcessArgs(infraCtrCommand)
- logrus.Debugf("Using %q as infra container entrypoint", entryCmd)
+ logrus.Debugf("Using %q as infra container command", infraCtrCommand)
g.RemoveMount("/dev/shm")
if isRootless {
@@ -148,9 +164,6 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm
options = append(options, WithRootFSFromImage(imgID, imgName, rawImageName))
options = append(options, WithName(containerName))
options = append(options, withIsInfra())
- if entrypointSet {
- options = append(options, WithEntrypoint(entryPoint))
- }
if len(p.config.InfraContainer.ConmonPidFile) > 0 {
options = append(options, WithConmonPidFile(p.config.InfraContainer.ConmonPidFile))
}