From 49ddb312dea5d298952ad460922ed3f518677214 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 11 Aug 2022 19:07:54 +0200 Subject: [PATCH 1/5] feat(server): added endpoint to remove package from arch-repo --- docs/api/source/includes/_repository.md | 29 +++++++++++++++++++++++++ src/repo/repo.v | 2 +- src/server/routes.v | 23 ++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/docs/api/source/includes/_repository.md b/docs/api/source/includes/_repository.md index fbbc329..9764e01 100644 --- a/docs/api/source/includes/_repository.md +++ b/docs/api/source/includes/_repository.md @@ -93,3 +93,32 @@ other already present arch-repos. Parameter | Description --------- | ----------- repo | Repository to publish package to + +## Remove package from arch-repo + + + +```shell +curl \ + -H 'X-Api-Key: secret' \ + -XDELETE \ + https://example.com/vieter/x86_64/mike +``` + +This endpoint allows you to remove a package from a given arch-repo. + +### HTTP Request + +`DELETE /:repo/:arch/:pkg` + +### URL Parameters + +Parameter | Description +--------- | ----------- +repo | Repository to delete package from +arch | Specific arch-repo to remove package from +pkg | Name of package to remove (without any version information) diff --git a/src/repo/repo.v b/src/repo/repo.v index c4b85c0..7de12cd 100644 --- a/src/repo/repo.v +++ b/src/repo/repo.v @@ -158,7 +158,7 @@ fn (r &RepoGroupManager) add_pkg_in_arch_repo(repo string, arch string, pkg &pac // remove_pkg_from_arch_repo removes a package from an arch-repo's database. It // returns false if the package wasn't present in the database. It also // optionally re-syncs the repo archives. -fn (r &RepoGroupManager) remove_pkg_from_arch_repo(repo string, arch string, pkg_name string, sync bool) ?bool { +pub fn (r &RepoGroupManager) remove_pkg_from_arch_repo(repo string, arch string, pkg_name string, sync bool) ?bool { repo_dir := os.join_path(r.repos_dir, repo, arch) // If the repository doesn't exist yet, the result is automatically false diff --git a/src/server/routes.v b/src/server/routes.v index fbf37df..3b86e20 100644 --- a/src/server/routes.v +++ b/src/server/routes.v @@ -57,6 +57,29 @@ fn (mut app App) get_repo_file(repo string, arch string, filename string) web.Re return app.file(full_path) } +['/:repo/:arch/:pkg'; delete] +fn (mut app App) delete_package(repo string, arch string, pkg string) web.Result { + if !app.is_authorized() { + return app.json(http.Status.unauthorized, new_response('Unauthorized.')) + } + + res := app.repo.remove_pkg_from_arch_repo(repo, arch, pkg, true) or { + app.lerror('Error while deleting package: $err.msg()') + + return app.json(http.Status.internal_server_error, new_response('Failed to delete package.')) + } + + if res { + app.linfo("Removed package '$pkg' from '$repo/$arch'") + + return app.json(http.Status.ok, new_response('Package removed.')) + } else { + app.linfo("Tried removing package '$pkg' from '$repo/$arch', but it doesn't exist.") + + return app.json(http.Status.not_found, new_response('Package not found.')) + } +} + // put_package handles publishing a package to a repository. ['/:repo/publish'; post] fn (mut app App) put_package(repo string) web.Result { From 6283cbea9cf0c655ea43a146bada31aef5ee9d7f Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 11 Aug 2022 19:16:38 +0200 Subject: [PATCH 2/5] feat(repo): added function to remove arch-repo --- src/repo/{repo.v => add.v} | 48 --------------------------- src/repo/remove.v | 68 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 48 deletions(-) rename src/repo/{repo.v => add.v} (77%) create mode 100644 src/repo/remove.v diff --git a/src/repo/repo.v b/src/repo/add.v similarity index 77% rename from src/repo/repo.v rename to src/repo/add.v index 7de12cd..0985c7a 100644 --- a/src/repo/repo.v +++ b/src/repo/add.v @@ -154,51 +154,3 @@ fn (r &RepoGroupManager) add_pkg_in_arch_repo(repo string, arch string, pkg &pac return true } - -// remove_pkg_from_arch_repo removes a package from an arch-repo's database. It -// returns false if the package wasn't present in the database. It also -// optionally re-syncs the repo archives. -pub fn (r &RepoGroupManager) remove_pkg_from_arch_repo(repo string, arch string, pkg_name string, sync bool) ?bool { - repo_dir := os.join_path(r.repos_dir, repo, arch) - - // If the repository doesn't exist yet, the result is automatically false - if !os.exists(repo_dir) { - return false - } - - // We iterate over every directory in the repo dir - // TODO filter so we only check directories - for d in os.ls(repo_dir)? { - // Because a repository only allows a single version of each package, - // we need only compare whether the name of the package is the same, - // not the version. - name := d.split('-')#[..-2].join('-') - - if name == pkg_name { - // We lock the mutex here to prevent other routines from creating a - // new archive while we remove an entry - lock r.mutex { - os.rmdir_all(os.join_path_single(repo_dir, d))? - } - - // Also remove the package archive - repo_pkg_dir := os.join_path(r.pkg_dir, repo, arch) - - archives := os.ls(repo_pkg_dir)?.filter(it.split('-')#[..-3].join('-') == name) - - for archive_name in archives { - full_path := os.join_path_single(repo_pkg_dir, archive_name) - os.rm(full_path)? - } - - // Sync the db archives if requested - if sync { - r.sync(repo, arch)? - } - - return true - } - } - - return false -} diff --git a/src/repo/remove.v b/src/repo/remove.v new file mode 100644 index 0000000..dd4f400 --- /dev/null +++ b/src/repo/remove.v @@ -0,0 +1,68 @@ +module repo + +import os + +// remove_pkg_from_arch_repo removes a package from an arch-repo's database. It +// returns false if the package wasn't present in the database. It also +// optionally re-syncs the repo archives. +pub fn (r &RepoGroupManager) remove_pkg_from_arch_repo(repo string, arch string, pkg_name string, sync bool) ?bool { + repo_dir := os.join_path(r.repos_dir, repo, arch) + + // If the repository doesn't exist yet, the result is automatically false + if !os.exists(repo_dir) { + return false + } + + // We iterate over every directory in the repo dir + // TODO filter so we only check directories + for d in os.ls(repo_dir)? { + // Because a repository only allows a single version of each package, + // we need only compare whether the name of the package is the same, + // not the version. + name := d.split('-')#[..-2].join('-') + + if name == pkg_name { + // We lock the mutex here to prevent other routines from creating a + // new archive while we remove an entry + lock r.mutex { + os.rmdir_all(os.join_path_single(repo_dir, d))? + } + + // Also remove the package archive + repo_pkg_dir := os.join_path(r.pkg_dir, repo, arch) + + archives := os.ls(repo_pkg_dir)?.filter(it.split('-')#[..-3].join('-') == name) + + for archive_name in archives { + full_path := os.join_path_single(repo_pkg_dir, archive_name) + os.rm(full_path)? + } + + // Sync the db archives if requested + if sync { + r.sync(repo, arch)? + } + + return true + } + } + + return false +} + +// remove_arch_repo removes an arch-repo & its packages. +pub fn (r &RepoGroupManager) remove_arch_repo(repo string, arch string) ?bool { + repo_dir := os.join_path(r.repos_dir, repo, arch) + + // If the repository doesn't exist yet, the result is automatically false + if !os.exists(repo_dir) { + return false + } + + os.rmdir_all(repo_dir)? + + pkg_dir := os.join_path(r.pkg_dir, repo, arch) + os.rmdir_all(pkg_dir)? + + return true +} From 68b7e5e71ec636fe1fdcb7338f02dd3f70e922ed Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 11 Aug 2022 19:28:17 +0200 Subject: [PATCH 3/5] feat(server): added routes for removing arch-repo & repo --- docs/api/source/includes/_repository.md | 55 ++++++++++++++++++ src/repo/remove.v | 17 ++++++ src/server/{routes.v => repo.v} | 23 -------- src/server/repo_remove.v | 77 +++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 23 deletions(-) rename src/server/{routes.v => repo.v} (82%) create mode 100644 src/server/repo_remove.v diff --git a/docs/api/source/includes/_repository.md b/docs/api/source/includes/_repository.md index 9764e01..a846904 100644 --- a/docs/api/source/includes/_repository.md +++ b/docs/api/source/includes/_repository.md @@ -122,3 +122,58 @@ Parameter | Description repo | Repository to delete package from arch | Specific arch-repo to remove package from pkg | Name of package to remove (without any version information) + +## Remove arch-repo + + + +```shell +curl \ + -H 'X-Api-Key: secret' \ + -XDELETE \ + https://example.com/vieter/x86_64 +``` + +This endpoint allows remove an entire arch-repo. + +### HTTP Request + +`DELETE /:repo/:arch` + +### URL Parameters + +Parameter | Description +--------- | ----------- +repo | Repository to delete arch-repo from +arch | Specific architecture to remove package + +## Remove repo + + + +```shell +curl \ + -H 'X-Api-Key: secret' \ + -XDELETE \ + https://example.com/vieter +``` + +This endpoint allows remove an entire repo. + +### HTTP Request + +`DELETE /:repo` + +### URL Parameters + +Parameter | Description +--------- | ----------- +repo | Repository to delete diff --git a/src/repo/remove.v b/src/repo/remove.v index dd4f400..add921c 100644 --- a/src/repo/remove.v +++ b/src/repo/remove.v @@ -66,3 +66,20 @@ pub fn (r &RepoGroupManager) remove_arch_repo(repo string, arch string) ?bool { return true } + +// remove_repo removes a repo & its packages. +pub fn (r &RepoGroupManager) remove_repo(repo string) ?bool { + repo_dir := os.join_path_single(r.repos_dir, repo) + + // If the repository doesn't exist yet, the result is automatically false + if !os.exists(repo_dir) { + return false + } + + os.rmdir_all(repo_dir)? + + pkg_dir := os.join_path_single(r.pkg_dir, repo) + os.rmdir_all(pkg_dir)? + + return true +} diff --git a/src/server/routes.v b/src/server/repo.v similarity index 82% rename from src/server/routes.v rename to src/server/repo.v index 3b86e20..fbf37df 100644 --- a/src/server/routes.v +++ b/src/server/repo.v @@ -57,29 +57,6 @@ fn (mut app App) get_repo_file(repo string, arch string, filename string) web.Re return app.file(full_path) } -['/:repo/:arch/:pkg'; delete] -fn (mut app App) delete_package(repo string, arch string, pkg string) web.Result { - if !app.is_authorized() { - return app.json(http.Status.unauthorized, new_response('Unauthorized.')) - } - - res := app.repo.remove_pkg_from_arch_repo(repo, arch, pkg, true) or { - app.lerror('Error while deleting package: $err.msg()') - - return app.json(http.Status.internal_server_error, new_response('Failed to delete package.')) - } - - if res { - app.linfo("Removed package '$pkg' from '$repo/$arch'") - - return app.json(http.Status.ok, new_response('Package removed.')) - } else { - app.linfo("Tried removing package '$pkg' from '$repo/$arch', but it doesn't exist.") - - return app.json(http.Status.not_found, new_response('Package not found.')) - } -} - // put_package handles publishing a package to a repository. ['/:repo/publish'; post] fn (mut app App) put_package(repo string) web.Result { diff --git a/src/server/repo_remove.v b/src/server/repo_remove.v new file mode 100644 index 0000000..642f26f --- /dev/null +++ b/src/server/repo_remove.v @@ -0,0 +1,77 @@ +module server + +import web +import net.http +import response { new_response } + +// delete_package tries to remove the given package. +['/:repo/:arch/:pkg'; delete] +fn (mut app App) delete_package(repo string, arch string, pkg string) web.Result { + if !app.is_authorized() { + return app.json(http.Status.unauthorized, new_response('Unauthorized.')) + } + + res := app.repo.remove_pkg_from_arch_repo(repo, arch, pkg, true) or { + app.lerror('Error while deleting package: $err.msg()') + + return app.json(http.Status.internal_server_error, new_response('Failed to delete package.')) + } + + if res { + app.linfo("Removed package '$pkg' from '$repo/$arch'") + + return app.json(http.Status.ok, new_response('Package removed.')) + } else { + app.linfo("Tried removing package '$pkg' from '$repo/$arch', but it doesn't exist.") + + return app.json(http.Status.not_found, new_response('Package not found.')) + } +} + +// delete_arch_repo tries to remove the given arch-repo. +['/:repo/:arch'; delete] +fn (mut app App) delete_arch_repo(repo string, arch string) web.Result { + if !app.is_authorized() { + return app.json(http.Status.unauthorized, new_response('Unauthorized.')) + } + + res := app.repo.remove_arch_repo(repo, arch) or { + app.lerror('Error while deleting arch-repo: $err.msg()') + + return app.json(http.Status.internal_server_error, new_response('Failed to delete arch-repo.')) + } + + if res { + app.linfo("Removed '$repo/$arch'") + + return app.json(http.Status.ok, new_response('Arch-repo removed.')) + } else { + app.linfo("Tried removing '$repo/$arch', but it doesn't exist.") + + return app.json(http.Status.not_found, new_response('Arch-repo not found.')) + } +} + +// delete_repo tries to remove the given repo. +['/:repo'; delete] +fn (mut app App) delete_repo(repo string) web.Result { + if !app.is_authorized() { + return app.json(http.Status.unauthorized, new_response('Unauthorized.')) + } + + res := app.repo.remove_repo(repo) or { + app.lerror('Error while deleting repo: $err.msg()') + + return app.json(http.Status.internal_server_error, new_response('Failed to delete repo.')) + } + + if res { + app.linfo("Removed '$repo'") + + return app.json(http.Status.ok, new_response('Repo removed.')) + } else { + app.linfo("Tried removing '$repo', but it doesn't exist.") + + return app.json(http.Status.not_found, new_response('Repo not found.')) + } +} From ba3b00572b3ddf31490f054b5bbf2288913da5af Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 11 Aug 2022 19:44:22 +0200 Subject: [PATCH 4/5] chore: updated changelog [CI SKIP] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a03c18c..b7138a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Targets with kind 'url' can provide a direct URL to a PKGBUILD instead of providing a Git repository * CLI commands for searching the AUR & directly adding packages +* HTTP routes for removing packages, arch-repos & repos ### Changed From 50918da67214ff69a29343f04a68f52e28f602dc Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 11 Aug 2022 19:47:26 +0200 Subject: [PATCH 5/5] docs: fixed some typos --- docs/api/source/includes/_repository.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/source/includes/_repository.md b/docs/api/source/includes/_repository.md index a846904..ff17f71 100644 --- a/docs/api/source/includes/_repository.md +++ b/docs/api/source/includes/_repository.md @@ -138,7 +138,7 @@ curl \ https://example.com/vieter/x86_64 ``` -This endpoint allows remove an entire arch-repo. +This endpoint allows removing an entire arch-repo. ### HTTP Request @@ -149,7 +149,7 @@ This endpoint allows remove an entire arch-repo. Parameter | Description --------- | ----------- repo | Repository to delete arch-repo from -arch | Specific architecture to remove package +arch | Specific architecture to remove ## Remove repo @@ -166,7 +166,7 @@ curl \ https://example.com/vieter ``` -This endpoint allows remove an entire repo. +This endpoint allows removing an entire repo. ### HTTP Request