cmd/uplinkng: port expanded option to show additional metadata (#4229)

This commit is contained in:
mya 2021-10-28 11:51:33 -05:00 committed by GitHub
parent edb8d656de
commit 9749f9756c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 3 deletions

View File

@ -12,6 +12,7 @@ import (
"storj.io/storj/cmd/uplinkng/ulext" "storj.io/storj/cmd/uplinkng/ulext"
"storj.io/storj/cmd/uplinkng/ulfs" "storj.io/storj/cmd/uplinkng/ulfs"
"storj.io/storj/cmd/uplinkng/ulloc" "storj.io/storj/cmd/uplinkng/ulloc"
"storj.io/uplink"
) )
type cmdLs struct { type cmdLs struct {
@ -20,6 +21,7 @@ type cmdLs struct {
access string access string
recursive bool recursive bool
encrypted bool encrypted bool
expanded bool
pending bool pending bool
utc bool utc bool
@ -42,6 +44,10 @@ func (c *cmdLs) Setup(params clingy.Parameters) {
c.pending = params.Flag("pending", "List pending object uploads instead", false, c.pending = params.Flag("pending", "List pending object uploads instead", false,
clingy.Transform(strconv.ParseBool), clingy.Transform(strconv.ParseBool),
).(bool) ).(bool)
c.expanded = params.Flag("expanded", "Use expanded output, showing object expiration times and whether there is custom metadata attached", false,
clingy.Short('x'),
clingy.Transform(strconv.ParseBool),
).(bool)
c.utc = params.Flag("utc", "Show all timestamps in UTC instead of local time", false, c.utc = params.Flag("utc", "Show all timestamps in UTC instead of local time", false,
clingy.Transform(strconv.ParseBool), clingy.Transform(strconv.ParseBool),
).(bool) ).(bool)
@ -87,13 +93,19 @@ func (c *cmdLs) listLocation(ctx clingy.Context, prefix ulloc.Location) error {
prefix = prefix.AsDirectoryish() prefix = prefix.AsDirectoryish()
} }
tw := newTabbedWriter(ctx.Stdout(), "KIND", "CREATED", "SIZE", "KEY") headers := []string{"KIND", "CREATED", "SIZE", "KEY"}
if c.expanded {
headers = append(headers, "EXPIRES", "META")
}
tw := newTabbedWriter(ctx.Stdout(), headers...)
defer tw.Done() defer tw.Done()
// create the object iterator of either existing objects or pending multipart uploads // create the object iterator of either existing objects or pending multipart uploads
iter, err := fs.List(ctx, prefix, &ulfs.ListOptions{ iter, err := fs.List(ctx, prefix, &ulfs.ListOptions{
Recursive: c.recursive, Recursive: c.recursive,
Pending: c.pending, Pending: c.pending,
Expanded: c.expanded,
}) })
if err != nil { if err != nil {
return err return err
@ -102,16 +114,30 @@ func (c *cmdLs) listLocation(ctx clingy.Context, prefix ulloc.Location) error {
// iterate and print the results // iterate and print the results
for iter.Next() { for iter.Next() {
obj := iter.Item() obj := iter.Item()
var parts []interface{}
if obj.IsPrefix { if obj.IsPrefix {
tw.WriteLine("PRE", "", "", obj.Loc.Loc()) parts = append(parts, "PRE", "", "", obj.Loc.Loc())
} else { if c.expanded {
tw.WriteLine("OBJ", formatTime(c.utc, obj.Created), obj.ContentLength, obj.Loc.Loc()) parts = append(parts, "", "")
} }
} else {
parts = append(parts, "OBJ", formatTime(c.utc, obj.Created), obj.ContentLength, obj.Loc.Loc())
if c.expanded {
parts = append(parts, formatTime(c.utc, obj.Expires), sumMetadataSize(obj.Metadata))
}
}
tw.WriteLine(parts...)
} }
return iter.Err() return iter.Err()
} }
func formatTime(utc bool, x time.Time) string { func formatTime(utc bool, x time.Time) string {
if x.IsZero() {
return ""
}
if utc { if utc {
x = x.UTC() x = x.UTC()
} else { } else {
@ -119,3 +145,12 @@ func formatTime(utc bool, x time.Time) string {
} }
return x.Format("2006-01-02 15:04:05") return x.Format("2006-01-02 15:04:05")
} }
func sumMetadataSize(md uplink.CustomMetadata) int {
size := 0
for k, v := range md {
size += len(k)
size += len(v)
}
return size
}

View File

@ -20,6 +20,7 @@ import (
type ListOptions struct { type ListOptions struct {
Recursive bool Recursive bool
Pending bool Pending bool
Expanded bool
} }
func (lo *ListOptions) isRecursive() bool { return lo != nil && lo.Recursive } func (lo *ListOptions) isRecursive() bool { return lo != nil && lo.Recursive }
@ -53,6 +54,8 @@ type ObjectInfo struct {
IsPrefix bool IsPrefix bool
Created time.Time Created time.Time
ContentLength int64 ContentLength int64
Expires time.Time
Metadata uplink.CustomMetadata
} }
// uplinkObjectToObjectInfo returns an objectInfo converted from an *uplink.Object. // uplinkObjectToObjectInfo returns an objectInfo converted from an *uplink.Object.
@ -62,6 +65,8 @@ func uplinkObjectToObjectInfo(bucket string, obj *uplink.Object) ObjectInfo {
IsPrefix: obj.IsPrefix, IsPrefix: obj.IsPrefix,
Created: obj.System.Created, Created: obj.System.Created,
ContentLength: obj.System.ContentLength, ContentLength: obj.System.ContentLength,
Expires: obj.System.Expires,
Metadata: obj.Custom,
} }
} }
@ -72,6 +77,8 @@ func uplinkUploadInfoToObjectInfo(bucket string, upl *uplink.UploadInfo) ObjectI
IsPrefix: upl.IsPrefix, IsPrefix: upl.IsPrefix,
Created: upl.System.Created, Created: upl.System.Created,
ContentLength: upl.System.ContentLength, ContentLength: upl.System.ContentLength,
Expires: upl.System.Expires,
Metadata: upl.Custom,
} }
} }

View File

@ -94,6 +94,7 @@ func (r *Remote) List(ctx context.Context, bucket, prefix string, opts *ListOpti
Prefix: parentPrefix, Prefix: parentPrefix,
Recursive: opts.Recursive, Recursive: opts.Recursive,
System: true, System: true,
Custom: opts.Expanded,
}), }),
) )
} else { } else {
@ -103,6 +104,7 @@ func (r *Remote) List(ctx context.Context, bucket, prefix string, opts *ListOpti
Prefix: parentPrefix, Prefix: parentPrefix,
Recursive: opts.Recursive, Recursive: opts.Recursive,
System: true, System: true,
Custom: opts.Expanded,
}), }),
) )
} }

View File

@ -78,6 +78,7 @@ uplinkng rm "sj://$BUCKET/multisegment-upload-testfile" --access $STORJ_ACCESS
uplinkng rm "sj://$BUCKET/diff-size-segments" --access $STORJ_ACCESS uplinkng rm "sj://$BUCKET/diff-size-segments" --access $STORJ_ACCESS
uplinkng ls "sj://$BUCKET" --access $STORJ_ACCESS uplinkng ls "sj://$BUCKET" --access $STORJ_ACCESS
uplinkng ls -x true "sj://$BUCKET" --access $STORJ_ACCESS
uplinkng rb "sj://$BUCKET" --access $STORJ_ACCESS uplinkng rb "sj://$BUCKET" --access $STORJ_ACCESS