cleaned up and added install subcommand
parent
5aeb4c8d7a
commit
0286d854d6
|
@ -2,6 +2,12 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
|
@ -20,6 +26,21 @@ version = "2.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
|
||||
[[package]]
|
||||
name = "camino"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -88,11 +109,14 @@ dependencies = [
|
|||
name = "lookaround"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
"configparser",
|
||||
"directories",
|
||||
"mac_address",
|
||||
"nix",
|
||||
"rand",
|
||||
"sys-info",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
]
|
||||
|
@ -249,6 +273,12 @@ dependencies = [
|
|||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.82"
|
||||
|
@ -260,6 +290,16 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys-info"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
|
|
|
@ -12,11 +12,14 @@ repository = "https://six-five-six-four.com/git/reactor/lookaround"
|
|||
version = "0.1.6"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.97"
|
||||
camino = "1.1.9"
|
||||
configparser = "3.0.0"
|
||||
directories = "5.0.0"
|
||||
mac_address = "1.1.8"
|
||||
nix = "0.29.0"
|
||||
rand = "0.8.4"
|
||||
sys-info = "0.9.1"
|
||||
thiserror = "1.0.30"
|
||||
tokio = { version = "1.14.0", features = ["fs", "net", "rt", "time"] }
|
||||
|
||||
|
|
39
README.md
39
README.md
|
@ -28,51 +28,38 @@ Make sure Cargo is installed from [RustUp.](https://rustup.rs/)
|
|||
cargo install lookaround
|
||||
|
||||
# Find your config directory
|
||||
# Prints something like `Using config dir "/home/user/.config/lookaround"`
|
||||
# e.g. `$HOME/.config/lookaround`
|
||||
lookaround config
|
||||
```
|
||||
|
||||
Create the files `client.ini` and/or `server.ini` in that directory
|
||||
(e.g. /home/user/.config/lookaround/server.ini)
|
||||
Use `$HOME/.config/lookaround/client.ini` as a hosts file if it's more convenient
|
||||
for your client to be the source of truth for nicknames.
|
||||
|
||||
```ini
|
||||
# Clients can store MAC-nickname pairs in client.ini, like a hosts file.
|
||||
# This is useful if your servers are short-lived and you want the clients
|
||||
# to be the source of truth for nicknames.
|
||||
[nicknames]
|
||||
11-11-11-11-11-11 = laptop
|
||||
22-22-22-22-22-22 = desktop
|
||||
11-11-11-11-11-11 = bob-laptop
|
||||
22-22-22-22-22-22 = alice-desktop
|
||||
```
|
||||
|
||||
LookAround will use the system's hostname as its server nickname.
|
||||
If you have a generic hostname like `ubuntu`, override this in `$HOME/.config/lookaround/server.ini`:
|
||||
|
||||
```ini
|
||||
# Long-lived servers can have their nickname configured in server.ini
|
||||
[server]
|
||||
nickname = my-computer
|
||||
nickname = alice-desktop
|
||||
```
|
||||
|
||||
## Auto-Start (Linux)
|
||||
|
||||
Put this systemd unit in `~/.config/systemd/user/lookaround.service`:
|
||||
Run `lookaround install` or `lookaround install $NICKNAME` if you want to set a nickname.
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=LookAround
|
||||
This will create `$HOME/.config/lookaround/server.ini` and `$HOME/.config/systemd/user/lookaround.service`, and start the systemd user service.
|
||||
|
||||
[Service]
|
||||
ExecStart=/home/user/.cargo/bin/lookaround server
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
Then start the service, check that it's running okay, and enable it for
|
||||
auto-start:
|
||||
To check that it's running
|
||||
|
||||
```bash
|
||||
systemctl --user start lookaround
|
||||
systemctl --user status lookaround
|
||||
systemctl --user enable lookaround
|
||||
lookaround client
|
||||
```
|
||||
|
||||
## Auto-Start (Windows)
|
||||
|
|
|
@ -9,6 +9,10 @@ pub fn try_config_dir() -> Option<PathBuf> {
|
|||
Some(try_project_dir()?.config_local_dir().into())
|
||||
}
|
||||
|
||||
pub fn try_server_config_path() -> Option<PathBuf> {
|
||||
Some(try_config_dir()?.join("server.ini"))
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AppError {
|
||||
#[error(transparent)]
|
||||
|
|
|
@ -1,7 +1,83 @@
|
|||
use crate::prelude::*;
|
||||
use anyhow::{Context as _, Result, anyhow, ensure};
|
||||
use std::{io::Write as _, process::Command};
|
||||
|
||||
pub(crate) fn main() -> Result<(), AppError> {
|
||||
let path = app_common::try_config_dir().unwrap().join("server.ini");
|
||||
pub(crate) fn main(nickname: Option<&str>) -> Result<()> {
|
||||
if let Some(nickname) = nickname {
|
||||
let path = app_common::try_server_config_path().context("can't find config dir")?;
|
||||
let text = format!(
|
||||
"[server]
|
||||
nickname = {nickname}
|
||||
"
|
||||
);
|
||||
|
||||
write_new(&path, &text).context("Didn't install LookAround server.ini")?;
|
||||
}
|
||||
|
||||
setup_autostart()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
fn setup_autostart() -> Result<()> {
|
||||
anyhow::bail!("LookAround autostart is only implemented for systemd + GNU/Linux");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn setup_autostart() -> Result<()> {
|
||||
let dirs = directories::BaseDirs::new().context("Could not find home dir")?;
|
||||
let home = dirs.config_local_dir();
|
||||
let path = home.join("systemd").join("user").join("lookaround.service");
|
||||
|
||||
let exe_path =
|
||||
Utf8PathBuf::from_path_buf(std::env::current_exe().context("Can't get current_exe")?)
|
||||
.map_err(|_| anyhow!("current_exe isn't valid UTF-8"))?;
|
||||
let text = format!(
|
||||
"[Unit]
|
||||
Description=LookAround
|
||||
|
||||
[Service]
|
||||
ExecStart={exe_path} server
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
"
|
||||
);
|
||||
|
||||
write_new(&path, &text).context("Didn't install systemd service unit")?;
|
||||
|
||||
ensure!(
|
||||
Command::new("systemctl")
|
||||
.args(["--user", "start", "lookaround"])
|
||||
.status()?
|
||||
.success(),
|
||||
"starting service failed"
|
||||
);
|
||||
ensure!(
|
||||
Command::new("systemctl")
|
||||
.args(["--user", "enable", "lookaround"])
|
||||
.status()?
|
||||
.success(),
|
||||
"enabling service failed"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_new(path: &Path, content: &str) -> Result<()> {
|
||||
use std::fs;
|
||||
fs::create_dir_all(
|
||||
path.parent()
|
||||
.context("Impossible, path should always have a parent")?,
|
||||
)?;
|
||||
match fs::File::create_new(path) {
|
||||
Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => {
|
||||
eprintln!("File already exists, won't overwrite: `{path:?}`")
|
||||
}
|
||||
Err(err) => Err(err)?,
|
||||
Ok(mut f) => f.write_all(content.as_bytes())?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -1,3 +1,4 @@
|
|||
use anyhow::{Result, bail};
|
||||
use prelude::*;
|
||||
|
||||
pub mod app_common;
|
||||
|
@ -9,7 +10,7 @@ mod prelude;
|
|||
mod server;
|
||||
pub mod tlv;
|
||||
|
||||
fn main() -> Result<(), AppError> {
|
||||
fn main() -> Result<()> {
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_io()
|
||||
.enable_time()
|
||||
|
@ -20,7 +21,7 @@ fn main() -> Result<(), AppError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn async_main() -> Result<(), AppError> {
|
||||
async fn async_main() -> Result<()> {
|
||||
let mut args = env::args();
|
||||
|
||||
let _exe_name = args.next();
|
||||
|
@ -32,19 +33,21 @@ async fn async_main() -> Result<(), AppError> {
|
|||
match subcommand.as_ref() {
|
||||
"--version" => {
|
||||
println!("lookaround v{}", env!("CARGO_PKG_VERSION"));
|
||||
Ok(())
|
||||
}
|
||||
"client" => client::client(args).await,
|
||||
"client" => client::client(args).await?,
|
||||
"config" => {
|
||||
config();
|
||||
Ok(())
|
||||
}
|
||||
"find-nick" => client::find_nick(args).await,
|
||||
"install" => install::main(),
|
||||
"my-ips" => my_ips(),
|
||||
"server" => server::server(args).await,
|
||||
x => Err(CliArgError::UnknownSubcommand(x.to_string()).into()),
|
||||
"find-nick" => client::find_nick(args).await?,
|
||||
"install" => {
|
||||
let nickname = args.next();
|
||||
install::main(nickname.as_deref())?
|
||||
}
|
||||
"my-ips" => my_ips()?,
|
||||
"server" => server::server(args).await?,
|
||||
x => bail!("Unknown subcommand `{x}`"),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn config() {
|
||||
|
|
|
@ -3,12 +3,13 @@ pub use std::{
|
|||
env,
|
||||
io::{Cursor, Write},
|
||||
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
|
||||
path::PathBuf,
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
pub use camino::Utf8PathBuf;
|
||||
pub use configparser::ini::Ini;
|
||||
pub use mac_address::{MacAddress, get_mac_address};
|
||||
pub use rand::RngCore;
|
||||
|
|
|
@ -42,10 +42,9 @@ pub async fn server<I: Iterator<Item = String>>(args: I) -> Result<(), AppError>
|
|||
fn configure<I: Iterator<Item = String>>(mut args: I) -> Result<Params, AppError> {
|
||||
let common = app_common::Params::default();
|
||||
let mut bind_addrs = vec![];
|
||||
let mut nickname = String::new();
|
||||
let mut nickname = sys_info::hostname().unwrap_or_default();
|
||||
|
||||
if let Some(dir) = app_common::try_config_dir() {
|
||||
let path = dir.join("server.ini");
|
||||
if let Some(path) = app_common::try_server_config_path() {
|
||||
let mut ini = Ini::new_cs();
|
||||
if ini.load(&path).is_ok() {
|
||||
if let Some(x) = ini.get("server", "nickname") {
|
||||
|
|
Loading…
Reference in New Issue