func PutRepositoryImagesV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) { namespace := ctx.Params(":namespace") repository := ctx.Params(":repository") r := new(models.Repository) if err := r.PutImages(namespace, repository); err != nil { log.Error("[REGISTRY API V1] Failed to save images: %v", err.Error()) result, _ := json.Marshal(map[string]string{"message": "Failed to save images"}) return http.StatusBadRequest, result } if ctx.Req.Header.Get("X-Docker-Token") == "true" { username, _, _ := utils.DecodeBasicAuth(ctx.Req.Header.Get("Authorization")) token := fmt.Sprintf("Token signature=%v,repository=\"%v/%v\",access=%v", utils.MD5(username), namespace, repository, "write") ctx.Resp.Header().Set("X-Docker-Token", token) ctx.Resp.Header().Set("WWW-Authenticate", token) } result, _ := json.Marshal(map[string]string{}) return http.StatusNoContent, result }
func PutRepositoryV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) { username, _, _ := utils.DecodeBasicAuth(ctx.Req.Header.Get("Authorization")) namespace := ctx.Params(":namespace") repository := ctx.Params(":repository") body, err := ctx.Req.Body().String() if err != nil { log.Error("[REGISTRY API V1] Failed to get request body: %v", err.Error()) result, _ := json.Marshal(map[string]string{"message": "Failed to get request body"}) return http.StatusBadRequest, result } r := new(models.Repository) if err := r.Put(namespace, repository, body, ctx.Req.Header.Get("User-Agent"), setting.APIVERSION_V1); err != nil { log.Error("[REGISTRY API V1] Failed to save repository %v/%v context: %v", namespace, repository, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Failed to save repository context"}) return http.StatusBadRequest, result } if ctx.Req.Header.Get("X-Docker-Token") == "true" { token := fmt.Sprintf("Token signature=%v,repository=\"%v/%v\",access=%v", utils.MD5(username), namespace, repository, "write") ctx.Resp.Header().Set("X-Docker-Token", token) ctx.Resp.Header().Set("WWW-Authenticate", token) } result, _ := json.Marshal(map[string]string{}) return http.StatusOK, result }
//PutRepositoryV1Handler will create or update the repository, it's first step of Docker push. //TODO: @1 When someone create or update the repository, it will be locked to forbidden others action include pull action. //TODO: @2 Add a config option for allow/forbidden Docker client pull action when a repository is locked. //TODO: @3 Intergated with [Crew](https://github.com/containerops/crew). //TODO: @4 Token will be store in Redis, and link the push action with username@repository. func PutRepositoryV1Handler(ctx *macaron.Context) (int, []byte) { var username, body string //var passwd string var err error if username, _, err = utils.DecodeBasicAuth(ctx.Req.Header.Get("Authorization")); err != nil { log.Errorf("[%s] decode Authorization error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Decode Authorization Error"}) return http.StatusUnauthorized, result } //When integrated with crew, like this: //@1: username, passwd, _ := utils.DecodeBasicAuth(ctx.Req.Header.Get("Authorization")) //@2: username, passwd authorizated in Crew. namespace := ctx.Params(":namespace") repository := ctx.Params(":repository") //When integrated the Crew, should be check the privilage. if username != namespace { } //In Docker Registry V1, the repository json data in the body of `PUT /v1/:namespace/:repository` if body, err = ctx.Req.Body().String(); err != nil { log.Errorf("[%s] get repository json from http body error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Get Repository JSON Error"}) return http.StatusBadRequest, result } //Create or update the repository. r := new(models.DockerV1) if e := r.Put(namespace, repository, body, ctx.Req.Header.Get("User-Agent")); e != nil { log.Errorf("[%s] put repository error: %s", ctx.Req.RequestURI, e.Error()) result, _ := json.Marshal(map[string]string{"Error": "PUT Repository Error"}) return http.StatusBadRequest, result } //If the Docker client use "X-Docker-Token", will return a randon token value. if ctx.Req.Header.Get("X-Docker-Token") == "true" { token := fmt.Sprintf("Token signature=%v,repository=\"%v/%v\",access=%v", utils.MD5(username), namespace, repository, "write") ctx.Resp.Header().Set("X-Docker-Token", token) ctx.Resp.Header().Set("WWW-Authenticate", token) } //TODO: When deploy multi instances of dockyard, the endpoints will schedule comply all instances stauts and arithmetic. ctx.Resp.Header().Set("X-Docker-Endpoints", setting.Domains) result, _ := json.Marshal(map[string]string{}) return http.StatusOK, result }
func GetRepositoryImagesV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) { namespace := ctx.Params(":namespace") repository := ctx.Params(":repository") r := new(models.Repository) if exists, err := r.Get(namespace, repository); err != nil { log.Error("[REGISTRY API V1] Failed to get repository %v/%v context: %v", namespace, repository, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Failed to get repository context"}) return http.StatusBadRequest, result } else if exists == false { log.Error("[REGISTRY API V1] Not found repository %v/%v", namespace, repository) result, _ := json.Marshal(map[string]string{"message": "Not found repository"}) return http.StatusNotFound, result } r.Download += 1 if err := r.Save(namespace, repository); err != nil { log.Error("[REGISTRY API V1] Failed to save repository %v/%v context: %v", namespace, repository, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Failed to save repository context"}) return http.StatusBadRequest, result } username, _, _ := utils.DecodeBasicAuth(ctx.Req.Header.Get("Authorization")) token := fmt.Sprintf("Token signature=%v,repository=\"%v/%v\",access=%v", utils.MD5(username), namespace, repository, "read") ctx.Resp.Header().Set("X-Docker-Token", token) ctx.Resp.Header().Set("WWW-Authenticate", token) ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(r.JSON))) return http.StatusOK, []byte(r.JSON) }
//GetRepositoryImagesV1Handler will return images json data. func GetRepositoryImagesV1Handler(ctx *macaron.Context) (int, []byte) { var username string var err error if username, _, err = utils.DecodeBasicAuth(ctx.Req.Header.Get("Authorization")); err != nil { log.Errorf("[%s] decode Authorization error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Decode Authorization Error"}) return http.StatusUnauthorized, result } namespace := ctx.Params(":namespace") repository := ctx.Params(":repository") r := new(models.DockerV1) if v1, err := r.Get(namespace, repository); err != nil { log.Errorf("[%s] get repository images data error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Get Repository Images Error"}) return http.StatusBadRequest, result } else { //If the Docker client use "X-Docker-Token", will return a randon token value. if ctx.Req.Header.Get("X-Docker-Token") == "true" { token := fmt.Sprintf("Token signature=%v,repository=\"%v/%v\",access=%v", utils.MD5(username), namespace, repository, "read") ctx.Resp.Header().Set("X-Docker-Token", token) ctx.Resp.Header().Set("WWW-Authenticate", token) } ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(v1.JSON))) return http.StatusOK, []byte(v1.JSON) } }