mirror of
https://github.com/containers/podman.git
synced 2025-06-21 01:19:15 +08:00
Restore --format table support
* system df * events * fix error handling from go routine * update tests to use gomega matchers for better error messages * system info * version * volume inspect Signed-off-by: Jhon Honce <jhonce@redhat.com>
This commit is contained in:
@ -11,7 +11,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
tm "github.com/buger/goterm"
|
tm "github.com/buger/goterm"
|
||||||
"github.com/containers/buildah/pkg/formats"
|
|
||||||
"github.com/containers/podman/v2/cmd/podman/parse"
|
"github.com/containers/podman/v2/cmd/podman/parse"
|
||||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v2/cmd/podman/report"
|
"github.com/containers/podman/v2/cmd/podman/report"
|
||||||
@ -93,7 +92,7 @@ func checkFlags(c *cobra.Command) error {
|
|||||||
if listOpts.Size || listOpts.Namespace {
|
if listOpts.Size || listOpts.Namespace {
|
||||||
return errors.Errorf("quiet conflicts with size and namespace")
|
return errors.Errorf("quiet conflicts with size and namespace")
|
||||||
}
|
}
|
||||||
if c.Flag("format").Changed && listOpts.Format != formats.JSONString {
|
if c.Flag("format").Changed && !parse.MatchesJSONFormat(listOpts.Format) {
|
||||||
// Quiet is overridden by Go template output.
|
// Quiet is overridden by Go template output.
|
||||||
listOpts.Quiet = false
|
listOpts.Quiet = false
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package parse
|
|||||||
|
|
||||||
import "regexp"
|
import "regexp"
|
||||||
|
|
||||||
var jsonFormatRegex = regexp.MustCompile(`^\s*(json|{{\s*json\s*( \.)?\s*}})\s*$`)
|
var jsonFormatRegex = regexp.MustCompile(`^\s*(json|{{\s*json\s*(\.)?\s*}})\s*$`)
|
||||||
|
|
||||||
// MatchesJSONFormat test CLI --format string to be a JSON request
|
// MatchesJSONFormat test CLI --format string to be a JSON request
|
||||||
func MatchesJSONFormat(s string) bool {
|
func MatchesJSONFormat(s string) bool {
|
||||||
|
@ -27,7 +27,7 @@ func TestMatchesJSONFormat(t *testing.T) {
|
|||||||
{"json . }}", false},
|
{"json . }}", false},
|
||||||
{"{{.ID }} json .", false},
|
{"{{.ID }} json .", false},
|
||||||
{"json .", false},
|
{"json .", false},
|
||||||
{"{{json.}}", false},
|
{"{{json.}}", true},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@ -2,15 +2,14 @@ package system
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||||
|
"github.com/containers/podman/v2/cmd/podman/report"
|
||||||
"github.com/containers/podman/v2/cmd/podman/validate"
|
"github.com/containers/podman/v2/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
@ -52,35 +51,21 @@ func df(cmd *cobra.Command, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
|
||||||
|
|
||||||
if dfOptions.Verbose {
|
if dfOptions.Verbose {
|
||||||
return printVerbose(reports)
|
return printVerbose(cmd, w, reports)
|
||||||
}
|
}
|
||||||
return printSummary(reports, dfOptions.Format)
|
return printSummary(w, cmd, reports)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printSummary(reports *entities.SystemDfReport, userFormat string) error {
|
func printSummary(w *tabwriter.Writer, cmd *cobra.Command, reports *entities.SystemDfReport) error {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dfSummaries []*dfSummary
|
dfSummaries []*dfSummary
|
||||||
active int
|
active int
|
||||||
size, reclaimable int64
|
size, reclaimable int64
|
||||||
format = "{{.Type}}\t{{.Total}}\t{{.Active}}\t{{.Size}}\t{{.Reclaimable}}\n"
|
|
||||||
w io.Writer = os.Stdout
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Images
|
|
||||||
if len(userFormat) > 0 {
|
|
||||||
if !strings.HasSuffix(userFormat, `\n`) {
|
|
||||||
userFormat += `\n`
|
|
||||||
}
|
|
||||||
// should be Unquoto from cmd line
|
|
||||||
userFormat, err := strconv.Unquote(`"` + userFormat + `"`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
format = userFormat
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, i := range reports.Images {
|
for _, i := range reports.Images {
|
||||||
if i.Containers > 0 {
|
if i.Containers > 0 {
|
||||||
active++
|
active++
|
||||||
@ -90,7 +75,6 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
|
|||||||
reclaimable += i.Size
|
reclaimable += i.Size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imageSummary := dfSummary{
|
imageSummary := dfSummary{
|
||||||
Type: "Images",
|
Type: "Images",
|
||||||
Total: len(reports.Images),
|
Total: len(reports.Images),
|
||||||
@ -101,7 +85,6 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
|
|||||||
dfSummaries = append(dfSummaries, &imageSummary)
|
dfSummaries = append(dfSummaries, &imageSummary)
|
||||||
|
|
||||||
// Containers
|
// Containers
|
||||||
|
|
||||||
var (
|
var (
|
||||||
conActive int
|
conActive int
|
||||||
conSize, conReclaimable int64
|
conSize, conReclaimable int64
|
||||||
@ -114,7 +97,6 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
|
|||||||
}
|
}
|
||||||
conSize += c.RWSize
|
conSize += c.RWSize
|
||||||
}
|
}
|
||||||
|
|
||||||
containerSummary := dfSummary{
|
containerSummary := dfSummary{
|
||||||
Type: "Containers",
|
Type: "Containers",
|
||||||
Total: len(reports.Containers),
|
Total: len(reports.Containers),
|
||||||
@ -122,7 +104,6 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
|
|||||||
size: conSize,
|
size: conSize,
|
||||||
reclaimable: conReclaimable,
|
reclaimable: conReclaimable,
|
||||||
}
|
}
|
||||||
|
|
||||||
dfSummaries = append(dfSummaries, &containerSummary)
|
dfSummaries = append(dfSummaries, &containerSummary)
|
||||||
|
|
||||||
// Volumes
|
// Volumes
|
||||||
@ -143,78 +124,94 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error {
|
|||||||
size: volumesSize,
|
size: volumesSize,
|
||||||
reclaimable: volumesReclaimable,
|
reclaimable: volumesReclaimable,
|
||||||
}
|
}
|
||||||
|
|
||||||
dfSummaries = append(dfSummaries, &volumeSummary)
|
dfSummaries = append(dfSummaries, &volumeSummary)
|
||||||
|
|
||||||
headers := "TYPE\tTOTAL\tACTIVE\tSIZE\tRECLAIMABLE\n"
|
// need to give un-exported fields
|
||||||
format = "{{range . }}" + format + "{{end}}"
|
hdrs := report.Headers(dfSummary{}, map[string]string{
|
||||||
if len(userFormat) == 0 {
|
"Size": "SIZE",
|
||||||
format = headers + format
|
"Reclaimable": "RECLAIMABLE",
|
||||||
|
})
|
||||||
|
|
||||||
|
row := "{{.Type}}\t{{.Total}}\t{{.Active}}\t{{.Size}}\t{{.Reclaimable}}\n"
|
||||||
|
if cmd.Flags().Changed("format") {
|
||||||
|
row = report.NormalizeFormat(dfOptions.Format)
|
||||||
}
|
}
|
||||||
return writeTemplate(w, format, dfSummaries)
|
row = "{{range . }}" + row + "{{end}}"
|
||||||
|
|
||||||
|
return writeTemplate(cmd, w, hdrs, row, dfSummaries)
|
||||||
}
|
}
|
||||||
|
|
||||||
func printVerbose(reports *entities.SystemDfReport) error {
|
func printVerbose(cmd *cobra.Command, w *tabwriter.Writer, reports *entities.SystemDfReport) error {
|
||||||
var (
|
defer w.Flush()
|
||||||
w io.Writer = os.Stdout
|
|
||||||
)
|
|
||||||
|
|
||||||
// Images
|
// Images
|
||||||
fmt.Print("\nImages space usage:\n\n")
|
fmt.Fprint(w, "Images space usage:\n\n")
|
||||||
// convert to dfImage for output
|
// convert to dfImage for output
|
||||||
dfImages := make([]*dfImage, 0, len(reports.Images))
|
dfImages := make([]*dfImage, 0, len(reports.Images))
|
||||||
for _, d := range reports.Images {
|
for _, d := range reports.Images {
|
||||||
dfImages = append(dfImages, &dfImage{SystemDfImageReport: d})
|
dfImages = append(dfImages, &dfImage{SystemDfImageReport: d})
|
||||||
}
|
}
|
||||||
imageHeaders := "REPOSITORY\tTAG\tIMAGE ID\tCREATED\tSIZE\tSHARED SIZE\tUNIQUE SIZE\tCONTAINERS\n"
|
hdrs := report.Headers(entities.SystemDfImageReport{}, map[string]string{
|
||||||
|
"ImageID": "IMAGE ID",
|
||||||
|
"SharedSize": "SHARED SIZE",
|
||||||
|
"UniqueSize": "UNIQUE SIZE",
|
||||||
|
})
|
||||||
imageRow := "{{.Repository}}\t{{.Tag}}\t{{.ImageID}}\t{{.Created}}\t{{.Size}}\t{{.SharedSize}}\t{{.UniqueSize}}\t{{.Containers}}\n"
|
imageRow := "{{.Repository}}\t{{.Tag}}\t{{.ImageID}}\t{{.Created}}\t{{.Size}}\t{{.SharedSize}}\t{{.UniqueSize}}\t{{.Containers}}\n"
|
||||||
format := imageHeaders + "{{range . }}" + imageRow + "{{end}}"
|
format := "{{range . }}" + imageRow + "{{end}}"
|
||||||
if err := writeTemplate(w, format, dfImages); err != nil {
|
if err := writeTemplate(cmd, w, hdrs, format, dfImages); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Containers
|
// Containers
|
||||||
fmt.Print("\nContainers space usage:\n\n")
|
fmt.Fprint(w, "\nContainers space usage:\n\n")
|
||||||
|
|
||||||
// convert to dfContainers for output
|
// convert to dfContainers for output
|
||||||
dfContainers := make([]*dfContainer, 0, len(reports.Containers))
|
dfContainers := make([]*dfContainer, 0, len(reports.Containers))
|
||||||
for _, d := range reports.Containers {
|
for _, d := range reports.Containers {
|
||||||
dfContainers = append(dfContainers, &dfContainer{SystemDfContainerReport: d})
|
dfContainers = append(dfContainers, &dfContainer{SystemDfContainerReport: d})
|
||||||
}
|
}
|
||||||
containerHeaders := "CONTAINER ID\tIMAGE\tCOMMAND\tLOCAL VOLUMES\tSIZE\tCREATED\tSTATUS\tNAMES\n"
|
hdrs = report.Headers(entities.SystemDfContainerReport{}, map[string]string{
|
||||||
|
"ContainerID": "CONTAINER ID",
|
||||||
|
"LocalVolumes": "LOCAL VOLUMES",
|
||||||
|
"RWSize": "SIZE",
|
||||||
|
})
|
||||||
containerRow := "{{.ContainerID}}\t{{.Image}}\t{{.Command}}\t{{.LocalVolumes}}\t{{.RWSize}}\t{{.Created}}\t{{.Status}}\t{{.Names}}\n"
|
containerRow := "{{.ContainerID}}\t{{.Image}}\t{{.Command}}\t{{.LocalVolumes}}\t{{.RWSize}}\t{{.Created}}\t{{.Status}}\t{{.Names}}\n"
|
||||||
format = containerHeaders + "{{range . }}" + containerRow + "{{end}}"
|
format = "{{range . }}" + containerRow + "{{end}}"
|
||||||
if err := writeTemplate(w, format, dfContainers); err != nil {
|
if err := writeTemplate(cmd, w, hdrs, format, dfContainers); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volumes
|
// Volumes
|
||||||
fmt.Print("\nLocal Volumes space usage:\n\n")
|
fmt.Fprint(w, "\nLocal Volumes space usage:\n\n")
|
||||||
|
|
||||||
dfVolumes := make([]*dfVolume, 0, len(reports.Volumes))
|
dfVolumes := make([]*dfVolume, 0, len(reports.Volumes))
|
||||||
// convert to dfVolume for output
|
// convert to dfVolume for output
|
||||||
for _, d := range reports.Volumes {
|
for _, d := range reports.Volumes {
|
||||||
dfVolumes = append(dfVolumes, &dfVolume{SystemDfVolumeReport: d})
|
dfVolumes = append(dfVolumes, &dfVolume{SystemDfVolumeReport: d})
|
||||||
}
|
}
|
||||||
volumeHeaders := "VOLUME NAME\tLINKS\tSIZE\n"
|
hdrs = report.Headers(entities.SystemDfVolumeReport{}, map[string]string{
|
||||||
|
"VolumeName": "VOLUME NAME",
|
||||||
|
})
|
||||||
volumeRow := "{{.VolumeName}}\t{{.Links}}\t{{.Size}}\n"
|
volumeRow := "{{.VolumeName}}\t{{.Links}}\t{{.Size}}\n"
|
||||||
format = volumeHeaders + "{{range . }}" + volumeRow + "{{end}}"
|
format = "{{range . }}" + volumeRow + "{{end}}"
|
||||||
return writeTemplate(w, format, dfVolumes)
|
return writeTemplate(cmd, w, hdrs, format, dfVolumes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeTemplate(w io.Writer, format string, output interface{}) error {
|
func writeTemplate(cmd *cobra.Command, w *tabwriter.Writer, hdrs []map[string]string, format string,
|
||||||
tmpl, err := template.New("dfout").Parse(format)
|
output interface{}) error {
|
||||||
|
defer w.Flush()
|
||||||
|
|
||||||
|
tmpl, err := template.New("df").Parse(format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w = tabwriter.NewWriter(w, 8, 2, 2, ' ', 0) //nolint
|
|
||||||
if err := tmpl.Execute(w, output); err != nil {
|
if !cmd.Flags().Changed("format") {
|
||||||
return err
|
if err := tmpl.Execute(w, hdrs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if flusher, ok := w.(interface{ Flush() error }); ok {
|
return tmpl.Execute(w, output)
|
||||||
return flusher.Flush()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type dfImage struct {
|
type dfImage struct {
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/containers/buildah/pkg/formats"
|
"github.com/containers/podman/v2/cmd/podman/parse"
|
||||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v2/cmd/podman/validate"
|
"github.com/containers/podman/v2/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v2/libpod/events"
|
"github.com/containers/podman/v2/libpod/events"
|
||||||
@ -28,6 +27,7 @@ var (
|
|||||||
RunE: eventsCmd,
|
RunE: eventsCmd,
|
||||||
Example: `podman events
|
Example: `podman events
|
||||||
podman events --filter event=create
|
podman events --filter event=create
|
||||||
|
podman events --format {{.Image}}
|
||||||
podman events --since 1h30s`,
|
podman events --since 1h30s`,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -51,60 +51,54 @@ func init() {
|
|||||||
_ = flags.MarkHidden("stream")
|
_ = flags.MarkHidden("stream")
|
||||||
}
|
}
|
||||||
|
|
||||||
func eventsCmd(cmd *cobra.Command, args []string) error {
|
func eventsCmd(cmd *cobra.Command, _ []string) error {
|
||||||
var (
|
|
||||||
err error
|
|
||||||
eventsError error
|
|
||||||
tmpl *template.Template
|
|
||||||
)
|
|
||||||
if strings.Join(strings.Fields(eventFormat), "") == "{{json.}}" {
|
|
||||||
eventFormat = formats.JSONString
|
|
||||||
}
|
|
||||||
if eventFormat != formats.JSONString {
|
|
||||||
tmpl, err = template.New("events").Parse(eventFormat)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(eventOptions.Since) > 0 || len(eventOptions.Until) > 0 {
|
if len(eventOptions.Since) > 0 || len(eventOptions.Until) > 0 {
|
||||||
eventOptions.FromStart = true
|
eventOptions.FromStart = true
|
||||||
}
|
}
|
||||||
eventChannel := make(chan *events.Event)
|
eventChannel := make(chan *events.Event, 1)
|
||||||
eventOptions.EventChan = eventChannel
|
eventOptions.EventChan = eventChannel
|
||||||
|
errChannel := make(chan error)
|
||||||
|
|
||||||
go func() {
|
var (
|
||||||
eventsError = registry.ContainerEngine().Events(context.Background(), eventOptions)
|
tmpl *template.Template
|
||||||
}()
|
doJSON bool
|
||||||
if eventsError != nil {
|
)
|
||||||
return eventsError
|
|
||||||
|
if cmd.Flags().Changed("format") {
|
||||||
|
doJSON = parse.MatchesJSONFormat(eventFormat)
|
||||||
|
if !doJSON {
|
||||||
|
var err error
|
||||||
|
tmpl, err = template.New("events").Parse(eventFormat)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w := bufio.NewWriter(os.Stdout)
|
go func() {
|
||||||
|
err := registry.ContainerEngine().Events(context.Background(), eventOptions)
|
||||||
|
errChannel <- err
|
||||||
|
}()
|
||||||
|
|
||||||
for event := range eventChannel {
|
for event := range eventChannel {
|
||||||
switch {
|
switch {
|
||||||
case eventFormat == formats.JSONString:
|
case event == nil:
|
||||||
|
// no-op
|
||||||
|
case doJSON:
|
||||||
jsonStr, err := event.ToJSONString()
|
jsonStr, err := event.ToJSONString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "unable to format json")
|
return errors.Wrapf(err, "unable to format json")
|
||||||
}
|
}
|
||||||
if _, err := w.Write([]byte(jsonStr)); err != nil {
|
fmt.Println(jsonStr)
|
||||||
return err
|
case cmd.Flags().Changed("format"):
|
||||||
}
|
if err := tmpl.Execute(os.Stdout, event); err != nil {
|
||||||
case len(eventFormat) > 0:
|
|
||||||
if err := tmpl.Execute(w, event); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fmt.Println("")
|
||||||
default:
|
default:
|
||||||
if _, err := w.Write([]byte(event.ToHumanReadable())); err != nil {
|
fmt.Println(event.ToHumanReadable())
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, err := w.Write([]byte("\n")); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := w.Flush(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
return <-errChannel
|
||||||
}
|
}
|
||||||
|
@ -69,26 +69,25 @@ func info(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if parse.MatchesJSONFormat(inFormat) {
|
switch {
|
||||||
|
case parse.MatchesJSONFormat(inFormat):
|
||||||
b, err := json.MarshalIndent(info, "", " ")
|
b, err := json.MarshalIndent(info, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Println(string(b))
|
fmt.Println(string(b))
|
||||||
return nil
|
case cmd.Flags().Changed("format"):
|
||||||
}
|
tmpl, err := template.New("info").Parse(inFormat)
|
||||||
if !cmd.Flag("format").Changed {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tmpl.Execute(os.Stdout, info)
|
||||||
|
default:
|
||||||
b, err := yaml.Marshal(info)
|
b, err := yaml.Marshal(info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Println(string(b))
|
fmt.Println(string(b))
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
tmpl, err := template.New("info").Parse(inFormat)
|
return nil
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = tmpl.Execute(os.Stdout, info)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/containers/buildah/pkg/formats"
|
|
||||||
"github.com/containers/podman/v2/cmd/podman/parse"
|
"github.com/containers/podman/v2/cmd/podman/parse"
|
||||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||||
|
"github.com/containers/podman/v2/cmd/podman/report"
|
||||||
"github.com/containers/podman/v2/cmd/podman/validate"
|
"github.com/containers/podman/v2/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v2/libpod/define"
|
"github.com/containers/podman/v2/libpod/define"
|
||||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||||
@ -41,31 +42,38 @@ func version(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
if parse.MatchesJSONFormat(versionFormat) {
|
||||||
case parse.MatchesJSONFormat(versionFormat):
|
|
||||||
s, err := json.MarshalToString(versions)
|
s, err := json.MarshalToString(versions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = io.WriteString(os.Stdout, s+"\n")
|
fmt.Println(s)
|
||||||
return err
|
|
||||||
case cmd.Flag("format").Changed:
|
|
||||||
out := formats.StdoutTemplate{Output: versions, Template: versionFormat}
|
|
||||||
err := out.Out()
|
|
||||||
if err != nil {
|
|
||||||
// On Failure, assume user is using older version of podman version --format and check client
|
|
||||||
versionFormat = strings.Replace(versionFormat, ".Server.", ".", 1)
|
|
||||||
out = formats.StdoutTemplate{Output: versions.Client, Template: versionFormat}
|
|
||||||
if err1 := out.Out(); err1 != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
||||||
defer w.Flush()
|
defer w.Flush()
|
||||||
|
|
||||||
|
if cmd.Flag("format").Changed {
|
||||||
|
row := report.NormalizeFormat(versionFormat)
|
||||||
|
tmpl, err := template.New("version 2.0.0").Parse(row)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tmpl.Execute(w, versions); err != nil {
|
||||||
|
// On Failure, assume user is using older version of podman version --format and check client
|
||||||
|
row = strings.Replace(row, ".Server.", ".", 1)
|
||||||
|
tmpl, err := template.New("version 1.0.0").Parse(row)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tmpl.Execute(w, versions.Client); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if versions.Server != nil {
|
if versions.Server != nil {
|
||||||
if _, err := fmt.Fprintf(w, "Client:\n"); err != nil {
|
if _, err := fmt.Fprintf(w, "Client:\n"); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -81,13 +89,13 @@ func version(cmd *cobra.Command, args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatVersion(writer io.Writer, version *define.Version) {
|
func formatVersion(w io.Writer, version *define.Version) {
|
||||||
fmt.Fprintf(writer, "Version:\t%s\n", version.Version)
|
fmt.Fprintf(w, "Version:\t%s\n", version.Version)
|
||||||
fmt.Fprintf(writer, "API Version:\t%s\n", version.APIVersion)
|
fmt.Fprintf(w, "API Version:\t%s\n", version.APIVersion)
|
||||||
fmt.Fprintf(writer, "Go Version:\t%s\n", version.GoVersion)
|
fmt.Fprintf(w, "Go Version:\t%s\n", version.GoVersion)
|
||||||
if version.GitCommit != "" {
|
if version.GitCommit != "" {
|
||||||
fmt.Fprintf(writer, "Git Commit:\t%s\n", version.GitCommit)
|
fmt.Fprintf(w, "Git Commit:\t%s\n", version.GitCommit)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(writer, "Built:\t%s\n", version.BuiltTime)
|
fmt.Fprintf(w, "Built:\t%s\n", version.BuiltTime)
|
||||||
fmt.Fprintf(writer, "OS/Arch:\t%s\n", version.OsArch)
|
fmt.Fprintf(w, "OS/Arch:\t%s\n", version.OsArch)
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,11 @@ package volumes
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
"github.com/containers/buildah/pkg/formats"
|
"github.com/containers/podman/v2/cmd/podman/parse"
|
||||||
"github.com/containers/podman/v2/cmd/podman/registry"
|
"github.com/containers/podman/v2/cmd/podman/registry"
|
||||||
|
"github.com/containers/podman/v2/cmd/podman/report"
|
||||||
"github.com/containers/podman/v2/pkg/domain/entities"
|
"github.com/containers/podman/v2/pkg/domain/entities"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -53,26 +53,21 @@ func inspect(cmd *cobra.Command, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
switch inspectFormat {
|
|
||||||
case "", formats.JSONString:
|
switch {
|
||||||
|
case parse.MatchesJSONFormat(inspectFormat), inspectFormat == "":
|
||||||
jsonOut, err := json.MarshalIndent(responses, "", " ")
|
jsonOut, err := json.MarshalIndent(responses, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error marshalling inspect JSON")
|
return errors.Wrapf(err, "error marshalling inspect JSON")
|
||||||
}
|
}
|
||||||
fmt.Println(string(jsonOut))
|
fmt.Println(string(jsonOut))
|
||||||
default:
|
default:
|
||||||
if !strings.HasSuffix(inspectFormat, "\n") {
|
row := "{{range . }}" + report.NormalizeFormat(inspectFormat) + "{{end}}"
|
||||||
inspectFormat += "\n"
|
tmpl, err := template.New("volumeInspect").Parse(row)
|
||||||
}
|
|
||||||
format := "{{range . }}" + inspectFormat + "{{end}}"
|
|
||||||
tmpl, err := template.New("volumeInspect").Parse(format)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tmpl.Execute(os.Stdout, responses); err != nil {
|
return tmpl.Execute(os.Stdout, responses)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -112,11 +112,15 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
errorChannel <- runtime.Events(r.Context(), readOpts)
|
errorChannel <- runtime.Events(r.Context(), readOpts)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var flush = func() {}
|
||||||
|
if flusher, ok := w.(http.Flusher); ok {
|
||||||
|
flush = flusher.Flush
|
||||||
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
if flusher, ok := w.(http.Flusher); ok {
|
flush()
|
||||||
flusher.Flush()
|
|
||||||
}
|
|
||||||
coder := json.NewEncoder(w)
|
coder := json.NewEncoder(w)
|
||||||
coder.SetEscapeHTML(true)
|
coder.SetEscapeHTML(true)
|
||||||
|
|
||||||
@ -124,6 +128,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
select {
|
select {
|
||||||
case err := <-errorChannel:
|
case err := <-errorChannel:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// FIXME StatusOK already sent above cannot send 500 here
|
||||||
utils.InternalServerError(w, err)
|
utils.InternalServerError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -136,9 +141,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
if err := coder.Encode(e); err != nil {
|
if err := coder.Encode(e); err != nil {
|
||||||
logrus.Errorf("unable to write json: %q", err)
|
logrus.Errorf("unable to write json: %q", err)
|
||||||
}
|
}
|
||||||
if flusher, ok := w.(http.Flusher); ok {
|
flush()
|
||||||
flusher.Flush()
|
|
||||||
}
|
|
||||||
case <-r.Context().Done():
|
case <-r.Context().Done():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,6 @@ var _ = Describe("Podman build", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("podman build --http_proxy flag", func() {
|
It("podman build --http_proxy flag", func() {
|
||||||
SkipIfRemote("FIXME: This is broken should be fixed") // This is hanging currently.
|
|
||||||
os.Setenv("http_proxy", "1.2.3.4")
|
os.Setenv("http_proxy", "1.2.3.4")
|
||||||
if IsRemote() {
|
if IsRemote() {
|
||||||
podmanTest.StopRemoteService()
|
podmanTest.StopRemoteService()
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
. "github.com/containers/podman/v2/test/utils"
|
. "github.com/containers/podman/v2/test/utils"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
. "github.com/onsi/gomega/gexec"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Podman events", func() {
|
var _ = Describe("Podman events", func() {
|
||||||
@ -126,26 +127,31 @@ var _ = Describe("Podman events", func() {
|
|||||||
SkipIfNotFedora()
|
SkipIfNotFedora()
|
||||||
_, ec, _ := podmanTest.RunLsContainer("")
|
_, ec, _ := podmanTest.RunLsContainer("")
|
||||||
Expect(ec).To(Equal(0))
|
Expect(ec).To(Equal(0))
|
||||||
|
|
||||||
test := podmanTest.Podman([]string{"events", "--stream=false", "--format", "json"})
|
test := podmanTest.Podman([]string{"events", "--stream=false", "--format", "json"})
|
||||||
test.WaitWithDefaultTimeout()
|
test.WaitWithDefaultTimeout()
|
||||||
Expect(test.ExitCode()).To(BeZero())
|
Expect(test).To(Exit(0))
|
||||||
|
|
||||||
jsonArr := test.OutputToStringArray()
|
jsonArr := test.OutputToStringArray()
|
||||||
Expect(len(jsonArr)).To(Not(BeZero()))
|
Expect(test.OutputToStringArray()).ShouldNot(BeEmpty())
|
||||||
|
|
||||||
eventsMap := make(map[string]string)
|
eventsMap := make(map[string]string)
|
||||||
err := json.Unmarshal([]byte(jsonArr[0]), &eventsMap)
|
err := json.Unmarshal([]byte(jsonArr[0]), &eventsMap)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
_, exist := eventsMap["Status"]
|
|
||||||
Expect(exist).To(BeTrue())
|
Expect(eventsMap).To(HaveKey("Status"))
|
||||||
|
|
||||||
test = podmanTest.Podman([]string{"events", "--stream=false", "--format", "{{json.}}"})
|
test = podmanTest.Podman([]string{"events", "--stream=false", "--format", "{{json.}}"})
|
||||||
test.WaitWithDefaultTimeout()
|
test.WaitWithDefaultTimeout()
|
||||||
Expect(test.ExitCode()).To(BeZero())
|
Expect(test).To(Exit(0))
|
||||||
|
|
||||||
jsonArr = test.OutputToStringArray()
|
jsonArr = test.OutputToStringArray()
|
||||||
Expect(len(jsonArr)).To(Not(BeZero()))
|
Expect(test.OutputToStringArray()).ShouldNot(BeEmpty())
|
||||||
|
|
||||||
eventsMap = make(map[string]string)
|
eventsMap = make(map[string]string)
|
||||||
err = json.Unmarshal([]byte(jsonArr[0]), &eventsMap)
|
err = json.Unmarshal([]byte(jsonArr[0]), &eventsMap)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
_, exist = eventsMap["Status"]
|
|
||||||
Expect(exist).To(BeTrue())
|
Expect(eventsMap).To(HaveKey("Status"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
167
vendor/github.com/containers/buildah/pkg/formats/formats.go
generated
vendored
167
vendor/github.com/containers/buildah/pkg/formats/formats.go
generated
vendored
@ -1,167 +0,0 @@
|
|||||||
package formats
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"text/tabwriter"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// JSONString const to save on duplicate variable names
|
|
||||||
JSONString = "json"
|
|
||||||
// IDString const to save on duplicates for Go templates
|
|
||||||
IDString = "{{.ID}}"
|
|
||||||
|
|
||||||
parsingErrorStr = "Template parsing error"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Writer interface for outputs
|
|
||||||
type Writer interface {
|
|
||||||
Out() error
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSONStructArray for JSON output
|
|
||||||
type JSONStructArray struct {
|
|
||||||
Output []interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StdoutTemplateArray for Go template output
|
|
||||||
type StdoutTemplateArray struct {
|
|
||||||
Output []interface{}
|
|
||||||
Template string
|
|
||||||
Fields map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSONStruct for JSON output
|
|
||||||
type JSONStruct struct {
|
|
||||||
Output interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// StdoutTemplate for Go template output
|
|
||||||
type StdoutTemplate struct {
|
|
||||||
Output interface{}
|
|
||||||
Template string
|
|
||||||
Fields map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
// YAMLStruct for YAML output
|
|
||||||
type YAMLStruct struct {
|
|
||||||
Output interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setJSONFormatEncoder(isTerminal bool, w io.Writer) *json.Encoder {
|
|
||||||
enc := json.NewEncoder(w)
|
|
||||||
enc.SetIndent("", " ")
|
|
||||||
if isTerminal {
|
|
||||||
enc.SetEscapeHTML(false)
|
|
||||||
}
|
|
||||||
return enc
|
|
||||||
}
|
|
||||||
|
|
||||||
// Out method for JSON Arrays
|
|
||||||
func (j JSONStructArray) Out() error {
|
|
||||||
buf := bytes.NewBuffer(nil)
|
|
||||||
enc := setJSONFormatEncoder(terminal.IsTerminal(int(os.Stdout.Fd())), buf)
|
|
||||||
if err := enc.Encode(j.Output); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
data := buf.Bytes()
|
|
||||||
|
|
||||||
// JSON returns a byte array with a literal null [110 117 108 108] in it
|
|
||||||
// if it is passed empty data. We used bytes.Compare to see if that is
|
|
||||||
// the case.
|
|
||||||
if diff := bytes.Compare(data, []byte("null")); diff == 0 {
|
|
||||||
data = []byte("[]")
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the we did get NULL back, we should spit out {} which is
|
|
||||||
// at least valid JSON for the consumer.
|
|
||||||
fmt.Printf("%s", data)
|
|
||||||
humanNewLine()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Out method for Go templates
|
|
||||||
func (t StdoutTemplateArray) Out() error {
|
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
|
|
||||||
if strings.HasPrefix(t.Template, "table") {
|
|
||||||
// replace any spaces with tabs in template so that tabwriter can align it
|
|
||||||
t.Template = strings.Replace(strings.TrimSpace(t.Template[5:]), " ", "\t", -1)
|
|
||||||
headerTmpl, err := template.New("header").Funcs(headerFunctions).Parse(t.Template)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, parsingErrorStr)
|
|
||||||
}
|
|
||||||
err = headerTmpl.Execute(w, t.Fields)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Fprintln(w, "")
|
|
||||||
}
|
|
||||||
t.Template = strings.Replace(t.Template, " ", "\t", -1)
|
|
||||||
tmpl, err := template.New("image").Funcs(basicFunctions).Parse(t.Template)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, parsingErrorStr)
|
|
||||||
}
|
|
||||||
for _, raw := range t.Output {
|
|
||||||
basicTmpl := tmpl.Funcs(basicFunctions)
|
|
||||||
if err := basicTmpl.Execute(w, raw); err != nil {
|
|
||||||
return errors.Wrapf(err, parsingErrorStr)
|
|
||||||
}
|
|
||||||
fmt.Fprintln(w, "")
|
|
||||||
}
|
|
||||||
return w.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Out method for JSON struct
|
|
||||||
func (j JSONStruct) Out() error {
|
|
||||||
data, err := json.MarshalIndent(j.Output, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("%s", data)
|
|
||||||
humanNewLine()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//Out method for Go templates
|
|
||||||
func (t StdoutTemplate) Out() error {
|
|
||||||
tmpl, err := template.New("image").Parse(t.Template)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "template parsing error")
|
|
||||||
}
|
|
||||||
err = tmpl.Execute(os.Stdout, t.Output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
humanNewLine()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Out method for YAML
|
|
||||||
func (y YAMLStruct) Out() error {
|
|
||||||
var buf []byte
|
|
||||||
var err error
|
|
||||||
buf, err = yaml.Marshal(y.Output)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("%s", string(buf))
|
|
||||||
humanNewLine()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// humanNewLine prints a new line at the end of the output only if stdout is the terminal
|
|
||||||
func humanNewLine() {
|
|
||||||
if terminal.IsTerminal(int(os.Stdout.Fd())) {
|
|
||||||
fmt.Println()
|
|
||||||
}
|
|
||||||
}
|
|
78
vendor/github.com/containers/buildah/pkg/formats/templates.go
generated
vendored
78
vendor/github.com/containers/buildah/pkg/formats/templates.go
generated
vendored
@ -1,78 +0,0 @@
|
|||||||
package formats
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
"text/template"
|
|
||||||
)
|
|
||||||
|
|
||||||
// basicFunctions are the set of initial
|
|
||||||
// functions provided to every template.
|
|
||||||
var basicFunctions = template.FuncMap{
|
|
||||||
"json": func(v interface{}) string {
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
enc := json.NewEncoder(buf)
|
|
||||||
enc.SetEscapeHTML(false)
|
|
||||||
_ = enc.Encode(v)
|
|
||||||
// Remove the trailing new line added by the encoder
|
|
||||||
return strings.TrimSpace(buf.String())
|
|
||||||
},
|
|
||||||
"split": strings.Split,
|
|
||||||
"join": strings.Join,
|
|
||||||
"title": strings.Title,
|
|
||||||
"lower": strings.ToLower,
|
|
||||||
"upper": strings.ToUpper,
|
|
||||||
"pad": padWithSpace,
|
|
||||||
"truncate": truncateWithLength,
|
|
||||||
}
|
|
||||||
|
|
||||||
// HeaderFunctions are used to created headers of a table.
|
|
||||||
// This is a replacement of basicFunctions for header generation
|
|
||||||
// because we want the header to remain intact.
|
|
||||||
// Some functions like `split` are irrelevant so not added.
|
|
||||||
var headerFunctions = template.FuncMap{
|
|
||||||
"json": func(v string) string {
|
|
||||||
return v
|
|
||||||
},
|
|
||||||
"title": func(v string) string {
|
|
||||||
return v
|
|
||||||
},
|
|
||||||
"lower": func(v string) string {
|
|
||||||
return v
|
|
||||||
},
|
|
||||||
"upper": func(v string) string {
|
|
||||||
return v
|
|
||||||
},
|
|
||||||
"truncate": func(v string, l int) string {
|
|
||||||
return v
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse creates a new anonymous template with the basic functions
|
|
||||||
// and parses the given format.
|
|
||||||
func Parse(format string) (*template.Template, error) {
|
|
||||||
return NewParse("", format)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewParse creates a new tagged template with the basic functions
|
|
||||||
// and parses the given format.
|
|
||||||
func NewParse(tag, format string) (*template.Template, error) {
|
|
||||||
return template.New(tag).Funcs(basicFunctions).Parse(format)
|
|
||||||
}
|
|
||||||
|
|
||||||
// padWithSpace adds whitespace to the input if the input is non-empty
|
|
||||||
func padWithSpace(source string, prefix, suffix int) string {
|
|
||||||
if source == "" {
|
|
||||||
return source
|
|
||||||
}
|
|
||||||
return strings.Repeat(" ", prefix) + source + strings.Repeat(" ", suffix)
|
|
||||||
}
|
|
||||||
|
|
||||||
// truncateWithLength truncates the source string up to the length provided by the input
|
|
||||||
func truncateWithLength(source string, length int) string {
|
|
||||||
if len(source) < length {
|
|
||||||
return source
|
|
||||||
}
|
|
||||||
return source[:length]
|
|
||||||
}
|
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -78,7 +78,6 @@ github.com/containers/buildah/manifests
|
|||||||
github.com/containers/buildah/pkg/blobcache
|
github.com/containers/buildah/pkg/blobcache
|
||||||
github.com/containers/buildah/pkg/chrootuser
|
github.com/containers/buildah/pkg/chrootuser
|
||||||
github.com/containers/buildah/pkg/cli
|
github.com/containers/buildah/pkg/cli
|
||||||
github.com/containers/buildah/pkg/formats
|
|
||||||
github.com/containers/buildah/pkg/manifests
|
github.com/containers/buildah/pkg/manifests
|
||||||
github.com/containers/buildah/pkg/overlay
|
github.com/containers/buildah/pkg/overlay
|
||||||
github.com/containers/buildah/pkg/parse
|
github.com/containers/buildah/pkg/parse
|
||||||
|
Reference in New Issue
Block a user