diff --git a/Cargo.lock b/Cargo.lock index 1549c85..7913500 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -207,7 +207,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "based" version = "0.1.0" -source = "git+https://git.hydrar.de/jmarya/based#cd10c64a1f96703894de9e40a95fd81cc50d244a" +source = "git+https://git.hydrar.de/jmarya/based#04852f2fbcc301d0c2b4098f613b9450b4474363" dependencies = [ "bcrypt", "chrono", @@ -1801,9 +1801,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -2135,9 +2135,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ryu" @@ -2616,9 +2616,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.91" +version = "2.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" +checksum = "70ae51629bf965c5c098cc9e87908a3df5301051a9e087d6f9bef5c9771ed126" dependencies = [ "proc-macro2", "quote", diff --git a/README.md b/README.md index c0edf15..56bf630 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,35 @@ Pacco is an application for managing and hosting pacman repositories. - Web UI for packages - API for pushing new packages - Smart mirroring + +## Usage +### Package Repo +To use the packages pacco provides, add the following to `pacman.conf`: + +```ini +# /etc/pacman.conf + +[repo] +Include = /etc/pacman.d/mirrorlist_pacco +``` + +Add `/etc/pacman.d/mirrorlist_pacco`: + +``` +# /etc/pacman.d/mirrorlist_pacco + +Server = https://example.com/pkg/$repo/$arch +``` + +### Add a new package +To upload a package you created with `makepkg` to a repo use curl: + +```sh +curl -X POST \ +-F "pkg=@./---.pkg.tar.zst" \ +-F "sig=@./---.pkg.tar.zst.sig" \ +-F "name=" \ +-F "arch=" \ +-F "version=" \ +"https:///pkg//upload" +``` diff --git a/docker-compose.yml b/docker-compose.yml index 1faf7f9..55d789d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,3 +8,16 @@ services: environment: - "RUST_LOG=info" - "ROCKET_ADDRESS=0.0.0.0" + - "DATABASE_URL=postgres://user:pass@postgres/watchdogs" + + postgres: + image: timescale/timescaledb:latest-pg16 + restart: always + ports: + - 5432:5432 + volumes: + - ./db:/var/lib/postgresql/data/ + environment: + - POSTGRES_USER=user + - POSTGRES_PASSWORD=pass + - POSTGRES_DB=pacco \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 739502a..4b880b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ use based::page::{Shell, render_page}; use based::request::{RequestContext, StringResponse}; use maud::html; +use pkg::Repository; use rocket::get; use rocket::routes; @@ -16,13 +17,18 @@ pub mod routes; #[get("/")] pub async fn index_page(ctx: RequestContext) -> StringResponse { + let repos: Vec = Repository::list(); + let content = html!( - h1 { "Hello World!" }; + h1 { "Repositories" }; + @for repo in repos { + p { (repo) }; + }; ); render_page( content, - "Hello World", + "Repositories", ctx, &Shell::new(html! {}, html! {}, Some(String::new())), ) diff --git a/src/pkg.rs b/src/pkg.rs index fecb16e..5d870a2 100644 --- a/src/pkg.rs +++ b/src/pkg.rs @@ -4,6 +4,26 @@ pub struct Repository { pub name: String, } +impl Repository { + pub fn list() -> Vec { + let mut repos = vec![]; + + for entry in std::fs::read_dir("./data").unwrap() { + let path = entry.unwrap().path(); + let file_name = path.file_name().unwrap().to_str().unwrap().to_string(); + repos.push(file_name); + } + + repos + } + + pub fn create(name: &str) -> Repository { + let path = PathBuf::from("./data").join(name); + std::fs::create_dir_all(path).unwrap(); + Repository::new(name).unwrap() + } +} + impl Repository { pub fn new(name: &str) -> Option { if PathBuf::from("./data").join(name).exists() { diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 78a2675..4dae008 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,7 +1,5 @@ -use based::page::{Shell, render_page}; -use based::request::api::FallibleApiResponse; -use based::request::{RawResponse, RequestContext, StringResponse, respond_with}; -use maud::html; +use based::request::api::{FallibleApiResponse, api_error}; +use based::request::{RawResponse, RequestContext, respond_with}; use rocket::http::{ContentType, Status}; use rocket::tokio::io::AsyncReadExt; use rocket::{FromForm, get, post}; @@ -39,8 +37,12 @@ pub async fn tmp_file_to_vec<'r>(tmp: &TempFile<'r>) -> Vec { pub async fn upload_pkg( repo: &str, upload: Form>, - user: based::auth::User, + user: based::auth::APIUser, ) -> FallibleApiResponse { + if !user.0.is_admin() { + return Err(api_error("Forbidden")); + } + let pkg = Package::new(repo, &upload.arch, &upload.name, &upload.version); pkg.save( @@ -101,18 +103,3 @@ pub async fn pkg_route(repo: &str, arch: &str, pkg_name: &str, ctx: RequestConte "Not found".as_bytes().to_vec(), ) } - -#[get("/")] -pub async fn index_page(ctx: RequestContext) -> StringResponse { - let content = html!( - h1 { "Hello World!" }; - ); - - render_page( - content, - "Hello World", - ctx, - &Shell::new(html! {}, html! {}, Some(String::new())), - ) - .await -}