mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 11:28:24 +00:00 
			
		
		
		
	Support for grouping RPMs using paths (#26984)
The current rpm repository places all packages in the same repository, and different systems (el7,f34) may hit packages that do not belong to this distribution ( #25304 ) , which now supports grouping of rpm.  Fixes #25304 . Fixes #27056 . Refactor: [#25866](https://github.com/go-gitea/gitea/pull/25866)
This commit is contained in:
		| @@ -512,19 +512,7 @@ func CommonRoutes() *web.Route { | ||||
| 			r.Get("/files/{id}/{version}/{filename}", pypi.DownloadPackageFile) | ||||
| 			r.Get("/simple/{id}", pypi.PackageMetadata) | ||||
| 		}, reqPackageAccess(perm.AccessModeRead)) | ||||
| 		r.Group("/rpm", func() { | ||||
| 			r.Get(".repo", rpm.GetRepositoryConfig) | ||||
| 			r.Get("/repository.key", rpm.GetRepositoryKey) | ||||
| 			r.Put("/upload", reqPackageAccess(perm.AccessModeWrite), rpm.UploadPackageFile) | ||||
| 			r.Group("/package/{name}/{version}/{architecture}", func() { | ||||
| 				r.Get("", rpm.DownloadPackageFile) | ||||
| 				r.Delete("", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile) | ||||
| 			}) | ||||
| 			r.Group("/repodata/{filename}", func() { | ||||
| 				r.Head("", rpm.CheckRepositoryFileExistence) | ||||
| 				r.Get("", rpm.GetRepositoryFile) | ||||
| 			}) | ||||
| 		}, reqPackageAccess(perm.AccessModeRead)) | ||||
| 		r.Group("/rpm", RpmRoutes(r), reqPackageAccess(perm.AccessModeRead)) | ||||
| 		r.Group("/rubygems", func() { | ||||
| 			r.Get("/specs.4.8.gz", rubygems.EnumeratePackages) | ||||
| 			r.Get("/latest_specs.4.8.gz", rubygems.EnumeratePackagesLatest) | ||||
| @@ -589,6 +577,82 @@ func CommonRoutes() *web.Route { | ||||
| 	return r | ||||
| } | ||||
|  | ||||
| // Support for uploading rpm packages with arbitrary depth paths | ||||
| func RpmRoutes(r *web.Route) func() { | ||||
| 	var ( | ||||
| 		groupRepoInfo = regexp.MustCompile(`\A((?:/(?:[^/]+))*|)\.repo\z`) | ||||
| 		groupUpload   = regexp.MustCompile(`\A((?:/(?:[^/]+))*|)/upload\z`) | ||||
| 		groupRpm      = regexp.MustCompile(`\A((?:/(?:[^/]+))*|)/package/([^/]+)/([^/]+)/([^/]+)(?:/([^/]+\.rpm)|)\z`) | ||||
| 		groupMetadata = regexp.MustCompile(`\A((?:/(?:[^/]+))*|)/repodata/([^/]+)\z`) | ||||
| 	) | ||||
|  | ||||
| 	return func() { | ||||
| 		r.Methods("HEAD,GET,POST,PUT,PATCH,DELETE", "*", func(ctx *context.Context) { | ||||
| 			path := ctx.Params("*") | ||||
| 			isHead := ctx.Req.Method == "HEAD" | ||||
| 			isGetHead := ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET" | ||||
| 			isPut := ctx.Req.Method == "PUT" | ||||
| 			isDelete := ctx.Req.Method == "DELETE" | ||||
|  | ||||
| 			if path == "/repository.key" && isGetHead { | ||||
| 				rpm.GetRepositoryKey(ctx) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			// get repo | ||||
| 			m := groupRepoInfo.FindStringSubmatch(path) | ||||
| 			if len(m) == 2 && isGetHead { | ||||
| 				ctx.SetParams("group", strings.Trim(m[1], "/")) | ||||
| 				rpm.GetRepositoryConfig(ctx) | ||||
| 				return | ||||
| 			} | ||||
| 			// get meta | ||||
| 			m = groupMetadata.FindStringSubmatch(path) | ||||
| 			if len(m) == 3 && isGetHead { | ||||
| 				ctx.SetParams("group", strings.Trim(m[1], "/")) | ||||
| 				ctx.SetParams("filename", m[2]) | ||||
| 				if isHead { | ||||
| 					rpm.CheckRepositoryFileExistence(ctx) | ||||
| 				} else { | ||||
| 					rpm.GetRepositoryFile(ctx) | ||||
| 				} | ||||
| 				return | ||||
| 			} | ||||
| 			// upload | ||||
| 			m = groupUpload.FindStringSubmatch(path) | ||||
| 			if len(m) == 2 && isPut { | ||||
| 				reqPackageAccess(perm.AccessModeWrite)(ctx) | ||||
| 				if ctx.Written() { | ||||
| 					return | ||||
| 				} | ||||
| 				ctx.SetParams("group", strings.Trim(m[1], "/")) | ||||
| 				rpm.UploadPackageFile(ctx) | ||||
| 				return | ||||
| 			} | ||||
| 			// rpm down/delete | ||||
| 			m = groupRpm.FindStringSubmatch(path) | ||||
| 			if len(m) == 6 { | ||||
| 				ctx.SetParams("group", strings.Trim(m[1], "/")) | ||||
| 				ctx.SetParams("name", m[2]) | ||||
| 				ctx.SetParams("version", m[3]) | ||||
| 				ctx.SetParams("architecture", m[4]) | ||||
| 				if isGetHead { | ||||
| 					rpm.DownloadPackageFile(ctx) | ||||
| 					return | ||||
| 				} else if isDelete { | ||||
| 					reqPackageAccess(perm.AccessModeWrite)(ctx) | ||||
| 					if ctx.Written() { | ||||
| 						return | ||||
| 					} | ||||
| 					rpm.DeletePackageFile(ctx) | ||||
| 				} | ||||
| 			} | ||||
| 			// default | ||||
| 			ctx.Status(http.StatusNotFound) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // ContainerRoutes provides endpoints that implement the OCI API to serve containers | ||||
| // These have to be mounted on `/v2/...` to comply with the OCI spec: | ||||
| // https://github.com/opencontainers/distribution-spec/blob/main/spec.md | ||||
|   | ||||
		Reference in New Issue
	
	Block a user