Customize Listen Address (#81)

Replace --port with --listen to allow specifying the interface as well

Also fix the docker-compose file and adjust tests to this change
This commit is contained in:
Marcel Röthke 2025-01-25 01:58:56 +01:00 committed by GitHub
parent 84d942213c
commit d5e7c88608
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 18 deletions

View file

@ -70,8 +70,11 @@ system startup. See the docker-compose documentation for more information.
The server is configured with command-line options. See The server is configured with command-line options. See
`taskchampion-sync-server --help` for full details. `taskchampion-sync-server --help` for full details.
The `--data-dir` option specifies where the server should store its data, and The `--listen` option specifies the interface and port the server listens on.
`--port` gives the port on which the HTTP server runs. It must contain an IP-Address or a DNS name and a port number. This option is
mandatory, but can be repeated to specify multiple interfaces or ports.
The `--data-dir` option specifies where the server should store its data.
By default, the server allows all client IDs. To limit the accepted client IDs, By default, the server allows all client IDs. To limit the accepted client IDs,
such as when running a personal server, use `--allow-client-id <client-id>`. such as when running a personal server, use `--allow-client-id <client-id>`.

View file

@ -56,7 +56,7 @@ services:
volume: volume:
nocopy: true nocopy: true
subpath: tss subpath: tss
command: --data-dir /tss/taskchampion-sync-server --port 8080 command: --data-dir /tss/taskchampion-sync-server --listen 0.0.0.0:8080
environment: environment:
- RUST_LOG=info - RUST_LOG=info
depends_on: depends_on:

View file

@ -21,10 +21,11 @@ fn command() -> Command {
.version(env!("CARGO_PKG_VERSION")) .version(env!("CARGO_PKG_VERSION"))
.about("Server for TaskChampion") .about("Server for TaskChampion")
.arg( .arg(
arg!(-p --port <PORT> "Port on which to serve") arg!(-l --listen <ADDRESS>)
.help("Port on which to serve") .help("Address and Port on which to listen on. Can be an IP Address or a DNS name followed by a colon and a port e.g. localhost:8080")
.value_parser(value_parser!(usize)) .value_parser(ValueParser::string())
.default_value("8080"), .action(ArgAction::Append)
.required(true),
) )
.arg( .arg(
arg!(-d --"data-dir" <DIR> "Directory in which to store data") arg!(-d --"data-dir" <DIR> "Directory in which to store data")
@ -62,7 +63,6 @@ async fn main() -> anyhow::Result<()> {
let matches = command().get_matches(); let matches = command().get_matches();
let data_dir: &OsString = matches.get_one("data-dir").unwrap(); let data_dir: &OsString = matches.get_one("data-dir").unwrap();
let port: usize = *matches.get_one("port").unwrap();
let snapshot_versions: u32 = *matches.get_one("snapshot-versions").unwrap(); let snapshot_versions: u32 = *matches.get_one("snapshot-versions").unwrap();
let snapshot_days: i64 = *matches.get_one("snapshot-days").unwrap(); let snapshot_days: i64 = *matches.get_one("snapshot-days").unwrap();
let client_id_allowlist: Option<HashSet<Uuid>> = matches let client_id_allowlist: Option<HashSet<Uuid>> = matches
@ -75,16 +75,17 @@ async fn main() -> anyhow::Result<()> {
}; };
let server = WebServer::new(config, client_id_allowlist, SqliteStorage::new(data_dir)?); let server = WebServer::new(config, client_id_allowlist, SqliteStorage::new(data_dir)?);
log::info!("Serving on port {}", port); let mut http_server = HttpServer::new(move || {
HttpServer::new(move || {
App::new() App::new()
.wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, print_error)) .wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, print_error))
.wrap(Logger::default()) .wrap(Logger::default())
.configure(|cfg| server.config(cfg)) .configure(|cfg| server.config(cfg))
}) });
.bind(format!("0.0.0.0:{}", port))? for listen_address in matches.get_many::<&str>("listen").unwrap() {
.run() log::info!("Serving on {}", listen_address);
.await?; http_server = http_server.bind(listen_address)?
}
http_server.run().await?;
Ok(()) Ok(())
} }
@ -104,14 +105,19 @@ mod test {
#[test] #[test]
fn command_allowed_client_ids_none() { fn command_allowed_client_ids_none() {
let matches = command().get_matches_from(["tss"]); let matches = command().get_matches_from(["tss", "--listen", "localhost:8080"]);
assert_eq!(allowed(&matches), None); assert_eq!(allowed(&matches), None);
} }
#[test] #[test]
fn command_allowed_client_ids_one() { fn command_allowed_client_ids_one() {
let matches = let matches = command().get_matches_from([
command().get_matches_from(["tss", "-C", "711d5cf3-0cf0-4eb8-9eca-6f7f220638c0"]); "tss",
"--listen",
"localhost:8080",
"-C",
"711d5cf3-0cf0-4eb8-9eca-6f7f220638c0",
]);
assert_eq!( assert_eq!(
allowed(&matches), allowed(&matches),
Some(vec![Uuid::parse_str( Some(vec![Uuid::parse_str(
@ -125,6 +131,8 @@ mod test {
fn command_allowed_client_ids_two() { fn command_allowed_client_ids_two() {
let matches = command().get_matches_from([ let matches = command().get_matches_from([
"tss", "tss",
"--listen",
"localhost:8080",
"-C", "-C",
"711d5cf3-0cf0-4eb8-9eca-6f7f220638c0", "711d5cf3-0cf0-4eb8-9eca-6f7f220638c0",
"-C", "-C",
@ -141,7 +149,13 @@ mod test {
#[test] #[test]
fn command_data_dir() { fn command_data_dir() {
let matches = command().get_matches_from(["tss", "--data-dir", "/foo/bar"]); let matches = command().get_matches_from([
"tss",
"--data-dir",
"/foo/bar",
"--listen",
"localhost:8080",
]);
assert_eq!(matches.get_one::<OsString>("data-dir").unwrap(), "/foo/bar"); assert_eq!(matches.get_one::<OsString>("data-dir").unwrap(), "/foo/bar");
} }