diff options
Diffstat (limited to 'pkg/domain/infra')
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 99 | ||||
-rw-r--r-- | pkg/domain/infra/abi/images.go | 14 | ||||
-rw-r--r-- | pkg/domain/infra/abi/system.go | 77 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 29 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/helpers.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/system.go | 10 |
6 files changed, 223 insertions, 8 deletions
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index ccbe6d4fd..a3a0a8202 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -4,9 +4,11 @@ package abi import ( "context" + "fmt" "io/ioutil" "strconv" "strings" + "sync" "github.com/containers/buildah" "github.com/containers/image/v5/manifest" @@ -14,6 +16,7 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/libpod/logs" "github.com/containers/libpod/pkg/checkpoint" "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/domain/infra/abi/terminal" @@ -709,3 +712,99 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta } return &report, nil } + +func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []string, options entities.ContainerLogsOptions) error { + if options.Writer == nil { + return errors.New("no io.Writer set for container logs") + } + + var wg sync.WaitGroup + + ctrs, err := getContainersByContext(false, options.Latest, containers, ic.Libpod) + if err != nil { + return err + } + + logOpts := &logs.LogOptions{ + Multi: len(ctrs) > 1, + Details: options.Details, + Follow: options.Follow, + Since: options.Since, + Tail: options.Tail, + Timestamps: options.Timestamps, + UseName: options.Names, + WaitGroup: &wg, + } + + chSize := len(ctrs) * int(options.Tail) + if chSize <= 0 { + chSize = 1 + } + logChannel := make(chan *logs.LogLine, chSize) + + if err := ic.Libpod.Log(ctrs, logOpts, logChannel); err != nil { + return err + } + + go func() { + wg.Wait() + close(logChannel) + }() + + for line := range logChannel { + fmt.Fprintln(options.Writer, line.String(logOpts)) + } + + return nil +} + +func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []string, options entities.ContainerCleanupOptions) ([]*entities.ContainerCleanupReport, error) { + var reports []*entities.ContainerCleanupReport + ctrs, err := getContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod) + if err != nil { + return nil, err + } + for _, ctr := range ctrs { + var err error + report := entities.ContainerCleanupReport{Id: ctr.ID()} + if options.Remove { + err = ic.Libpod.RemoveContainer(ctx, ctr, false, true) + if err != nil { + report.RmErr = errors.Wrapf(err, "failed to cleanup and remove container %v", ctr.ID()) + } + } else { + err := ctr.Cleanup(ctx) + if err != nil { + report.CleanErr = errors.Wrapf(err, "failed to cleanup container %v", ctr.ID()) + } + } + + if options.RemoveImage { + _, imageName := ctr.Image() + ctrImage, err := ic.Libpod.ImageRuntime().NewFromLocal(imageName) + if err != nil { + report.RmiErr = err + reports = append(reports, &report) + continue + } + _, err = ic.Libpod.RemoveImage(ctx, ctrImage, false) + report.RmiErr = err + } + reports = append(reports, &report) + } + return reports, nil +} + +func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []string, options entities.ContainerInitOptions) ([]*entities.ContainerInitReport, error) { + var reports []*entities.ContainerInitReport + ctrs, err := getContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod) + if err != nil { + return nil, err + } + for _, ctr := range ctrs { + report := entities.ContainerInitReport{Id: ctr.ID()} + report.Err = ctr.Init(ctx) + reports = append(reports, &report) + } + return reports, nil +} diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 13abfa2e3..402bbb45e 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -15,6 +15,7 @@ import ( "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/transports/alltransports" "github.com/containers/image/v5/types" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/image" libpodImage "github.com/containers/libpod/libpod/image" "github.com/containers/libpod/pkg/domain/entities" @@ -27,10 +28,11 @@ import ( ) func (ir *ImageEngine) Exists(_ context.Context, nameOrId string) (*entities.BoolReport, error) { - if _, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId); err != nil { - return &entities.BoolReport{}, nil + _, err := ir.Libpod.ImageRuntime().NewFromLocal(nameOrId) + if err != nil && errors.Cause(err) != define.ErrNoSuchImage { + return nil, err } - return &entities.BoolReport{Value: true}, nil + return &entities.BoolReport{Value: err == nil}, nil } func (ir *ImageEngine) Delete(ctx context.Context, nameOrId []string, opts entities.ImageDeleteOptions) (*entities.ImageDeleteReport, error) { @@ -392,8 +394,10 @@ func (ir *ImageEngine) Load(ctx context.Context, opts entities.ImageLoadOptions) if err != nil { return nil, errors.Wrap(err, "image loaded but no additional tags were created") } - if err := newImage.TagImage(opts.Name); err != nil { - return nil, errors.Wrapf(err, "error adding %q to image %q", opts.Name, newImage.InputName) + if len(opts.Name) > 0 { + if err := newImage.TagImage(fmt.Sprintf("%s:%s", opts.Name, opts.Tag)); err != nil { + return nil, errors.Wrapf(err, "error adding %q to image %q", opts.Name, newImage.InputName) + } } return &entities.ImageLoadReport{Name: name}, nil } diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index 8aaa69847..adec94f6c 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -4,10 +4,87 @@ package abi import ( "context" + "net" + "strings" "github.com/containers/libpod/libpod/define" + api "github.com/containers/libpod/pkg/api/server" + "github.com/containers/libpod/pkg/domain/entities" + iopodman "github.com/containers/libpod/pkg/varlink" + iopodmanAPI "github.com/containers/libpod/pkg/varlinkapi" + "github.com/containers/libpod/version" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/varlink/go/varlink" ) func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) { return ic.Libpod.Info() } + +func (ic *ContainerEngine) RestService(_ context.Context, opts entities.ServiceOptions) error { + var ( + listener net.Listener + err error + ) + + if opts.URI != "" { + fields := strings.Split(opts.URI, ":") + if len(fields) == 1 { + return errors.Errorf("%s is an invalid socket destination", opts.URI) + } + address := strings.Join(fields[1:], ":") + listener, err = net.Listen(fields[0], address) + if err != nil { + return errors.Wrapf(err, "unable to create socket %s", opts.URI) + } + } + + server, err := api.NewServerWithSettings(ic.Libpod, opts.Timeout, &listener) + if err != nil { + return err + } + defer func() { + if err := server.Shutdown(); err != nil { + logrus.Warnf("Error when stopping API service: %s", err) + } + }() + + err = server.Serve() + _ = listener.Close() + return err +} + +func (ic *ContainerEngine) VarlinkService(_ context.Context, opts entities.ServiceOptions) error { + var varlinkInterfaces = []*iopodman.VarlinkInterface{ + iopodmanAPI.New(opts.Command, ic.Libpod), + } + + service, err := varlink.NewService( + "Atomic", + "podman", + version.Version, + "https://github.com/containers/libpod", + ) + if err != nil { + return errors.Wrapf(err, "unable to create new varlink service") + } + + for _, i := range varlinkInterfaces { + if err := service.RegisterInterface(i); err != nil { + return errors.Errorf("unable to register varlink interface %v", i) + } + } + + // Run the varlink server at the given address + if err = service.Listen(opts.URI, opts.Timeout); err != nil { + switch err.(type) { + case varlink.ServiceTimeoutError: + logrus.Infof("varlink service expired (use --timeout to increase session time beyond %s ms, 0 means never timeout)", opts.Timeout.String()) + return nil + default: + return errors.Wrapf(err, "unable to start varlink service") + } + } + return nil +} diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index b22c6e3ba..1a430e3d0 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -242,7 +242,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [ } // narrow the list to running only for _, c := range allCtrs { - if c.State == define.ContainerStateRunning.String() { + if c.ContainerState == define.ContainerStateRunning.String() { ctrs = append(ctrs, c) } } @@ -276,7 +276,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st } // narrow the list to exited only for _, c := range allCtrs { - if c.State == define.ContainerStateExited.String() { + if c.ContainerState == define.ContainerStateExited.String() { ctrs = append(ctrs, c) } } @@ -305,6 +305,11 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG return &entities.ContainerCreateReport{Id: response.ID}, nil } +func (ic *ContainerEngine) ContainerLogs(ctx context.Context, containers []string, options entities.ContainerLogsOptions) error { + // The endpoint is not ready yet and requires some more work. + return errors.New("not implemented yet") +} + func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, options entities.AttachOptions) error { return errors.New("not implemented") } @@ -329,3 +334,23 @@ func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrId string, _ changes, err := containers.Diff(ic.ClientCxt, nameOrId) return &entities.DiffReport{Changes: changes}, err } + +func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []string, options entities.ContainerCleanupOptions) ([]*entities.ContainerCleanupReport, error) { + return nil, errors.New("not implemented") +} + +func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []string, options entities.ContainerInitOptions) ([]*entities.ContainerInitReport, error) { + var reports []*entities.ContainerInitReport + ctrs, err := getContainersByContext(ic.ClientCxt, options.All, namesOrIds) + if err != nil { + return nil, err + } + for _, ctr := range ctrs { + err := containers.ContainerInit(ic.ClientCxt, ctr.ID) + reports = append(reports, &entities.ContainerInitReport{ + Err: err, + Id: ctr.ID, + }) + } + return reports, nil +} diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go index 682d60d6a..4d7e45897 100644 --- a/pkg/domain/infra/tunnel/helpers.go +++ b/pkg/domain/infra/tunnel/helpers.go @@ -30,7 +30,7 @@ func getContainersByContext(contextWithConnection context.Context, all bool, nam for _, id := range namesOrIds { var found bool for _, con := range c { - if id == con.ID || strings.HasPrefix(con.ID, id) || util.StringInSlice(id, con.Names) { + if id == con.ID || strings.HasPrefix(con.ID, id) || util.StringInSlice(id, con.ContainerNames) { cons = append(cons, con) found = true break diff --git a/pkg/domain/infra/tunnel/system.go b/pkg/domain/infra/tunnel/system.go index 5d6346234..7c7a55c05 100644 --- a/pkg/domain/infra/tunnel/system.go +++ b/pkg/domain/infra/tunnel/system.go @@ -2,11 +2,21 @@ package tunnel import ( "context" + "errors" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/bindings/system" + "github.com/containers/libpod/pkg/domain/entities" ) func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) { return system.Info(ic.ClientCxt) } + +func (ic *ContainerEngine) RestService(_ context.Context, _ entities.ServiceOptions) error { + panic(errors.New("rest service is not supported when tunneling")) +} + +func (ic *ContainerEngine) VarlinkService(_ context.Context, _ entities.ServiceOptions) error { + panic(errors.New("varlink service is not supported when tunneling")) +} |