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

	body, _ := ctx.Req.Body().Bytes()
	if err := module.CheckClientStatus(body); err != nil {
		module.CleanCache(imageId, setting.APIVERSION_ACI)
		log.Error("[ACI API] Failed to push aci: %v", err.Error())

		failmsg := module.FillRespMsg(false, err.Error(), "")
		result, _ := json.Marshal(failmsg)
		return http.StatusInternalServerError, result
	}

	namespace := ctx.Params(":namespace")
	acifile := ctx.Params(":acifile")
	signfile := ctx.Params(":signfile")

	//TODO: only for testing,pubkey will be read and saved via user management module
	pubkeyspath := module.GetPubkeysPath(namespace, repository, setting.APIVERSION_ACI)
	acifilepath := module.GetLayerPath(imageId, acifile, setting.APIVERSION_ACI)
	signfilepath := module.GetSignaturePath(imageId, signfile, setting.APIVERSION_ACI)
	manipath := module.GetManifestPath(imageId, setting.APIVERSION_ACI)
	if err := module.VerifyAciSignature(acifilepath, signfilepath, pubkeyspath); err != nil {
		module.CleanCache(imageId, setting.APIVERSION_ACI)
		log.Error("[ACI API] Failed to verify Aci: %v", err.Error())

		failmsg := module.FillRespMsg(false, "", err.Error())
		result, _ := json.Marshal(failmsg)
		return http.StatusInternalServerError, result
	}

	//If aci image is existent,it should update the db and delete the old image after executed successfully
	var oldimageId = ""
	tag := strings.Trim(acifile, ".aci")
	t := new(models.Tag)
	if exists, err := t.Get(namespace, repository, tag); err == nil && exists {
		oldimageId = t.ImageId
	}

	a := new(models.Aci)
	if err := a.Update(namespace, repository, tag, imageId, manipath, signfilepath, acifilepath); err != nil {
		module.CleanCache(imageId, setting.APIVERSION_ACI)
		log.Error("[ACI API] Failed to update %v/%v: %v", namespace, repository, err.Error())

		failmsg := module.FillRespMsg(false, "", err.Error())
		result, _ := json.Marshal(failmsg)
		return http.StatusInternalServerError, result
	}

	//Delete old aci directory after redis is updated
	if oldimageId != "" {
		module.CleanCache(oldimageId, setting.APIVERSION_ACI)
	}

	successmsg := module.FillRespMsg(true, "", "")
	result, _ := json.Marshal(successmsg)
	return http.StatusOK, result
}
Example #2
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 #3
0
func PutAciHandler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) {
	imageId := ctx.Params(":imageId")
	acifile := ctx.Params(":acifile")

	acifilepath := module.GetLayerPath(imageId, acifile, setting.APIVERSION_ACI)

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

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}
Example #4
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
}