Example #1
0
func GetTagsListV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	r := new(models.Repository)
	if _, err := r.Get(namespace, repository); err != nil {
		log.Error("[REGISTRY API V2] Failed to get repository %v/%v: %v", namespace, repository, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get repository"})
		return http.StatusBadRequest, result
	}

	data := map[string]interface{}{}

	data["name"] = fmt.Sprintf("%s/%s", namespace, repository)

	tagslist := r.GetTagslist()
	if len(tagslist) <= 0 {
		log.Error("[REGISTRY API V2] Repository %v/%v tags list is empty", namespace, repository)

		result, _ := json.Marshal(map[string]string{"message": "Tags list is empty"})
		return http.StatusNotFound, result
	}
	data["tags"] = tagslist

	result, _ := json.Marshal(data)
	return http.StatusOK, result
}
Example #2
0
func GetTagsListV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	r := new(models.Repository)
	if has, _, err := r.Has(namespace, repository); err != nil || has == false {
		log.Error("[REGISTRY API V2] Repository not found: %v", repository)

		result, _ := json.Marshal(map[string]string{"message": "Repository not found"})
		return http.StatusNotFound, result
	}

	data := map[string]interface{}{}
	tags := []string{}

	data["name"] = fmt.Sprintf("%s/%s", namespace, repository)

	for _, value := range r.Tags {
		t := new(models.Tag)
		if err := t.GetByKey(value); err != nil {
			log.Error("[REGISTRY API V2] Tag not found: %v", err.Error())

			result, _ := json.Marshal(map[string]string{"message": "Tag not found"})
			return http.StatusNotFound, result
		}

		tags = append(tags, t.Name)
	}

	data["tags"] = tags

	result, _ := json.Marshal(data)
	return http.StatusOK, result
}
Example #3
0
// TBD: discovery template should be updated to keep in line with ACI
func DiscoveryACIHandler(ctx *macaron.Context, log *logs.BeeLogger) {
	img := ctx.Params(":imagename")

	t, err := template.ParseFiles("conf/acifetchtemplate.html")
	if err != nil {
		log.Error("[ACI API] Discovery parse template file failed: %v", err.Error())
		ctx.Resp.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(ctx.Resp, fmt.Sprintf("%v", err))
		return
	}

	err = t.Execute(ctx.Resp, struct {
		Name       string
		ServerName string
		ListenMode string
	}{
		Name:       img,
		ServerName: setting.Domains,
		ListenMode: setting.ListenMode,
	})
	if err != nil {
		log.Error("[ACI API] Discovery respond failed: %v", err.Error())
		fmt.Fprintf(ctx.Resp, fmt.Sprintf("%v", err))
	}
}
Example #4
0
func GetManifestsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	t := new(models.Tag)

	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")
	if err := t.Get(namespace, repository, ctx.Params(":tag")); err != nil {
		log.Error("[REGISTRY API V2] Manifest not found: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Manifest not found"})
		return http.StatusNotFound, result
	}

	digest, err := utils.DigestManifest([]byte(t.Manifest))
	if err != nil {
		log.Error("[REGISTRY API V2] Get manifest digest failed: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Get manifest digest failed"})
		return http.StatusBadRequest, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/json; charset=utf-8")
	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(t.Manifest)))

	return http.StatusOK, []byte(t.Manifest)
}
Example #5
0
func PutImageLayerv1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	basePath := setting.ImagePath
	imagePath := fmt.Sprintf("%v/images/%v", basePath, imageId)
	layerfile := fmt.Sprintf("%v/images/%v/layer", basePath, imageId)

	if !utils.IsDirExist(imagePath) {
		os.MkdirAll(imagePath, os.ModePerm)
	}

	if _, err := os.Stat(layerfile); err == nil {
		os.Remove(layerfile)
	}

	data, _ := ioutil.ReadAll(ctx.Req.Request.Body)
	if err := ioutil.WriteFile(layerfile, data, 0777); err != nil {
		log.Error("[REGISTRY API V1] Put Image Layer File Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image Layer File Error"})
		return http.StatusBadRequest, result
	}

	i := new(models.Image)
	if err := i.PutLayer(imageId, layerfile, true, int64(len(data))); err != nil {
		log.Error("[REGISTRY API V1] Put Image Layer File Data Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image Layer File Data Error"})
		return http.StatusBadRequest, result
	}

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #6
0
func GetFileInfo(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	path := ctx.Req.Header.Get(headerPath)
	log.Info("[OSS][getFileInfo] Path: %s", path)

	result, err := metaDriver.GetFileMetaInfo(path, false)
	if err != nil {
		log.Error("[OSS][getFileInfo] get metainfo error, key: %s, error: %s", path, err)
		return http.StatusInternalServerError, []byte(err.Error())
	}

	if len(result) == 0 {
		log.Info("[OSS][getFileInfo] metainfo not exists, key: %s", path)
		return http.StatusNotFound, []byte(err.Error())
	}

	resultMap := make(map[string]interface{})
	resultMap["fragment-info"] = result
	jsonResult, err := json.Marshal(resultMap)
	if err != nil {
		log.Error("json.Marshal error, key: %s, error: %s", path, err)
		return http.StatusInternalServerError, []byte(err.Error())
	}

	log.Info("[getFileInfo] success, path: %s, result: %s", path, string(jsonResult))
	return http.StatusOK, jsonResult
}
Example #7
0
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] Put images error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put V1 images error"})
		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
}
Example #8
0
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] Get request body error: %v", err.Error())
		result, _ := json.Marshal(map[string]string{"message": "Put V1 repository failed,request body is empty"})
		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] Put repository error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": err.Error()})
		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
}
Example #9
0
func GetManifestsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")
	tag := ctx.Params(":tag")

	t := new(models.Tag)
	if exists, err := t.Get(namespace, repository, tag); err != nil || !exists {
		log.Error("[REGISTRY API V2] Not found manifest: %v", err)

		result, _ := json.Marshal(map[string]string{"message": "Not found manifest"})
		return http.StatusNotFound, result
	}

	digest, err := signature.DigestManifest([]byte(t.Manifest))
	if err != nil {
		log.Error("[REGISTRY API V2] Failed to get manifest digest: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get manifest digest"})
		return http.StatusInternalServerError, result
	}

	contenttype := []string{"", "application/json; charset=utf-8", "application/vnd.docker.distribution.manifest.v2+json"}
	ctx.Resp.Header().Set("Content-Type", contenttype[t.Schema])

	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(t.Manifest)))

	return http.StatusOK, []byte(t.Manifest)
}
Example #10
0
func GetImageJSONV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	var jsonInfo string
	var payload string
	var err error

	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if jsonInfo, err = i.GetJSON(imageId); err != nil {
		log.Error("[REGISTRY API V1] Search Image JSON Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Search Image JSON Error"})
		return http.StatusNotFound, result
	}

	if payload, err = i.GetChecksumPayload(imageId); err != nil {
		log.Error("[REGISTRY API V1] Search Image Checksum Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Search Image Checksum Error"})
		return http.StatusNotFound, result
	}

	ctx.Resp.Header().Set("X-Docker-Checksum-Payload", fmt.Sprintf("sha256:%v", payload))
	ctx.Resp.Header().Set("X-Docker-Size", fmt.Sprint(i.Size))
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(jsonInfo)))

	return http.StatusOK, []byte(jsonInfo)
}
Example #11
0
func PutImageChecksumV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	checksum := strings.Split(ctx.Req.Header.Get("X-Docker-Checksum"), ":")[1]
	payload := strings.Split(ctx.Req.Header.Get("X-Docker-Checksum-Payload"), ":")[1]

	log.Debug("[REGISTRY API V1] Image Checksum : %v", checksum)
	log.Debug("[REGISTRY API V1] Image Payload: %v", payload)

	i := new(models.Image)
	if err := i.PutChecksum(imageId, checksum, true, payload); err != nil {
		log.Error("[REGISTRY API V1] Put Image Checksum & Payload Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image Checksum & Payload Error"})
		return http.StatusBadRequest, result
	}

	if err := i.PutAncestry(imageId); err != nil {
		log.Error("[REGISTRY API V1] Put Image Ancestry Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Put Image Ancestry Error"})
		return http.StatusBadRequest, result
	}

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #12
0
func InitiateUpload(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	image := ctx.Params(":image")
	if image == "" {
		log.Error("[ACI API]Get image name failed")
		result, _ := json.Marshal(map[string]string{"message": "Get image name failed"})
		return http.StatusNotFound, result
	}

	uploadNum := strconv.Itoa(newUpload(image))

	var prefix string
	prefix = setting.ListenMode + "://" + setting.Domains + "/ac-push"

	deets := initiateDetails{
		ACIPushVersion: "0.0.1",
		Multipart:      false,
		ManifestURL:    prefix + "/manifest/" + uploadNum,
		SignatureURL:   prefix + "/signature/" + uploadNum,
		ACIURL:         prefix + "/aci/" + uploadNum,
		CompletedURL:   prefix + "/complete/" + uploadNum,
	}

	result, _ := json.Marshal(deets)
	return http.StatusInternalServerError, result

}
Example #13
0
func GetPubkeys(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	var pubkey []byte
	var err error

	pubkeypath := setting.ImagePath + "/acpool/" + "pubkeys.gpg"
	if pubkey, err = ioutil.ReadFile(pubkeypath); err != nil {
		log.Error("[ACI API] Get pubkey file failed: %v", err.Error())
		result, _ := json.Marshal(map[string]string{"message": "Get pubkey file failed"})
		return http.StatusNotFound, result
	}
	return http.StatusOK, pubkey
}
Example #14
0
func ReceiveAciUpload(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	num, err := strconv.Atoi(ctx.Params(":num"))
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v", err)
		result, _ := json.Marshal(map[string]string{})
		return http.StatusNotFound, result
	}

	up := getUpload(num)
	if up == nil {
		fmt.Fprintf(os.Stderr, "%v", err)
		result, _ := json.Marshal(map[string]string{})
		return http.StatusNotFound, result
	}

	_, err = os.Stat(up.Image)
	if err == nil {
		log.Error("[ACI API]item already uploaded")
		result, _ := json.Marshal(map[string]string{"message": "item already uploaded"})
		return http.StatusConflict, result
	} else if !os.IsNotExist(err) {
		fmt.Fprintf(os.Stderr, "%v", err)
		result, _ := json.Marshal(map[string]string{})
		return http.StatusInternalServerError, result
	}

	aci, err := os.OpenFile(tmpACIPath(num),
		os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v", err)
		result, _ := json.Marshal(map[string]string{})
		return http.StatusInternalServerError, result
	}
	defer aci.Close()

	_, err = io.Copy(aci, ctx.Req.Request.Body)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v", err)
		result, _ := json.Marshal(map[string]string{})
		return http.StatusInternalServerError, result
	}

	err = gotACI(num)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v", err)
		result, _ := json.Marshal(map[string]string{})
		return http.StatusInternalServerError, result
	}
	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #15
0
func UploadFile(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	metaInfo, _, err := uploadFileReadParam(&ctx.Req.Header)
	if err != nil {
		log.Error("[OSS][uploadFile] read param error: %v", err)
		return http.StatusBadRequest, []byte(err.Error())
	}
	data, err := ctx.Req.Body().Bytes()
	if err != nil {
		log.Error("[OSS]read request body error: %s", err)
		return http.StatusBadRequest, []byte(err.Error())
	}

	statusCode, err := ossupload(data, metaInfo)
	if err != nil {
		log.Error("[OSS][uploadFile] upload error: %v", err)
		return statusCode, []byte(err.Error())
	}

	if err = metaDriver.StoreMetaInfoV1(metaInfo); err != nil {
		log.Error("[OSS]store metaInfo error: %s", err)
		return http.StatusInternalServerError, []byte(err.Error())
	}

	log.Info("[OSS][postFile] success. path: %s, fragmentIndex: %d, bytesRange: %d-%d, isLast: %v", metaInfo.Path, metaInfo.Value.Index, metaInfo.Value.Start, metaInfo.Value.End, metaInfo.Value.IsLast)

	return http.StatusOK, nil
}
Example #16
0
func DeleteFile(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	path := ctx.Req.Header.Get(headerPath)

	log.Info("[OSS][deleteFile] path: %s", path)

	var err error

	if err = metaDriver.DeleteFileMetaInfoV1(path); err != nil {
		log.Error("[OSS]delete metainfo error for path: %s, error: %s", path, err)
		return http.StatusInternalServerError, []byte(err.Error())
	}

	log.Info("[OSS][deleteFile] success. path: %s", path)
	return http.StatusNoContent, nil
}
Example #17
0
func GetImageAncestryV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if _, err := i.Get(imageId); err != nil {
		log.Error("[REGISTRY API V1] Failed to get image %v ancestry: %v", imageId, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get image ancestry"})
		return http.StatusBadRequest, result
	}

	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(i.Ancestry)))

	return http.StatusOK, []byte(i.Ancestry)
}
Example #18
0
func PutManifestHandler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	manipath := module.GetManifestPath(imageId, setting.APIVERSION_ACI)

	data, _ := ctx.Req.Body().Bytes()
	if err := ioutil.WriteFile(manipath, data, 0777); err != nil {
		//Temporary directory would be deleted in PostCompleteHandler
		log.Error("[ACI API] Failed to save manifest file: %v", err.Error())
		result, _ := json.Marshal(map[string]string{"message": "Failed to save manifest"})
		return http.StatusInternalServerError, result
	}

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #19
0
func PutAciHandler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")
	acifile := ctx.Params(":acifile")

	acipath := module.GetAciPath(imageId, acifile)

	data, _ := ctx.Req.Body().Bytes()
	if err := ioutil.WriteFile(acipath, data, 0777); err != nil {
		//Temporary directory would be deleted in PostCompleteHandler
		log.Error("[ACI API] Save aci file failed: %v", err.Error())
		result, _ := json.Marshal(map[string]string{"message": "Save aci file failed"})
		return http.StatusInternalServerError, result
	}

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #20
0
func PutBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	desc := ctx.Params(":uuid")
	uuid := strings.Split(desc, "?")[0]

	digest := ctx.Query("digest")
	tarsum := strings.Split(digest, ":")[1]

	imagePathTmp := module.GetImagePath(uuid, setting.APIVERSION_V2)
	layerPathTmp := module.GetLayerPath(uuid, "layer", setting.APIVERSION_V2)
	imagePath := module.GetImagePath(tarsum, setting.APIVERSION_V2)
	layerPath := module.GetLayerPath(tarsum, "layer", setting.APIVERSION_V2)

	reqbody, _ := ctx.Req.Body().Bytes()
	layerlen, err := module.SaveLayerLocal(imagePathTmp, layerPathTmp, imagePath, layerPath, reqbody)
	if err != nil {
		log.Error("[REGISTRY API V2] Failed to save layer %v: %v", layerPath, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to save layer file"})
		return http.StatusInternalServerError, result
	}

	//saving specific tarsum every times is in order to split the same tarsum in HEAD handler
	i := new(models.Image)
	i.Path, i.Size = layerPath, int64(layerlen)
	if err := i.Save(tarsum); err != nil {
		log.Error("[REGISTRY API V2] Failed to save tarsum %v: %v", tarsum, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to save tarsum"})
		return http.StatusBadRequest, result
	}

	random := fmt.Sprintf("%s://%s/v2/%s/%s/blobs/%s",
		setting.ListenMode,
		setting.Domains,
		ctx.Params(":namespace"),
		ctx.Params(":repository"),
		digest)

	ctx.Resp.Header().Set("Content-Type", "text/plain; charset=utf-8")
	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Location", random)

	result, _ := json.Marshal(map[string]string{})
	return http.StatusCreated, result
}
Example #21
0
func PatchBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	desc := ctx.Params(":uuid")
	uuid := strings.Split(desc, "?")[0]

	imagePathTmp := module.GetImagePath(uuid, setting.APIVERSION_V2)
	layerPathTmp := module.GetLayerPath(uuid, "layer", setting.APIVERSION_V2)

	//saving specific tarsum every times is in order to split the same tarsum in HEAD handler
	if !utils.IsDirExist(imagePathTmp) {
		os.MkdirAll(imagePathTmp, os.ModePerm)
	}

	if _, err := os.Stat(layerPathTmp); err == nil {
		os.Remove(layerPathTmp)
	}

	data, _ := ctx.Req.Body().Bytes()
	if err := ioutil.WriteFile(layerPathTmp, data, 0777); err != nil {
		log.Error("[REGISTRY API V2] Failed to save layer %v: %v", layerPathTmp, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to save layer file"})
		return http.StatusInternalServerError, result
	}

	state := utils.MD5(fmt.Sprintf("%s/%s/%d", namespace, repository, time.Now().UnixNano()/int64(time.Millisecond)))
	random := fmt.Sprintf("%s://%s/v2/%s/%s/blobs/uploads/%s?_state=%s",
		setting.ListenMode,
		setting.Domains,
		namespace,
		repository,
		uuid,
		state)

	ctx.Resp.Header().Set("Content-Type", "text/plain; charset=utf-8")
	ctx.Resp.Header().Set("Docker-Upload-Uuid", uuid)
	ctx.Resp.Header().Set("Location", random)
	ctx.Resp.Header().Set("Range", fmt.Sprintf("0-%v", len(data)-1))

	result, _ := json.Marshal(map[string]string{})
	return http.StatusAccepted, result
}
Example #22
0
func PutBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	desc := ctx.Params(":uuid")
	uuid := strings.Split(desc, "?")[0]

	digest := ctx.Query("digest")
	tarsum := strings.Split(digest, ":")[1]

	imagePathTmp := fmt.Sprintf("%v/%v", setting.ImagePath, uuid)
	layerfileTmp := fmt.Sprintf("%v/%v/layer", setting.ImagePath, uuid)
	imagePath := fmt.Sprintf("%v/tarsum/%v", setting.ImagePath, tarsum)
	layerfile := fmt.Sprintf("%v/tarsum/%v/layer", setting.ImagePath, tarsum)

	reqbody, _ := ctx.Req.Body().Bytes()
	layerlen, err := module.CopyImgLayer(imagePathTmp, layerfileTmp, imagePath, layerfile, reqbody)
	if err != nil {
		log.Error("[REGISTRY API V2] Save layerfile failed: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Save layerfile failed"})
		return http.StatusBadRequest, result
	}

	//saving specific tarsum every times is in order to split the same tarsum in HEAD handler
	i := new(models.Image)
	i.Path, i.Size = layerfile, int64(layerlen)
	if err := i.PutTarsum(tarsum); err != nil {
		log.Error("[REGISTRY API V2] Save tarsum failed: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Save tarsum failed"})
		return http.StatusBadRequest, result
	}

	random := fmt.Sprintf("%s://%s/v2/%s/%s/blobs/%s",
		setting.ListenMode,
		setting.Domains,
		ctx.Params(":namespace"),
		ctx.Params(":repository"),
		digest)

	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Location", random)

	result, _ := json.Marshal(map[string]string{})
	return http.StatusCreated, result
}
Example #23
0
func GetACIHandler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	var img []byte
	var err error

	name := ctx.Params(":acname")

	//support to fetch images from location storage, it will be supported to fetch from cloud etc.
	imgpath := setting.ImagePath + "/acpool/" + name
	if img, err = ioutil.ReadFile(imgpath); err != nil {
		// TBD: consider to fetch image from other storage medium

		log.Error("[ACI API] Get ACI file failed: %v", err.Error())
		result, _ := json.Marshal(map[string]string{"message": "Get ACI file failed"})
		return http.StatusNotFound, result
	}

	return http.StatusOK, img

}
Example #24
0
func PatchBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	desc := ctx.Params(":uuid")
	uuid := strings.Split(desc, "?")[0]

	imagePathTmp := fmt.Sprintf("%v/%v", setting.ImagePath, uuid)
	layerfileTmp := fmt.Sprintf("%v/%v/layer", setting.ImagePath, uuid)

	//saving specific tarsum every times is in order to split the same tarsum in HEAD handler
	if !utils.IsDirExist(imagePathTmp) {
		os.MkdirAll(imagePathTmp, os.ModePerm)
	}

	if _, err := os.Stat(layerfileTmp); err == nil {
		os.Remove(layerfileTmp)
	}

	data, _ := ioutil.ReadAll(ctx.Req.Request.Body)
	if err := ioutil.WriteFile(layerfileTmp, data, 0777); err != nil {
		log.Error("[REGISTRY API V2] Save layerfile failed: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Save layerfile failed"})
		return http.StatusBadRequest, result
	}

	state := utils.MD5(fmt.Sprintf("%s/%s/%s", namespace, repository, time.Now().UnixNano()/int64(time.Millisecond)))
	random := fmt.Sprintf("https://%s/v2/%s/%s/blobs/uploads/%s?_state=%s",
		setting.Domains,
		namespace,
		repository,
		uuid,
		state)

	ctx.Resp.Header().Set("Docker-Upload-Uuid", uuid)
	ctx.Resp.Header().Set("Location", random)
	ctx.Resp.Header().Set("Range", fmt.Sprintf("0-%v", len(data)-1))

	result, _ := json.Marshal(map[string]string{})
	return http.StatusAccepted, result
}
Example #25
0
func GetImageAncestryV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if has, _, err := i.Has(imageId); err != nil {
		log.Error("[REGISTRY API V1] Read Image Ancestry Error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Read Image Ancestry Error"})
		return http.StatusBadRequest, result
	} else if has == false {
		log.Error("[REGISTRY API V1] Read Image None: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Read Image None"})
		return http.StatusNotFound, result
	}

	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(i.Ancestry)))

	return http.StatusOK, []byte(i.Ancestry)
}
Example #26
0
func PutTagV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")
	tag := ctx.Params(":tag")

	bodystr, _ := ctx.Req.Body().String()

	rege, _ := regexp.Compile(`"([[:alnum:]]+)"`)
	imageIds := rege.FindStringSubmatch(bodystr)

	r := new(models.Repository)
	if err := r.PutTag(imageIds[1], namespace, repository, tag); err != nil {
		log.Error("[REGISTRY API V1] Failed to save repository %v/%v tag: %v", namespace, repository, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to save repository tag"})
		return http.StatusBadRequest, result
	}

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #27
0
func GetBlobsV2Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	digest := ctx.Params(":digest")

	tarsum := strings.Split(digest, ":")[1]

	i := new(models.Image)
	if exists, err := i.Get(tarsum); err != nil {
		log.Error("[REGISTRY API V2] Failed to get tarsum %v: %v", tarsum, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get tarsum"})
		return http.StatusBadRequest, result
	} else if !exists {
		log.Error("[REGISTRY API V2] Not found tarsum: %v: %v", tarsum, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Not found tarsum"})
		return http.StatusNotFound, result
	}

	layer, err := module.DownloadLayer(i.Path)
	if err != nil {
		log.Error("[REGISTRY API V2] Failed to get layer: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to read layer file"})
		return http.StatusInternalServerError, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
	ctx.Resp.Header().Set("Docker-Content-Digest", digest)
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(layer)))

	return http.StatusOK, layer
}
Example #28
0
//Support to push acis
func PostUploadHandler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	acifile := ctx.Params(":acifile")
	signfile := fmt.Sprintf("%v%v", acifile, ".asc")

	//TODO: only for testing,pubkey will be read and saved via user management module
	pubkeyspath := module.GetPubkeysPath(namespace, repository, setting.APIVERSION_ACI)
	if _, err := os.Stat(pubkeyspath); err != nil {
		if err := os.MkdirAll(pubkeyspath, os.ModePerm); err != nil {
			log.Error("[ACI API] Failed to create pubkeys path %v: %v", pubkeyspath, err.Error())

			result, _ := json.Marshal(map[string]string{"message": "Failed to create pubkeys path"})
			return http.StatusInternalServerError, result
		}
	}

	imageId := utils.MD5(uuid.NewV4().String())
	imagepath := module.GetImagePath(imageId, setting.APIVERSION_ACI)
	if err := os.MkdirAll(imagepath, os.ModePerm); err != nil {
		log.Error("[ACI API] Failed to create aci path %v: %v", imagepath, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to create aci path"})
		return http.StatusInternalServerError, result
	}

	prefix := fmt.Sprintf("%v://%v/ac/push/%v/%v/", setting.ListenMode, setting.Domains, namespace, repository)
	endpoint := models.UploadDetails{
		ACIPushVersion: "0.0.1", //TODO: follow ACI push spec
		Multipart:      false,
		ManifestURL:    prefix + imageId + "/manifest",
		SignatureURL:   prefix + imageId + "/signature/" + signfile,
		ACIURL:         prefix + imageId + "/aci/" + acifile,
		CompletedURL:   prefix + imageId + "/complete/" + acifile + "/" + signfile,
	}

	result, _ := json.Marshal(endpoint)
	return http.StatusOK, result
}
Example #29
0
func GetTagV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	repo := new(models.Repository)
	if has, _, err := repo.Has(namespace, repository); err != nil {
		log.Error("[REGISTRY API V1] Read repository json error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Get V1 tag failed,wrong name or repository"})
		return http.StatusBadRequest, result
	} else if has == false {
		log.Error("[REGISTRY API V1] Read repository no found. %v/%v", namespace, repository)

		result, _ := json.Marshal(map[string]string{"message": "Get V1 tag failed,read repository no found"})
		return http.StatusNotFound, result
	}

	tag := map[string]string{}

	for _, value := range repo.Tags {
		t := new(models.Tag)
		if err := db.Get(t, value); err != nil {
			log.Error(fmt.Sprintf("[REGISTRY API V1]  %s/%s Tags is not exist", namespace, repository))

			result, _ := json.Marshal(map[string]string{"message": fmt.Sprintf("%s/%s Tags is not exist", namespace, repository)})
			return http.StatusNotFound, result
		}

		tag[t.Name] = t.ImageId
	}

	result, _ := json.Marshal(tag)
	return http.StatusOK, result
}
Example #30
0
func GetImageLayerV1Handler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")

	i := new(models.Image)
	if _, err := i.Get(imageId); err != nil {
		log.Error("[REGISTRY API V1] Failed to get image %v layer: %v", imageId, err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to get image layer"})
		return http.StatusNotFound, result
	}

	layerfile := i.Path
	if _, err := os.Stat(layerfile); err != nil {
		log.Error("[REGISTRY API V1] Image layer file state error: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Image layer file state error"})
		return http.StatusInternalServerError, result
	}

	file, err := ioutil.ReadFile(layerfile)
	if err != nil {
		log.Error("[REGISTRY API V1] Failed to read image layer: %v", err.Error())

		result, _ := json.Marshal(map[string]string{"message": "Failed to read image layer"})
		return http.StatusInternalServerError, result
	}

	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
	ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(file)))

	return http.StatusOK, file
}