mize daemon service and some timetrack stuff as well
This commit is contained in:
91
flake.nix
91
flake.nix
@@ -43,7 +43,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
in {
|
in rec {
|
||||||
############################## PACKAGES ##############################
|
############################## PACKAGES ##############################
|
||||||
|
|
||||||
packages = rec {
|
packages = rec {
|
||||||
@@ -109,6 +109,52 @@ in {
|
|||||||
libsoup_3
|
libsoup_3
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
mize = osCrane.buildPackage {
|
||||||
|
src = fileSetForCrate ./packages/mize;
|
||||||
|
cargoExtraArgs = "-p mize";
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkgs.pkg-config
|
||||||
|
pkgs.gobject-introspection
|
||||||
|
pkgs.gobject-introspection.dev
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
git # needed to build spacetimedb as it needs to get it's git hash for setting it's version
|
||||||
|
at-spi2-atk
|
||||||
|
atkmm
|
||||||
|
cairo
|
||||||
|
gdk-pixbuf
|
||||||
|
glib
|
||||||
|
gtk3
|
||||||
|
harfbuzz
|
||||||
|
librsvg
|
||||||
|
libsoup_3
|
||||||
|
pango
|
||||||
|
webkitgtk_4_1
|
||||||
|
openssl
|
||||||
|
wasm-bindgen-cli
|
||||||
|
lld_20
|
||||||
|
xdotool
|
||||||
|
];
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH = with pkgs; pkgs.lib.makeLibraryPath [
|
||||||
|
xdotool
|
||||||
|
webkitgtk_4_1
|
||||||
|
pango
|
||||||
|
openssl
|
||||||
|
at-spi2-atk
|
||||||
|
atkmm
|
||||||
|
cairo
|
||||||
|
gdk-pixbuf
|
||||||
|
glib
|
||||||
|
gtk3
|
||||||
|
harfbuzz
|
||||||
|
librsvg
|
||||||
|
libsoup_3
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
############################## DEV SHELLS ##############################
|
############################## DEV SHELLS ##############################
|
||||||
@@ -264,6 +310,49 @@ in {
|
|||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
############################## NIXOS MODULES ##############################
|
||||||
|
nixosModules.default = { system, lib, config, ... }: {
|
||||||
|
options.mize = {
|
||||||
|
debuginary = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
example = "/home/user/here/mize";
|
||||||
|
description = "If set to NOT null, the mize daemon service will use this path instead of $${self.packages.system.mize}/bin/mize''";
|
||||||
|
};
|
||||||
|
debugConfigFile = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
example = "/home/user/here/mize.toml";
|
||||||
|
description = "If set to NOT null, the mize daemon service will use the config file at this path instead of one written to the nix store";
|
||||||
|
};
|
||||||
|
config = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.anything;
|
||||||
|
default = {};
|
||||||
|
example = {
|
||||||
|
dat_dir = "home/user/my_mize_data";
|
||||||
|
spacetime.url = "spacetime.example.com";
|
||||||
|
};
|
||||||
|
description = "mize config for the daemon";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
systemd.user.services.mize = {
|
||||||
|
description = "the mize daemon";
|
||||||
|
wantedBy = [ "default.target" ];
|
||||||
|
After = [ "graphical-session.target" ];
|
||||||
|
PartOf = [ "graphical-session.target" ]; # this should mean DISPLAY and WAYLAND_DISPLAY are set in the service env...
|
||||||
|
environment = {
|
||||||
|
MIZE_CONFIG_FILES = let fileInStore = (pkgs.formats.toml {}).generate "mize-daemon-config.toml" config.mize.config; in if config.mize.debugConfigFile then "${config.mize.debugConfigFile}" else "${fileInStore}";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "on-failure";
|
||||||
|
ExecStart = if config.mize.debuginary == null then "${self.packages.${system}.mize}/bin/mize daemon" else "${config.mize.debugBinary} daemon";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# for what we do the nixos and home-manager api is identical
|
||||||
|
homeModules.default = nixosModules.default;
|
||||||
|
|
||||||
}) // {
|
}) // {
|
||||||
|
|
||||||
|
|||||||
8
md
8
md
@@ -30,12 +30,12 @@ function deploy_lush {
|
|||||||
if ! tmux has-session -t ppc-deploy 2>/dev/null; then
|
if ! tmux has-session -t ppc-deploy 2>/dev/null; then
|
||||||
echo "Created new tmux session...."
|
echo "Created new tmux session...."
|
||||||
tmux new-session -d -s ppc-deploy "nix develop git+file:///home/me/here/mize#buildShell"
|
tmux new-session -d -s ppc-deploy "nix develop git+file:///home/me/here/mize#buildShell"
|
||||||
tmux send-keys -t ppc-deploy "cargo build --featuers desktop --manifest-path /home/me/here/mize/packages/ppc/Cargo.toml" Enter
|
tmux send-keys -t ppc-deploy "cargo build --featuers desktop --manifest-path /home/me/here/mize/packages/mize/Cargo.toml" Enter
|
||||||
tmux send-keys -t ppc-deploy "systemctl --user restart ppc" Enter
|
tmux send-keys -t ppc-deploy "systemctl --user restart mize" Enter
|
||||||
else
|
else
|
||||||
echo "using existing session..."
|
echo "using existing session..."
|
||||||
tmux send-keys -t ppc-deploy "cargo build --features desktop --manifest-path /home/me/here/mize/packages/ppc/Cargo.toml" Enter
|
tmux send-keys -t ppc-deploy "cargo build --features desktop --manifest-path /home/me/here/mize/packages/mize/Cargo.toml" Enter
|
||||||
tmux send-keys -t ppc-deploy "systemctl --user restart ppc" Enter
|
tmux send-keys -t ppc-deploy "systemctl --user restart mize" Enter
|
||||||
fi
|
fi
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
@@ -66,9 +66,13 @@ pub fn mount(sub_matches: &ArgMatches) -> MizeResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(sub_matches: &ArgMatches) -> MizeResult<()> {
|
pub fn daemon(sub_matches: &ArgMatches) -> MizeResult<()> {
|
||||||
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
|
||||||
|
|
||||||
|
// load all parts we need for any mize application... making a fat daemon for now.
|
||||||
|
// in the future parts should be loaded on demand (from .so files and from parts.mize.works)
|
||||||
|
ppc
|
||||||
|
|
||||||
instance.wait();
|
instance.wait();
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ fn main() {
|
|||||||
// match command
|
// match command
|
||||||
let result = match cli_matches.subcommand() {
|
let result = match cli_matches.subcommand() {
|
||||||
// mi daemon
|
// mi daemon
|
||||||
Some(("run", sub_matches)) => cli::run(sub_matches),
|
Some(("daemon", sub_matches)) => cli::run(sub_matches),
|
||||||
|
|
||||||
Some(("is-running", sub_matches)) => cli::is_running(sub_matches),
|
Some(("is-running", sub_matches)) => cli::is_running(sub_matches),
|
||||||
|
|
||||||
@@ -130,11 +130,7 @@ fn cli_matches() -> clap::ArgMatches {
|
|||||||
.help("specify a config file")
|
.help("specify a config file")
|
||||||
.global(true),
|
.global(true),
|
||||||
)
|
)
|
||||||
.subcommand(
|
.subcommand(Command::new("daemon").about("Run a MiZe Instance as a daemon"))
|
||||||
Command::new("run")
|
|
||||||
.aliases(["r"])
|
|
||||||
.about("Run a MiZe Instance"),
|
|
||||||
)
|
|
||||||
.subcommand(Command::new("stop").about("Stop a MiZe Instance"))
|
.subcommand(Command::new("stop").about("Stop a MiZe Instance"))
|
||||||
.subcommand(Command::new("mount").aliases(["m"]))
|
.subcommand(Command::new("mount").aliases(["m"]))
|
||||||
.subcommand(
|
.subcommand(
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ path = "lib.rs"
|
|||||||
name = "ppc"
|
name = "ppc"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["target-os", "server", "client", "desktop"]
|
default = ["target-os", "server", "client" ]
|
||||||
target-os = [ "clap", "mize/target-os", "marts/target-os", "tracing", "webbrowser", "base64", "serde_json", "serde" ]
|
target-os = [ "clap", "mize/target-os", "marts/target-os", "tracing", "webbrowser", "base64", "serde_json", "serde" ]
|
||||||
target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-js", "marts/target-js", "base64", "serde_json", "serde", "openidconnect", "dioxus", "dioxus-web", "web-sys", "web-sys/Document", "dioxus/web" ]
|
target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-js", "marts/target-js", "base64", "serde_json", "serde", "openidconnect", "dioxus", "dioxus-web", "web-sys", "web-sys/Document", "dioxus/web" ]
|
||||||
server = [ "axum", "axum-extra", "openidconnect", "serde", "serde_json", "reqwest", "rand", "url", "time", "tokio", "dioxus/ssr", "dioxus/server", "dioxus/fullstack", "dioxus/router", "dioxus-ssr", "html-escape", "axum-oidc", "tower", "tower-sessions", "marts/server", "target-os" ]
|
server = [ "axum", "axum-extra", "openidconnect", "serde", "serde_json", "reqwest", "rand", "url", "time", "tokio", "dioxus/ssr", "dioxus/server", "dioxus/fullstack", "dioxus/router", "dioxus-ssr", "html-escape", "axum-oidc", "tower", "tower-sessions", "marts/server", "target-os" ]
|
||||||
desktop = ["dioxus/desktop", "marts/desktop", "target-os"]
|
desktop = ["dioxus/desktop", "marts/desktop", "target-os"]
|
||||||
client = []
|
client = [ "tokio", "openidconnect" ]
|
||||||
webbrowser = ["dep:webbrowser"]
|
webbrowser = ["dep:webbrowser"]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use base64::{
|
|||||||
alphabet::STANDARD,
|
alphabet::STANDARD,
|
||||||
engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig},
|
engine::{DecodePaddingMode, GeneralPurpose, GeneralPurposeConfig},
|
||||||
};
|
};
|
||||||
|
use chrono::{DateTime, Local, NaiveDateTime, TimeDelta, Utc};
|
||||||
use dioxus::{fullstack::ClientResponse, html::ol};
|
use dioxus::{fullstack::ClientResponse, html::ol};
|
||||||
use mize::{Mize, MizeError, MizePart, MizeResult, item::ItemData, mize_err, mize_part};
|
use mize::{Mize, MizeError, MizePart, MizeResult, item::ItemData, mize_err, mize_part};
|
||||||
use openidconnect::{
|
use openidconnect::{
|
||||||
@@ -52,6 +53,7 @@ pub struct ClientSecrets {
|
|||||||
id_token: String,
|
id_token: String,
|
||||||
access_token: String,
|
access_token: String,
|
||||||
refresh_token: String,
|
refresh_token: String,
|
||||||
|
expiry: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MizePart for ClientAuth {
|
impl MizePart for ClientAuth {
|
||||||
@@ -97,7 +99,14 @@ impl ClientAuth {
|
|||||||
let mut mize_clone = self.mize.clone();
|
let mut mize_clone = self.mize.clone();
|
||||||
self.mize.spawn_background("auth.refresh", move || {
|
self.mize.spawn_background("auth.refresh", move || {
|
||||||
loop {
|
loop {
|
||||||
thread::sleep(Duration::from_hours(23));
|
let auth = mize_clone.get_part_native::<ClientAuth>("auth")?;
|
||||||
|
let to_sleep = Utc::now()
|
||||||
|
- auth.secrets.as_ref().unwrap().expiry.clone()
|
||||||
|
- TimeDelta::minutes(20);
|
||||||
|
drop(auth);
|
||||||
|
println!("refresh_thread: going to sleep for: {}", to_sleep);
|
||||||
|
thread::sleep(to_sleep.to_std()?);
|
||||||
|
println!("refresh_thread: sleeping done");
|
||||||
let mut auth = mize_clone.get_part_native::<ClientAuth>("auth")?;
|
let mut auth = mize_clone.get_part_native::<ClientAuth>("auth")?;
|
||||||
auth.refresh()?;
|
auth.refresh()?;
|
||||||
drop(auth);
|
drop(auth);
|
||||||
@@ -118,6 +127,13 @@ pub fn client_auth(mize: &mut Mize) -> MizeResult<()> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// do a refresh if the tokens have expired
|
||||||
|
if (secrets.is_some() && secrets.unwrap().expiry < Utc::now()) {
|
||||||
|
secrets = Some(
|
||||||
|
mize.spawn_async_blocking("refresh_low", refresh_flow(mize.clone(), secrets.unwrap()))?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "target-os")]
|
#[cfg(feature = "target-os")]
|
||||||
{
|
{
|
||||||
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
|
let mut cli = mize.get_part_native::<marts::CliPart>("cli")?;
|
||||||
@@ -260,11 +276,15 @@ async fn refresh_flow(mut mize: Mize, old_secrets: ClientSecrets) -> MizeResult<
|
|||||||
.exchange_refresh_token(&refresh_token)?
|
.exchange_refresh_token(&refresh_token)?
|
||||||
.request_async(&http_client)
|
.request_async(&http_client)
|
||||||
.await?;
|
.await?;
|
||||||
|
let expires_in = res.expires_in().ok_or(mize_err!(
|
||||||
|
"no expiry information was in token response of the refresh flow"
|
||||||
|
))?;
|
||||||
|
|
||||||
return Ok(ClientSecrets {
|
return Ok(ClientSecrets {
|
||||||
id_token: res.id_token().unwrap().to_string(),
|
id_token: res.id_token().unwrap().to_string(),
|
||||||
access_token: res.access_token().secret().to_owned(),
|
access_token: res.access_token().secret().to_owned(),
|
||||||
refresh_token: res.refresh_token().unwrap().secret().to_owned(),
|
refresh_token: res.refresh_token().unwrap().secret().to_owned(),
|
||||||
|
expiry: Utc::now() + expires_in,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,10 +398,15 @@ async fn auth_flow(mut mize: Mize) -> MizeResult<ClientSecrets> {
|
|||||||
.refresh_token()
|
.refresh_token()
|
||||||
.ok_or(mize_err!("no refresh token present"))?;
|
.ok_or(mize_err!("no refresh token present"))?;
|
||||||
|
|
||||||
|
let expires_in = token_response.expires_in().ok_or(mize_err!(
|
||||||
|
"no expiry information was in token response of the refresh flow"
|
||||||
|
))?;
|
||||||
|
|
||||||
Ok(ClientSecrets {
|
Ok(ClientSecrets {
|
||||||
id_token: id_token.to_string(),
|
id_token: id_token.to_string(),
|
||||||
access_token: token_response.access_token().secret().to_string(),
|
access_token: token_response.access_token().secret().to_string(),
|
||||||
refresh_token: refresh.secret().to_owned(),
|
refresh_token: refresh.secret().to_owned(),
|
||||||
|
expiry: Utc::now() + expires_in,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,22 @@ mod platform {
|
|||||||
|
|
||||||
#[cfg(feature = "target-os")]
|
#[cfg(feature = "target-os")]
|
||||||
pub mod os {
|
pub mod os {
|
||||||
|
#[cfg(feature = "server")]
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
#[cfg(feature = "desktop")]
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "target-os")]
|
#[cfg(feature = "target-os")]
|
||||||
|
#[cfg(feature = "website")]
|
||||||
mod website;
|
mod website;
|
||||||
|
|
||||||
#[cfg(feature = "target-os")]
|
#[cfg(feature = "target-os")]
|
||||||
|
#[cfg(feature = "server")]
|
||||||
pub use platform::os::server::server;
|
pub use platform::os::server::server;
|
||||||
#[cfg(feature = "target-os")]
|
#[cfg(feature = "target-os")]
|
||||||
|
#[cfg(feature = "desktop")]
|
||||||
pub use platform::os::ui;
|
pub use platform::os::ui;
|
||||||
|
|
||||||
pub mod auth {
|
pub mod auth {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
use axum::{Json, http::StatusCode};
|
||||||
|
use serde_json::{Value, json};
|
||||||
|
use std::net::SocketAddr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
@@ -108,7 +111,10 @@ pub async fn start_server(mize: &mut Mize) -> MizeResult<()> {
|
|||||||
.layer(tower_http::trace::TraceLayer::new_for_http())
|
.layer(tower_http::trace::TraceLayer::new_for_http())
|
||||||
// not authenticated routes
|
// not authenticated routes
|
||||||
.route("/", get(ppc_main_page))
|
.route("/", get(ppc_main_page))
|
||||||
.route("/oidc_display_code_and_state", get(display_code_and_state));
|
.route("/oidc_display_code_and_state", get(display_code_and_state))
|
||||||
|
// .well-known routes for matrix
|
||||||
|
.route("/.well-known/matrix/server", get(well_known_matrix_server))
|
||||||
|
.route("/.well-known/matrix/client", get(well_known_matrix_client));
|
||||||
|
|
||||||
tracing::info!("Running on http://{listen_addr}:{port}");
|
tracing::info!("Running on http://{listen_addr}:{port}");
|
||||||
|
|
||||||
@@ -199,3 +205,21 @@ async fn display_code_and_state(Query(params): Query<CallbackParams>) -> Html<St
|
|||||||
|
|
||||||
Html(html)
|
Html(html)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handler for /.well-known/matrix/server
|
||||||
|
async fn well_known_matrix_server() -> (StatusCode, Json<Value>) {
|
||||||
|
let response = json!({
|
||||||
|
"m.server": "matrix.ppc.social:443"
|
||||||
|
});
|
||||||
|
(StatusCode::OK, Json(response))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler for /.well-known/matrix/client
|
||||||
|
async fn well_known_matrix_client() -> (StatusCode, Json<Value>) {
|
||||||
|
let response = json!({
|
||||||
|
"m.homeserver": {
|
||||||
|
"base_url": "https://matrix.ppc.social:443"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
(StatusCode::OK, Json(response))
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ use crate::{
|
|||||||
spacetime::SpacetimePart,
|
spacetime::SpacetimePart,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MizeConfig = mconf!{
|
||||||
|
hi "t"
|
||||||
|
rustBinary "hello" ''
|
||||||
|
println!("hello world");
|
||||||
|
''
|
||||||
|
};
|
||||||
|
|
||||||
#[mize_part]
|
#[mize_part]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TimeTrack {
|
pub struct TimeTrack {
|
||||||
|
|||||||
Reference in New Issue
Block a user