diff options
Diffstat (limited to 'pkg/domain/infra')
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 65 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 14 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 35 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 104 |
4 files changed, 182 insertions, 36 deletions
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index d2c8aefdc..8e0ffc075 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -338,20 +338,51 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string, return reports, nil } -func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) { - ctrs, err := getContainersByContext(false, options.Latest, namesOrIds, ic.Libpod) - if err != nil { - return nil, err +func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, []error, error) { + if options.Latest { + ctr, err := ic.Libpod.GetLatestContainer() + if err != nil { + if errors.Cause(err) == define.ErrNoSuchCtr { + return nil, []error{errors.Wrapf(err, "no containers to inspect")}, nil + } + return nil, nil, err + } + + inspect, err := ctr.Inspect(options.Size) + if err != nil { + return nil, nil, err + } + + return []*entities.ContainerInspectReport{ + { + InspectContainerData: inspect, + }, + }, nil, nil } - reports := make([]*entities.ContainerInspectReport, 0, len(ctrs)) - for _, c := range ctrs { - data, err := c.Inspect(options.Size) + var ( + reports = make([]*entities.ContainerInspectReport, 0, len(namesOrIds)) + errs = []error{} + ) + for _, name := range namesOrIds { + ctr, err := ic.Libpod.LookupContainer(name) if err != nil { - return nil, err + // ErrNoSuchCtr is non-fatal, other errors will be + // treated as fatal. + if errors.Cause(err) == define.ErrNoSuchCtr { + errs = append(errs, errors.Errorf("no such container %s", name)) + continue + } + return nil, nil, err + } + + inspect, err := ctr.Inspect(options.Size) + if err != nil { + return nil, nil, err } - reports = append(reports, &entities.ContainerInspectReport{InspectContainerData: data}) + + reports = append(reports, &entities.ContainerInspectReport{InspectContainerData: inspect}) } - return reports, nil + return reports, errs, nil } func (ic *ContainerEngine) ContainerTop(ctx context.Context, options entities.TopOptions) (*entities.StringSliceReport, error) { @@ -511,9 +542,14 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st } func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecGenerator) (*entities.ContainerCreateReport, error) { - if err := generate.CompleteSpec(ctx, ic.Libpod, s); err != nil { + warn, err := generate.CompleteSpec(ctx, ic.Libpod, s) + if err != nil { return nil, err } + // Print warnings + for _, w := range warn { + fmt.Fprintf(os.Stderr, "%s\n", w) + } ctr, err := generate.MakeContainer(ctx, ic.Libpod, s) if err != nil { return nil, err @@ -773,9 +809,14 @@ func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrID string, o } func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) { - if err := generate.CompleteSpec(ctx, ic.Libpod, opts.Spec); err != nil { + warn, err := generate.CompleteSpec(ctx, ic.Libpod, opts.Spec) + if err != nil { return nil, err } + // Print warnings + for _, w := range warn { + fmt.Fprintf(os.Stderr, "%s\n", w) + } ctr, err := generate.MakeContainer(ctx, ic.Libpod, opts.Spec) if err != nil { return nil, err diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index e630d9bc8..0f9ddfec4 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -184,24 +184,28 @@ func (ir *ImageEngine) Pull(ctx context.Context, rawImage string, options entiti return &entities.ImagePullReport{Images: foundIDs}, nil } -func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts entities.InspectOptions) ([]*entities.ImageInspectReport, error) { +func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts entities.InspectOptions) ([]*entities.ImageInspectReport, []error, error) { reports := []*entities.ImageInspectReport{} + errs := []error{} for _, i := range namesOrIDs { img, err := ir.Libpod.ImageRuntime().NewFromLocal(i) if err != nil { - return nil, err + // This is probably a no such image, treat as nonfatal. + errs = append(errs, err) + continue } result, err := img.Inspect(ctx) if err != nil { - return nil, err + // This is more likely to be fatal. + return nil, nil, err } report := entities.ImageInspectReport{} if err := domainUtils.DeepCopy(&report, result); err != nil { - return nil, err + return nil, nil, err } reports = append(reports, &report) } - return reports, nil + return reports, errs, nil } func (ir *ImageEngine) Push(ctx context.Context, source string, destination string, options entities.ImagePushOptions) error { diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 8f6f5c8b7..45fbc64f8 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -185,20 +185,27 @@ func (ic *ContainerEngine) ContainerPrune(ctx context.Context, options entities. return containers.Prune(ic.ClientCxt, options.Filters) } -func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) { - ctrs, err := getContainersByContext(ic.ClientCxt, false, namesOrIds) - if err != nil { - return nil, err - } - reports := make([]*entities.ContainerInspectReport, 0, len(ctrs)) - for _, con := range ctrs { - data, err := containers.Inspect(ic.ClientCxt, con.ID, &options.Size) +func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, []error, error) { + var ( + reports = make([]*entities.ContainerInspectReport, 0, len(namesOrIds)) + errs = []error{} + ) + for _, name := range namesOrIds { + inspect, err := containers.Inspect(ic.ClientCxt, name, &options.Size) if err != nil { - return nil, err + errModel, ok := err.(entities.ErrorModel) + if !ok { + return nil, nil, err + } + if errModel.ResponseCode == 404 { + errs = append(errs, errors.Errorf("no such container %q", name)) + continue + } + return nil, nil, err } - reports = append(reports, &entities.ContainerInspectReport{InspectContainerData: data}) + reports = append(reports, &entities.ContainerInspectReport{InspectContainerData: inspect}) } - return reports, nil + return reports, errs, nil } func (ic *ContainerEngine) ContainerTop(ctx context.Context, options entities.TopOptions) (*entities.StringSliceReport, error) { @@ -340,6 +347,9 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG if err != nil { return nil, err } + for _, w := range response.Warnings { + fmt.Fprintf(os.Stderr, "%s\n", w) + } return &entities.ContainerCreateReport{Id: response.ID}, nil } @@ -497,6 +507,9 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta if err != nil { return nil, err } + for _, w := range con.Warnings { + fmt.Fprintf(os.Stderr, "%s\n", w) + } report := entities.ContainerRunReport{Id: con.ID} // Attach if !opts.Detach { diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index fc7ac0aa8..35189cb0a 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -1,10 +1,13 @@ package tunnel import ( + "archive/tar" + "bytes" "context" + "io" "io/ioutil" "os" - "path" + "path/filepath" "strings" "github.com/containers/common/pkg/config" @@ -16,6 +19,7 @@ import ( utils2 "github.com/containers/libpod/utils" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.BoolReport, error) { @@ -157,16 +161,25 @@ func (ir *ImageEngine) Untag(ctx context.Context, nameOrID string, tags []string return nil } -func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts entities.InspectOptions) ([]*entities.ImageInspectReport, error) { +func (ir *ImageEngine) Inspect(ctx context.Context, namesOrIDs []string, opts entities.InspectOptions) ([]*entities.ImageInspectReport, []error, error) { reports := []*entities.ImageInspectReport{} + errs := []error{} for _, i := range namesOrIDs { r, err := images.GetImage(ir.ClientCxt, i, &opts.Size) if err != nil { - return nil, err + errModel, ok := err.(entities.ErrorModel) + if !ok { + return nil, nil, err + } + if errModel.ResponseCode == 404 { + errs = append(errs, errors.Wrapf(err, "unable to inspect %q", i)) + continue + } + return nil, nil, err } reports = append(reports, r) } - return reports, nil + return reports, errs, nil } func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) (*entities.ImageLoadReport, error) { @@ -267,14 +280,27 @@ func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) { } func (ir *ImageEngine) Build(ctx context.Context, containerFiles []string, opts entities.BuildOptions) (*entities.BuildReport, error) { - if len(containerFiles) > 1 { - return nil, errors.New("something") + var tarReader io.Reader + tarfile, err := archive.Tar(opts.ContextDirectory, 0) + if err != nil { + return nil, err } - tarfile, err := archive.Tar(path.Base(containerFiles[0]), 0) + tarReader = tarfile + cwd, err := os.Getwd() if err != nil { return nil, err } - return images.Build(ir.ClientCxt, containerFiles, opts, tarfile) + if cwd != opts.ContextDirectory { + fn := func(h *tar.Header, r io.Reader) (data []byte, update bool, skip bool, err error) { + h.Name = filepath.Join(filepath.Base(opts.ContextDirectory), h.Name) + return nil, false, false, nil + } + tarReader, err = transformArchive(tarfile, false, fn) + if err != nil { + return nil, err + } + } + return images.Build(ir.ClientCxt, containerFiles, opts, tarReader) } func (ir *ImageEngine) Tree(ctx context.Context, nameOrID string, opts entities.ImageTreeOptions) (*entities.ImageTreeReport, error) { @@ -288,3 +314,65 @@ func (ir *ImageEngine) Shutdown(_ context.Context) { func (ir *ImageEngine) Sign(ctx context.Context, names []string, options entities.SignOptions) (*entities.SignReport, error) { return nil, errors.New("not implemented yet") } + +// Sourced from openshift image builder + +// TransformFileFunc is given a chance to transform an arbitrary input file. +type TransformFileFunc func(h *tar.Header, r io.Reader) (data []byte, update bool, skip bool, err error) + +// filterArchive transforms the provided input archive to a new archive, +// giving the fn a chance to transform arbitrary files. +func filterArchive(r io.Reader, w io.Writer, fn TransformFileFunc) error { + tr := tar.NewReader(r) + tw := tar.NewWriter(w) + + var body io.Reader = tr + + for { + h, err := tr.Next() + if err == io.EOF { + return tw.Close() + } + if err != nil { + return err + } + + name := h.Name + data, ok, skip, err := fn(h, tr) + logrus.Debugf("Transform %q -> %q: data=%t ok=%t skip=%t err=%v", name, h.Name, data != nil, ok, skip, err) + if err != nil { + return err + } + if skip { + continue + } + if ok { + h.Size = int64(len(data)) + body = bytes.NewBuffer(data) + } + if err := tw.WriteHeader(h); err != nil { + return err + } + if _, err := io.Copy(tw, body); err != nil { + return err + } + } +} + +func transformArchive(r io.Reader, compressed bool, fn TransformFileFunc) (io.Reader, error) { + var cwe error + pr, pw := io.Pipe() + go func() { + if compressed { + in, err := archive.DecompressStream(r) + if err != nil { + cwe = pw.CloseWithError(err) + return + } + r = in + } + err := filterArchive(r, pw, fn) + cwe = pw.CloseWithError(err) + }() + return pr, cwe +} |