//GetImageJSONV1Handler is getting image json data function. //When docker client push an image, dockyard return http status code '400' or '404' if haven't it. Then the docker client will push the json data and layer file. //If dockyard has the image and return 200, the docker client will ignore it and push another iamge. func GetImageJSONV1Handler(ctx *macaron.Context) (int, []byte) { //TODO: If standalone == true, Dockyard will check HEADER Authorization; if standalone == false, Dockyard will check HEADER TOEKN. imageID := ctx.Params(":image") image := new(models.DockerImageV1) if i, err := image.Get(imageID); err != nil && err == gorm.ErrRecordNotFound { log.WithFields(log.Fields{ "image": i.ImageID, }).Info("Image Not Found.") result, _ := json.Marshal(map[string]string{}) return http.StatusNotFound, result } else if err != nil && err != gorm.ErrRecordNotFound { log.Errorf("[%s] get image error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Get Image Error"}) return http.StatusBadRequest, result } else { ctx.Resp.Header().Set("X-Docker-Checksum-Payload", i.Checksum) ctx.Resp.Header().Set("X-Docker-Size", fmt.Sprint(i.Size)) ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(i.JSON))) return http.StatusOK, []byte(i.JSON) } }
//GetImageAncestryV1Handler func GetImageAncestryV1Handler(ctx *macaron.Context) (int, []byte) { //TODO: If standalone == true, Dockyard will check HEADER Authorization; if standalone == false, Dockyard will check HEADER TOEKN. imageID := ctx.Params(":image") image := new(models.DockerImageV1) if i, err := image.Get(imageID); err != nil { log.Errorf("[%s] get image ancestry error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Get Image Ancestry Error"}) return http.StatusBadRequest, result } else { ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(i.Ancestry))) return http.StatusOK, []byte(i.Ancestry) } }
//GetImageLayerV1Handler func GetImageLayerV1Handler(ctx *macaron.Context) { //TODO: If standalone == true, Dockyard will check HEADER Authorization; if standalone == false, Dockyard will check HEADER TOEKN. imageID := ctx.Params(":image") image := new(models.DockerImageV1) if i, err := image.Get(imageID); err != nil { log.Errorf("[%s] get image ancestry error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Get Image Layer Error"}) ctx.Resp.WriteHeader(http.StatusBadRequest) ctx.Resp.Write(result) return } else { if file, err := os.Open(i.Path); err != nil { log.Errorf("[%s] get image layer file status: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Get Image Layer File Status Error"}) ctx.Resp.WriteHeader(http.StatusBadRequest) ctx.Resp.Write(result) return } else { size := strconv.FormatInt(i.Size, 10) ctx.Resp.Header().Set("Content-Description", "File Transfer") ctx.Resp.Header().Set("Content-Type", "application/octet-stream") ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", i.ImageID)) ctx.Resp.Header().Set("Content-Length", size) ctx.Resp.Header().Set("Expires", "0") ctx.Resp.Header().Set("Cache-Control", "must-revalidate") ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary") ctx.Resp.Header().Set("Pragma", "public") file.Seek(0, 0) defer file.Close() io.Copy(ctx.Resp, file) ctx.Resp.WriteHeader(http.StatusOK) return } } }
//PutImageChecksumV1Handler is put image checksum and payload value in the database. func PutImageChecksumV1Handler(ctx *macaron.Context) (int, []byte) { //TODO: If standalone == true, Dockyard will check HEADER Authorization; if standalone == false, Dockyard will check HEADER TOEKN. imageID := ctx.Params(":image") checksum := ctx.Req.Header.Get("X-Docker-Checksum") payload := ctx.Req.Header.Get("X-Docker-Checksum-Payload") image := new(models.DockerImageV1) if err := image.PutChecksum(imageID, checksum, payload); err != nil { log.Errorf("[%s] Failed to set image checksum and payload error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Put Image Checksum And Payload Data Error"}) return http.StatusBadRequest, result } //TODO: Verify the file's checksum. result, _ := json.Marshal(map[string]string{}) return http.StatusOK, result }
//PutImageLayerV1Handler is save image layer file in the server. func PutImageLayerV1Handler(ctx *macaron.Context) (int, []byte) { //TODO: If standalone == true, Dockyard will check HEADER Authorization; if standalone == false, Dockyard will check HEADER TOEKN. imageID := ctx.Params(":image") basePath := setting.DockerV1Storage imagePath := fmt.Sprintf("%s/images/%s", basePath, imageID) layerfile := fmt.Sprintf("%s/images/%s/%s", basePath, imageID, imageID) if !utils.IsDirExist(imagePath) { os.MkdirAll(imagePath, os.ModePerm) } if _, err := os.Stat(layerfile); err == nil { os.Remove(layerfile) } if file, err := os.Create(layerfile); err != nil { log.Errorf("[%s] Create image file error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Write Image File Error."}) return http.StatusBadRequest, result } else { io.Copy(file, ctx.Req.Request.Body) } size, _ := utils.GetFileSize(layerfile) image := new(models.DockerImageV1) if err := image.PutLayer(imageID, layerfile, size); err != nil { log.Errorf("[%s] Failed to save image layer data error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Put Image Layer Data Error"}) return http.StatusBadRequest, result } result, _ := json.Marshal(map[string]string{}) return http.StatusOK, result }
//PutImageJSONV1Handler is func PutImageJSONV1Handler(ctx *macaron.Context) (int, []byte) { //TODO: If standalone == true, Dockyard will check HEADER Authorization; if standalone == false, Dockyard will check HEADER TOEKN. if body, err := ctx.Req.Body().String(); err != nil { log.Errorf("[%s] get image json from http body error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Get Image JSON Error"}) return http.StatusBadRequest, result } else if err == nil { imageID := ctx.Params(":image") image := new(models.DockerImageV1) if err := image.PutJSON(imageID, body); err != nil { log.Errorf("[%s] put image json error: %s", ctx.Req.RequestURI, err.Error()) result, _ := json.Marshal(map[string]string{"Error": "Put Image JSON Error"}) return http.StatusBadRequest, result } } result, _ := json.Marshal(map[string]string{}) return http.StatusOK, result }