summaryrefslogtreecommitdiff
path: root/pkg/api
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api')
-rw-r--r--pkg/api/handlers/compat/containers_create.go5
-rw-r--r--pkg/api/handlers/compat/containers_stats.go30
-rw-r--r--pkg/api/handlers/compat/events.go2
-rw-r--r--pkg/api/handlers/compat/images.go76
-rw-r--r--pkg/api/handlers/compat/images_push.go112
-rw-r--r--pkg/api/handlers/compat/resize.go15
-rw-r--r--pkg/api/handlers/libpod/images.go2
-rw-r--r--pkg/api/handlers/libpod/images_pull.go2
-rw-r--r--pkg/api/handlers/libpod/manifests.go2
-rw-r--r--pkg/api/handlers/libpod/swagger.go2
-rw-r--r--pkg/api/handlers/utils/images.go25
-rw-r--r--pkg/api/server/handler_api.go6
-rw-r--r--pkg/api/server/register_containers.go7
-rw-r--r--pkg/api/server/server.go21
14 files changed, 158 insertions, 149 deletions
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 8e9e1fb39..0b5cbd343 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -71,13 +71,12 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
imgNameOrID := newImage.ID()
// if the img had multi names with the same sha256 ID, should use the InputName, not the ID
if len(newImage.Names()) > 1 {
- imageRef, err := utils.ParseDockerReference(resolvedName)
- if err != nil {
+ if err := utils.IsRegistryReference(resolvedName); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
// maybe the InputName has no tag, so use full name to display
- imgNameOrID = imageRef.DockerReference().String()
+ imgNameOrID = resolvedName
}
sg := specgen.NewSpecGenerator(imgNameOrID, cliOpts.RootFS)
diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go
index 694b57bb1..851955207 100644
--- a/pkg/api/handlers/compat/containers_stats.go
+++ b/pkg/api/handlers/compat/containers_stats.go
@@ -22,7 +22,8 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- Stream bool `schema:"stream"`
+ Stream bool `schema:"stream"`
+ OneShot bool `schema:"one-shot"` //added schema for one shot
}{
Stream: true,
}
@@ -30,6 +31,10 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
+ if query.Stream && query.OneShot { // mismatch. one-shot can only be passed with stream=false
+ utils.Error(w, "invalid combination of stream and one-shot", http.StatusBadRequest, define.ErrInvalidArg)
+ return
+ }
name := utils.GetName(r)
ctnr, err := runtime.LookupContainer(name)
@@ -56,6 +61,16 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
return
}
+ coder := json.NewEncoder(w)
+ // Write header and content type.
+ w.WriteHeader(http.StatusOK)
+ w.Header().Add("Content-Type", "application/json")
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+
+ // Setup JSON encoder for streaming.
+ coder.SetEscapeHTML(true)
var preRead time.Time
var preCPUStats CPUStats
if query.Stream {
@@ -75,17 +90,6 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) {
}
}
- // Write header and content type.
- w.WriteHeader(http.StatusOK)
- w.Header().Add("Content-Type", "application/json")
- if flusher, ok := w.(http.Flusher); ok {
- flusher.Flush()
- }
-
- // Setup JSON encoder for streaming.
- coder := json.NewEncoder(w)
- coder.SetEscapeHTML(true)
-
streamLabel: // A label to flatten the scope
select {
case <-r.Context().Done():
@@ -199,7 +203,7 @@ streamLabel: // A label to flatten the scope
flusher.Flush()
}
- if !query.Stream {
+ if !query.Stream || query.OneShot {
return
}
diff --git a/pkg/api/handlers/compat/events.go b/pkg/api/handlers/compat/events.go
index 405e616c5..9fbac91e0 100644
--- a/pkg/api/handlers/compat/events.go
+++ b/pkg/api/handlers/compat/events.go
@@ -75,7 +75,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
coder := json.NewEncoder(w)
coder.SetEscapeHTML(true)
- for stream := true; stream; stream = query.Stream {
+ for {
select {
case err := <-errorChannel:
if err != nil {
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index 3f4320efa..7b336c470 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -1,7 +1,6 @@
package compat
import (
- "context"
"encoding/json"
"fmt"
"io/ioutil"
@@ -13,12 +12,12 @@ import (
"github.com/containers/common/libimage"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/manifest"
+ "github.com/containers/image/v5/pkg/shortnames"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/api/handlers"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/auth"
- "github.com/containers/podman/v3/pkg/channel"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/containers/storage"
@@ -210,6 +209,11 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) {
})
}
+type pullResult struct {
+ images []*libimage.Image
+ err error
+}
+
func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
// 200 no error
// 404 repo does not exist or no read access
@@ -231,6 +235,14 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
fromImage := mergeNameAndTagOrDigest(query.FromImage, query.Tag)
+ // without this early check this function would return 200 but reported error via body stream soon after
+ // it's better to let caller know early via HTTP status code that request cannot be processed
+ _, err := shortnames.Resolve(runtime.SystemContext(), fromImage)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrap(err, "failed to resolve image name"))
+ return
+ }
+
authConf, authfile, key, err := auth.GetCredentials(r)
if err != nil {
utils.Error(w, "failed to retrieve repository credentials", http.StatusBadRequest, errors.Wrapf(err, "failed to parse %q header for %s", key, r.URL.String()))
@@ -247,26 +259,14 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
}
pullOptions.Writer = os.Stderr // allows for debugging on the server
- stderr := channel.NewWriter(make(chan []byte))
- defer stderr.Close()
-
progress := make(chan types.ProgressProperties)
+
pullOptions.Progress = progress
- var img string
- runCtx, cancel := context.WithCancel(context.Background())
+ pullResChan := make(chan pullResult)
go func() {
- defer cancel()
- pulledImages, err := runtime.LibimageRuntime().Pull(runCtx, fromImage, config.PullPolicyAlways, pullOptions)
- if err != nil {
- stderr.Write([]byte(err.Error() + "\n"))
- } else {
- if len(pulledImages) == 0 {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.New("internal error: no images pulled"))
- return
- }
- img = pulledImages[0].ID()
- }
+ pulledImages, err := runtime.LibimageRuntime().Pull(r.Context(), fromImage, config.PullPolicyAlways, pullOptions)
+ pullResChan <- pullResult{images: pulledImages, err: err}
}()
flush := func() {
@@ -281,7 +281,6 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
enc := json.NewEncoder(w)
enc.SetEscapeHTML(true)
- var failed bool
loop: // break out of for/select infinite loop
for {
@@ -312,32 +311,31 @@ loop: // break out of for/select infinite loop
}
report.Id = e.Artifact.Digest.Encoded()[0:12]
if err := enc.Encode(report); err != nil {
- stderr.Write([]byte(err.Error()))
- }
- flush()
- case e := <-stderr.Chan():
- failed = true
- report.Error = string(e)
- if err := enc.Encode(report); err != nil {
logrus.Warnf("Failed to json encode error %q", err.Error())
}
flush()
- case <-runCtx.Done():
- if !failed {
- if utils.IsLibpodRequest(r) {
- report.Status = "Pull complete"
+ case pullRes := <-pullResChan:
+ err := pullRes.err
+ pulledImages := pullRes.images
+ if err != nil {
+ report.Error = err.Error()
+ } else {
+ if len(pulledImages) > 0 {
+ img := pulledImages[0].ID()
+ if utils.IsLibpodRequest(r) {
+ report.Status = "Pull complete"
+ } else {
+ report.Status = "Download complete"
+ }
+ report.Id = img[0:12]
} else {
- report.Status = "Download complete"
- }
- report.Id = img[0:12]
- if err := enc.Encode(report); err != nil {
- logrus.Warnf("Failed to json encode error %q", err.Error())
+ report.Error = "internal error: no images pulled"
}
- flush()
}
- break loop // break out of for/select infinite loop
- case <-r.Context().Done():
- // Client has closed connection
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+ flush()
break loop // break out of for/select infinite loop
}
}
diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go
index db02af445..62f8cdc77 100644
--- a/pkg/api/handlers/compat/images_push.go
+++ b/pkg/api/handlers/compat/images_push.go
@@ -1,7 +1,6 @@
package compat
import (
- "context"
"encoding/json"
"fmt"
"io/ioutil"
@@ -12,7 +11,6 @@ import (
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/auth"
- "github.com/containers/podman/v3/pkg/channel"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/containers/storage"
@@ -101,46 +99,33 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
destination = imageName
}
- errorWriter := channel.NewWriter(make(chan []byte))
- defer errorWriter.Close()
-
- statusWriter := channel.NewWriter(make(chan []byte))
- defer statusWriter.Close()
-
- runCtx, cancel := context.WithCancel(context.Background())
- var failed bool
-
- go func() {
- defer cancel()
-
- statusWriter.Write([]byte(fmt.Sprintf("The push refers to repository [%s]", imageName)))
-
- err := imageEngine.Push(runCtx, imageName, destination, options)
- if err != nil {
- if errors.Cause(err) != storage.ErrImageUnknown {
- errorWriter.Write([]byte("An image does not exist locally with the tag: " + imageName))
- } else {
- errorWriter.Write([]byte(err.Error()))
- }
- }
- }()
-
- flush := func() {
- if flusher, ok := w.(http.Flusher); ok {
- flusher.Flush()
- }
+ flush := func() {}
+ if flusher, ok := w.(http.Flusher); ok {
+ flush = flusher.Flush
}
w.WriteHeader(http.StatusOK)
w.Header().Add("Content-Type", "application/json")
flush()
+ var report jsonmessage.JSONMessage
enc := json.NewEncoder(w)
enc.SetEscapeHTML(true)
+ report.Status = fmt.Sprintf("The push refers to repository [%s]", imageName)
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+ flush()
+
+ pushErrChan := make(chan error)
+ go func() {
+ pushErrChan <- imageEngine.Push(r.Context(), imageName, destination, options)
+ }()
+
loop: // break out of for/select infinite loop
for {
- var report jsonmessage.JSONMessage
+ report = jsonmessage.JSONMessage{}
select {
case e := <-options.Progress:
@@ -160,43 +145,50 @@ loop: // break out of for/select infinite loop
}
report.ID = e.Artifact.Digest.Encoded()[0:12]
if err := enc.Encode(report); err != nil {
- errorWriter.Write([]byte(err.Error()))
+ logrus.Warnf("Failed to json encode error %q", err.Error())
}
flush()
- case e := <-statusWriter.Chan():
- report.Status = string(e)
- if err := enc.Encode(report); err != nil {
- errorWriter.Write([]byte(err.Error()))
+ case err := <-pushErrChan:
+ if err != nil {
+ var msg string
+ if errors.Cause(err) != storage.ErrImageUnknown {
+ msg = "An image does not exist locally with the tag: " + imageName
+ } else {
+ msg = err.Error()
+ }
+ report.Error = &jsonmessage.JSONError{
+ Message: msg,
+ }
+ report.ErrorMessage = msg
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+ flush()
+ break loop
}
- flush()
- case e := <-errorWriter.Chan():
- failed = true
- report.Error = &jsonmessage.JSONError{
- Message: string(e),
+
+ digestBytes, err := ioutil.ReadAll(digestFile)
+ if err != nil {
+ report.Error = &jsonmessage.JSONError{
+ Message: err.Error(),
+ }
+ report.ErrorMessage = err.Error()
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to json encode error %q", err.Error())
+ }
+ flush()
+ break loop
}
- report.ErrorMessage = string(e)
+ tag := query.Tag
+ if tag == "" {
+ tag = "latest"
+ }
+ report.Status = fmt.Sprintf("%s: digest: %s", tag, string(digestBytes))
if err := enc.Encode(report); err != nil {
logrus.Warnf("Failed to json encode error %q", err.Error())
}
+
flush()
- case <-runCtx.Done():
- if !failed {
- digestBytes, err := ioutil.ReadAll(digestFile)
- if err == nil {
- tag := query.Tag
- if tag == "" {
- tag = "latest"
- }
- report.Status = fmt.Sprintf("%s: digest: %s", tag, string(digestBytes))
- if err := enc.Encode(report); err != nil {
- logrus.Warnf("Failed to json encode error %q", err.Error())
- }
- flush()
- }
- }
- break loop // break out of for/select infinite loop
- case <-r.Context().Done():
- // Client has closed connection
break loop // break out of for/select infinite loop
}
}
diff --git a/pkg/api/handlers/compat/resize.go b/pkg/api/handlers/compat/resize.go
index 23ed33a22..f65e313fc 100644
--- a/pkg/api/handlers/compat/resize.go
+++ b/pkg/api/handlers/compat/resize.go
@@ -46,20 +46,13 @@ func ResizeTTY(w http.ResponseWriter, r *http.Request) {
utils.ContainerNotFound(w, name, err)
return
}
- if state, err := ctnr.State(); err != nil {
- utils.InternalServerError(w, errors.Wrapf(err, "cannot obtain container state"))
- return
- } else if state != define.ContainerStateRunning && !query.IgnoreNotRunning {
- utils.Error(w, "Container not running", http.StatusConflict,
- fmt.Errorf("container %q in wrong state %q", name, state.String()))
- return
- }
- // If container is not running, ignore since this can be a race condition, and is expected
if err := ctnr.AttachResize(sz); err != nil {
- if errors.Cause(err) != define.ErrCtrStateInvalid || !query.IgnoreNotRunning {
+ if errors.Cause(err) != define.ErrCtrStateInvalid {
utils.InternalServerError(w, errors.Wrapf(err, "cannot resize container"))
- return
+ } else {
+ utils.Error(w, "Container not running", http.StatusConflict, err)
}
+ return
}
// This is not a 204, even though we write nothing, for compatibility
// reasons.
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index a90408bfd..fc6ab4b4c 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -482,7 +482,7 @@ func PushImage(w http.ResponseWriter, r *http.Request) {
destination = source
}
- if _, err := utils.ParseDockerReference(destination); err != nil {
+ if err := utils.IsRegistryReference(destination); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index 7545ba235..fe56aa31d 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -48,7 +48,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
}
// Make sure that the reference has no transport or the docker one.
- if _, err := utils.ParseDockerReference(query.Reference); err != nil {
+ if err := utils.IsRegistryReference(query.Reference); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index f21eb2e80..2f36db583 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -169,7 +169,7 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) {
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- if _, err := utils.ParseDockerReference(query.Destination); err != nil {
+ if err := utils.IsRegistryReference(query.Destination); err != nil {
utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
return
}
diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go
index 9450a70d9..19eced986 100644
--- a/pkg/api/handlers/libpod/swagger.go
+++ b/pkg/api/handlers/libpod/swagger.go
@@ -95,7 +95,7 @@ type swagInfoResponse struct {
// swagger:response NetworkRmReport
type swagNetworkRmReport struct {
// in:body
- Body entities.NetworkRmReport
+ Body []entities.NetworkRmReport
}
// Network inspect
diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go
index 2662cd368..2a1908d63 100644
--- a/pkg/api/handlers/utils/images.go
+++ b/pkg/api/handlers/utils/images.go
@@ -15,22 +15,19 @@ import (
"github.com/pkg/errors"
)
-// ParseDockerReference parses the specified image name to a
-// `types.ImageReference` and enforces it to refer to a docker-transport
-// reference.
-func ParseDockerReference(name string) (types.ImageReference, error) {
- dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name())
+// IsRegistryReference checks if the specified name points to the "docker://"
+// transport. If it points to no supported transport, we'll assume a
+// non-transport reference pointing to an image (e.g., "fedora:latest").
+func IsRegistryReference(name string) error {
imageRef, err := alltransports.ParseImageName(name)
- if err == nil && imageRef.Transport().Name() != docker.Transport.Name() {
- return nil, errors.Errorf("reference %q must be a docker reference", name)
- } else if err != nil {
- origErr := err
- imageRef, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, name))
- if err != nil {
- return nil, errors.Wrapf(origErr, "reference %q must be a docker reference", name)
- }
+ if err != nil {
+ // No supported transport -> assume a docker-stype reference.
+ return nil
}
- return imageRef, nil
+ if imageRef.Transport().Name() == docker.Transport.Name() {
+ return nil
+ }
+ return errors.Errorf("unsupport transport %s in %q: only docker transport is supported", imageRef.Transport().Name(), name)
}
// ParseStorageReference parses the specified image name to a
diff --git a/pkg/api/server/handler_api.go b/pkg/api/server/handler_api.go
index 28b8706a8..becc674c0 100644
--- a/pkg/api/server/handler_api.go
+++ b/pkg/api/server/handler_api.go
@@ -63,6 +63,12 @@ func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
w.Header().Set("Libpod-API-Version", lv)
w.Header().Set("Server", "Libpod/"+lv+" ("+runtime.GOOS+")")
+ if s.CorsHeaders != "" {
+ w.Header().Set("Access-Control-Allow-Origin", s.CorsHeaders)
+ w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth, Connection, Upgrade, X-Registry-Config")
+ w.Header().Set("Access-Control-Allow-Methods", "HEAD, GET, POST, DELETE, PUT, OPTIONS")
+ }
+
h(w, r)
logrus.Debugf("APIHandler(%s) -- %s %s END", rid, r.Method, r.URL.String())
}
diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go
index 536c4707a..88ebb4df5 100644
--- a/pkg/api/server/register_containers.go
+++ b/pkg/api/server/register_containers.go
@@ -375,6 +375,11 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// type: boolean
// default: true
// description: Stream the output
+ // - in: query
+ // name: one-shot
+ // type: boolean
+ // default: false
+ // description: Provide a one-shot response in which preCPU stats are blank, resulting in a single cycle return.
// produces:
// - application/json
// responses:
@@ -1359,6 +1364,8 @@ func (s *APIServer) registerContainersHandlers(r *mux.Router) error {
// $ref: "#/responses/ok"
// 404:
// $ref: "#/responses/NoSuchContainer"
+ // 409:
+ // $ref: "#/responses/ConflictError"
// 500:
// $ref: "#/responses/InternalError"
r.HandleFunc(VersionedPath("/libpod/containers/{name}/resize"), s.APIHandler(compat.ResizeTTY)).Methods(http.MethodPost)
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 972541bc6..1e8faf8f5 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -34,10 +34,12 @@ type APIServer struct {
context.CancelFunc // Stop APIServer
idleTracker *idle.Tracker // Track connections to support idle shutdown
pprof *http.Server // Sidecar http server for providing performance data
+ CorsHeaders string // Inject CORS headers to each request
}
// Number of seconds to wait for next request, if exceeded shutdown server
const (
+ DefaultCorsHeaders = ""
DefaultServiceDuration = 300 * time.Second
UnlimitedServiceDuration = 0 * time.Second
)
@@ -45,17 +47,22 @@ const (
// shutdownOnce ensures Shutdown() may safely be called from several go routines
var shutdownOnce sync.Once
+type Options struct {
+ Timeout time.Duration
+ CorsHeaders string
+}
+
// NewServer will create and configure a new API server with all defaults
func NewServer(runtime *libpod.Runtime) (*APIServer, error) {
- return newServer(runtime, DefaultServiceDuration, nil)
+ return newServer(runtime, DefaultServiceDuration, nil, DefaultCorsHeaders)
}
// NewServerWithSettings will create and configure a new API server using provided settings
-func NewServerWithSettings(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener) (*APIServer, error) {
- return newServer(runtime, duration, listener)
+func NewServerWithSettings(runtime *libpod.Runtime, listener *net.Listener, opts Options) (*APIServer, error) {
+ return newServer(runtime, opts.Timeout, listener, opts.CorsHeaders)
}
-func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener) (*APIServer, error) {
+func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener, corsHeaders string) (*APIServer, error) {
// If listener not provided try socket activation protocol
if listener == nil {
if _, found := os.LookupEnv("LISTEN_PID"); !found {
@@ -71,6 +78,11 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
}
listener = &listeners[0]
}
+ if corsHeaders == "" {
+ logrus.Debug("CORS Headers were not set")
+ } else {
+ logrus.Debugf("CORS Headers were set to %s", corsHeaders)
+ }
logrus.Infof("API server listening on %q", (*listener).Addr())
router := mux.NewRouter().UseEncodedPath()
@@ -88,6 +100,7 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
idleTracker: idle,
Listener: *listener,
Runtime: runtime,
+ CorsHeaders: corsHeaders,
}
router.NotFoundHandler = http.HandlerFunc(