Handle push/pull of repositories
This commit is contained in:
parent
d8fa52b7b5
commit
11c4294846
3 changed files with 128 additions and 9 deletions
|
@ -15,7 +15,8 @@ import (
|
|||
const CONFIGFILE = "/var/lib/docker/.dockercfg"
|
||||
|
||||
// the registry server we want to login against
|
||||
const REGISTRY_SERVER = "https://registry.docker.io"
|
||||
//const REGISTRY_SERVER = "https://registry.docker.io"
|
||||
const REGISTRY_SERVER = "http://192.168.56.1:5000"
|
||||
|
||||
type AuthConfig struct {
|
||||
Username string `json:"username"`
|
||||
|
|
35
commands.go
35
commands.go
|
@ -423,7 +423,8 @@ func (srv *Server) CmdImport(stdin io.ReadCloser, stdout io.Writer, args ...stri
|
|||
}
|
||||
|
||||
func (srv *Server) CmdPush(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||
cmd := rcli.Subcmd(stdout, "push", "[OPTIONS] IMAGE", "Push an image to the registry")
|
||||
cmd := rcli.Subcmd(stdout, "push", "[OPTIONS] IMAGE", "Push an image or a repository to the registry")
|
||||
user := cmd.String("u", "", "specify the user for the repository")
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -432,16 +433,31 @@ func (srv *Server) CmdPush(stdin io.ReadCloser, stdout io.Writer, args ...string
|
|||
return nil
|
||||
}
|
||||
|
||||
// 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(cmd.Arg(0))
|
||||
if err != nil {
|
||||
return err
|
||||
if *user == "" {
|
||||
return fmt.Errorf("Not logged in and no user specified\n")
|
||||
}
|
||||
// If it fails, try to get the repository
|
||||
if repo, exists := srv.runtime.repositories.Repositories[cmd.Arg(0)]; exists {
|
||||
if err := srv.runtime.graph.PushRepository(*user, cmd.Arg(0), repo); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// FIXME: Handle repositories, etc. Not jist images
|
||||
return srv.runtime.graph.PushImage(img)
|
||||
}
|
||||
|
||||
func (srv *Server) CmdPull(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||
cmd := rcli.Subcmd(stdout, "pull", "[OPTIONS] IMAGE", "Pull an image from the registry")
|
||||
cmd := rcli.Subcmd(stdout, "pull", "[OPTIONS] IMAGE", "Pull an image or a repository from the registry")
|
||||
user := cmd.String("u", "", "specify the user for the repository")
|
||||
if err := cmd.Parse(args); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -449,8 +465,15 @@ func (srv *Server) CmdPull(stdin io.ReadCloser, stdout io.Writer, args ...string
|
|||
cmd.Usage()
|
||||
return nil
|
||||
}
|
||||
// FIXME: Handle repositories, etc. Not jist images
|
||||
return srv.runtime.graph.PullImage(cmd.Arg(0))
|
||||
|
||||
if srv.runtime.graph.LookupRemoteImage(cmd.Arg(0)) {
|
||||
return srv.runtime.graph.PullImage(cmd.Arg(0))
|
||||
}
|
||||
if *user == "" {
|
||||
return fmt.Errorf("Not loggin and no user specified\n")
|
||||
}
|
||||
// FIXME: Allow pull repo:tag
|
||||
return srv.runtime.graph.PullRepository(*user, cmd.Arg(0), "", srv.runtime.repositories)
|
||||
}
|
||||
|
||||
func (srv *Server) CmdImages(stdin io.ReadCloser, stdout io.Writer, args ...string) error {
|
||||
|
|
99
registry.go
99
registry.go
|
@ -3,6 +3,7 @@ package docker
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/dotcloud/docker/auth"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -12,7 +13,7 @@ import (
|
|||
|
||||
//FIXME: Set the endpoint in a conf file or via commandline
|
||||
//const REGISTRY_ENDPOINT = "http://registry-creack.dotcloud.com/v1"
|
||||
const REGISTRY_ENDPOINT = "http://192.168.56.1:5000/v1"
|
||||
const REGISTRY_ENDPOINT = auth.REGISTRY_SERVER + "/v1"
|
||||
|
||||
// Build an Image object from raw json data
|
||||
func NewImgJson(src []byte) (*Image, error) {
|
||||
|
@ -67,6 +68,15 @@ func (graph *Graph) getRemoteHistory(imgId string) ([]*Image, error) {
|
|||
return history, nil
|
||||
}
|
||||
|
||||
// Check if an image exists in the Registry
|
||||
func (graph *Graph) LookupRemoteImage(imgId string) bool {
|
||||
res, err := http.Get(REGISTRY_ENDPOINT + "/images/" + imgId + "/json")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return res.StatusCode == 307
|
||||
}
|
||||
|
||||
// Retrieve an image from the Registry.
|
||||
// Returns the Image object as well as the layer as an Archive (io.Reader)
|
||||
func (graph *Graph) getRemoteImage(imgId string) (*Image, Archive, error) {
|
||||
|
@ -118,6 +128,46 @@ func (graph *Graph) PullImage(imgId string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// FIXME: Handle the askedTag parameter
|
||||
func (graph *Graph) PullRepository(user, repoName, askedTag string, repositories *TagStore) error {
|
||||
client := &http.Client{}
|
||||
|
||||
req, err := http.NewRequest("GET", REGISTRY_ENDPOINT+"/users/"+user+"/"+repoName, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
authStruct, err := auth.LoadConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.SetBasicAuth(authStruct.Username, authStruct.Password)
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rawJson, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t := map[string]string{}
|
||||
if err = json.Unmarshal(rawJson, &t); err != nil {
|
||||
return err
|
||||
}
|
||||
for tag, rev := range t {
|
||||
if err = graph.PullImage(rev); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = repositories.Set(repoName, tag, rev); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = repositories.Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Push a local image to the registry with its history if needed
|
||||
func (graph *Graph) PushImage(imgOrig *Image) error {
|
||||
client := &http.Client{}
|
||||
|
@ -130,9 +180,12 @@ func (graph *Graph) PushImage(imgOrig *Image) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("Error while retreiving the path for {%s}: %s", img.Id, err)
|
||||
}
|
||||
// FIXME: try json with URF8
|
||||
// FIXME: try json with UTF8
|
||||
jsonData := strings.NewReader(string(jsonRaw))
|
||||
req, err := http.NewRequest("PUT", REGISTRY_ENDPOINT+"/images/"+img.Id+"/json", jsonData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := client.Do(req)
|
||||
if err != nil || res.StatusCode != 200 {
|
||||
if res == nil {
|
||||
|
@ -199,3 +252,45 @@ func (graph *Graph) PushImage(imgOrig *Image) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (graph *Graph) pushTag(user, repo, revision, tag string) error {
|
||||
|
||||
if tag == "" {
|
||||
tag = "lastest"
|
||||
}
|
||||
|
||||
revision = "\"" + revision + "\""
|
||||
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("PUT", REGISTRY_ENDPOINT+"/users/"+user+"/"+repo+"/"+tag, strings.NewReader(revision))
|
||||
req.Header.Add("Content-type", "application/json")
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Result of push tag: %d\n", res.StatusCode)
|
||||
switch res.StatusCode {
|
||||
default:
|
||||
return fmt.Errorf("Error %d\n", res.StatusCode)
|
||||
case 200:
|
||||
case 201:
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (graph *Graph) PushRepository(user, repoName string, repo Repository) error {
|
||||
for tag, imgId := range repo {
|
||||
fmt.Printf("tag: %s, imgId: %s\n", tag, imgId)
|
||||
img, err := graph.Get(imgId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = graph.PushImage(img); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = graph.pushTag(user, repoName, imgId, tag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue