mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	api: types: keep info.SecurityOptions a string slice
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
(cherry picked from commit 514ca09426)
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
			
			
This commit is contained in:
		
							parent
							
								
									2737519f9a
								
							
						
					
					
						commit
						0a5732d1cf
					
				
					 8 changed files with 84 additions and 57 deletions
				
			
		| 
						 | 
				
			
			@ -16,7 +16,6 @@ import (
 | 
			
		|||
	"github.com/docker/docker/api/types/registry"
 | 
			
		||||
	timetypes "github.com/docker/docker/api/types/time"
 | 
			
		||||
	"github.com/docker/docker/api/types/versions"
 | 
			
		||||
	"github.com/docker/docker/api/types/versions/v1p24"
 | 
			
		||||
	"github.com/docker/docker/pkg/ioutils"
 | 
			
		||||
	"golang.org/x/net/context"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -42,16 +41,24 @@ func (s *systemRouter) getInfo(ctx context.Context, w http.ResponseWriter, r *ht
 | 
			
		|||
 | 
			
		||||
	if versions.LessThan(httputils.VersionFromContext(ctx), "1.25") {
 | 
			
		||||
		// TODO: handle this conversion in engine-api
 | 
			
		||||
		oldInfo := &v1p24.Info{
 | 
			
		||||
			InfoBase:        info.InfoBase,
 | 
			
		||||
		type oldInfo struct {
 | 
			
		||||
			*types.Info
 | 
			
		||||
			ExecutionDriver string
 | 
			
		||||
		}
 | 
			
		||||
		old := &oldInfo{
 | 
			
		||||
			Info:            info,
 | 
			
		||||
			ExecutionDriver: "<not supported>",
 | 
			
		||||
		}
 | 
			
		||||
		for _, s := range info.SecurityOptions {
 | 
			
		||||
			if s.Key == "Name" {
 | 
			
		||||
				oldInfo.SecurityOptions = append(oldInfo.SecurityOptions, s.Value)
 | 
			
		||||
			}
 | 
			
		||||
		nameOnlySecurityOptions := []string{}
 | 
			
		||||
		kvSecOpts, err := types.DecodeSecurityOptions(old.SecurityOptions)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		return httputils.WriteJSON(w, http.StatusOK, oldInfo)
 | 
			
		||||
		for _, s := range kvSecOpts {
 | 
			
		||||
			nameOnlySecurityOptions = append(nameOnlySecurityOptions, s.Name)
 | 
			
		||||
		}
 | 
			
		||||
		old.SecurityOptions = nameOnlySecurityOptions
 | 
			
		||||
		return httputils.WriteJSON(w, http.StatusOK, old)
 | 
			
		||||
	}
 | 
			
		||||
	return httputils.WriteJSON(w, http.StatusOK, info)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,11 @@
 | 
			
		|||
package types
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/api/types/container"
 | 
			
		||||
| 
						 | 
				
			
			@ -158,9 +161,9 @@ type Commit struct {
 | 
			
		|||
	Expected string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InfoBase contains the base response of Remote API:
 | 
			
		||||
// Info contains response of Remote API:
 | 
			
		||||
// GET "/info"
 | 
			
		||||
type InfoBase struct {
 | 
			
		||||
type Info struct {
 | 
			
		||||
	ID                 string
 | 
			
		||||
	Containers         int
 | 
			
		||||
	ContainersRunning  int
 | 
			
		||||
| 
						 | 
				
			
			@ -219,18 +222,49 @@ type InfoBase struct {
 | 
			
		|||
	ContainerdCommit   Commit
 | 
			
		||||
	RuncCommit         Commit
 | 
			
		||||
	InitCommit         Commit
 | 
			
		||||
	SecurityOptions    []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SecurityOpt holds key/value pair about a security option
 | 
			
		||||
type SecurityOpt struct {
 | 
			
		||||
// KeyValue holds a key/value pair
 | 
			
		||||
type KeyValue struct {
 | 
			
		||||
	Key, Value string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Info contains response of Remote API:
 | 
			
		||||
// GET "/info"
 | 
			
		||||
type Info struct {
 | 
			
		||||
	*InfoBase
 | 
			
		||||
	SecurityOptions []SecurityOpt
 | 
			
		||||
// SecurityOpt contains the name and options of a security option
 | 
			
		||||
type SecurityOpt struct {
 | 
			
		||||
	Name    string
 | 
			
		||||
	Options []KeyValue
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DecodeSecurityOptions decodes a security options string slice to a type safe
 | 
			
		||||
// SecurityOpt
 | 
			
		||||
func DecodeSecurityOptions(opts []string) ([]SecurityOpt, error) {
 | 
			
		||||
	so := []SecurityOpt{}
 | 
			
		||||
	for _, opt := range opts {
 | 
			
		||||
		// support output from a < 1.13 docker daemon
 | 
			
		||||
		if !strings.Contains(opt, "=") {
 | 
			
		||||
			so = append(so, SecurityOpt{Name: opt})
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		secopt := SecurityOpt{}
 | 
			
		||||
		split := strings.Split(opt, ",")
 | 
			
		||||
		for _, s := range split {
 | 
			
		||||
			kv := strings.SplitN(s, "=", 2)
 | 
			
		||||
			if len(kv) != 2 {
 | 
			
		||||
				return nil, fmt.Errorf("invalid security option %q", s)
 | 
			
		||||
			}
 | 
			
		||||
			if kv[0] == "" || kv[1] == "" {
 | 
			
		||||
				return nil, errors.New("invalid empty security option")
 | 
			
		||||
			}
 | 
			
		||||
			if kv[0] == "name" {
 | 
			
		||||
				secopt.Name = kv[1]
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			secopt.Options = append(secopt.Options, KeyValue{Key: kv[0], Value: kv[1]})
 | 
			
		||||
		}
 | 
			
		||||
		so = append(so, secopt)
 | 
			
		||||
	}
 | 
			
		||||
	return so, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PluginsInfo is a temp struct holding Plugins name
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
// Package v1p24 provides specific API types for the API version 1, patch 24.
 | 
			
		||||
package v1p24
 | 
			
		||||
 | 
			
		||||
import "github.com/docker/docker/api/types"
 | 
			
		||||
 | 
			
		||||
// Info is a backcompatibility struct for the API 1.24
 | 
			
		||||
type Info struct {
 | 
			
		||||
	*types.InfoBase
 | 
			
		||||
	ExecutionDriver string
 | 
			
		||||
	SecurityOptions []string
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -172,16 +172,21 @@ func prettyPrintInfo(dockerCli *command.DockerCli, info types.Info) error {
 | 
			
		|||
			fmt.Fprintf(dockerCli.Out(), "\n")
 | 
			
		||||
		}
 | 
			
		||||
		if len(info.SecurityOptions) != 0 {
 | 
			
		||||
			kvs, err := types.DecodeSecurityOptions(info.SecurityOptions)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			fmt.Fprintf(dockerCli.Out(), "Security Options:\n")
 | 
			
		||||
			for _, o := range info.SecurityOptions {
 | 
			
		||||
				switch o.Key {
 | 
			
		||||
				case "Name":
 | 
			
		||||
					fmt.Fprintf(dockerCli.Out(), " %s\n", o.Value)
 | 
			
		||||
				case "Profile":
 | 
			
		||||
					if o.Value != "default" {
 | 
			
		||||
						fmt.Fprintf(dockerCli.Err(), "  WARNING: You're not using the default seccomp profile\n")
 | 
			
		||||
			for _, so := range kvs {
 | 
			
		||||
				fmt.Fprintf(dockerCli.Out(), " %s\n", so.Name)
 | 
			
		||||
				for _, o := range so.Options {
 | 
			
		||||
					switch o.Key {
 | 
			
		||||
					case "profile":
 | 
			
		||||
						if o.Value != "default" {
 | 
			
		||||
							fmt.Fprintf(dockerCli.Err(), "  WARNING: You're not using the default seccomp profile\n")
 | 
			
		||||
						}
 | 
			
		||||
						fmt.Fprintf(dockerCli.Out(), "  Profile: %s\n", o.Value)
 | 
			
		||||
					}
 | 
			
		||||
					fmt.Fprintf(dockerCli.Out(), "  %s: %s\n", o.Key, o.Value)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,10 +46,8 @@ func TestInfo(t *testing.T) {
 | 
			
		|||
				return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
 | 
			
		||||
			}
 | 
			
		||||
			info := &types.Info{
 | 
			
		||||
				InfoBase: &types.InfoBase{
 | 
			
		||||
					ID:         "daemonID",
 | 
			
		||||
					Containers: 3,
 | 
			
		||||
				},
 | 
			
		||||
				ID:         "daemonID",
 | 
			
		||||
				Containers: 3,
 | 
			
		||||
			}
 | 
			
		||||
			b, err := json.Marshal(info)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package daemon
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
| 
						 | 
				
			
			@ -69,29 +70,26 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
 | 
			
		|||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	securityOptions := []types.SecurityOpt{}
 | 
			
		||||
	securityOptions := []string{}
 | 
			
		||||
	if sysInfo.AppArmor {
 | 
			
		||||
		securityOptions = append(securityOptions, types.SecurityOpt{Key: "Name", Value: "apparmor"})
 | 
			
		||||
		securityOptions = append(securityOptions, "name=apparmor")
 | 
			
		||||
	}
 | 
			
		||||
	if sysInfo.Seccomp && supportsSeccomp {
 | 
			
		||||
		profile := daemon.seccompProfilePath
 | 
			
		||||
		if profile == "" {
 | 
			
		||||
			profile = "default"
 | 
			
		||||
		}
 | 
			
		||||
		securityOptions = append(securityOptions,
 | 
			
		||||
			types.SecurityOpt{Key: "Name", Value: "seccomp"},
 | 
			
		||||
			types.SecurityOpt{Key: "Profile", Value: profile},
 | 
			
		||||
		)
 | 
			
		||||
		securityOptions = append(securityOptions, fmt.Sprintf("name=seccomp,profile=%s", profile))
 | 
			
		||||
	}
 | 
			
		||||
	if selinuxEnabled() {
 | 
			
		||||
		securityOptions = append(securityOptions, types.SecurityOpt{Key: "Name", Value: "selinux"})
 | 
			
		||||
		securityOptions = append(securityOptions, "name=selinux")
 | 
			
		||||
	}
 | 
			
		||||
	uid, gid := daemon.GetRemappedUIDGID()
 | 
			
		||||
	if uid != 0 || gid != 0 {
 | 
			
		||||
		securityOptions = append(securityOptions, types.SecurityOpt{Key: "Name", Value: "userns"})
 | 
			
		||||
		securityOptions = append(securityOptions, "name=userns")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	v := &types.InfoBase{
 | 
			
		||||
	v := &types.Info{
 | 
			
		||||
		ID:                 daemon.ID,
 | 
			
		||||
		Containers:         int(cRunning + cPaused + cStopped),
 | 
			
		||||
		ContainersRunning:  int(cRunning),
 | 
			
		||||
| 
						 | 
				
			
			@ -129,6 +127,7 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
 | 
			
		|||
		HTTPSProxy:         sockets.GetProxyEnv("https_proxy"),
 | 
			
		||||
		NoProxy:            sockets.GetProxyEnv("no_proxy"),
 | 
			
		||||
		LiveRestoreEnabled: daemon.configStore.LiveRestoreEnabled,
 | 
			
		||||
		SecurityOptions:    securityOptions,
 | 
			
		||||
		Isolation:          daemon.defaultIsolation,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -143,12 +142,7 @@ func (daemon *Daemon) SystemInfo() (*types.Info, error) {
 | 
			
		|||
	}
 | 
			
		||||
	v.Name = hostname
 | 
			
		||||
 | 
			
		||||
	i := &types.Info{
 | 
			
		||||
		InfoBase:        v,
 | 
			
		||||
		SecurityOptions: securityOptions,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return i, nil
 | 
			
		||||
	return v, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SystemVersion returns version information about the daemon.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
// FillPlatformInfo fills the platform related info.
 | 
			
		||||
func (daemon *Daemon) FillPlatformInfo(v *types.InfoBase, sysInfo *sysinfo.SysInfo) {
 | 
			
		||||
func (daemon *Daemon) FillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo) {
 | 
			
		||||
	v.MemoryLimit = sysInfo.MemoryLimit
 | 
			
		||||
	v.SwapLimit = sysInfo.SwapLimit
 | 
			
		||||
	v.KernelMemory = sysInfo.KernelMemory
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,5 +6,5 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
// FillPlatformInfo fills the platform related info.
 | 
			
		||||
func (daemon *Daemon) FillPlatformInfo(v *types.InfoBase, sysInfo *sysinfo.SysInfo) {
 | 
			
		||||
func (daemon *Daemon) FillPlatformInfo(v *types.Info, sysInfo *sysinfo.SysInfo) {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue