make listening address configurable
All checks were successful
Build Multiarch Container Image / call-reusable-workflow (push) Successful in 20m20s

This commit is contained in:
Sebastian Hugentobler 2024-06-26 08:06:48 +02:00
parent 191e5b66c3
commit 672c50e5c5
Signed by: shu
GPG Key ID: BB32CF3CA052C2F0
7 changed files with 47 additions and 11 deletions

2
Cargo.lock generated
View File

@ -889,7 +889,7 @@ dependencies = [
[[package]] [[package]]
name = "little-hesinde" name = "little-hesinde"
version = "0.1.3" version = "0.1.4"
dependencies = [ dependencies = [
"calibre-db", "calibre-db",
"clap", "clap",

View File

@ -1,4 +1,4 @@
FROM docker.io/rust:1-alpine3.19 AS builder FROM docker.io/rust:1-alpine3.20 AS builder
RUN apk --no-cache add \ RUN apk --no-cache add \
musl-dev musl-dev
@ -17,7 +17,7 @@ RUN cp "./target/$(arch)-unknown-linux-musl/release/little-hesinde" /app
FROM scratch FROM scratch
COPY --from=builder /app /app COPY --from=builder /app /app
CMD ["/app", "--", "/library"] CMD ["/app", "--listen-address", "[::]:3000", "--", "/library"]
VOLUME ["/library"] VOLUME ["/library"]
EXPOSE 3000 EXPOSE 3000

View File

@ -33,10 +33,19 @@ From there on `cargo run` and `cargo build` and so on can be used.
# Configuration # Configuration
The binary takes exactly one argument, the path to the calibre library folder. ```
Usage: little-hesinde [OPTIONS] -- <LIBRARY_PATH>
The listening port is hardcoded to `3000` for now, as is the listening on all Arguments:
interfaces. <LIBRARY_PATH> Calibre library path
Options:
-l, --listen-address <LISTEN_ADDRESS> Address to listen on [default: [::1]:3000]
-h, --help Print help
-V, --version Print version
```
Example: `little-hesinde -l [::]4000 -- ~/Documents/library/`
# Usage # Usage

View File

@ -1,6 +1,6 @@
[package] [package]
name = "little-hesinde" name = "little-hesinde"
version = "0.1.3" version = "0.1.4"
edition = "2021" edition = "2021"
license = { workspace = true } license = { workspace = true }
authors = { workspace = true } authors = { workspace = true }

View File

@ -6,6 +6,9 @@ use clap::Parser;
#[derive(Parser)] #[derive(Parser)]
#[command(version, about, long_about = None)] #[command(version, about, long_about = None)]
pub struct Cli { pub struct Cli {
/// Address to listen on
#[arg(short, long, default_value = "[::1]:3000")]
pub listen_address: String,
/// Calibre library path /// Calibre library path
#[arg(last = true)] #[arg(last = true)]
pub library_path: String, pub library_path: String,

View File

@ -1,6 +1,10 @@
//! Configuration data. //! Configuration data.
use std::path::{Path, PathBuf}; use std::{
net::SocketAddr,
net::ToSocketAddrs,
path::{Path, PathBuf},
};
use thiserror::Error; use thiserror::Error;
@ -15,14 +19,20 @@ pub enum ConfigError {
/// Calibre database does not exist. /// Calibre database does not exist.
#[error("no metadata.db in {0}")] #[error("no metadata.db in {0}")]
MetadataNotFound(String), MetadataNotFound(String),
/// Error converting a string to a listening address.
#[error("failed to convert into listening address")]
ListeningAddressError(String),
} }
/// Application configuration. /// Application configuration.
#[derive(Debug, Clone)]
pub struct Config { pub struct Config {
/// Calibre library folder. /// Calibre library folder.
pub library_path: PathBuf, pub library_path: PathBuf,
/// Calibre metadata file path. /// Calibre metadata file path.
pub metadata_path: PathBuf, pub metadata_path: PathBuf,
/// Address to listen on.
pub listen_address: SocketAddr,
} }
impl Config { impl Config {
@ -48,10 +58,21 @@ impl Config {
.to_string(); .to_string();
return Err(ConfigError::MetadataNotFound(metadata_path)); return Err(ConfigError::MetadataNotFound(metadata_path));
} }
let listen_address = args
.listen_address
.to_socket_addrs()
.map_err(|e| {
ConfigError::ListeningAddressError(format!("{}: {e:?}", args.listen_address))
})?
.next()
.ok_or(ConfigError::ListeningAddressError(
args.listen_address.clone(),
))?;
Ok(Self { Ok(Self {
library_path, library_path,
metadata_path, metadata_path,
listen_address,
}) })
} }
} }

View File

@ -71,7 +71,7 @@ pub mod opds {
pub mod templates; pub mod templates;
pub const APP_NAME: &str = "little-hesinde"; pub const APP_NAME: &str = "little-hesinde";
pub const VERSION: &str = "0.1.3"; pub const VERSION: &str = "0.1.4";
/// Internal marker data in lieu of a proper `Accept` header. /// Internal marker data in lieu of a proper `Accept` header.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -90,7 +90,10 @@ pub struct Files;
/// Main entry point to run the ebook server with a calibre library specified in `config`. /// Main entry point to run the ebook server with a calibre library specified in `config`.
pub async fn run(config: Config) -> Result<(), std::io::Error> { pub async fn run(config: Config) -> Result<(), std::io::Error> {
let calibre = Calibre::load(&config.metadata_path).expect("failed to load calibre database"); let calibre = Calibre::load(&config.metadata_path).expect("failed to load calibre database");
let app_state = Arc::new(AppState { calibre, config }); let app_state = Arc::new(AppState {
calibre,
config: config.clone(),
});
let html_routes = Route::new() let html_routes = Route::new()
.at("/", get(handlers::recent::handler)) .at("/", get(handlers::recent::handler))
@ -130,7 +133,7 @@ pub async fn run(config: Config) -> Result<(), std::io::Error> {
.data(app_state) .data(app_state)
.with(Tracing); .with(Tracing);
let server = Server::new(TcpListener::bind("[::]:3000")) let server = Server::new(TcpListener::bind(config.listen_address))
.name("cops-web") .name("cops-web")
.run(app); .run(app);