Browse code

bump to master

Victor Vieux authored on 2013/05/09 09:20:16
Showing 12 changed files
... ...
@@ -1,5 +1,30 @@
1 1
 # Changelog
2 2
 
3
+## 0.3.1 (2013-05-08)
4
+ + Builder: Implement the autorun capability within docker builder
5
+ + Builder: Add caching to docker builder
6
+ + Builder: Add support for docker builder with native API as top level command
7
+ + Runtime: Add go version to debug infos
8
+ + Builder: Implement ENV within docker builder
9
+ + Registry: Add docker search top level command in order to search a repository
10
+ + Images: output graph of images to dot (graphviz)
11
+ + Documentation: new introduction and high-level overview
12
+ + Documentation: Add the documentation for docker builder
13
+ + Website: new high-level overview
14
+ - Makefile: Swap "go get" for "go get -d", especially to compile on go1.1rc
15
+ - Images: fix ByParent function
16
+ - Builder: Check the command existance prior create and add Unit tests for the case
17
+ - Registry: Fix pull for official images with specific tag
18
+ - Registry: Fix issue when login in with a different user and trying to push
19
+ - Documentation: CSS fix for docker documentation to make REST API docs look better.
20
+ - Documentation: Fixed CouchDB example page header mistake
21
+ - Documentation: fixed README formatting
22
+ * Registry: Improve checksum - async calculation
23
+ * Runtime: kernel version - don't show the dash if flavor is empty
24
+ * Documentation: updated www.docker.io website.
25
+ * Builder: use any whitespaces instead of tabs
26
+ * Packaging: packaging ubuntu; issue #510: Use goland-stable PPA package to build docker
27
+
3 28
 ## 0.3.0 (2013-05-06)
4 29
  + Registry: Implement the new registry
5 30
  + Documentation: new example: sharing data between 2 couchdb databases
... ...
@@ -39,7 +39,7 @@ $(DOCKER_BIN): $(DOCKER_DIR)
39 39
 $(DOCKER_DIR):
40 40
 	@mkdir -p $(dir $@)
41 41
 	@if [ -h $@ ]; then rm -f $@; fi; ln -sf $(CURDIR)/ $@
42
-	@(cd $(DOCKER_MAIN); go get $(GO_OPTIONS))
42
+	@(cd $(DOCKER_MAIN); go get -d $(GO_OPTIONS))
43 43
 
44 44
 whichrelease:
45 45
 	echo $(RELEASE_VERSION)
... ...
@@ -18,6 +18,7 @@ type ApiInfo struct {
18 18
 	Version     string
19 19
 	Images      int
20 20
 	Debug       bool
21
+	GoVersion   string
21 22
 	NFd         int `json:",omitempty"`
22 23
 	NGoroutines int `json:",omitempty"`
23 24
 }
... ...
@@ -22,7 +22,7 @@ import (
22 22
 	"unicode"
23 23
 )
24 24
 
25
-const VERSION = "0.3.0"
25
+const VERSION = "0.3.1"
26 26
 
27 27
 var (
28 28
 	GIT_COMMIT string
... ...
@@ -362,7 +362,7 @@ func CmdInfo(args ...string) error {
362 362
 	if err != nil {
363 363
 		return err
364 364
 	}
365
-	fmt.Printf("containers: %d\nversion: %s\nimages: %d\n", out.Containers, out.Version, out.Images)
365
+	fmt.Printf("containers: %d\nversion: %s\nimages: %d\nGo version: %s\n", out.Containers, out.Version, out.Images, out.GoVersion)
366 366
 	if out.Debug {
367 367
 		fmt.Println("debug mode enabled")
368 368
 		fmt.Printf("fds: %d\ngoroutines: %d\n", out.NFd, out.NGoroutines)
... ...
@@ -874,6 +874,7 @@ Display system-wide information
874 874
 		"Containers":11,
875 875
 		"Version":"0.2.2",
876 876
 		"Images":16,
877
+		"GoVersion":"go1.0.3",
877 878
 		"Debug":false
878 879
 	   }
879 880
 
... ...
@@ -330,3 +330,7 @@ section.header {
330 330
 @media (max-width: 480px) {
331 331
   
332 332
 }
333
+/* Misc fixes */
334
+table th {
335
+  text-align: left;
336
+}
... ...
@@ -449,4 +449,9 @@ section.header {
449 449
 @media (max-width: 480px) {
450 450
 
451 451
 
452
+}
453
+
454
+/* Misc fixes */
455
+table th {
456
+  text-align: left;
452 457
 }
453 458
\ No newline at end of file
... ...
@@ -9,14 +9,18 @@ import (
9 9
 	"path"
10 10
 	"path/filepath"
11 11
 	"strings"
12
+	"sync"
12 13
 	"time"
13 14
 )
14 15
 
15 16
 // A Graph is a store for versioned filesystem images and the relationship between them.
16 17
 type Graph struct {
17
-	Root       string
18
-	idIndex    *TruncIndex
19
-	httpClient *http.Client
18
+	Root         string
19
+	idIndex      *TruncIndex
20
+	httpClient   *http.Client
21
+	checksumLock map[string]*sync.Mutex
22
+	lockSumFile  *sync.Mutex
23
+	lockSumMap   *sync.Mutex
20 24
 }
21 25
 
22 26
 // NewGraph instantiates a new graph at the given root path in the filesystem.
... ...
@@ -27,12 +31,15 @@ func NewGraph(root string) (*Graph, error) {
27 27
 		return nil, err
28 28
 	}
29 29
 	// Create the root directory if it doesn't exists
30
-	if err := os.Mkdir(root, 0700); err != nil && !os.IsExist(err) {
30
+	if err := os.MkdirAll(root, 0700); err != nil && !os.IsExist(err) {
31 31
 		return nil, err
32 32
 	}
33 33
 	graph := &Graph{
34
-		Root:    abspath,
35
-		idIndex: NewTruncIndex(),
34
+		Root:         abspath,
35
+		idIndex:      NewTruncIndex(),
36
+		checksumLock: make(map[string]*sync.Mutex),
37
+		lockSumFile:  &sync.Mutex{},
38
+		lockSumMap:   &sync.Mutex{},
36 39
 	}
37 40
 	if err := graph.restore(); err != nil {
38 41
 		return nil, err
... ...
@@ -82,6 +89,11 @@ func (graph *Graph) Get(name string) (*Image, error) {
82 82
 		return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.Id)
83 83
 	}
84 84
 	img.graph = graph
85
+	graph.lockSumMap.Lock()
86
+	defer graph.lockSumMap.Unlock()
87
+	if _, exists := graph.checksumLock[img.Id]; !exists {
88
+		graph.checksumLock[img.Id] = &sync.Mutex{}
89
+	}
85 90
 	return img, nil
86 91
 }
87 92
 
... ...
@@ -103,7 +115,7 @@ func (graph *Graph) Create(layerData Archive, container *Container, comment, aut
103 103
 	if err := graph.Register(layerData, img); err != nil {
104 104
 		return nil, err
105 105
 	}
106
-	img.Checksum()
106
+	go img.Checksum()
107 107
 	return img, nil
108 108
 }
109 109
 
... ...
@@ -131,6 +143,7 @@ func (graph *Graph) Register(layerData Archive, img *Image) error {
131 131
 	}
132 132
 	img.graph = graph
133 133
 	graph.idIndex.Add(img.Id)
134
+	graph.checksumLock[img.Id] = &sync.Mutex{}
134 135
 	return nil
135 136
 }
136 137
 
... ...
@@ -35,8 +35,9 @@ func LoadImage(root string) (*Image, error) {
35 35
 	if err != nil {
36 36
 		return nil, err
37 37
 	}
38
-	var img Image
39
-	if err := json.Unmarshal(jsonData, &img); err != nil {
38
+	img := &Image{}
39
+
40
+	if err := json.Unmarshal(jsonData, img); err != nil {
40 41
 		return nil, err
41 42
 	}
42 43
 	if err := ValidateId(img.Id); err != nil {
... ...
@@ -52,8 +53,7 @@ func LoadImage(root string) (*Image, error) {
52 52
 	} else if !stat.IsDir() {
53 53
 		return nil, fmt.Errorf("Couldn't load image %s: %s is not a directory", img.Id, layerPath(root))
54 54
 	}
55
-
56
-	return &img, nil
55
+	return img, nil
57 56
 }
58 57
 
59 58
 func StoreImage(img *Image, layerData Archive, root string) error {
... ...
@@ -261,19 +261,22 @@ func (img *Image) layer() (string, error) {
261 261
 }
262 262
 
263 263
 func (img *Image) Checksum() (string, error) {
264
+	img.graph.checksumLock[img.Id].Lock()
265
+	defer img.graph.checksumLock[img.Id].Unlock()
266
+
264 267
 	root, err := img.root()
265 268
 	if err != nil {
266 269
 		return "", err
267 270
 	}
268 271
 
269 272
 	checksumDictPth := path.Join(root, "..", "..", "checksums")
270
-	checksums := new(map[string]string)
273
+	checksums := make(map[string]string)
271 274
 
272 275
 	if checksumDict, err := ioutil.ReadFile(checksumDictPth); err == nil {
273
-		if err := json.Unmarshal(checksumDict, checksums); err != nil {
276
+		if err := json.Unmarshal(checksumDict, &checksums); err != nil {
274 277
 			return "", err
275 278
 		}
276
-		if checksum, ok := (*checksums)[img.Id]; ok {
279
+		if checksum, ok := checksums[img.Id]; ok {
277 280
 			return checksum, nil
278 281
 		}
279 282
 	}
... ...
@@ -299,20 +302,26 @@ func (img *Image) Checksum() (string, error) {
299 299
 	if _, err := h.Write([]byte("\n")); err != nil {
300 300
 		return "", err
301 301
 	}
302
+
302 303
 	if _, err := io.Copy(h, layerData); err != nil {
303 304
 		return "", err
304 305
 	}
305 306
 
306 307
 	hash := "sha256:" + hex.EncodeToString(h.Sum(nil))
307
-	if *checksums == nil {
308
-		*checksums = map[string]string{}
308
+	checksums[img.Id] = hash
309
+
310
+	// Reload the json file to make sure not to overwrite faster sums
311
+	img.graph.lockSumFile.Lock()
312
+	defer img.graph.lockSumFile.Unlock()
313
+	if checksumDict, err := ioutil.ReadFile(checksumDictPth); err == nil {
314
+		if err := json.Unmarshal(checksumDict, &checksums); err != nil {
315
+			return "", err
316
+		}
309 317
 	}
310
-	(*checksums)[img.Id] = hash
311 318
 	checksumJson, err := json.Marshal(checksums)
312 319
 	if err != nil {
313 320
 		return hash, err
314 321
 	}
315
-
316 322
 	if err := ioutil.WriteFile(checksumDictPth, checksumJson, 0600); err != nil {
317 323
 		return hash, err
318 324
 	}
... ...
@@ -1,3 +1,30 @@
1
+lxc-docker (0.3.1-1) precise; urgency=low
2
+ - Builder: Implement the autorun capability within docker builder
3
+ - Builder: Add caching to docker builder
4
+ - Builder: Add support for docker builder with native API as top level command
5
+ - Runtime: Add go version to debug infos
6
+ - Builder: Implement ENV within docker builder
7
+ - Registry: Add docker search top level command in order to search a repository
8
+ - Images: output graph of images to dot (graphviz)
9
+ - Documentation: new introduction and high-level overview
10
+ - Documentation: Add the documentation for docker builder
11
+ - Website: new high-level overview
12
+ - Makefile: Swap "go get" for "go get -d", especially to compile on go1.1rc
13
+ - Images: fix ByParent function
14
+ - Builder: Check the command existance prior create and add Unit tests for the case
15
+ - Registry: Fix pull for official images with specific tag
16
+ - Registry: Fix issue when login in with a different user and trying to push
17
+ - Documentation: CSS fix for docker documentation to make REST API docs look better.
18
+ - Documentation: Fixed CouchDB example page header mistake
19
+ - Documentation: fixed README formatting
20
+ - Registry: Improve checksum - async calculation
21
+ - Runtime: kernel version - don't show the dash if flavor is empty
22
+ - Documentation: updated www.docker.io website.
23
+ - Builder: use any whitespaces instead of tabs
24
+ - Packaging: packaging ubuntu; issue #510: Use goland-stable PPA package to build docker
25
+
26
+ -- dotCloud <ops@dotcloud.com>  Fri, 8 May 2013 00:00:00 -0700
27
+
1 28
 lxc-docker (0.3.0-1) precise; urgency=low
2 29
   - Registry: Implement the new registry
3 30
   - Documentation: new example: sharing data between 2 couchdb databases
... ...
@@ -194,18 +194,16 @@ func (graph *Graph) getRemoteTags(stdout io.Writer, registries []string, reposit
194 194
 			return nil, fmt.Errorf("Repository not found")
195 195
 		}
196 196
 
197
-		result := new(map[string]string)
197
+		result := make(map[string]string)
198 198
 
199 199
 		rawJson, err := ioutil.ReadAll(res.Body)
200 200
 		if err != nil {
201 201
 			return nil, err
202 202
 		}
203
-		if err = json.Unmarshal(rawJson, result); err != nil {
203
+		if err = json.Unmarshal(rawJson, &result); err != nil {
204 204
 			return nil, err
205 205
 		}
206
-
207
-		return *result, nil
208
-
206
+		return result, nil
209 207
 	}
210 208
 	return nil, fmt.Errorf("Could not reach any registry endpoint")
211 209
 }
... ...
@@ -308,6 +306,50 @@ func (graph *Graph) PullRepository(stdout io.Writer, remote, askedTag string, re
308 308
 		return fmt.Errorf("Index response didn't contain any endpoints")
309 309
 	}
310 310
 
311
+	checksumsJson, err := ioutil.ReadAll(res.Body)
312
+	if err != nil {
313
+		return err
314
+	}
315
+
316
+	// Reload the json file to make sure not to overwrite faster sums
317
+	err = func() error {
318
+		localChecksums := make(map[string]string)
319
+		remoteChecksums := []struct {
320
+			Id       string `json: "id"`
321
+			Checksum string `json: "checksum"`
322
+		}{}
323
+		checksumDictPth := path.Join(graph.Root, "..", "checksums")
324
+
325
+		if err := json.Unmarshal(checksumsJson, &remoteChecksums); err != nil {
326
+			return err
327
+		}
328
+
329
+		graph.lockSumFile.Lock()
330
+		defer graph.lockSumFile.Unlock()
331
+
332
+		if checksumDict, err := ioutil.ReadFile(checksumDictPth); err == nil {
333
+			if err := json.Unmarshal(checksumDict, &localChecksums); err != nil {
334
+				return err
335
+			}
336
+		}
337
+
338
+		for _, elem := range remoteChecksums {
339
+			localChecksums[elem.Id] = elem.Checksum
340
+		}
341
+
342
+		checksumsJson, err = json.Marshal(localChecksums)
343
+		if err != nil {
344
+			return err
345
+		}
346
+		if err := ioutil.WriteFile(checksumDictPth, checksumsJson, 0600); err != nil {
347
+			return err
348
+		}
349
+		return nil
350
+	}()
351
+	if err != nil {
352
+		return err
353
+	}
354
+
311 355
 	var tagsList map[string]string
312 356
 	if askedTag == "" {
313 357
 		tagsList, err = graph.getRemoteTags(stdout, endpoints, remote, token)
... ...
@@ -427,9 +469,15 @@ func pushImageRec(graph *Graph, stdout io.Writer, img *Image, registry string, t
427 427
 	if err != nil {
428 428
 		return fmt.Errorf("Failed to upload layer: %s", err)
429 429
 	}
430
-	res3.Body.Close()
430
+	defer res3.Body.Close()
431
+
431 432
 	if res3.StatusCode != 200 {
432
-		return fmt.Errorf("Received HTTP code %d while uploading layer", res3.StatusCode)
433
+		errBody, err := ioutil.ReadAll(res3.Body)
434
+		if err != nil {
435
+			return fmt.Errorf("HTTP code %d while uploading metadata and error when"+
436
+				" trying to parse response body: %v", res.StatusCode, err)
437
+		}
438
+		return fmt.Errorf("Received HTTP code %d while uploading layer: %s", res3.StatusCode, errBody)
433 439
 	}
434 440
 	return nil
435 441
 }
... ...
@@ -612,8 +660,7 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re
612 612
 }
613 613
 
614 614
 func (graph *Graph) Checksums(output io.Writer, repo Repository) ([]map[string]string, error) {
615
-	var result []map[string]string
616
-	checksums := map[string]string{}
615
+	checksums := make(map[string]string)
617 616
 	for _, id := range repo {
618 617
 		img, err := graph.Get(id)
619 618
 		if err != nil {
... ...
@@ -634,7 +681,7 @@ func (graph *Graph) Checksums(output io.Writer, repo Repository) ([]map[string]s
634 634
 		}
635 635
 	}
636 636
 	i := 0
637
-	result = make([]map[string]string, len(checksums))
637
+	result := make([]map[string]string, len(checksums))
638 638
 	for id, sum := range checksums {
639 639
 		result[i] = map[string]string{
640 640
 			"id":       id,
... ...
@@ -201,6 +201,7 @@ func (srv *Server) DockerInfo() ApiInfo {
201 201
 	out.Containers = len(srv.runtime.List())
202 202
 	out.Version = VERSION
203 203
 	out.Images = imgcount
204
+	out.GoVersion = runtime.Version()
204 205
 	if os.Getenv("DEBUG") != "" {
205 206
 		out.Debug = true
206 207
 		out.NFd = getTotalUsedFds()