api: types: keep info.SecurityOptions a string slice

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
Antonio Murdaca 2016-11-16 22:30:29 +01:00
parent 96f50e9b70
commit 514ca09426
No known key found for this signature in database
GPG Key ID: B2BEAD150DE936B9
8 changed files with 84 additions and 57 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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