Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com>
unclejack authored on 2015/06/16 18:51:27... | ... |
@@ -11,7 +11,7 @@ import ( |
11 | 11 |
"github.com/docker/docker/pkg/system" |
12 | 12 |
) |
13 | 13 |
|
14 |
-// canonicalTarNameForPath returns platform-specific filepath |
|
14 |
+// CanonicalTarNameForPath returns platform-specific filepath |
|
15 | 15 |
// to canonical posix-style path for tar archival. p is relative |
16 | 16 |
// path. |
17 | 17 |
func CanonicalTarNameForPath(p string) (string, error) { |
... | ... |
@@ -133,7 +133,7 @@ func testBreakout(untarFn string, tmpdir string, headers []*tar.Header) error { |
133 | 133 |
helloStat.Size() != fi.Size() || |
134 | 134 |
!bytes.Equal(helloData, b) { |
135 | 135 |
// codepath taken if hello has been modified |
136 |
- return fmt.Errorf("archive breakout: file %q has been modified. Contents: expected=%q, got=%q. FileInfo: expected=%#v, got=%#v.", hello, helloData, b, helloStat, fi) |
|
136 |
+ return fmt.Errorf("archive breakout: file %q has been modified. Contents: expected=%q, got=%q. FileInfo: expected=%#v, got=%#v", hello, helloData, b, helloStat, fi) |
|
137 | 137 |
} |
138 | 138 |
|
139 | 139 |
// Check that nothing in dest/ has the same content as victim/hello. |
... | ... |
@@ -58,6 +58,10 @@ func untar() { |
58 | 58 |
os.Exit(0) |
59 | 59 |
} |
60 | 60 |
|
61 |
+// Untar reads a stream of bytes from `archive`, parses it as a tar archive, |
|
62 |
+// and unpacks it into the directory at `dest`. |
|
63 |
+// The archive may be compressed with one of the following algorithms: |
|
64 |
+// identity (uncompressed), gzip, bzip2, xz. |
|
61 | 65 |
func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error { |
62 | 66 |
if tarArchive == nil { |
63 | 67 |
return fmt.Errorf("Empty archive") |
... | ... |
@@ -133,17 +137,18 @@ func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error |
133 | 133 |
return fmt.Errorf("Untar re-exec error: %v: output: %s", err, output) |
134 | 134 |
} |
135 | 135 |
return nil |
136 |
- } else { |
|
137 |
- cmd.Env = append(cmd.Env, fmt.Sprintf("OPT=%s", data)) |
|
138 |
- out, err := cmd.CombinedOutput() |
|
139 |
- if err != nil { |
|
140 |
- return fmt.Errorf("Untar %s %s", err, out) |
|
141 |
- } |
|
142 |
- return nil |
|
143 | 136 |
} |
137 |
+ cmd.Env = append(cmd.Env, fmt.Sprintf("OPT=%s", data)) |
|
138 |
+ out, err := cmd.CombinedOutput() |
|
139 |
+ if err != nil { |
|
140 |
+ return fmt.Errorf("Untar %s %s", err, out) |
|
141 |
+ } |
|
142 |
+ return nil |
|
144 | 143 |
|
145 | 144 |
} |
146 | 145 |
|
146 |
+// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other. |
|
147 |
+// If either Tar or Untar fails, TarUntar aborts and returns the error. |
|
147 | 148 |
func TarUntar(src, dst string) error { |
148 | 149 |
return chrootArchiver.TarUntar(src, dst) |
149 | 150 |
} |
... | ... |
@@ -69,6 +69,9 @@ func applyLayer() { |
69 | 69 |
os.Exit(0) |
70 | 70 |
} |
71 | 71 |
|
72 |
+// ApplyLayer parses a diff in the standard layer format from `layer`, and |
|
73 |
+// applies it to the directory `dest`. Returns the size in bytes of the |
|
74 |
+// contents of the layer. |
|
72 | 75 |
func ApplyLayer(dest string, layer archive.ArchiveReader) (size int64, err error) { |
73 | 76 |
dest = filepath.Clean(dest) |
74 | 77 |
decompressed, err := archive.DecompressStream(layer) |
... | ... |
@@ -20,7 +20,7 @@ func Empty(pattern string) bool { |
20 | 20 |
return pattern == "" |
21 | 21 |
} |
22 | 22 |
|
23 |
-// Cleanpatterns takes a slice of patterns returns a new |
|
23 |
+// CleanPatterns takes a slice of patterns returns a new |
|
24 | 24 |
// slice of patterns cleaned with filepath.Clean, stripped |
25 | 25 |
// of any empty patterns and lets the caller know whether the |
26 | 26 |
// slice contains any exception patterns (prefixed with !). |
... | ... |
@@ -73,7 +73,7 @@ func Matches(file string, patterns []string) (bool, error) { |
73 | 73 |
return OptimizedMatches(file, patterns, patDirs) |
74 | 74 |
} |
75 | 75 |
|
76 |
-// Matches is basically the same as fileutils.Matches() but optimized for archive.go. |
|
76 |
+// OptimizedMatches is basically the same as fileutils.Matches() but optimized for archive.go. |
|
77 | 77 |
// It will assume that the inputs have been preprocessed and therefore the function |
78 | 78 |
// doen't need to do as much error checking and clean-up. This was done to avoid |
79 | 79 |
// repeating these steps on each file being checked during the archive process. |
... | ... |
@@ -8,6 +8,8 @@ import ( |
8 | 8 |
_ "code.google.com/p/gosqlite/sqlite3" // registers sqlite |
9 | 9 |
) |
10 | 10 |
|
11 |
+// NewSqliteConn opens a connection to a sqlite |
|
12 |
+// database. |
|
11 | 13 |
func NewSqliteConn(root string) (*Database, error) { |
12 | 14 |
conn, err := sql.Open("sqlite3", root) |
13 | 15 |
if err != nil { |
... | ... |
@@ -41,17 +41,25 @@ type Edge struct { |
41 | 41 |
ParentID string |
42 | 42 |
} |
43 | 43 |
|
44 |
+// Entities stores the list of entities |
|
44 | 45 |
type Entities map[string]*Entity |
46 |
+ |
|
47 |
+// Edges stores the relationships between entities |
|
45 | 48 |
type Edges []*Edge |
46 | 49 |
|
50 |
+// WalkFunc is a function invoked to process an individual entity |
|
47 | 51 |
type WalkFunc func(fullPath string, entity *Entity) error |
48 | 52 |
|
49 |
-// Graph database for storing entities and their relationships |
|
53 |
+// Database is a graph database for storing entities and their relationships |
|
50 | 54 |
type Database struct { |
51 | 55 |
conn *sql.DB |
52 | 56 |
mux sync.RWMutex |
53 | 57 |
} |
54 | 58 |
|
59 |
+// IsNonUniqueNameError processes the error to check if it's caused by |
|
60 |
+// a constraint violation. |
|
61 |
+// This is necessary because the error isn't the same across various |
|
62 |
+// sqlite versions. |
|
55 | 63 |
func IsNonUniqueNameError(err error) bool { |
56 | 64 |
str := err.Error() |
57 | 65 |
// sqlite 3.7.17-1ubuntu1 returns: |
... | ... |
@@ -72,7 +80,7 @@ func IsNonUniqueNameError(err error) bool { |
72 | 72 |
return false |
73 | 73 |
} |
74 | 74 |
|
75 |
-// Create a new graph database initialized with a root entity |
|
75 |
+// NewDatabase creates a new graph database initialized with a root entity |
|
76 | 76 |
func NewDatabase(conn *sql.DB) (*Database, error) { |
77 | 77 |
if conn == nil { |
78 | 78 |
return nil, fmt.Errorf("Database connection cannot be nil") |
... | ... |
@@ -163,7 +171,7 @@ func (db *Database) Set(fullPath, id string) (*Entity, error) { |
163 | 163 |
return e, nil |
164 | 164 |
} |
165 | 165 |
|
166 |
-// Return true if a name already exists in the database |
|
166 |
+// Exists returns true if a name already exists in the database |
|
167 | 167 |
func (db *Database) Exists(name string) bool { |
168 | 168 |
db.mux.RLock() |
169 | 169 |
defer db.mux.RUnlock() |
... | ... |
@@ -190,14 +198,14 @@ func (db *Database) setEdge(parentPath, name string, e *Entity, tx *sql.Tx) erro |
190 | 190 |
return nil |
191 | 191 |
} |
192 | 192 |
|
193 |
-// Return the root "/" entity for the database |
|
193 |
+// RootEntity returns the root "/" entity for the database |
|
194 | 194 |
func (db *Database) RootEntity() *Entity { |
195 | 195 |
return &Entity{ |
196 | 196 |
id: "0", |
197 | 197 |
} |
198 | 198 |
} |
199 | 199 |
|
200 |
-// Return the entity for a given path |
|
200 |
+// Get returns the entity for a given path |
|
201 | 201 |
func (db *Database) Get(name string) *Entity { |
202 | 202 |
db.mux.RLock() |
203 | 203 |
defer db.mux.RUnlock() |
... | ... |
@@ -274,7 +282,7 @@ func (db *Database) Walk(name string, walkFunc WalkFunc, depth int) error { |
274 | 274 |
return nil |
275 | 275 |
} |
276 | 276 |
|
277 |
-// Return the children of the specified entity |
|
277 |
+// Children returns the children of the specified entity |
|
278 | 278 |
func (db *Database) Children(name string, depth int) ([]WalkMeta, error) { |
279 | 279 |
db.mux.RLock() |
280 | 280 |
defer db.mux.RUnlock() |
... | ... |
@@ -287,7 +295,7 @@ func (db *Database) Children(name string, depth int) ([]WalkMeta, error) { |
287 | 287 |
return db.children(e, name, depth, nil) |
288 | 288 |
} |
289 | 289 |
|
290 |
-// Return the parents of a specified entity |
|
290 |
+// Parents returns the parents of a specified entity |
|
291 | 291 |
func (db *Database) Parents(name string) ([]string, error) { |
292 | 292 |
db.mux.RLock() |
293 | 293 |
defer db.mux.RUnlock() |
... | ... |
@@ -299,7 +307,7 @@ func (db *Database) Parents(name string) ([]string, error) { |
299 | 299 |
return db.parents(e) |
300 | 300 |
} |
301 | 301 |
|
302 |
-// Return the refrence count for a specified id |
|
302 |
+// Refs returns the refrence count for a specified id |
|
303 | 303 |
func (db *Database) Refs(id string) int { |
304 | 304 |
db.mux.RLock() |
305 | 305 |
defer db.mux.RUnlock() |
... | ... |
@@ -311,7 +319,7 @@ func (db *Database) Refs(id string) int { |
311 | 311 |
return count |
312 | 312 |
} |
313 | 313 |
|
314 |
-// Return all the id's path references |
|
314 |
+// RefPaths returns all the id's path references |
|
315 | 315 |
func (db *Database) RefPaths(id string) Edges { |
316 | 316 |
db.mux.RLock() |
317 | 317 |
defer db.mux.RUnlock() |
... | ... |
@@ -360,7 +368,7 @@ func (db *Database) Delete(name string) error { |
360 | 360 |
return nil |
361 | 361 |
} |
362 | 362 |
|
363 |
-// Remove the entity with the specified id |
|
363 |
+// Purge removes the entity with the specified id |
|
364 | 364 |
// Walk the graph to make sure all references to the entity |
365 | 365 |
// are removed and return the number of references removed |
366 | 366 |
func (db *Database) Purge(id string) (int, error) { |
... | ... |
@@ -480,7 +488,7 @@ func (db *Database) children(e *Entity, name string, depth int, entities []WalkM |
480 | 480 |
if depth != 0 { |
481 | 481 |
nDepth := depth |
482 | 482 |
if depth != -1 { |
483 |
- nDepth -= 1 |
|
483 |
+ nDepth-- |
|
484 | 484 |
} |
485 | 485 |
entities, err = db.children(child, meta.FullPath, nDepth, entities) |
486 | 486 |
if err != nil { |
... | ... |
@@ -523,12 +531,12 @@ func (db *Database) child(parent *Entity, name string) *Entity { |
523 | 523 |
return &Entity{id} |
524 | 524 |
} |
525 | 525 |
|
526 |
-// Return the id used to reference this entity |
|
526 |
+// ID returns the id used to reference this entity |
|
527 | 527 |
func (e *Entity) ID() string { |
528 | 528 |
return e.id |
529 | 529 |
} |
530 | 530 |
|
531 |
-// Return the paths sorted by depth |
|
531 |
+// Paths returns the paths sorted by depth |
|
532 | 532 |
func (e Entities) Paths() []string { |
533 | 533 |
out := make([]string, len(e)) |
534 | 534 |
var i int |
... | ... |
@@ -10,7 +10,7 @@ func split(p string) []string { |
10 | 10 |
return strings.Split(p, "/") |
11 | 11 |
} |
12 | 12 |
|
13 |
-// Returns the depth or number of / in a given path |
|
13 |
+// PathDepth returns the depth or number of / in a given path |
|
14 | 14 |
func PathDepth(p string) int { |
15 | 15 |
parts := split(p) |
16 | 16 |
if len(parts) == 2 && parts[1] == "" { |
... | ... |
@@ -7,7 +7,7 @@ import ( |
7 | 7 |
"github.com/docker/docker/pkg/jsonmessage" |
8 | 8 |
) |
9 | 9 |
|
10 |
-// Request a given URL and return an io.Reader |
|
10 |
+// Download requests a given URL and returns an io.Reader |
|
11 | 11 |
func Download(url string) (resp *http.Response, err error) { |
12 | 12 |
if resp, err = http.Get(url); err != nil { |
13 | 13 |
return nil, err |
... | ... |
@@ -18,6 +18,7 @@ func Download(url string) (resp *http.Response, err error) { |
18 | 18 |
return resp, nil |
19 | 19 |
} |
20 | 20 |
|
21 |
+// NewHTTPRequestError returns a JSON response error |
|
21 | 22 |
func NewHTTPRequestError(msg string, res *http.Response) error { |
22 | 23 |
return &jsonmessage.JSONError{ |
23 | 24 |
Message: msg, |
... | ... |
@@ -26,6 +26,8 @@ func ResumableRequestReader(c *http.Client, r *http.Request, maxfail uint32, tot |
26 | 26 |
return &resumableRequestReader{client: c, request: r, maxFailures: maxfail, totalSize: totalsize} |
27 | 27 |
} |
28 | 28 |
|
29 |
+// ResumableRequestReaderWithInitialResponse makes it possible to resume |
|
30 |
+// reading the body of an already initiated request. |
|
29 | 31 |
func ResumableRequestReaderWithInitialResponse(c *http.Client, r *http.Request, maxfail uint32, totalsize int64, initialResponse *http.Response) io.ReadCloser { |
30 | 32 |
return &resumableRequestReader{client: c, request: r, maxFailures: maxfail, totalSize: totalsize, currentResponse: initialResponse} |
31 | 33 |
} |
... | ... |
@@ -1,5 +1,5 @@ |
1 | 1 |
/* |
2 |
-listenbuffer uses the kernel's listening backlog functionality to queue |
|
2 |
+Package listenbuffer uses the kernel's listening backlog functionality to queue |
|
3 | 3 |
connections, allowing applications to start listening immediately and handle |
4 | 4 |
connections later. This is signaled by closing the activation channel passed to |
5 | 5 |
the constructor. |