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 }
//Support to fetch acis func GetPubkeysHandler(ctx *macaron.Context, log *logs.BeeLogger) (int, []byte) { namespace := ctx.Params(":namespace") repository := ctx.Params(":repository") pubkeysPath := module.GetPubkeysPath(namespace, repository, setting.APIVERSION_ACI) if _, err := os.Stat(pubkeysPath); err != nil { log.Error("[ACI API] Pubkeys path %v is invalid: %v", pubkeysPath, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Pubkeys path is invalid"}) return http.StatusInternalServerError, result } files, err := ioutil.ReadDir(pubkeysPath) if err != nil { log.Error("[ACI API] Failed to read pubkeys path %v: %v", pubkeysPath, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Failed to read pubkeys path"}) return http.StatusInternalServerError, result } var pubkey []byte if len(files) <= 0 { log.Error("[ACI API] Not found pubkey") result, _ := json.Marshal(map[string]string{"message": "Not found pubkey"}) return http.StatusNotFound, result } // TODO: support single pubkey per user now, to consider whether to support multiple pubkeys per user in the future filename := pubkeysPath + "/" + files[0].Name() pubkey, err = ioutil.ReadFile(filename) if err != nil { log.Error("[ACI API] Failed to read pubkey %v: %v", filename, err.Error()) result, _ := json.Marshal(map[string]string{"message": "Failed to read pubkey"}) return http.StatusInternalServerError, result } return http.StatusOK, pubkey }
//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 }