| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package docker |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "encoding/json" |
|
| 4 | 5 |
"fmt" |
| 5 | 6 |
"io" |
| 6 | 7 |
"io/ioutil" |
| ... | ... |
@@ -300,3 +301,26 @@ func (graph *Graph) Heads() (map[string]*Image, error) {
|
| 300 | 300 |
func (graph *Graph) imageRoot(id string) string {
|
| 301 | 301 |
return path.Join(graph.Root, id) |
| 302 | 302 |
} |
| 303 |
+ |
|
| 304 |
+func (graph *Graph) getStoredChecksums() (map[string]string, error) {
|
|
| 305 |
+ checksums := make(map[string]string) |
|
| 306 |
+ // FIXME: Store the checksum in memory |
|
| 307 |
+ |
|
| 308 |
+ if checksumDict, err := ioutil.ReadFile(path.Join(graph.Root, "checksums")); err == nil {
|
|
| 309 |
+ if err := json.Unmarshal(checksumDict, &checksums); err != nil {
|
|
| 310 |
+ return nil, err |
|
| 311 |
+ } |
|
| 312 |
+ } |
|
| 313 |
+ return checksums, nil |
|
| 314 |
+} |
|
| 315 |
+ |
|
| 316 |
+func (graph *Graph) storeChecksums(checksums map[string]string) error {
|
|
| 317 |
+ checksumJson, err := json.Marshal(checksums) |
|
| 318 |
+ if err != nil {
|
|
| 319 |
+ return err |
|
| 320 |
+ } |
|
| 321 |
+ if err := ioutil.WriteFile(path.Join(graph.Root, "checksums"), checksumJson, 0600); err != nil {
|
|
| 322 |
+ return err |
|
| 323 |
+ } |
|
| 324 |
+ return nil |
|
| 325 |
+} |
| ... | ... |
@@ -295,16 +295,12 @@ func (img *Image) Checksum() (string, error) {
|
| 295 | 295 |
return "", err |
| 296 | 296 |
} |
| 297 | 297 |
|
| 298 |
- checksumDictPth := path.Join(root, "..", "..", "checksums") |
|
| 299 |
- checksums := make(map[string]string) |
|
| 300 |
- |
|
| 301 |
- if checksumDict, err := ioutil.ReadFile(checksumDictPth); err == nil {
|
|
| 302 |
- if err := json.Unmarshal(checksumDict, &checksums); err != nil {
|
|
| 303 |
- return "", err |
|
| 304 |
- } |
|
| 305 |
- if checksum, ok := checksums[img.Id]; ok {
|
|
| 306 |
- return checksum, nil |
|
| 307 |
- } |
|
| 298 |
+ checksums, err := img.graph.getStoredChecksums() |
|
| 299 |
+ if err != nil {
|
|
| 300 |
+ return "", err |
|
| 301 |
+ } |
|
| 302 |
+ if checksum, ok := checksums[img.Id]; ok {
|
|
| 303 |
+ return checksum, nil |
|
| 308 | 304 |
} |
| 309 | 305 |
|
| 310 | 306 |
layer, err := img.layer() |
| ... | ... |
@@ -343,24 +339,23 @@ func (img *Image) Checksum() (string, error) {
|
| 343 | 343 |
if _, err := io.Copy(h, layerData); err != nil {
|
| 344 | 344 |
return "", err |
| 345 | 345 |
} |
| 346 |
- |
|
| 347 | 346 |
hash := "sha256:" + hex.EncodeToString(h.Sum(nil)) |
| 348 |
- checksums[img.Id] = hash |
|
| 349 | 347 |
|
| 350 | 348 |
// Reload the json file to make sure not to overwrite faster sums |
| 351 | 349 |
img.graph.lockSumFile.Lock() |
| 352 | 350 |
defer img.graph.lockSumFile.Unlock() |
| 353 |
- if checksumDict, err := ioutil.ReadFile(checksumDictPth); err == nil {
|
|
| 354 |
- if err := json.Unmarshal(checksumDict, &checksums); err != nil {
|
|
| 355 |
- return "", err |
|
| 356 |
- } |
|
| 357 |
- } |
|
| 358 |
- checksumJson, err := json.Marshal(checksums) |
|
| 351 |
+ |
|
| 352 |
+ checksums, err = img.graph.getStoredChecksums() |
|
| 359 | 353 |
if err != nil {
|
| 360 |
- return hash, err |
|
| 354 |
+ return "", err |
|
| 361 | 355 |
} |
| 362 |
- if err := ioutil.WriteFile(checksumDictPth, checksumJson, 0600); err != nil {
|
|
| 356 |
+ |
|
| 357 |
+ checksums[img.Id] = hash |
|
| 358 |
+ |
|
| 359 |
+ // Dump the checksums to disc |
|
| 360 |
+ if err := img.graph.storeChecksums(checksums); err != nil {
|
|
| 363 | 361 |
return hash, err |
| 364 | 362 |
} |
| 363 |
+ |
|
| 365 | 364 |
return hash, nil |
| 366 | 365 |
} |
| ... | ... |
@@ -578,6 +578,24 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re |
| 578 | 578 |
return filteredRepo, nil |
| 579 | 579 |
} |
| 580 | 580 |
|
| 581 |
+// Retrieve the checksum of an image |
|
| 582 |
+// Priority: |
|
| 583 |
+// - Check on the stored checksums |
|
| 584 |
+// - Check if the archive is exists, if it does not, ask the registry |
|
| 585 |
+// - If the archive does exists, process the checksum from it |
|
| 586 |
+// - If the archive does not exists and not found on registry, process checksum from layer |
|
| 587 |
+func (graph *Graph) getChecksum(imageId string) (string, error) {
|
|
| 588 |
+ img, err := graph.Get(imageId) |
|
| 589 |
+ if err != nil {
|
|
| 590 |
+ return "", err |
|
| 591 |
+ } |
|
| 592 |
+ checksum, err := img.Checksum() |
|
| 593 |
+ if err != nil {
|
|
| 594 |
+ return "", err |
|
| 595 |
+ } |
|
| 596 |
+ return checksum, nil |
|
| 597 |
+} |
|
| 598 |
+ |
|
| 581 | 599 |
type ImgListJson struct {
|
| 582 | 600 |
Id string `json:"id"` |
| 583 | 601 |
Checksum string `json:"checksum,omitempty"` |
| ... | ... |
@@ -592,7 +610,14 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re |
| 592 | 592 |
var imgList []*ImgListJson |
| 593 | 593 |
|
| 594 | 594 |
for _, id := range localRepo {
|
| 595 |
- imgList = append(imgList, &ImgListJson{Id: id})
|
|
| 595 |
+ checksum, err := graph.getChecksum(id) |
|
| 596 |
+ if err != nil {
|
|
| 597 |
+ return err |
|
| 598 |
+ } |
|
| 599 |
+ imgList = append(imgList, &ImgListJson{
|
|
| 600 |
+ Id: id, |
|
| 601 |
+ Checksum: checksum, |
|
| 602 |
+ }) |
|
| 596 | 603 |
} |
| 597 | 604 |
|
| 598 | 605 |
imgListJson, err := json.Marshal(imgList) |
| ... | ... |
@@ -666,21 +691,6 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re |
| 666 | 666 |
} |
| 667 | 667 |
} |
| 668 | 668 |
|
| 669 |
- for _, elem := range imgList {
|
|
| 670 |
- img, err := graph.Get(elem.Id) |
|
| 671 |
- if err != nil {
|
|
| 672 |
- return err |
|
| 673 |
- } |
|
| 674 |
- if elem.Checksum, err = img.Checksum(); err != nil {
|
|
| 675 |
- return err |
|
| 676 |
- } |
|
| 677 |
- } |
|
| 678 |
- imgListJson, err = json.Marshal(imgList) |
|
| 679 |
- if err != nil {
|
|
| 680 |
- return err |
|
| 681 |
- } |
|
| 682 |
- Debugf("json sent: %s\n", imgListJson)
|
|
| 683 |
- |
|
| 684 | 669 |
req2, err := http.NewRequest("PUT", INDEX_ENDPOINT+"/repositories/"+remote+"/images", bytes.NewReader(imgListJson))
|
| 685 | 670 |
if err != nil {
|
| 686 | 671 |
return err |