diff options
25 files changed, 138 insertions, 86 deletions
@@ -770,20 +770,29 @@ install.docker-full: install.docker install.docker-docs .PHONY: install.systemd ifneq (,$(findstring systemd,$(BUILDTAGS))) -install.systemd: +PODMAN_UNIT_FILES = contrib/systemd/auto-update/podman-auto-update.service \ + contrib/systemd/system/podman.service \ + contrib/systemd/system/podman-restart.service + +%.service: %.service.in + sed -e 's;@@PODMAN@@;$(BINDIR)/podman;g' $< >$@.tmp.$$ \ + && mv -f $@.tmp.$$ $@ + +install.systemd: $(PODMAN_UNIT_FILES) install ${SELINUXOPT} -m 755 -d ${DESTDIR}${SYSTEMDDIR} ${DESTDIR}${USERSYSTEMDDIR} # User services install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service ${DESTDIR}${USERSYSTEMDDIR}/podman-auto-update.service install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer ${DESTDIR}${USERSYSTEMDDIR}/podman-auto-update.timer - install ${SELINUXOPT} -m 644 contrib/systemd/user/podman.socket ${DESTDIR}${USERSYSTEMDDIR}/podman.socket - install ${SELINUXOPT} -m 644 contrib/systemd/user/podman.service ${DESTDIR}${USERSYSTEMDDIR}/podman.service - install ${SELINUXOPT} -m 644 contrib/systemd/user/podman-restart.service ${DESTDIR}${USERSYSTEMDDIR}/podman-restart.service + install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket ${DESTDIR}${USERSYSTEMDDIR}/podman.socket + install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service ${DESTDIR}${USERSYSTEMDDIR}/podman.service + install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service ${DESTDIR}${USERSYSTEMDDIR}/podman-restart.service # System services install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service ${DESTDIR}${SYSTEMDDIR}/podman-auto-update.service install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer ${DESTDIR}${SYSTEMDDIR}/podman-auto-update.timer install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket ${DESTDIR}${SYSTEMDDIR}/podman.socket install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service ${DESTDIR}${SYSTEMDDIR}/podman.service install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service ${DESTDIR}${SYSTEMDDIR}/podman-restart.service + rm -f $(PODMAN_UNIT_FILES) else install.systemd: endif diff --git a/cmd/podman/images/buildx.go b/cmd/podman/images/buildx.go index 5c8e5aaa0..2577a3a74 100644 --- a/cmd/podman/images/buildx.go +++ b/cmd/podman/images/buildx.go @@ -14,11 +14,12 @@ var ( // If we are adding new buildx features, we will add them by default // to podman build. buildxCmd = &cobra.Command{ - Use: "buildx", - Short: "Build images", - Long: "Build images", - RunE: validate.SubCommandExists, - Hidden: true, + Use: "buildx", + Aliases: []string{"builder"}, + Short: "Build images", + Long: "Build images", + RunE: validate.SubCommandExists, + Hidden: true, } ) diff --git a/cmd/podman/images/prune.go b/cmd/podman/images/prune.go index 6c39e5c69..fc7451c41 100644 --- a/cmd/podman/images/prune.go +++ b/cmd/podman/images/prune.go @@ -36,6 +36,11 @@ var ( func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Command: pruneCmd, + Parent: buildxCmd, + }) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: pruneCmd, Parent: imageCmd, }) diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go index 11e54578a..42a998461 100644 --- a/cmd/podman/images/search.go +++ b/cmd/podman/images/search.go @@ -3,6 +3,7 @@ package images import ( "fmt" "os" + "strings" "github.com/containers/common/pkg/auth" "github.com/containers/common/pkg/completion" @@ -79,7 +80,7 @@ func searchFlags(cmd *cobra.Command) { filterFlagName := "filter" flags.StringSliceVarP(&searchOptions.Filters, filterFlagName, "f", []string{}, "Filter output based on conditions provided (default [])") - //TODO add custom filter function + // TODO add custom filter function _ = cmd.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone) formatFlagName := "format" @@ -90,7 +91,7 @@ func searchFlags(cmd *cobra.Command) { flags.IntVar(&searchOptions.Limit, limitFlagName, 0, "Limit the number of results") _ = cmd.RegisterFlagCompletionFunc(limitFlagName, completion.AutocompleteNone) - flags.BoolVar(&searchOptions.NoTrunc, "no-trunc", false, "Do not truncate the output") + flags.Bool("no-trunc", true, "Do not truncate the output. Default: true") authfileFlagName := "authfile" flags.StringVar(&searchOptions.Authfile, authfileFlagName, auth.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") @@ -132,11 +133,20 @@ func imageSearch(cmd *cobra.Command, args []string) error { if err != nil { return err } - if len(searchReport) == 0 { return nil } + noTrunc, _ := cmd.Flags().GetBool("no-trunc") + isJSON := report.IsJSON(searchOptions.Format) + for i, element := range searchReport { + d := strings.ReplaceAll(element.Description, "\n", " ") + if len(d) > 44 && !(noTrunc || isJSON) { + d = strings.TrimSpace(d[:44]) + "..." + } + searchReport[i].Description = d + } + hdrs := report.Headers(entities.ImageSearchReport{}, nil) renderHeaders := true var row string @@ -145,12 +155,12 @@ func imageSearch(cmd *cobra.Command, args []string) error { if len(searchOptions.Filters) != 0 { return errors.Errorf("filters are not applicable to list tags result") } - if report.IsJSON(searchOptions.Format) { + if isJSON { listTagsEntries := buildListTagsJSON(searchReport) return printArbitraryJSON(listTagsEntries) } row = "{{.Name}}\t{{.Tag}}\n" - case report.IsJSON(searchOptions.Format): + case isJSON: return printArbitraryJSON(searchReport) case cmd.Flags().Changed("format"): renderHeaders = report.HasTable(searchOptions.Format) @@ -190,7 +200,7 @@ func printArbitraryJSON(v interface{}) error { } func buildListTagsJSON(searchReport []entities.ImageSearchReport) []listEntryTag { - entries := []listEntryTag{} + entries := make([]listEntryTag, 0) ReportLoop: for _, report := range searchReport { diff --git a/cmd/podman/system/service_abi.go b/cmd/podman/system/service_abi.go index 0a4be6aea..b9bd7538f 100644 --- a/cmd/podman/system/service_abi.go +++ b/cmd/podman/system/service_abi.go @@ -93,7 +93,7 @@ func restService(flags *pflag.FlagSet, cfg *entities.PodmanConfig, opts entities return err } defer func() { - if err := server.Shutdown(false); err != nil { + if err := server.Shutdown(true); err != nil { logrus.Warnf("Error when stopping API service: %s", err) } }() diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index fa513932f..3a4026038 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -435,7 +435,7 @@ BUILDTAGS=$BUILDTAGS make binaries %install install -dp %{buildroot}%{_unitdir} install -dp %{buildroot}%{_usr}/lib/systemd/user -PODMAN_VERSION=%{version} %{__make} PREFIX=%{buildroot}%{_prefix} ETCDIR=%{buildroot}%{_sysconfdir} \ +PODMAN_VERSION=%{version} %{__make} DESTDIR=%{buildroot} PREFIX=%{_prefix} ETCDIR=%{_sysconfdir} \ install.bin-nobuild \ install.remote-nobuild \ %if %{with doc} diff --git a/contrib/systemd/auto-update/podman-auto-update.service b/contrib/systemd/auto-update/podman-auto-update.service.in index dc5fac8cf..de4460d60 100644 --- a/contrib/systemd/auto-update/podman-auto-update.service +++ b/contrib/systemd/auto-update/podman-auto-update.service.in @@ -6,8 +6,8 @@ After=network-online.target [Service] Type=oneshot -ExecStart=/usr/bin/podman auto-update -ExecStartPost=/usr/bin/podman image prune -f +ExecStart=@@PODMAN@@ auto-update +ExecStartPost=@@PODMAN@@ image prune -f [Install] WantedBy=multi-user.target default.target diff --git a/contrib/systemd/system/podman-restart.service b/contrib/systemd/system/podman-restart.service.in index baf12b3ae..a2951e111 100644 --- a/contrib/systemd/system/podman-restart.service +++ b/contrib/systemd/system/podman-restart.service.in @@ -6,7 +6,7 @@ StartLimitIntervalSec=0 [Service] Type=oneshot Environment=LOGGING="--log-level=info" -ExecStart=/usr/bin/podman $LOGGING start --all --filter restart-policy=always +ExecStart=@@PODMAN@@ $LOGGING start --all --filter restart-policy=always [Install] WantedBy=multi-user.target diff --git a/contrib/systemd/system/podman.service b/contrib/systemd/system/podman.service.in index cefb13ae3..132671dff 100644 --- a/contrib/systemd/system/podman.service +++ b/contrib/systemd/system/podman.service.in @@ -9,7 +9,7 @@ StartLimitIntervalSec=0 Type=exec KillMode=process Environment=LOGGING="--log-level=info" -ExecStart=/usr/bin/podman $LOGGING system service +ExecStart=@@PODMAN@@ $LOGGING system service [Install] WantedBy=multi-user.target diff --git a/docs/source/markdown/podman-search.1.md b/docs/source/markdown/podman-search.1.md index d541e5c93..c3729aa26 100644 --- a/docs/source/markdown/podman-search.1.md +++ b/docs/source/markdown/podman-search.1.md @@ -81,7 +81,7 @@ The result contains the Image name and its tag, one line for every tag associate #### **--no-trunc** -Do not truncate the output (default *false*). +Do not truncate the output (default *true*). #### **--tls-verify** diff --git a/libpod/runtime_volume_linux.go b/libpod/runtime_volume_linux.go index b08693529..ed3cc971c 100644 --- a/libpod/runtime_volume_linux.go +++ b/libpod/runtime_volume_linux.go @@ -230,11 +230,7 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo logrus.Debugf("Removing container %s (depends on volume %q)", ctr.ID(), v.Name()) - // TODO: do we want to set force here when removing - // containers? - // I'm inclined to say no, in case someone accidentally - // wipes a container they're using... - if err := r.removeContainer(ctx, ctr, false, false, false, timeout); err != nil { + if err := r.removeContainer(ctx, ctr, force, false, false, timeout); err != nil { return errors.Wrapf(err, "error removing container %s that depends on volume %s", ctr.ID(), v.Name()) } } diff --git a/libpod/shutdown/handler.go b/libpod/shutdown/handler.go index b0feafa0b..9add05c9c 100644 --- a/libpod/shutdown/handler.go +++ b/libpod/shutdown/handler.go @@ -5,9 +5,10 @@ import ( "os/signal" "sync" "syscall" + "time" "github.com/pkg/errors" - "github.com/sirupsen/logrus" + logrusImport "github.com/sirupsen/logrus" ) var ( @@ -25,6 +26,7 @@ var ( // Ordering that on-shutdown handlers will be invoked. handlerOrder []string shutdownInhibit sync.RWMutex + logrus = logrusImport.WithField("PID", os.Getpid()) ) // Start begins handling SIGTERM and SIGINT and will run the given on-signal @@ -44,25 +46,31 @@ func Start() error { go func() { select { case <-cancelChan: + logrus.Infof("Received shutdown.Stop(), terminating!") signal.Stop(sigChan) close(sigChan) close(cancelChan) stopped = true return case sig := <-sigChan: - logrus.Infof("Received shutdown signal %v, terminating!", sig) + logrus.Infof("Received shutdown signal %q, terminating!", sig.String()) shutdownInhibit.Lock() handlerLock.Lock() + for _, name := range handlerOrder { handler, ok := handlers[name] if !ok { - logrus.Errorf("Shutdown handler %s definition not found!", name) + logrus.Errorf("Shutdown handler %q definition not found!", name) continue } - logrus.Infof("Invoking shutdown handler %s", name) + + logrus.Infof("Invoking shutdown handler %q", name) + start := time.Now() if err := handler(sig); err != nil { - logrus.Errorf("Running shutdown handler %s: %v", name, err) + logrus.Errorf("Running shutdown handler %q: %v", name, err) } + logrus.Debugf("Completed shutdown handler %q, duration %v", name, + time.Since(start).Round(time.Second)) } handlerLock.Unlock() shutdownInhibit.Unlock() diff --git a/pkg/api/handlers/compat/images_search.go b/pkg/api/handlers/compat/images_search.go index 01282513e..e9cc3e2b6 100644 --- a/pkg/api/handlers/compat/images_search.go +++ b/pkg/api/handlers/compat/images_search.go @@ -22,7 +22,6 @@ func SearchImages(w http.ResponseWriter, r *http.Request) { query := struct { Term string `json:"term"` Limit int `json:"limit"` - NoTrunc bool `json:"noTrunc"` Filters map[string][]string `json:"filters"` TLSVerify bool `json:"tlsVerify"` ListTags bool `json:"listTags"` @@ -50,7 +49,6 @@ func SearchImages(w http.ResponseWriter, r *http.Request) { options := entities.ImageSearchOptions{ Authfile: authfile, Limit: query.Limit, - NoTrunc: query.NoTrunc, ListTags: query.ListTags, Filters: filters, } diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index aa573eaa6..95a8b4939 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -1090,10 +1090,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // default: 25 // description: maximum number of results // - in: query - // name: noTrunc - // type: boolean - // description: do not truncate any of the result strings - // - in: query // name: filters // type: string // description: | diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index 6e9578cd1..8c5c7aeeb 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -207,7 +207,7 @@ func (s *APIServer) setupSystemd() { func (s *APIServer) Serve() error { s.setupPprof() - if err := shutdown.Register("server", func(sig os.Signal) error { + if err := shutdown.Register("service", func(sig os.Signal) error { return s.Shutdown(true) }); err != nil { return err @@ -272,20 +272,24 @@ func (s *APIServer) setupPprof() { // Shutdown is a clean shutdown waiting on existing clients func (s *APIServer) Shutdown(halt bool) error { - if s.idleTracker.Duration == UnlimitedServiceDuration && !halt { - logrus.Debug("API service shutdown request ignored as Duration is UnlimitedService") + switch { + case halt: + logrus.Debug("API service forced shutdown, ignoring timeout Duration") + case s.idleTracker.Duration == UnlimitedServiceDuration: + logrus.Debug("API service shutdown request ignored as timeout Duration is UnlimitedService") return nil } shutdownOnce.Do(func() { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - _, file, line, _ := runtime.Caller(1) - logrus.Debugf("API service shutdown by %s:%d, %d/%d connection(s)", - file, line, s.idleTracker.ActiveConnections(), s.idleTracker.TotalConnections()) - } + logrus.Debugf("API service shutdown, %d/%d connection(s)", + s.idleTracker.ActiveConnections(), s.idleTracker.TotalConnections()) // Gracefully shutdown server(s), duration of wait same as idle window - ctx, cancel := context.WithTimeout(context.Background(), s.idleTracker.Duration) + deadline := 1 * time.Second + if s.idleTracker.Duration > 0 { + deadline = s.idleTracker.Duration + } + ctx, cancel := context.WithTimeout(context.Background(), deadline) go func() { defer cancel() @@ -296,7 +300,6 @@ func (s *APIServer) Shutdown(halt bool) error { }() <-ctx.Done() }) - return nil } diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go index dc6bd91c3..a44a3527f 100644 --- a/pkg/bindings/images/types.go +++ b/pkg/bindings/images/types.go @@ -133,8 +133,6 @@ type SearchOptions struct { Filters map[string][]string // Limit the number of results. Limit *int - // NoTrunc will not truncate the output. - NoTrunc *bool // SkipTLSVerify to skip HTTPS and certificate verification. SkipTLSVerify *bool // ListTags search the available tags of the repository diff --git a/pkg/bindings/images/types_search_options.go b/pkg/bindings/images/types_search_options.go index e38ef9fb1..4424f1504 100644 --- a/pkg/bindings/images/types_search_options.go +++ b/pkg/bindings/images/types_search_options.go @@ -62,21 +62,6 @@ func (o *SearchOptions) GetLimit() int { return *o.Limit } -// WithNoTrunc set field NoTrunc to given value -func (o *SearchOptions) WithNoTrunc(value bool) *SearchOptions { - o.NoTrunc = &value - return o -} - -// GetNoTrunc returns value of field NoTrunc -func (o *SearchOptions) GetNoTrunc() bool { - if o.NoTrunc == nil { - var z bool - return z - } - return *o.NoTrunc -} - // WithSkipTLSVerify set field SkipTLSVerify to given value func (o *SearchOptions) WithSkipTLSVerify(value bool) *SearchOptions { o.SkipTLSVerify = &value diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index 4bb8de69b..f1ef538e4 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -129,8 +129,8 @@ func init() { func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) ([]controller, error) { if cgroup2 { controllers := []controller{} - subtreeControl := cgroupRoot + "/cgroup.subtree_control" - // rootless cgroupv2: check available controllers for current user ,systemd or servicescope will inherit + controllersFile := cgroupRoot + "/cgroup.controllers" + // rootless cgroupv2: check available controllers for current user, systemd or servicescope will inherit if rootless.IsRootless() { userSlice, err := getCgroupPathForCurrentProcess() if err != nil { @@ -138,13 +138,13 @@ func getAvailableControllers(exclude map[string]controllerHandler, cgroup2 bool) } //userSlice already contains '/' so not adding here basePath := cgroupRoot + userSlice - subtreeControl = fmt.Sprintf("%s/cgroup.subtree_control", basePath) + controllersFile = fmt.Sprintf("%s/cgroup.controllers", basePath) } - subtreeControlBytes, err := ioutil.ReadFile(subtreeControl) + controllersFileBytes, err := ioutil.ReadFile(controllersFile) if err != nil { - return nil, errors.Wrapf(err, "failed while reading controllers for cgroup v2 from %q", subtreeControl) + return nil, errors.Wrapf(err, "failed while reading controllers for cgroup v2 from %q", controllersFile) } - for _, controllerName := range strings.Fields(string(subtreeControlBytes)) { + for _, controllerName := range strings.Fields(string(controllersFileBytes)) { c := controller{ name: controllerName, symlink: false, diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index 2822b1ad7..ac5e6f410 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -218,8 +218,6 @@ type ImageSearchOptions struct { Filters []string // Limit the number of results. Limit int - // NoTrunc will not truncate the output. - NoTrunc bool // SkipTLSVerify to skip HTTPS and certificate verification. SkipTLSVerify types.OptionalBool // ListTags search the available tags of the repository diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 8a0b87cab..d2222c017 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -417,6 +417,7 @@ func (ir *ImageEngine) Import(ctx context.Context, options entities.ImageImportO return &entities.ImageImportReport{Id: imageID}, nil } +// Search for images using term and filters func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.ImageSearchOptions) ([]entities.ImageSearchReport, error) { filter, err := libimage.ParseSearchFilter(opts.Filters) if err != nil { @@ -427,7 +428,7 @@ func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.Im Authfile: opts.Authfile, Filter: *filter, Limit: opts.Limit, - NoTrunc: opts.NoTrunc, + NoTrunc: true, InsecureSkipTLSVerify: opts.SkipTLSVerify, ListTags: opts.ListTags, } @@ -454,7 +455,7 @@ func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.Im return reports, nil } -// GetConfig returns a copy of the configuration used by the runtime +// Config returns a copy of the configuration used by the runtime func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) { return ir.Libpod.GetConfig() } diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index d41a20348..b8af2de68 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -12,7 +12,7 @@ import ( "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/types" - images "github.com/containers/podman/v3/pkg/bindings/images" + "github.com/containers/podman/v3/pkg/bindings/images" "github.com/containers/podman/v3/pkg/domain/entities" "github.com/containers/podman/v3/pkg/domain/entities/reports" "github.com/containers/podman/v3/pkg/domain/utils" @@ -323,7 +323,7 @@ func (ir *ImageEngine) Search(ctx context.Context, term string, opts entities.Im options := new(images.SearchOptions) options.WithAuthfile(opts.Authfile).WithFilters(mappedFilters).WithLimit(opts.Limit) - options.WithListTags(opts.ListTags).WithNoTrunc(opts.NoTrunc) + options.WithListTags(opts.ListTags) if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined { if s == types.OptionalBoolTrue { options.WithSkipTLSVerify(true) diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index b4ec7447e..56af64f04 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -446,4 +446,25 @@ RUN > file2 }) + It("podman builder prune", func() { + dockerfile := `FROM quay.io/libpod/alpine:latest +RUN > file +` + dockerfile2 := `FROM quay.io/libpod/alpine:latest +RUN > file2 +` + podmanTest.BuildImageWithLabel(dockerfile, "foobar.com/workdir:latest", "false", "abc") + podmanTest.BuildImageWithLabel(dockerfile2, "foobar.com/workdir:latest", "false", "xyz") + // --force used to to avoid y/n question + result := podmanTest.Podman([]string{"builder", "prune", "--filter", "label=abc", "--force"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(len(result.OutputToStringArray())).To(Equal(1)) + + //check if really abc is removed + result = podmanTest.Podman([]string{"image", "list", "--filter", "label=abc"}) + Expect(len(result.OutputToStringArray())).To(Equal(0)) + + }) + }) diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index f82c3d9d1..243b1a307 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -2,6 +2,7 @@ package integration import ( "bytes" + "encoding/json" "fmt" "io/ioutil" "os" @@ -9,6 +10,7 @@ import ( "strconv" "text/template" + "github.com/containers/podman/v3/pkg/domain/entities" . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -123,6 +125,15 @@ registries = ['{{.Host}}:{{.Port}}']` Expect(search).Should(Exit(0)) Expect(search.IsJSONOutputValid()).To(BeTrue()) Expect(search.OutputToString()).To(ContainSubstring("docker.io/library/alpine")) + + // Test for https://github.com/containers/podman/issues/11894 + contents := make([]entities.ImageSearchReport, 0) + err := json.Unmarshal(search.Out.Contents(), &contents) + Expect(err).ToNot(HaveOccurred()) + Expect(len(contents)).To(BeNumerically(">", 0), "No results from image search") + for _, element := range contents { + Expect(element.Description).ToNot(HaveSuffix("...")) + } }) It("podman search format json list tags", func() { @@ -135,13 +146,17 @@ registries = ['{{.Host}}:{{.Port}}']` Expect(search.OutputToString()).To(ContainSubstring("2.7")) }) - It("podman search no-trunc flag", func() { - search := podmanTest.Podman([]string{"search", "--no-trunc", "alpine"}) + // Test for https://github.com/containers/podman/issues/11894 + It("podman search no-trunc=false flag", func() { + search := podmanTest.Podman([]string{"search", "--no-trunc=false", "alpine", "--format={{.Description}}"}) search.WaitWithDefaultTimeout() Expect(search).Should(Exit(0)) - Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 1)) - Expect(search.LineInOutputContains("docker.io/library/alpine")).To(BeTrue()) - Expect(search.LineInOutputContains("...")).To(BeFalse()) + + for _, line := range search.OutputToStringArray() { + if len(line) > 44 { + Expect(line).To(HaveSuffix("..."), line+" should have been truncated") + } + } }) It("podman search limit flag", func() { diff --git a/test/e2e/system_service_test.go b/test/e2e/system_service_test.go index 684ac56b4..9a4d687c3 100644 --- a/test/e2e/system_service_test.go +++ b/test/e2e/system_service_test.go @@ -65,7 +65,7 @@ var _ = Describe("podman system service", func() { pprofPort := randomPort() session := podmanTest.Podman([]string{ - "system", "service", "--log-level=info", "--time=0", + "system", "service", "--log-level=debug", "--time=0", "--pprof-address=localhost:" + pprofPort, address.String(), }) defer session.Kill() @@ -91,7 +91,7 @@ var _ = Describe("podman system service", func() { Expect(body).ShouldNot(BeEmpty()) session.Interrupt().Wait(2 * time.Second) - Eventually(session, 2).Should(Exit(1)) + Eventually(session).Should(Exit(1)) }) It("are not available", func() { @@ -103,7 +103,7 @@ var _ = Describe("podman system service", func() { } session := podmanTest.Podman([]string{ - "system", "service", "--log-level=info", "--time=0", address.String(), + "system", "service", "--log-level=debug", "--time=0", address.String(), }) defer session.Kill() @@ -113,7 +113,7 @@ var _ = Describe("podman system service", func() { Expect(session.Err.Contents()).ShouldNot(ContainSubstring(magicComment)) session.Interrupt().Wait(2 * time.Second) - Eventually(session, 2).Should(Exit(1)) + Eventually(session).Should(Exit(1)) }) }) }) diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats index 490d635e5..7128f1b65 100644 --- a/test/system/160-volumes.bats +++ b/test/system/160-volumes.bats @@ -97,6 +97,14 @@ Labels.l | $mylabel run_podman volume rm $myvolume } +# Removing volumes with --force +@test "podman volume rm --force" { + run_podman run -d --volume myvol:/myvol $IMAGE top + cid=$output + run_podman 2 volume rm myvol + is "$output" "Error: volume myvol is being used by the following container(s): $cid: volume is being used" "should error since container is running" + run_podman volume rm myvol --force +} # Running scripts (executables) from a volume @test "podman volume: exec/noexec" { |