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-17 16:23:36 +01:00
parent 84d942213c
commit e686e0feef
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
`taskchampion-sync-server --help` for full details.
The `--data-dir` option specifies where the server should store its data, and
`--port` gives the port on which the HTTP server runs.
The `--listen` option specifies the interface and port the server listens on.
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,
such as when running a personal server, use `--allow-client-id <client-id>`.

View file

@ -56,7 +56,7 @@ services:
volume:
nocopy: true
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:
- RUST_LOG=info
depends_on:

View file

@ -21,10 +21,11 @@ fn command() -> Command {
.version(env!("CARGO_PKG_VERSION"))
.about("Server for TaskChampion")
.arg(
arg!(-p --port <PORT> "Port on which to serve")
.help("Port on which to serve")
.value_parser(value_parser!(usize))
.default_value("8080"),
arg!(-l --listen <ADDRESS>)
.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(ValueParser::string())
.action(ArgAction::Append)
.required(true),
)
.arg(
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 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_days: i64 = *matches.get_one("snapshot-days").unwrap();
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)?);
log::info!("Serving on port {}", port);
HttpServer::new(move || {
let mut http_server = HttpServer::new(move || {
App::new()
.wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, print_error))
.wrap(Logger::default())
.configure(|cfg| server.config(cfg))
})
.bind(format!("0.0.0.0:{}", port))?
.run()
.await?;
});
for listen_address in matches.get_many::<&str>("listen").unwrap() {
log::info!("Serving on {}", listen_address);
http_server = http_server.bind(listen_address)?
}
http_server.run().await?;
Ok(())
}
@ -104,14 +105,19 @@ mod test {
#[test]
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);
}
#[test]
fn command_allowed_client_ids_one() {
let matches =
command().get_matches_from(["tss", "-C", "711d5cf3-0cf0-4eb8-9eca-6f7f220638c0"]);
let matches = command().get_matches_from([
"tss",
"--listen",
"localhost:8080",
"-C",
"711d5cf3-0cf0-4eb8-9eca-6f7f220638c0",
]);
assert_eq!(
allowed(&matches),
Some(vec![Uuid::parse_str(
@ -125,6 +131,8 @@ mod test {
fn command_allowed_client_ids_two() {
let matches = command().get_matches_from([
"tss",
"--listen",
"localhost:8080",
"-C",
"711d5cf3-0cf0-4eb8-9eca-6f7f220638c0",
"-C",
@ -141,7 +149,13 @@ mod test {
#[test]
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");
}