diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/generic/swagger.go | 1 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 44 | ||||
-rw-r--r-- | pkg/api/server/register_pods.go | 27 | ||||
-rw-r--r-- | pkg/spec/config_linux_cgo.go | 12 | ||||
-rw-r--r-- | pkg/spec/createconfig.go | 67 |
5 files changed, 106 insertions, 45 deletions
diff --git a/pkg/api/handlers/generic/swagger.go b/pkg/api/handlers/generic/swagger.go index 8df961b94..27e1fc18d 100644 --- a/pkg/api/handlers/generic/swagger.go +++ b/pkg/api/handlers/generic/swagger.go @@ -16,7 +16,6 @@ type swagCtrWaitResponse struct { Body struct { // container exit code StatusCode int - error message Error struct { Message string } diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 7298f3c61..916534fc7 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -10,7 +10,7 @@ import ( ) func (s *APIServer) registerImagesHandlers(r *mux.Router) error { - // swagger:operation POST /images/create images createImage + // swagger:operation POST /images/create compat_images createImage // // --- // summary: Create an image from an image @@ -40,7 +40,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // schema: // $ref: '#/responses/GenericError' r.Handle(VersionedPath("/images/create"), APIHandler(s.Context, generic.CreateImageFromImage)).Methods(http.MethodPost).Queries("fromImage", "{fromImage}") - // swagger:operation POST /images/create images createImage + // swagger:operation POST /images/create compat_images createImage // --- // summary: Create an image from Source // description: Create an image by either pulling it from a registry or importing it. @@ -69,7 +69,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // schema: // $ref: '#/responses/GenericError' r.Handle(VersionedPath("/images/create"), APIHandler(s.Context, generic.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") - // swagger:operation GET /images/json images listImages + // swagger:operation GET /images/json compat_images listImages // --- // summary: List Images // description: Returns a list of images on the server. Note that it uses a different, smaller representation of an image than inspecting a single image. @@ -85,7 +85,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/json"), APIHandler(s.Context, generic.GetImages)).Methods(http.MethodGet) - // swagger:operation POST /images/load images loadImage + // swagger:operation POST /images/load compat_images loadImage // // --- // summary: Import image @@ -107,7 +107,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/load"), APIHandler(s.Context, handlers.LoadImage)).Methods(http.MethodPost) - // swagger:operation POST /images/prune images pruneImages + // swagger:operation POST /images/prune compat_images pruneImages // --- // summary: Prune unused images // description: Remove images from local storage that are not being used by a container @@ -132,7 +132,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/prune"), APIHandler(s.Context, generic.PruneImages)).Methods(http.MethodPost) - // swagger:operation GET /images/search images searchImages + // swagger:operation GET /images/search compat_images searchImages // --- // summary: Search images // description: Search registries for an image @@ -161,7 +161,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/search"), APIHandler(s.Context, handlers.SearchImages)).Methods(http.MethodGet) - // swagger:operation DELETE /images/{nameOrID} images removeImage + // swagger:operation DELETE /images/{nameOrID} compat_images removeImage // --- // summary: Remove Image // description: Delete an image from local storage @@ -173,20 +173,20 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - in: query // name: noprune // type: bool - // description: not supported + // description: not supported. will be logged as an invalid parameter if enabled // produces: // - application/json // responses: // '200': // $ref: "#/responses/DocsImageDeleteResponse" - // '404': + // '400': // $ref: '#/responses/BadParamError' // '409': // $ref: '#/responses/ConflictError' // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/{name:..*}"), APIHandler(s.Context, handlers.RemoveImage)).Methods(http.MethodDelete) - // swagger:operation GET /images/{nameOrID}/get images exportImage + // swagger:operation GET /images/{nameOrID}/get compat_images exportImage // --- // summary: Export an image // description: Export an image in tarball format @@ -200,10 +200,13 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // responses: // '200': // description: no error + // schema: + // type: string + // format: binary // '500': // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/{name:..*}/get"), APIHandler(s.Context, generic.ExportImage)).Methods(http.MethodGet) - // swagger:operation GET /images/{nameOrID}/history images imageHistory + // swagger:operation GET /images/{nameOrID}/history compat_images imageHistory // --- // summary: History of an image // description: Return parent layers of an image. @@ -222,7 +225,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/images/{name:..*}/history"), APIHandler(s.Context, handlers.HistoryImage)).Methods(http.MethodGet) - // swagger:operation GET /images/{nameOrID}/json images inspectImage + // swagger:operation GET /images/{nameOrID}/json compat_images inspectImage // --- // summary: Inspect an image // description: Return low-level information about an image. @@ -241,7 +244,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // '500': // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/images/{name:..*}/json"), APIHandler(s.Context, generic.GetImage)) - // swagger:operation POST /images/{nameOrID}/tag images tagImage + // swagger:operation POST /images/{nameOrID}/tag compat_images tagImage // --- // summary: Tag an image // description: Tag an image so that it becomes part of a repository. @@ -272,7 +275,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // 500: // $ref: '#/responses/InternalError' r.Handle(VersionedPath("/images/{name:..*}/tag"), APIHandler(s.Context, handlers.TagImage)).Methods(http.MethodPost) - // swagger:operation POST /commit/ commit commitContainer + // swagger:operation POST /commit/ compat_commit commitContainer // --- // summary: Create a new image from a container // parameters: @@ -377,7 +380,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // swagger:operation POST /libpod/images/load images libpodLoadImage // --- // summary: Import image - // description: tbd + // description: Load a set of images and tags into a repository. // parameters: // - in: query // name: quiet @@ -463,10 +466,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // name: force // type: bool // description: remove the image even if used by containers or has other tags - // - in: query - // name: noprune - // type: bool - // description: not supported // produces: // - application/json // responses: @@ -474,6 +473,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // schema: // items: // $ref: "#/responses/DocsIageDeleteResponse" + // '400': + // $ref: "#/responses/BadParamError" // '404': // $ref: '#/responses/NoSuchImage' // '409': @@ -503,6 +504,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // responses: // '200': // description: no error + // schema: + // type: string + // format: binary // '404': // $ref: '#/responses/NoSuchImage' // '500': @@ -521,8 +525,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - application/json // responses: // '200': - // schema: - // items: // $ref: "#/responses/DocsLibpodInspectImageResponse" // '404': // $ref: '#/responses/NoSuchImage' diff --git a/pkg/api/server/register_pods.go b/pkg/api/server/register_pods.go index 1f09e8f0e..5069326b6 100644 --- a/pkg/api/server/register_pods.go +++ b/pkg/api/server/register_pods.go @@ -19,11 +19,14 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // descriptions: needs description and plumbing for filters // responses: // '200': - // $ref: "#/responses/ListPodsResponse" + // properties: + // items: + // $ref: "#/responses/ListPodsResponse" + // type: array // '400': // $ref: "#/responses/BadParamError" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/json"), APIHandler(s.Context, libpod.Pods)).Methods(http.MethodGet) r.Handle(VersionedPath("/libpod/pods/create"), APIHandler(s.Context, libpod.PodCreate)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/prune pods PrunePods @@ -43,7 +46,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '400': // $ref: "#/responses/BadParamError" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/prune"), APIHandler(s.Context, libpod.PodPrune)).Methods(http.MethodPost) // swagger:operation DELETE /libpod/pods/{nameOrID} pods removePod // --- @@ -67,7 +70,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}"), APIHandler(s.Context, libpod.PodDelete)).Methods(http.MethodDelete) // swagger:operation GET /libpod/pods/{nameOrID}/json pods inspectPod // --- @@ -85,7 +88,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/json"), APIHandler(s.Context, libpod.PodInspect)).Methods(http.MethodGet) // swagger:operation GET /libpod/pods/{nameOrID}/exists pods podExists // --- @@ -104,7 +107,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/exists"), APIHandler(s.Context, libpod.PodExists)).Methods(http.MethodGet) // swagger:operation POST /libpod/pods/{nameOrID}/kill pods killPod // --- @@ -130,7 +133,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '409': // $ref: "#/responses/ConflictError" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/kill"), APIHandler(s.Context, libpod.PodKill)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/pause pods pausePod // --- @@ -148,7 +151,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/pause"), APIHandler(s.Context, libpod.PodPause)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/restart pods restartPod // --- @@ -166,7 +169,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/restart"), APIHandler(s.Context, libpod.PodRestart)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/start pods startPod // --- @@ -186,7 +189,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/start"), APIHandler(s.Context, libpod.PodStart)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/stop pods stopPod // --- @@ -212,7 +215,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/stop"), APIHandler(s.Context, libpod.PodStop)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{nameOrID}/unpause pods unpausePod // --- @@ -230,7 +233,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // '404': // $ref: "#/responses/NoSuchPod" // '500': - // $ref: "#responses/InternalError" + // $ref: "#/responses/InternalError" r.Handle(VersionedPath("/libpod/pods/{name:..*}/unpause"), APIHandler(s.Context, libpod.PodUnpause)).Methods(http.MethodPost) return nil } diff --git a/pkg/spec/config_linux_cgo.go b/pkg/spec/config_linux_cgo.go index c47156456..ae83c9d52 100644 --- a/pkg/spec/config_linux_cgo.go +++ b/pkg/spec/config_linux_cgo.go @@ -8,13 +8,24 @@ import ( spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" seccomp "github.com/seccomp/containers-golang" + "github.com/sirupsen/logrus" ) func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) { var seccompConfig *spec.LinuxSeccomp var err error + if config.SeccompPolicy == SeccompPolicyImage && config.SeccompProfileFromImage != "" { + logrus.Debug("Loading seccomp profile from the security config") + seccompConfig, err = seccomp.LoadProfile(config.SeccompProfileFromImage, configSpec) + if err != nil { + return nil, errors.Wrap(err, "loading seccomp profile failed") + } + return seccompConfig, nil + } + if config.SeccompProfilePath != "" { + logrus.Debugf("Loading seccomp profile from %q", config.SeccompProfilePath) seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath) if err != nil { return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath) @@ -24,6 +35,7 @@ func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.Linu return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath) } } else { + logrus.Debug("Loading default seccomp profile") seccompConfig, err = seccomp.GetDefaultProfile(configSpec) if err != nil { return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath) diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go index 6d058229b..fb222083b 100644 --- a/pkg/spec/createconfig.go +++ b/pkg/spec/createconfig.go @@ -2,6 +2,7 @@ package createconfig import ( "os" + "sort" "strconv" "strings" "syscall" @@ -106,19 +107,63 @@ type NetworkConfig struct { PublishAll bool //publish-all } +// SeccompPolicy determines which seccomp profile gets applied to the container. +type SeccompPolicy int + +const ( + // SeccompPolicyDefault - if set use SecurityConfig.SeccompProfilePath, + // otherwise use the default profile. The SeccompProfilePath might be + // explicitly set by the user. + SeccompPolicyDefault SeccompPolicy = iota + // SeccompPolicyImage - if set use SecurityConfig.SeccompProfileFromImage, + // otherwise follow SeccompPolicyDefault. + SeccompPolicyImage +) + +// Map for easy lookups of supported policies. +var supportedSeccompPolicies = map[string]SeccompPolicy{ + "": SeccompPolicyDefault, + "default": SeccompPolicyDefault, + "image": SeccompPolicyImage, +} + +// LookupSeccompPolicy looksup the corresponding SeccompPolicy for the specified +// string. If none is found, an errors is returned including the list of +// supported policies. +// Note that an empty string resolved to SeccompPolicyDefault. +func LookupSeccompPolicy(s string) (SeccompPolicy, error) { + policy, exists := supportedSeccompPolicies[s] + if exists { + return policy, nil + } + + // Sort the keys first as maps are non-deterministic. + keys := []string{} + for k := range supportedSeccompPolicies { + if k != "" { + keys = append(keys, k) + } + } + sort.Strings(keys) + + return -1, errors.Errorf("invalid seccomp policy %q: valid policies are %+q", s, keys) +} + // SecurityConfig configures the security features for the container type SecurityConfig struct { - CapAdd []string // cap-add - CapDrop []string // cap-drop - LabelOpts []string //SecurityOpts - NoNewPrivs bool //SecurityOpts - ApparmorProfile string //SecurityOpts - SeccompProfilePath string //SecurityOpts - SecurityOpts []string - Privileged bool //privileged - ReadOnlyRootfs bool //read-only - ReadOnlyTmpfs bool //read-only-tmpfs - Sysctl map[string]string //sysctl + CapAdd []string // cap-add + CapDrop []string // cap-drop + LabelOpts []string //SecurityOpts + NoNewPrivs bool //SecurityOpts + ApparmorProfile string //SecurityOpts + SeccompProfilePath string //SecurityOpts + SeccompProfileFromImage string // seccomp profile from the container image + SeccompPolicy SeccompPolicy + SecurityOpts []string + Privileged bool //privileged + ReadOnlyRootfs bool //read-only + ReadOnlyTmpfs bool //read-only-tmpfs + Sysctl map[string]string //sysctl } // CreateConfig is a pre OCI spec structure. It represents user input from varlink or the CLI |