Browse code

Merge pull request #5756 from crosbymichael/move-units-to-pkg

Move duration and size to units pkg

Victor Vieux authored on 2014/05/15 03:36:14
Showing 11 changed files
... ...
@@ -28,6 +28,7 @@ import (
28 28
 	"github.com/dotcloud/docker/nat"
29 29
 	"github.com/dotcloud/docker/pkg/signal"
30 30
 	"github.com/dotcloud/docker/pkg/term"
31
+	"github.com/dotcloud/docker/pkg/units"
31 32
 	"github.com/dotcloud/docker/registry"
32 33
 	"github.com/dotcloud/docker/runconfig"
33 34
 	"github.com/dotcloud/docker/utils"
... ...
@@ -884,14 +885,14 @@ func (cli *DockerCli) CmdHistory(args ...string) error {
884 884
 				fmt.Fprintf(w, "%s\t", utils.TruncateID(outID))
885 885
 			}
886 886
 
887
-			fmt.Fprintf(w, "%s ago\t", utils.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))))
887
+			fmt.Fprintf(w, "%s ago\t", units.HumanDuration(time.Now().UTC().Sub(time.Unix(out.GetInt64("Created"), 0))))
888 888
 
889 889
 			if *noTrunc {
890 890
 				fmt.Fprintf(w, "%s\t", out.Get("CreatedBy"))
891 891
 			} else {
892 892
 				fmt.Fprintf(w, "%s\t", utils.Trunc(out.Get("CreatedBy"), 45))
893 893
 			}
894
-			fmt.Fprintf(w, "%s\n", utils.HumanSize(out.GetInt64("Size")))
894
+			fmt.Fprintf(w, "%s\n", units.HumanSize(out.GetInt64("Size")))
895 895
 		} else {
896 896
 			if *noTrunc {
897 897
 				fmt.Fprintln(w, outID)
... ...
@@ -1249,7 +1250,7 @@ func (cli *DockerCli) CmdImages(args ...string) error {
1249 1249
 				}
1250 1250
 
1251 1251
 				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")))
1252
+					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")))
1253 1253
 				} else {
1254 1254
 					fmt.Fprintln(w, outID)
1255 1255
 				}
... ...
@@ -1323,7 +1324,7 @@ func (cli *DockerCli) printTreeNode(noTrunc bool, image *engine.Env, prefix stri
1323 1323
 		imageID = utils.TruncateID(image.Get("Id"))
1324 1324
 	}
1325 1325
 
1326
-	fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, utils.HumanSize(image.GetInt64("VirtualSize")))
1326
+	fmt.Fprintf(cli.out, "%s%s Virtual Size: %s", prefix, imageID, units.HumanSize(image.GetInt64("VirtualSize")))
1327 1327
 	if image.GetList("RepoTags")[0] != "<none>:<none>" {
1328 1328
 		fmt.Fprintf(cli.out, " Tags: %s\n", strings.Join(image.GetList("RepoTags"), ", "))
1329 1329
 	} else {
... ...
@@ -1408,12 +1409,12 @@ func (cli *DockerCli) CmdPs(args ...string) error {
1408 1408
 				outCommand = utils.Trunc(outCommand, 20)
1409 1409
 			}
1410 1410
 			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, ","))
1411
+			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, ","))
1412 1412
 			if *size {
1413 1413
 				if out.GetInt("SizeRootFs") > 0 {
1414
-					fmt.Fprintf(w, "%s (virtual %s)\n", utils.HumanSize(out.GetInt64("SizeRw")), utils.HumanSize(out.GetInt64("SizeRootFs")))
1414
+					fmt.Fprintf(w, "%s (virtual %s)\n", units.HumanSize(out.GetInt64("SizeRw")), units.HumanSize(out.GetInt64("SizeRootFs")))
1415 1415
 				} else {
1416
-					fmt.Fprintf(w, "%s\n", utils.HumanSize(out.GetInt64("SizeRw")))
1416
+					fmt.Fprintf(w, "%s\n", units.HumanSize(out.GetInt64("SizeRw")))
1417 1417
 				}
1418 1418
 			} else {
1419 1419
 				fmt.Fprint(w, "\n")
... ...
@@ -8,7 +8,7 @@ import (
8 8
 	"strings"
9 9
 
10 10
 	"github.com/dotcloud/docker/pkg/libcontainer"
11
-	"github.com/dotcloud/docker/utils"
11
+	"github.com/dotcloud/docker/pkg/units"
12 12
 )
13 13
 
14 14
 type Action func(*libcontainer.Container, interface{}, string) error
... ...
@@ -75,7 +75,7 @@ func memory(container *libcontainer.Container, context interface{}, value string
75 75
 		return fmt.Errorf("cannot set cgroups when they are disabled")
76 76
 	}
77 77
 
78
-	v, err := utils.RAMInBytes(value)
78
+	v, err := units.RAMInBytes(value)
79 79
 	if err != nil {
80 80
 		return err
81 81
 	}
... ...
@@ -88,7 +88,7 @@ func memoryReservation(container *libcontainer.Container, context interface{}, v
88 88
 		return fmt.Errorf("cannot set cgroups when they are disabled")
89 89
 	}
90 90
 
91
-	v, err := utils.RAMInBytes(value)
91
+	v, err := units.RAMInBytes(value)
92 92
 	if err != nil {
93 93
 		return err
94 94
 	}
... ...
@@ -2,9 +2,10 @@ package daemon
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"github.com/dotcloud/docker/utils"
6 5
 	"sync"
7 6
 	"time"
7
+
8
+	"github.com/dotcloud/docker/pkg/units"
8 9
 )
9 10
 
10 11
 type State struct {
... ...
@@ -22,12 +23,12 @@ func (s *State) String() string {
22 22
 	defer s.RUnlock()
23 23
 
24 24
 	if s.Running {
25
-		return fmt.Sprintf("Up %s", utils.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
25
+		return fmt.Sprintf("Up %s", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))
26 26
 	}
27 27
 	if s.FinishedAt.IsZero() {
28 28
 		return ""
29 29
 	}
30
-	return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, utils.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
30
+	return fmt.Sprintf("Exited (%d) %s ago", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
31 31
 }
32 32
 
33 33
 func (s *State) IsRunning() bool {
34 34
new file mode 100644
... ...
@@ -0,0 +1,2 @@
0
+Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
1
+Victor Vieux <vieux@docker.com> (@vieux)
0 2
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+package units
1
+
2
+import (
3
+	"fmt"
4
+	"time"
5
+)
6
+
7
+// HumanDuration returns a human-readable approximation of a duration
8
+// (eg. "About a minute", "4 hours ago", etc.)
9
+func HumanDuration(d time.Duration) string {
10
+	if seconds := int(d.Seconds()); seconds < 1 {
11
+		return "Less than a second"
12
+	} else if seconds < 60 {
13
+		return fmt.Sprintf("%d seconds", seconds)
14
+	} else if minutes := int(d.Minutes()); minutes == 1 {
15
+		return "About a minute"
16
+	} else if minutes < 60 {
17
+		return fmt.Sprintf("%d minutes", minutes)
18
+	} else if hours := int(d.Hours()); hours == 1 {
19
+		return "About an hour"
20
+	} else if hours < 48 {
21
+		return fmt.Sprintf("%d hours", hours)
22
+	} else if hours < 24*7*2 {
23
+		return fmt.Sprintf("%d days", hours/24)
24
+	} else if hours < 24*30*3 {
25
+		return fmt.Sprintf("%d weeks", hours/24/7)
26
+	} else if hours < 24*365*2 {
27
+		return fmt.Sprintf("%d months", hours/24/30)
28
+	}
29
+	return fmt.Sprintf("%f years", d.Hours()/24/365)
30
+}
0 31
new file mode 100644
... ...
@@ -0,0 +1,56 @@
0
+package units
1
+
2
+import (
3
+	"fmt"
4
+	"regexp"
5
+	"strconv"
6
+	"strings"
7
+)
8
+
9
+// HumanSize returns a human-readable approximation of a size
10
+// using SI standard (eg. "44kB", "17MB")
11
+func HumanSize(size int64) string {
12
+	i := 0
13
+	var sizef float64
14
+	sizef = float64(size)
15
+	units := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
16
+	for sizef >= 1000.0 {
17
+		sizef = sizef / 1000.0
18
+		i++
19
+	}
20
+	return fmt.Sprintf("%.4g %s", sizef, units[i])
21
+}
22
+
23
+// Parses a human-readable string representing an amount of RAM
24
+// in bytes, kibibytes, mebibytes or gibibytes, and returns the
25
+// number of bytes, or -1 if the string is unparseable.
26
+// Units are case-insensitive, and the 'b' suffix is optional.
27
+func RAMInBytes(size string) (bytes int64, err error) {
28
+	re, error := regexp.Compile("^(\\d+)([kKmMgG])?[bB]?$")
29
+	if error != nil {
30
+		return -1, error
31
+	}
32
+
33
+	matches := re.FindStringSubmatch(size)
34
+
35
+	if len(matches) != 3 {
36
+		return -1, fmt.Errorf("Invalid size: '%s'", size)
37
+	}
38
+
39
+	memLimit, error := strconv.ParseInt(matches[1], 10, 0)
40
+	if error != nil {
41
+		return -1, error
42
+	}
43
+
44
+	unit := strings.ToLower(matches[2])
45
+
46
+	if unit == "k" {
47
+		memLimit *= 1024
48
+	} else if unit == "m" {
49
+		memLimit *= 1024 * 1024
50
+	} else if unit == "g" {
51
+		memLimit *= 1024 * 1024 * 1024
52
+	}
53
+
54
+	return memLimit, nil
55
+}
0 56
new file mode 100644
... ...
@@ -0,0 +1,54 @@
0
+package units
1
+
2
+import (
3
+	"strings"
4
+	"testing"
5
+)
6
+
7
+func TestHumanSize(t *testing.T) {
8
+
9
+	size := strings.Trim(HumanSize(1000), " \t")
10
+	expect := "1 kB"
11
+	if size != expect {
12
+		t.Errorf("1000 -> expected '%s', got '%s'", expect, size)
13
+	}
14
+
15
+	size = strings.Trim(HumanSize(1024), " \t")
16
+	expect = "1.024 kB"
17
+	if size != expect {
18
+		t.Errorf("1024 -> expected '%s', got '%s'", expect, size)
19
+	}
20
+}
21
+
22
+func TestRAMInBytes(t *testing.T) {
23
+	assertRAMInBytes(t, "32", false, 32)
24
+	assertRAMInBytes(t, "32b", false, 32)
25
+	assertRAMInBytes(t, "32B", false, 32)
26
+	assertRAMInBytes(t, "32k", false, 32*1024)
27
+	assertRAMInBytes(t, "32K", false, 32*1024)
28
+	assertRAMInBytes(t, "32kb", false, 32*1024)
29
+	assertRAMInBytes(t, "32Kb", false, 32*1024)
30
+	assertRAMInBytes(t, "32Mb", false, 32*1024*1024)
31
+	assertRAMInBytes(t, "32Gb", false, 32*1024*1024*1024)
32
+
33
+	assertRAMInBytes(t, "", true, -1)
34
+	assertRAMInBytes(t, "hello", true, -1)
35
+	assertRAMInBytes(t, "-32", true, -1)
36
+	assertRAMInBytes(t, " 32 ", true, -1)
37
+	assertRAMInBytes(t, "32 mb", true, -1)
38
+	assertRAMInBytes(t, "32m b", true, -1)
39
+	assertRAMInBytes(t, "32bm", true, -1)
40
+}
41
+
42
+func assertRAMInBytes(t *testing.T, size string, expectError bool, expectedBytes int64) {
43
+	actualBytes, err := RAMInBytes(size)
44
+	if (err != nil) && !expectError {
45
+		t.Errorf("Unexpected error parsing '%s': %s", size, err)
46
+	}
47
+	if (err == nil) && expectError {
48
+		t.Errorf("Expected to get an error parsing '%s', but got none (bytes=%d)", size, actualBytes)
49
+	}
50
+	if actualBytes != expectedBytes {
51
+		t.Errorf("Expected '%s' to parse as %d bytes, got %d", size, expectedBytes, actualBytes)
52
+	}
53
+}
... ...
@@ -10,6 +10,7 @@ import (
10 10
 	"github.com/dotcloud/docker/opts"
11 11
 	flag "github.com/dotcloud/docker/pkg/mflag"
12 12
 	"github.com/dotcloud/docker/pkg/sysinfo"
13
+	"github.com/dotcloud/docker/pkg/units"
13 14
 	"github.com/dotcloud/docker/utils"
14 15
 )
15 16
 
... ...
@@ -120,7 +121,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
120 120
 
121 121
 	var flMemory int64
122 122
 	if *flMemoryString != "" {
123
-		parsedMemory, err := utils.RAMInBytes(*flMemoryString)
123
+		parsedMemory, err := units.RAMInBytes(*flMemoryString)
124 124
 		if err != nil {
125 125
 			return nil, nil, cmd, err
126 126
 		}
... ...
@@ -3,10 +3,12 @@ package utils
3 3
 import (
4 4
 	"encoding/json"
5 5
 	"fmt"
6
-	"github.com/dotcloud/docker/pkg/term"
7 6
 	"io"
8 7
 	"strings"
9 8
 	"time"
9
+
10
+	"github.com/dotcloud/docker/pkg/term"
11
+	"github.com/dotcloud/docker/pkg/units"
10 12
 )
11 13
 
12 14
 type JSONError struct {
... ...
@@ -41,11 +43,11 @@ func (p *JSONProgress) String() string {
41 41
 	if p.Current <= 0 && p.Total <= 0 {
42 42
 		return ""
43 43
 	}
44
-	current := HumanSize(int64(p.Current))
44
+	current := units.HumanSize(int64(p.Current))
45 45
 	if p.Total <= 0 {
46 46
 		return fmt.Sprintf("%8v", current)
47 47
 	}
48
-	total := HumanSize(int64(p.Total))
48
+	total := units.HumanSize(int64(p.Total))
49 49
 	percentage := int(float64(p.Current)/float64(p.Total)*100) / 2
50 50
 	if width > 110 {
51 51
 		pbBox = fmt.Sprintf("[%s>%s] ", strings.Repeat("=", percentage), strings.Repeat(" ", 50-percentage))
... ...
@@ -16,7 +16,6 @@ import (
16 16
 	"os"
17 17
 	"os/exec"
18 18
 	"path/filepath"
19
-	"regexp"
20 19
 	"runtime"
21 20
 	"strconv"
22 21
 	"strings"
... ...
@@ -84,79 +83,6 @@ func Errorf(format string, a ...interface{}) {
84 84
 	logf("error", format, a...)
85 85
 }
86 86
 
87
-// HumanDuration returns a human-readable approximation of a duration
88
-// (eg. "About a minute", "4 hours ago", etc.)
89
-func HumanDuration(d time.Duration) string {
90
-	if seconds := int(d.Seconds()); seconds < 1 {
91
-		return "Less than a second"
92
-	} else if seconds < 60 {
93
-		return fmt.Sprintf("%d seconds", seconds)
94
-	} else if minutes := int(d.Minutes()); minutes == 1 {
95
-		return "About a minute"
96
-	} else if minutes < 60 {
97
-		return fmt.Sprintf("%d minutes", minutes)
98
-	} else if hours := int(d.Hours()); hours == 1 {
99
-		return "About an hour"
100
-	} else if hours < 48 {
101
-		return fmt.Sprintf("%d hours", hours)
102
-	} else if hours < 24*7*2 {
103
-		return fmt.Sprintf("%d days", hours/24)
104
-	} else if hours < 24*30*3 {
105
-		return fmt.Sprintf("%d weeks", hours/24/7)
106
-	} else if hours < 24*365*2 {
107
-		return fmt.Sprintf("%d months", hours/24/30)
108
-	}
109
-	return fmt.Sprintf("%f years", d.Hours()/24/365)
110
-}
111
-
112
-// HumanSize returns a human-readable approximation of a size
113
-// using SI standard (eg. "44kB", "17MB")
114
-func HumanSize(size int64) string {
115
-	i := 0
116
-	var sizef float64
117
-	sizef = float64(size)
118
-	units := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
119
-	for sizef >= 1000.0 {
120
-		sizef = sizef / 1000.0
121
-		i++
122
-	}
123
-	return fmt.Sprintf("%.4g %s", sizef, units[i])
124
-}
125
-
126
-// Parses a human-readable string representing an amount of RAM
127
-// in bytes, kibibytes, mebibytes or gibibytes, and returns the
128
-// number of bytes, or -1 if the string is unparseable.
129
-// Units are case-insensitive, and the 'b' suffix is optional.
130
-func RAMInBytes(size string) (bytes int64, err error) {
131
-	re, error := regexp.Compile("^(\\d+)([kKmMgG])?[bB]?$")
132
-	if error != nil {
133
-		return -1, error
134
-	}
135
-
136
-	matches := re.FindStringSubmatch(size)
137
-
138
-	if len(matches) != 3 {
139
-		return -1, fmt.Errorf("Invalid size: '%s'", size)
140
-	}
141
-
142
-	memLimit, error := strconv.ParseInt(matches[1], 10, 0)
143
-	if error != nil {
144
-		return -1, error
145
-	}
146
-
147
-	unit := strings.ToLower(matches[2])
148
-
149
-	if unit == "k" {
150
-		memLimit *= 1024
151
-	} else if unit == "m" {
152
-		memLimit *= 1024 * 1024
153
-	} else if unit == "g" {
154
-		memLimit *= 1024 * 1024 * 1024
155
-	}
156
-
157
-	return memLimit, nil
158
-}
159
-
160 87
 func Trunc(s string, maxlen int) string {
161 88
 	if len(s) <= maxlen {
162 89
 		return s
... ...
@@ -6,7 +6,6 @@ import (
6 6
 	"io"
7 7
 	"io/ioutil"
8 8
 	"os"
9
-	"strings"
10 9
 	"testing"
11 10
 )
12 11
 
... ...
@@ -271,54 +270,6 @@ func TestCompareKernelVersion(t *testing.T) {
271 271
 		-1)
272 272
 }
273 273
 
274
-func TestHumanSize(t *testing.T) {
275
-
276
-	size := strings.Trim(HumanSize(1000), " \t")
277
-	expect := "1 kB"
278
-	if size != expect {
279
-		t.Errorf("1000 -> expected '%s', got '%s'", expect, size)
280
-	}
281
-
282
-	size = strings.Trim(HumanSize(1024), " \t")
283
-	expect = "1.024 kB"
284
-	if size != expect {
285
-		t.Errorf("1024 -> expected '%s', got '%s'", expect, size)
286
-	}
287
-}
288
-
289
-func TestRAMInBytes(t *testing.T) {
290
-	assertRAMInBytes(t, "32", false, 32)
291
-	assertRAMInBytes(t, "32b", false, 32)
292
-	assertRAMInBytes(t, "32B", false, 32)
293
-	assertRAMInBytes(t, "32k", false, 32*1024)
294
-	assertRAMInBytes(t, "32K", false, 32*1024)
295
-	assertRAMInBytes(t, "32kb", false, 32*1024)
296
-	assertRAMInBytes(t, "32Kb", false, 32*1024)
297
-	assertRAMInBytes(t, "32Mb", false, 32*1024*1024)
298
-	assertRAMInBytes(t, "32Gb", false, 32*1024*1024*1024)
299
-
300
-	assertRAMInBytes(t, "", true, -1)
301
-	assertRAMInBytes(t, "hello", true, -1)
302
-	assertRAMInBytes(t, "-32", true, -1)
303
-	assertRAMInBytes(t, " 32 ", true, -1)
304
-	assertRAMInBytes(t, "32 mb", true, -1)
305
-	assertRAMInBytes(t, "32m b", true, -1)
306
-	assertRAMInBytes(t, "32bm", true, -1)
307
-}
308
-
309
-func assertRAMInBytes(t *testing.T, size string, expectError bool, expectedBytes int64) {
310
-	actualBytes, err := RAMInBytes(size)
311
-	if (err != nil) && !expectError {
312
-		t.Errorf("Unexpected error parsing '%s': %s", size, err)
313
-	}
314
-	if (err == nil) && expectError {
315
-		t.Errorf("Expected to get an error parsing '%s', but got none (bytes=%d)", size, actualBytes)
316
-	}
317
-	if actualBytes != expectedBytes {
318
-		t.Errorf("Expected '%s' to parse as %d bytes, got %d", size, expectedBytes, actualBytes)
319
-	}
320
-}
321
-
322 274
 func TestParseHost(t *testing.T) {
323 275
 	var (
324 276
 		defaultHttpHost = "127.0.0.1"