Signed-off-by: Ying Li <ying.li@docker.com>
| ... | ... |
@@ -123,7 +123,7 @@ func MergeSwarmSpecToGRPC(s types.Spec, spec swarmapi.ClusterSpec) (swarmapi.Clu |
| 123 | 123 |
spec.CAConfig.SigningCACert = []byte(s.CAConfig.SigningCACert) |
| 124 | 124 |
} |
| 125 | 125 |
if s.CAConfig.SigningCAKey != "" {
|
| 126 |
- // do prpagate the signing CA key here because we want to provide it TO the swarm APIs |
|
| 126 |
+ // do propagate the signing CA key here because we want to provide it TO the swarm APIs |
|
| 127 | 127 |
spec.CAConfig.SigningCAKey = []byte(s.CAConfig.SigningCAKey) |
| 128 | 128 |
} |
| 129 | 129 |
spec.CAConfig.ForceRotate = s.CAConfig.ForceRotate |
| ... | ... |
@@ -36,7 +36,8 @@ type JSONProgress struct {
|
| 36 | 36 |
Total int64 `json:"total,omitempty"` |
| 37 | 37 |
Start int64 `json:"start,omitempty"` |
| 38 | 38 |
// If true, don't show xB/yB |
| 39 |
- HideCounts bool `json:"hidecounts,omitempty"` |
|
| 39 |
+ HideCounts bool `json:"hidecounts,omitempty"` |
|
| 40 |
+ Units string `json:"units,omitempty"` |
|
| 40 | 41 |
} |
| 41 | 42 |
|
| 42 | 43 |
func (p *JSONProgress) String() string {
|
| ... | ... |
@@ -55,11 +56,16 @@ func (p *JSONProgress) String() string {
|
| 55 | 55 |
if p.Current <= 0 && p.Total <= 0 {
|
| 56 | 56 |
return "" |
| 57 | 57 |
} |
| 58 |
- current := units.HumanSize(float64(p.Current)) |
|
| 59 | 58 |
if p.Total <= 0 {
|
| 60 |
- return fmt.Sprintf("%8v", current)
|
|
| 59 |
+ switch p.Units {
|
|
| 60 |
+ case "": |
|
| 61 |
+ current := units.HumanSize(float64(p.Current)) |
|
| 62 |
+ return fmt.Sprintf("%8v", current)
|
|
| 63 |
+ default: |
|
| 64 |
+ return fmt.Sprintf("%d %s", p.Current, p.Units)
|
|
| 65 |
+ } |
|
| 61 | 66 |
} |
| 62 |
- total := units.HumanSize(float64(p.Total)) |
|
| 67 |
+ |
|
| 63 | 68 |
percentage := int(float64(p.Current)/float64(p.Total)*100) / 2 |
| 64 | 69 |
if percentage > 50 {
|
| 65 | 70 |
percentage = 50 |
| ... | ... |
@@ -73,13 +79,25 @@ func (p *JSONProgress) String() string {
|
| 73 | 73 |
pbBox = fmt.Sprintf("[%s>%s] ", strings.Repeat("=", percentage), strings.Repeat(" ", numSpaces))
|
| 74 | 74 |
} |
| 75 | 75 |
|
| 76 |
- if !p.HideCounts {
|
|
| 76 |
+ switch {
|
|
| 77 |
+ case p.HideCounts: |
|
| 78 |
+ case p.Units == "": // no units, use bytes |
|
| 79 |
+ current := units.HumanSize(float64(p.Current)) |
|
| 80 |
+ total := units.HumanSize(float64(p.Total)) |
|
| 81 |
+ |
|
| 77 | 82 |
numbersBox = fmt.Sprintf("%8v/%v", current, total)
|
| 78 | 83 |
|
| 79 | 84 |
if p.Current > p.Total {
|
| 80 | 85 |
// remove total display if the reported current is wonky. |
| 81 | 86 |
numbersBox = fmt.Sprintf("%8v", current)
|
| 82 | 87 |
} |
| 88 |
+ default: |
|
| 89 |
+ numbersBox = fmt.Sprintf("%d/%d %s", p.Current, p.Total, p.Units)
|
|
| 90 |
+ |
|
| 91 |
+ if p.Current > p.Total {
|
|
| 92 |
+ // remove total display if the reported current is wonky. |
|
| 93 |
+ numbersBox = fmt.Sprintf("%d %s", p.Current, p.Units)
|
|
| 94 |
+ } |
|
| 83 | 95 |
} |
| 84 | 96 |
|
| 85 | 97 |
if p.Current > 0 && p.Start > 0 && percentage < 50 {
|
| ... | ... |
@@ -65,22 +65,50 @@ func TestProgress(t *testing.T) {
|
| 65 | 65 |
if jp5.String() != expected {
|
| 66 | 66 |
t.Fatalf("Expected %q, got %q", expected, jp5.String())
|
| 67 | 67 |
} |
| 68 |
+ |
|
| 69 |
+ expected = "[=========================> ] 50/100 units" |
|
| 70 |
+ if termsz != nil && termsz.Width <= 110 {
|
|
| 71 |
+ expected = " 50/100 units" |
|
| 72 |
+ } |
|
| 73 |
+ jp6 := JSONProgress{Current: 50, Total: 100, Units: "units"}
|
|
| 74 |
+ if jp6.String() != expected {
|
|
| 75 |
+ t.Fatalf("Expected %q, got %q", expected, jp6.String())
|
|
| 76 |
+ } |
|
| 77 |
+ |
|
| 78 |
+ // this number can't be negative |
|
| 79 |
+ expected = "[==================================================>] 50 units" |
|
| 80 |
+ if termsz != nil && termsz.Width <= 110 {
|
|
| 81 |
+ expected = " 50 units" |
|
| 82 |
+ } |
|
| 83 |
+ jp7 := JSONProgress{Current: 50, Total: 40, Units: "units"}
|
|
| 84 |
+ if jp7.String() != expected {
|
|
| 85 |
+ t.Fatalf("Expected %q, got %q", expected, jp7.String())
|
|
| 86 |
+ } |
|
| 87 |
+ |
|
| 88 |
+ expected = "[=========================> ] " |
|
| 89 |
+ if termsz != nil && termsz.Width <= 110 {
|
|
| 90 |
+ expected = "" |
|
| 91 |
+ } |
|
| 92 |
+ jp8 := JSONProgress{Current: 50, Total: 100, HideCounts: true}
|
|
| 93 |
+ if jp8.String() != expected {
|
|
| 94 |
+ t.Fatalf("Expected %q, got %q", expected, jp8.String())
|
|
| 95 |
+ } |
|
| 68 | 96 |
} |
| 69 | 97 |
|
| 70 | 98 |
func TestJSONMessageDisplay(t *testing.T) {
|
| 71 | 99 |
now := time.Now() |
| 72 | 100 |
messages := map[JSONMessage][]string{
|
| 73 | 101 |
// Empty |
| 74 |
- JSONMessage{}: {"\n", "\n"},
|
|
| 102 |
+ {}: {"\n", "\n"},
|
|
| 75 | 103 |
// Status |
| 76 |
- JSONMessage{
|
|
| 104 |
+ {
|
|
| 77 | 105 |
Status: "status", |
| 78 | 106 |
}: {
|
| 79 | 107 |
"status\n", |
| 80 | 108 |
"status\n", |
| 81 | 109 |
}, |
| 82 | 110 |
// General |
| 83 |
- JSONMessage{
|
|
| 111 |
+ {
|
|
| 84 | 112 |
Time: now.Unix(), |
| 85 | 113 |
ID: "ID", |
| 86 | 114 |
From: "From", |
| ... | ... |
@@ -90,7 +118,7 @@ func TestJSONMessageDisplay(t *testing.T) {
|
| 90 | 90 |
fmt.Sprintf("%v ID: (from From) status\n", time.Unix(now.Unix(), 0).Format(jsonlog.RFC3339NanoFixed)),
|
| 91 | 91 |
}, |
| 92 | 92 |
// General, with nano precision time |
| 93 |
- JSONMessage{
|
|
| 93 |
+ {
|
|
| 94 | 94 |
TimeNano: now.UnixNano(), |
| 95 | 95 |
ID: "ID", |
| 96 | 96 |
From: "From", |
| ... | ... |
@@ -100,7 +128,7 @@ func TestJSONMessageDisplay(t *testing.T) {
|
| 100 | 100 |
fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
|
| 101 | 101 |
}, |
| 102 | 102 |
// General, with both times Nano is preferred |
| 103 |
- JSONMessage{
|
|
| 103 |
+ {
|
|
| 104 | 104 |
Time: now.Unix(), |
| 105 | 105 |
TimeNano: now.UnixNano(), |
| 106 | 106 |
ID: "ID", |
| ... | ... |
@@ -111,7 +139,7 @@ func TestJSONMessageDisplay(t *testing.T) {
|
| 111 | 111 |
fmt.Sprintf("%v ID: (from From) status\n", time.Unix(0, now.UnixNano()).Format(jsonlog.RFC3339NanoFixed)),
|
| 112 | 112 |
}, |
| 113 | 113 |
// Stream over status |
| 114 |
- JSONMessage{
|
|
| 114 |
+ {
|
|
| 115 | 115 |
Status: "status", |
| 116 | 116 |
Stream: "stream", |
| 117 | 117 |
}: {
|
| ... | ... |
@@ -119,7 +147,7 @@ func TestJSONMessageDisplay(t *testing.T) {
|
| 119 | 119 |
"stream", |
| 120 | 120 |
}, |
| 121 | 121 |
// With progress message |
| 122 |
- JSONMessage{
|
|
| 122 |
+ {
|
|
| 123 | 123 |
Status: "status", |
| 124 | 124 |
ProgressMessage: "progressMessage", |
| 125 | 125 |
}: {
|
| ... | ... |
@@ -127,7 +155,7 @@ func TestJSONMessageDisplay(t *testing.T) {
|
| 127 | 127 |
"status progressMessage", |
| 128 | 128 |
}, |
| 129 | 129 |
// With progress, stream empty |
| 130 |
- JSONMessage{
|
|
| 130 |
+ {
|
|
| 131 | 131 |
Status: "status", |
| 132 | 132 |
Stream: "", |
| 133 | 133 |
Progress: &JSONProgress{Current: 1},
|
| ... | ... |
@@ -18,6 +18,8 @@ type Progress struct {
|
| 18 | 18 |
|
| 19 | 19 |
// If true, don't show xB/yB |
| 20 | 20 |
HideCounts bool |
| 21 |
+ // If not empty, use units instead of bytes for counts |
|
| 22 |
+ Units string |
|
| 21 | 23 |
|
| 22 | 24 |
// Aux contains extra information not presented to the user, such as |
| 23 | 25 |
// digests for push signing. |
| ... | ... |
@@ -117,7 +117,7 @@ func (out *progressOutput) WriteProgress(prog progress.Progress) error {
|
| 117 | 117 |
if prog.Message != "" {
|
| 118 | 118 |
formatted = out.sf.formatStatus(prog.ID, prog.Message) |
| 119 | 119 |
} else {
|
| 120 |
- jsonProgress := jsonmessage.JSONProgress{Current: prog.Current, Total: prog.Total, HideCounts: prog.HideCounts}
|
|
| 120 |
+ jsonProgress := jsonmessage.JSONProgress{Current: prog.Current, Total: prog.Total, HideCounts: prog.HideCounts, Units: prog.Units}
|
|
| 121 | 121 |
formatted = out.sf.formatProgress(prog.ID, prog.Action, &jsonProgress, prog.Aux) |
| 122 | 122 |
} |
| 123 | 123 |
_, err := out.out.Write(formatted) |