зеркало из https://github.com/microsoft/docker.git
Checksum system overhaul
This commit is contained in:
Родитель
e81a53eea9
Коммит
6e2ddf6f60
|
@ -529,9 +529,6 @@ func (srv *Server) CmdPush(stdin io.ReadCloser, stdout rcli.DockerConn, args ...
|
|||
Debugf("Pushing [%s] to [%s]\n", local, remote)
|
||||
|
||||
// Try to get the image
|
||||
// FIXME: Handle lookup
|
||||
// FIXME: Also push the tags in case of ./docker push myrepo:mytag
|
||||
// img, err := srv.runtime.LookupImage(cmd.Arg(0))
|
||||
img, err := srv.runtime.graph.Get(local)
|
||||
if err != nil {
|
||||
Debugf("The push refers to a repository [%s] (len: %d)\n", local, len(srv.runtime.repositories.Repositories[local]))
|
||||
|
|
20
graph.go
20
graph.go
|
@ -81,13 +81,6 @@ func (graph *Graph) Get(name string) (*Image, error) {
|
|||
return nil, fmt.Errorf("Image stored at '%s' has wrong id '%s'", id, img.Id)
|
||||
}
|
||||
img.graph = graph
|
||||
|
||||
if img.Checksum == "" {
|
||||
err := img.FixChecksum()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return img, nil
|
||||
}
|
||||
|
||||
|
@ -105,17 +98,11 @@ func (graph *Graph) Create(layerData Archive, container *Container, comment, aut
|
|||
img.Parent = container.Image
|
||||
img.Container = container.Id
|
||||
img.ContainerConfig = *container.Config
|
||||
// FIXME: If an image is imported from a raw URL (not created from a container),
|
||||
// its checksum will not be computed, which will cause a push to fail
|
||||
checksum, err := container.RwChecksum()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
img.Checksum = checksum
|
||||
}
|
||||
if err := graph.Register(layerData, img); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
img.Checksum()
|
||||
return img, nil
|
||||
}
|
||||
|
||||
|
@ -309,7 +296,10 @@ func (graph *Graph) Checksums(repo Repository) ([]map[string]string, error) {
|
|||
return nil, err
|
||||
}
|
||||
err = img.WalkHistory(func(image *Image) error {
|
||||
checksums[image.Id] = image.Checksum
|
||||
checksums[image.Id], err = image.Checksum()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
|
|
60
image.go
60
image.go
|
@ -1,7 +1,9 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -18,7 +20,6 @@ import (
|
|||
type Image struct {
|
||||
Id string `json:"id"`
|
||||
Parent string `json:"parent,omitempty"`
|
||||
Checksum string `json:"checksum,omitempty"`
|
||||
Comment string `json:"comment,omitempty"`
|
||||
Created time.Time `json:"created"`
|
||||
Container string `json:"container,omitempty"`
|
||||
|
@ -260,30 +261,57 @@ func (img *Image) layer() (string, error) {
|
|||
return layerPath(root), nil
|
||||
}
|
||||
|
||||
func (img *Image) FixChecksum() error {
|
||||
func (img *Image) Checksum() (string, error) {
|
||||
root, err := img.root()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
checksumDictPth := path.Join(root, "..", "..", "checksums")
|
||||
checksums := new(map[string]string)
|
||||
|
||||
if checksumDict, err := ioutil.ReadFile(checksumDictPth); err == nil {
|
||||
if err := json.Unmarshal(checksumDict, checksums); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if checksum, ok := (*checksums)[img.Id]; ok {
|
||||
return checksum, nil
|
||||
}
|
||||
}
|
||||
|
||||
layer, err := img.layer()
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
layerData, err := Tar(layer, Xz)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
sum, err := HashData(layerData)
|
||||
h := sha256.New()
|
||||
if _, err := io.Copy(h, layerData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
jsonData, err := ioutil.ReadFile(jsonPath(root))
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
img.Checksum = sum
|
||||
jsonData, err := json.Marshal(img)
|
||||
if _, err := io.Copy(h, bytes.NewBuffer(jsonData)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
hash := "sha256:"+hex.EncodeToString(h.Sum(nil))
|
||||
if *checksums == nil {
|
||||
*checksums = map[string]string{}
|
||||
}
|
||||
(*checksums)[img.Id] = hash
|
||||
checksumJson, err := json.Marshal(checksums)
|
||||
if err != nil {
|
||||
return err
|
||||
return hash, err
|
||||
}
|
||||
root, err := img.root()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
if err := ioutil.WriteFile(checksumDictPth, checksumJson, 0600); err != nil {
|
||||
return hash, err
|
||||
}
|
||||
if err := ioutil.WriteFile(jsonPath(root), jsonData, 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return hash, nil
|
||||
}
|
||||
|
|
14
registry.go
14
registry.go
|
@ -327,6 +327,12 @@ func pushImageRec(graph *Graph, stdout io.Writer, img *Image, registry string, t
|
|||
}
|
||||
req.Header.Add("Content-type", "application/json")
|
||||
req.Header.Set("Authorization", "Token " + strings.Join(token, ","))
|
||||
|
||||
checksum, err := img.Checksum()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error while retrieving checksum for %s: %v", img.Id, err)
|
||||
}
|
||||
req.Header.Set("X-Docker-Checksum", checksum)
|
||||
res, err := doWithCookies(client, req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to upload metadata: %s", err)
|
||||
|
@ -457,7 +463,7 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re
|
|||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("PUT", INDEX_ENDPOINT+"/repositories/"+remote, bytes.NewReader(imgListJson))
|
||||
req, err := http.NewRequest("PUT", INDEX_ENDPOINT+"/repositories/"+remote+"/", bytes.NewReader(imgListJson))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -468,7 +474,7 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res.Body.Close()
|
||||
defer res.Body.Close()
|
||||
for res.StatusCode >= 300 && res.StatusCode < 400 {
|
||||
Debugf("Redirected to %s\n", res.Header.Get("Location"))
|
||||
req, err = http.NewRequest("PUT", res.Header.Get("Location"), bytes.NewReader(imgListJson))
|
||||
|
@ -482,10 +488,12 @@ func (graph *Graph) PushRepository(stdout io.Writer, remote string, localRepo Re
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res.Body.Close()
|
||||
defer res.Body.Close()
|
||||
}
|
||||
|
||||
if res.StatusCode != 200 && res.StatusCode != 201 {
|
||||
info, err := ioutil.ReadAll(res.Body)
|
||||
Debugf("%v %v", err, string(info))
|
||||
return fmt.Errorf("Error: Status %d trying to push repository %s", res.StatusCode, remote)
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче