Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d33b465

Browse files
committed
Move duration and size to units pkg
Docker-DCO-1.1-Signed-off-by: Michael Crosby <[email protected]> (github: crosbymichael)
1 parent 0d78799 commit d33b465

11 files changed

Lines changed: 165 additions & 140 deletions

File tree

api/client/commands.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/dotcloud/docker/nat"
2929
"github.com/dotcloud/docker/pkg/signal"
3030
"github.com/dotcloud/docker/pkg/term"
31+
"github.com/dotcloud/docker/pkg/units"
3132
"github.com/dotcloud/docker/registry"
3233
"github.com/dotcloud/docker/runconfig"
3334
"github.com/dotcloud/docker/utils"
@@ -884,14 +885,14 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
884885
fmt.Fprintf(w, "%s\t", utils.TruncateID(outID))
885886
}
886887

887-
fmt.Fprintf(w, "%s ago\t", utils.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))))
888+
fmt.Fprintf(w, "%s ago\t", units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))))
888889

889890
if *noTrunc {
890891
fmt.Fprintf(w, "%s\t", out.Get("CreatedBy"))
891892
} else {
892893
fmt.Fprintf(w, "%s\t", utils.Trunc(out.Get("CreatedBy"), 45))
893894
}
894-
fmt.Fprintf(w, "%s\n", utils.HumanSize(out.GetInt64("Size")))
895+
fmt.Fprintf(w, "%s\n", units.HumanSize(out.GetInt64("Size")))
895896
} else {
896897
if *noTrunc {
897898
fmt.Fprintln(w, outID)
@@ -1249,7 +1250,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
12491250
}
12501251

12511252
if !*quiet {
1252-
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, outID, utils.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), utils.HumanSize(out.GetInt64("VirtualSize")))
1253+
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\n", repo, tag, outID, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), units.HumanSize(out.GetInt64("VirtualSize")))
12531254
} else {
12541255
fmt.Fprintln(w, outID)
12551256
}
@@ -1323,7 +1324,7 @@ func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix stri
13231324
imageID = utils.TruncateID(image.Get("Id"))
13241325
}
13251326

1326-
fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, utils.HumanSize(image.GetInt64("VirtualSize")))
1327+
fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, units.HumanSize(image.GetInt64("VirtualSize")))
13271328
if image.GetList("RepoTags")[0] != "<none>:<none>" {
13281329
fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.GetList("RepoTags"), ", "))
13291330
} else {
@@ -1408,12 +1409,12 @@ func (cli *DockerCli) CmdPs(args ...string) error {
14081409
outCommand = utils.Trunc(outCommand, 20)
14091410
}
14101411
ports.ReadListFrom([]byte(out.Get("Ports")))
1411-
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", outID, out.Get("Image"), outCommand, utils.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), out.Get("Status"), api.DisplayablePorts(ports), strings.Join(outNames, ","))
1412+
fmt.Fprintf(w, "%s\t%s\t%s\t%s ago\t%s\t%s\t%s\t", outID, out.Get("Image"), outCommand, units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))), out.Get("Status"), api.DisplayablePorts(ports), strings.Join(outNames, ","))
14121413
if *size {
14131414
if out.GetInt("SizeRootFs") > 0 {
1414-
fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.GetInt64("SizeRw")), utils.HumanSize(out.GetInt64("SizeRootFs")))
1415+
fmt.Fprintf(w, "%s (virtual %s)\n", units.HumanSize(out.GetInt64("SizeRw")), units.HumanSize(out.GetInt64("SizeRootFs")))
14151416
} else {
1416-
fmt.Fprintf(w, "%s\n", utils.HumanSize(out.GetInt64("SizeRw")))
1417+
fmt.Fprintf(w, "%s\n", units.HumanSize(out.GetInt64("SizeRw")))
14171418
}
14181419
} else {
14191420
fmt.Fprint(w, "\n")

daemon/execdriver/native/configuration/parse.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"strings"
99

1010
"github.com/dotcloud/docker/pkg/libcontainer"
11-
"github.com/dotcloud/docker/utils"
11+
"github.com/dotcloud/docker/pkg/units"
1212
)
1313

1414
type Action func(*libcontainer.Container, interface{}, string) error
@@ -75,7 +75,7 @@ func memory(container *libcontainer.Container, context interface{}, value string
7575
return fmt.Errorf("cannot set cgroups when they are disabled")
7676
}
7777

78-
v, err := utils.RAMInBytes(value)
78+
v, err := units.RAMInBytes(value)
7979
if err != nil {
8080
return err
8181
}
@@ -88,7 +88,7 @@ func memoryReservation(container *libcontainer.Container, context interface{}, v
8888
return fmt.Errorf("cannot set cgroups when they are disabled")
8989
}
9090

91-
v, err := utils.RAMInBytes(value)
91+
v, err := units.RAMInBytes(value)
9292
if err != nil {
9393
return err
9494
}

daemon/state.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package daemon
22

33
import (
44
"fmt"
5-
"github.com/dotcloud/docker/utils"
65
"sync"
76
"time"
7+
8+
"github.com/dotcloud/docker/pkg/units"
89
)
910

1011
type State struct {
@@ -22,12 +23,12 @@ func (s *State) String() string {
2223
defer s.RUnlock()
2324

2425
if s.Running {
25-
return fmt.Sprintf("Up %s", utils.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
26+
return fmt.Sprintf("Up %s", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
2627
}
2728
if s.FinishedAt.IsZero() {
2829
return ""
2930
}
30-
return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, utils.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
31+
return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
3132
}
3233

3334
func (s *State) IsRunning() bool {

pkg/units/MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Michael Crosby <[email protected]> (@crosbymichael)
2+
Victor Vieux <[email protected]> (@vieux)

pkg/units/duration.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package units
2+
3+
import (
4+
"fmt"
5+
"time"
6+
)
7+
8+
// HumanDuration returns a human-readable approximation of a duration
9+
// (eg. "About a minute", "4 hours ago", etc.)
10+
func HumanDuration(d time.Duration) string {
11+
if seconds := int(d.Seconds()); seconds < 1 {
12+
return "Less than a second"
13+
} else if seconds < 60 {
14+
return fmt.Sprintf("%d seconds", seconds)
15+
} else if minutes := int(d.Minutes()); minutes == 1 {
16+
return "About a minute"
17+
} else if minutes < 60 {
18+
return fmt.Sprintf("%d minutes", minutes)
19+
} else if hours := int(d.Hours()); hours == 1 {
20+
return "About an hour"
21+
} else if hours < 48 {
22+
return fmt.Sprintf("%d hours", hours)
23+
} else if hours < 24*7*2 {
24+
return fmt.Sprintf("%d days", hours/24)
25+
} else if hours < 24*30*3 {
26+
return fmt.Sprintf("%d weeks", hours/24/7)
27+
} else if hours < 24*365*2 {
28+
return fmt.Sprintf("%d months", hours/24/30)
29+
}
30+
return fmt.Sprintf("%f years", d.Hours()/24/365)
31+
}

pkg/units/size.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package units
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strconv"
7+
"strings"
8+
)
9+
10+
// HumanSize returns a human-readable approximation of a size
11+
// using SI standard (eg. "44kB", "17MB")
12+
func HumanSize(size int64) string {
13+
i := 0
14+
var sizef float64
15+
sizef = float64(size)
16+
units := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
17+
for sizef >= 1000.0 {
18+
sizef = sizef / 1000.0
19+
i++
20+
}
21+
return fmt.Sprintf("%.4g %s", sizef, units[i])
22+
}
23+
24+
// Parses a human-readable string representing an amount of RAM
25+
// in bytes, kibibytes, mebibytes or gibibytes, and returns the
26+
// number of bytes, or -1 if the string is unparseable.
27+
// Units are case-insensitive, and the 'b' suffix is optional.
28+
func RAMInBytes(size string) (bytes int64, err error) {
29+
re, error := regexp.Compile("^(\\d+)([kKmMgG])?[bB]?$")
30+
if error != nil {
31+
return -1, error
32+
}
33+
34+
matches := re.FindStringSubmatch(size)
35+
36+
if len(matches) != 3 {
37+
return -1, fmt.Errorf("Invalid size: '%s'", size)
38+
}
39+
40+
memLimit, error := strconv.ParseInt(matches[1], 10, 0)
41+
if error != nil {
42+
return -1, error
43+
}
44+
45+
unit := strings.ToLower(matches[2])
46+
47+
if unit == "k" {
48+
memLimit *= 1024
49+
} else if unit == "m" {
50+
memLimit *= 1024 * 1024
51+
} else if unit == "g" {
52+
memLimit *= 1024 * 1024 * 1024
53+
}
54+
55+
return memLimit, nil
56+
}

pkg/units/size_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package units
2+
3+
import (
4+
"strings"
5+
"testing"
6+
)
7+
8+
func TestHumanSize(t *testing.T) {
9+
10+
size := strings.Trim(HumanSize(1000), " \t")
11+
expect := "1 kB"
12+
if size != expect {
13+
t.Errorf("1000 -> expected '%s', got '%s'", expect, size)
14+
}
15+
16+
size = strings.Trim(HumanSize(1024), " \t")
17+
expect = "1.024 kB"
18+
if size != expect {
19+
t.Errorf("1024 -> expected '%s', got '%s'", expect, size)
20+
}
21+
}
22+
23+
func TestRAMInBytes(t *testing.T) {
24+
assertRAMInBytes(t, "32", false, 32)
25+
assertRAMInBytes(t, "32b", false, 32)
26+
assertRAMInBytes(t, "32B", false, 32)
27+
assertRAMInBytes(t, "32k", false, 32*1024)
28+
assertRAMInBytes(t, "32K", false, 32*1024)
29+
assertRAMInBytes(t, "32kb", false, 32*1024)
30+
assertRAMInBytes(t, "32Kb", false, 32*1024)
31+
assertRAMInBytes(t, "32Mb", false, 32*1024*1024)
32+
assertRAMInBytes(t, "32Gb", false, 32*1024*1024*1024)
33+
34+
assertRAMInBytes(t, "", true, -1)
35+
assertRAMInBytes(t, "hello", true, -1)
36+
assertRAMInBytes(t, "-32", true, -1)
37+
assertRAMInBytes(t, " 32 ", true, -1)
38+
assertRAMInBytes(t, "32 mb", true, -1)
39+
assertRAMInBytes(t, "32m b", true, -1)
40+
assertRAMInBytes(t, "32bm", true, -1)
41+
}
42+
43+
func assertRAMInBytes(t *testing.T, size string, expectError bool, expectedBytes int64) {
44+
actualBytes, err := RAMInBytes(size)
45+
if (err != nil) && !expectError {
46+
t.Errorf("Unexpected error parsing '%s': %s", size, err)
47+
}
48+
if (err == nil) && expectError {
49+
t.Errorf("Expected to get an error parsing '%s', but got none (bytes=%d)", size, actualBytes)
50+
}
51+
if actualBytes != expectedBytes {
52+
t.Errorf("Expected '%s' to parse as %d bytes, got %d", size, expectedBytes, actualBytes)
53+
}
54+
}

runconfig/parse.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/dotcloud/docker/opts"
1111
flag "github.com/dotcloud/docker/pkg/mflag"
1212
"github.com/dotcloud/docker/pkg/sysinfo"
13+
"github.com/dotcloud/docker/pkg/units"
1314
"github.com/dotcloud/docker/utils"
1415
)
1516

@@ -119,7 +120,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
119120

120121
var flMemory int64
121122
if *flMemoryString != "" {
122-
parsedMemory, err := utils.RAMInBytes(*flMemoryString)
123+
parsedMemory, err := units.RAMInBytes(*flMemoryString)
123124
if err != nil {
124125
return nil, nil, cmd, err
125126
}

utils/jsonmessage.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ package utils
33
import (
44
"encoding/json"
55
"fmt"
6-
"github.com/dotcloud/docker/pkg/term"
76
"io"
87
"strings"
98
"time"
9+
10+
"github.com/dotcloud/docker/pkg/term"
11+
"github.com/dotcloud/docker/pkg/units"
1012
)
1113

1214
type JSONError struct {
@@ -41,11 +43,11 @@ func (p *JSONProgress) String() string {
4143
if p.Current <= 0 && p.Total <= 0 {
4244
return ""
4345
}
44-
current := HumanSize(int64(p.Current))
46+
current := units.HumanSize(int64(p.Current))
4547
if p.Total <= 0 {
4648
return fmt.Sprintf("%8v", current)
4749
}
48-
total := HumanSize(int64(p.Total))
50+
total := units.HumanSize(int64(p.Total))
4951
percentage := int(float64(p.Current)/float64(p.Total)*100) / 2
5052
if width > 110 {
5153
pbBox = fmt.Sprintf("[%s>%s] ", strings.Repeat("=", percentage), strings.Repeat(" ", 50-percentage))

utils/utils.go

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"os"
1717
"os/exec"
1818
"path/filepath"
19-
"regexp"
2019
"runtime"
2120
"strconv"
2221
"strings"
@@ -83,79 +82,6 @@ func Errorf(format string, a ...interface{}) {
8382
logf("error", format, a...)
8483
}
8584

86-
// HumanDuration returns a human-readable approximation of a duration
87-
// (eg. "About a minute", "4 hours ago", etc.)
88-
func HumanDuration(d time.Duration) string {
89-
if seconds := int(d.Seconds()); seconds < 1 {
90-
return "Less than a second"
91-
} else if seconds < 60 {
92-
return fmt.Sprintf("%d seconds", seconds)
93-
} else if minutes := int(d.Minutes()); minutes == 1 {
94-
return "About a minute"
95-
} else if minutes < 60 {
96-
return fmt.Sprintf("%d minutes", minutes)
97-
} else if hours := int(d.Hours()); hours == 1 {
98-
return "About an hour"
99-
} else if hours < 48 {
100-
return fmt.Sprintf("%d hours", hours)
101-
} else if hours < 24*7*2 {
102-
return fmt.Sprintf("%d days", hours/24)
103-
} else if hours < 24*30*3 {
104-
return fmt.Sprintf("%d weeks", hours/24/7)
105-
} else if hours < 24*365*2 {
106-
return fmt.Sprintf("%d months", hours/24/30)
107-
}
108-
return fmt.Sprintf("%f years", d.Hours()/24/365)
109-
}
110-
111-
// HumanSize returns a human-readable approximation of a size
112-
// using SI standard (eg. "44kB", "17MB")
113-
func HumanSize(size int64) string {
114-
i := 0
115-
var sizef float64
116-
sizef = float64(size)
117-
units := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
118-
for sizef >= 1000.0 {
119-
sizef = sizef / 1000.0
120-
i++
121-
}
122-
return fmt.Sprintf("%.4g %s", sizef, units[i])
123-
}
124-
125-
// Parses a human-readable string representing an amount of RAM
126-
// in bytes, kibibytes, mebibytes or gibibytes, and returns the
127-
// number of bytes, or -1 if the string is unparseable.
128-
// Units are case-insensitive, and the 'b' suffix is optional.
129-
func RAMInBytes(size string) (bytes int64, err error) {
130-
re, error := regexp.Compile("^(\\d+)([kKmMgG])?[bB]?$")
131-
if error != nil {
132-
return -1, error
133-
}
134-
135-
matches := re.FindStringSubmatch(size)
136-
137-
if len(matches) != 3 {
138-
return -1, fmt.Errorf("Invalid size: '%s'", size)
139-
}
140-
141-
memLimit, error := strconv.ParseInt(matches[1], 10, 0)
142-
if error != nil {
143-
return -1, error
144-
}
145-
146-
unit := strings.ToLower(matches[2])
147-
148-
if unit == "k" {
149-
memLimit *= 1024
150-
} else if unit == "m" {
151-
memLimit *= 1024 * 1024
152-
} else if unit == "g" {
153-
memLimit *= 1024 * 1024 * 1024
154-
}
155-
156-
return memLimit, nil
157-
}
158-
15985
func Trunc(s string, maxlen int) string {
16086
if len(s) <= maxlen {
16187
return s

0 commit comments

Comments
 (0)