// GetManifests handles GET /api/repositories/manifests func (ra *RepositoryAPI) GetManifests() { repoName := ra.GetString("repo_name") tag := ra.GetString("tag") if len(repoName) == 0 || len(tag) == 0 { ra.CustomAbort(http.StatusBadRequest, "repo_name or tag is nil") } projectName := getProjectName(repoName) project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("failed to get project %s: %v", projectName, err) ra.CustomAbort(http.StatusInternalServerError, "") } if project.Public == 0 { userID := ra.ValidateUser() if !checkProjectPermission(userID, project.ProjectID) { ra.CustomAbort(http.StatusForbidden, "") } } rc, err := ra.initRepositoryClient(repoName) if err != nil { log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } item := models.RepoItem{} mediaTypes := []string{schema1.MediaTypeManifest} _, _, payload, err := rc.PullManifest(tag, mediaTypes) if err != nil { if regErr, ok := err.(*registry_error.Error); ok { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } log.Errorf("error occurred while getting manifest of %s:%s: %v", repoName, tag, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } mani := models.Manifest{} err = json.Unmarshal(payload, &mani) if err != nil { log.Errorf("Failed to decode json from response for manifests, repo name: %s, tag: %s, error: %v", repoName, tag, err) ra.RenderError(http.StatusInternalServerError, "Internal Server Error") return } v1Compatibility := mani.History[0].V1Compatibility err = json.Unmarshal([]byte(v1Compatibility), &item) if err != nil { log.Errorf("Failed to decode V1 field for repo, repo name: %s, tag: %s, error: %v", repoName, tag, err) ra.RenderError(http.StatusInternalServerError, "Internal Server Error") return } item.DurationDays = strconv.Itoa(int(time.Since(item.Created).Hours()/24)) + " days" ra.Data["json"] = item ra.ServeJSON() }
// Head ... func (p *ProjectAPI) Head() { projectName := p.GetString("project_name") if len(projectName) == 0 { p.CustomAbort(http.StatusBadRequest, "project_name is needed") } project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("error occurred in GetProjectByName: %v", err) p.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } // only public project can be Headed by user without login if project != nil && project.Public == 1 { return } userID := p.ValidateUser() if project == nil { p.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound)) } if !checkProjectPermission(userID, project.ProjectID) { p.CustomAbort(http.StatusForbidden, http.StatusText(http.StatusForbidden)) } }
func (c *Checker) enter() (string, error) { project, err := dao.GetProjectByName(c.project) if err != nil { c.logger.Errorf("an error occurred while getting project %s in DB: %v", c.project, err) return "", err } err = c.createProject(project.Public == 1) if err == nil { c.logger.Infof("project %s is created on %s with user %s", c.project, c.dstURL, c.dstUsr) return StatePullManifest, nil } // other job may be also doing the same thing when the current job // is creating project, so when the response code is 409, continue // to do next step if err == ErrConflict { c.logger.Warningf("the status code is 409 when creating project %s on %s with user %s, try to do next step", c.project, c.dstURL, c.dstUsr) return StatePullManifest, nil } c.logger.Errorf("an error occurred while creating project %s on %s with user %s : %v", c.project, c.dstURL, c.dstUsr, err) return "", err }
// GetTags handles GET /api/repositories/tags func (ra *RepositoryAPI) GetTags() { repoName := ra.GetString("repo_name") if len(repoName) == 0 { ra.CustomAbort(http.StatusBadRequest, "repo_name is nil") } projectName := getProjectName(repoName) project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("failed to get project %s: %v", projectName, err) ra.CustomAbort(http.StatusInternalServerError, "") } if project.Public == 0 { userID := ra.ValidateUser() if !checkProjectPermission(userID, project.ProjectID) { ra.CustomAbort(http.StatusForbidden, "") } } rc, err := ra.initRepositoryClient(repoName) if err != nil { log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } tags := []string{} ts, err := rc.ListTag() if err != nil { regErr, ok := err.(*registry_error.Error) if !ok { log.Errorf("error occurred while listing tags of %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } // TODO remove the logic if the bug of registry is fixed // It's a workaround for a bug of registry: when listing tags of // a repository which is being pushed, a "NAME_UNKNOWN" error will // been returned, while the catalog API can list this repository. if regErr.StatusCode != http.StatusNotFound { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } } tags = append(tags, ts...) sort.Strings(tags) ra.Data["json"] = tags ra.ServeJSON() }
// GetPoliciesByRepository returns policies according the repository func GetPoliciesByRepository(repository string) ([]*models.RepPolicy, error) { repository = strings.TrimSpace(repository) repository = strings.TrimRight(repository, "/") projectName := repository[:strings.LastIndex(repository, "/")] project, err := dao.GetProjectByName(projectName) if err != nil { return nil, err } policies, err := dao.GetRepPolicyByProject(project.ProjectID) if err != nil { return nil, err } return policies, nil }
// GetTags handles GET /api/repositories/tags func (ra *RepositoryAPI) GetTags() { repoName := ra.GetString("repo_name") if len(repoName) == 0 { ra.CustomAbort(http.StatusBadRequest, "repo_name is nil") } projectName := getProjectName(repoName) project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("failed to get project %s: %v", projectName, err) ra.CustomAbort(http.StatusInternalServerError, "") } if project.Public == 0 { userID := ra.ValidateUser() if !checkProjectPermission(userID, project.ProjectID) { ra.CustomAbort(http.StatusForbidden, "") } } rc, err := ra.initRepositoryClient(repoName) if err != nil { log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } tags := []string{} ts, err := rc.ListTag() if err != nil { if regErr, ok := err.(*registry_error.Error); ok { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } log.Errorf("error occurred while listing tags of %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } tags = append(tags, ts...) sort.Strings(tags) ra.Data["json"] = tags ra.ServeJSON() }
func (c *Checker) enter() (string, error) { enter: exist, canWrite, err := c.projectExist() if err != nil { c.logger.Errorf("an error occurred while checking existence of project %s on %s with user %s : %v", c.project, c.dstURL, c.dstUsr, err) return "", err } if !exist { project, err := dao.GetProjectByName(c.project) if err != nil { c.logger.Errorf("an error occurred while getting project %s on %s: %v", c.project, c.srcURL, err) return "", err } err = c.createProject(project.Public == 1) if err != nil { // other job may be also doing the same thing when the current job // is creating project, so when the response code is 409, re-check // the existence of project if err == ErrConflict { goto enter } else { c.logger.Errorf("an error occurred while creating project %s on %s with user %s : %v", c.project, c.dstURL, c.dstUsr, err) return "", err } } c.logger.Infof("project %s is created on %s with user %s", c.project, c.dstURL, c.dstUsr) return StatePullManifest, nil } c.logger.Infof("project %s already exists on %s", c.project, c.dstURL) if !canWrite { err = fmt.Errorf("the user %s is unauthorized to write to project %s on %s", c.dstUsr, c.project, c.dstURL) c.logger.Errorf("%v", err) return "", err } c.logger.Infof("the user %s has write privilege to project %s on %s", c.dstUsr, c.project, c.dstURL) return StatePullManifest, nil }
// Delete ... func (ra *RepositoryAPI) Delete() { repoName := ra.GetString("repo_name") if len(repoName) == 0 { ra.CustomAbort(http.StatusBadRequest, "repo_name is nil") } projectName := getProjectName(repoName) project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("failed to get project %s: %v", projectName, err) ra.CustomAbort(http.StatusInternalServerError, "") } if project.Public == 0 { userID := ra.ValidateUser() if !hasProjectAdminRole(userID, project.ProjectID) { ra.CustomAbort(http.StatusForbidden, "") } } rc, err := ra.initRepositoryClient(repoName) if err != nil { log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } tags := []string{} tag := ra.GetString("tag") if len(tag) == 0 { tagList, err := rc.ListTag() if err != nil { if regErr, ok := err.(*registry_error.Error); ok { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } log.Errorf("error occurred while listing tags of %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } // TODO remove the logic if the bug of registry is fixed if len(tagList) == 0 { ra.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound)) } tags = append(tags, tagList...) } else { tags = append(tags, tag) } user, _, ok := ra.Ctx.Request.BasicAuth() if !ok { user, err = ra.getUsername() if err != nil { log.Errorf("failed to get user: %v", err) } } for _, t := range tags { if err := rc.DeleteTag(t); err != nil { if regErr, ok := err.(*registry_error.Error); ok { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } log.Errorf("error occurred while deleting tags of %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } log.Infof("delete tag: %s %s", repoName, t) go TriggerReplicationByRepository(repoName, []string{t}, models.RepOpDelete) go func(tag string) { if err := dao.AccessLog(user, projectName, repoName, tag, "delete"); err != nil { log.Errorf("failed to add access log: %v", err) } }(t) } go func() { log.Debug("refreshing catalog cache") if err := cache.RefreshCatalogCache(); err != nil { log.Errorf("error occurred while refresh catalog cache: %v", err) } }() }