overhaul context

This commit is contained in:
Aiden McClelland
2021-08-31 19:16:29 -06:00
parent 118f26af89
commit 34e599f826
16 changed files with 126 additions and 258 deletions

View File

@@ -1,6 +1,6 @@
use anyhow::anyhow;
use basic_cookies::Cookie;
use chrono::{DateTime, NaiveDateTime, Utc};
use chrono::{DateTime, Utc};
use clap::ArgMatches;
use http::header::COOKIE;
use http::HeaderValue;
@@ -11,14 +11,14 @@ use rpc_toolkit::yajrc::RpcError;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::context::EitherContext;
use crate::context::{CliContext, RpcContext};
use crate::middleware::auth::{get_id, hash_token};
use crate::util::{display_none, display_serializable, IoFormat};
use crate::{ensure_code, Error, ResultExt};
#[command(subcommands(login, logout, session))]
pub fn auth(#[context] ctx: EitherContext) -> Result<EitherContext, Error> {
Ok(ctx)
pub fn auth() -> Result<(), Error> {
Ok(())
}
pub fn parse_metadata(_: &str, _: &ArgMatches<'_>) -> Result<Value, Error> {
@@ -40,12 +40,20 @@ fn gen_pwd() {
)
}
#[command(display(display_none), metadata(authenticated = false))]
// fn cli_login(ctx: CliContext, password: Option<String>, metadata: Value) -> Result<(), Error> {
// todo!()
// }
#[command(
// custom_cli(cli_login),
display(display_none),
metadata(authenticated = false)
)]
pub async fn login(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[request] req: &RequestParts,
#[response] res: &mut ResponseParts,
#[arg] password: String,
#[arg] password: Option<String>,
#[arg(
parse(parse_metadata),
default = "",
@@ -53,8 +61,8 @@ pub async fn login(
)]
metadata: Value,
) -> Result<(), Error> {
let rpc_ctx = ctx.as_rpc().unwrap();
let mut handle = rpc_ctx.secret_store.acquire().await?;
let password = password.unwrap_or_default();
let mut handle = ctx.secret_store.acquire().await?;
let pw_hash = sqlx::query!("SELECT password FROM account")
.fetch_one(&mut handle)
.await?
@@ -99,7 +107,7 @@ pub async fn login(
#[command(display(display_none), metadata(authenticated = false))]
pub async fn logout(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[request] req: &RequestParts,
) -> Result<(), Error> {
if let Some(cookie_header) = req.headers.get(COOKIE) {
@@ -135,8 +143,8 @@ pub struct SessionList {
}
#[command(subcommands(list, kill))]
pub async fn session(#[context] ctx: EitherContext) -> Result<EitherContext, Error> {
Ok(ctx)
pub async fn session() -> Result<(), Error> {
Ok(())
}
fn display_sessions(arg: SessionList, matches: &ArgMatches<'_>) {
@@ -174,7 +182,7 @@ fn display_sessions(arg: SessionList, matches: &ArgMatches<'_>) {
#[command(display(display_sessions))]
pub async fn list(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[request] req: &RequestParts,
#[allow(unused_variables)]
#[arg(long = "format")]
@@ -185,7 +193,7 @@ pub async fn list(
sessions: sqlx::query!(
"SELECT * FROM session WHERE logged_out IS NULL OR logged_out > CURRENT_TIMESTAMP"
)
.fetch_all(&mut ctx.as_rpc().unwrap().secret_store.acquire().await?)
.fetch_all(&mut ctx.secret_store.acquire().await?)
.await?
.into_iter()
.map(|row| {
@@ -210,15 +218,14 @@ fn parse_comma_separated(arg: &str, _: &ArgMatches<'_>) -> Result<Vec<String>, R
#[command(display(display_none))]
pub async fn kill(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[arg(parse(parse_comma_separated))] ids: Vec<String>,
) -> Result<(), Error> {
let rpc_ctx = ctx.as_rpc().unwrap();
sqlx::query(&format!(
"UPDATE session SET logged_out = CURRENT_TIMESTAMP WHERE id IN ('{}')",
ids.join("','")
))
.execute(&mut rpc_ctx.secret_store.acquire().await?)
.execute(&mut ctx.secret_store.acquire().await?)
.await?;
Ok(())
}

View File

@@ -1,5 +1,5 @@
use clap::Arg;
use embassy::context::{CliContext, EitherContext};
use embassy::context::CliContext;
use embassy::Error;
use rpc_toolkit::run_cli;
use rpc_toolkit::yajrc::RpcError;
@@ -35,6 +35,7 @@ fn inner_main() -> Result<(), Error> {
});
EitherContext::Cli(CliContext::init(matches)?)
},
(),
|e: RpcError| {
match e.data {
Some(Value::String(s)) => eprintln!("{}: {}", e.message, s),

View File

@@ -2,7 +2,7 @@ use std::path::Path;
use std::time::Duration;
use anyhow::anyhow;
use embassy::context::{EitherContext, RpcContext};
use embassy::context::RpcContext;
use embassy::db::model::Database;
use embassy::db::subscribe;
use embassy::hostname::{get_hostname, get_id};
@@ -46,7 +46,7 @@ async fn inner_main(cfg_path: Option<&str>) -> Result<(), Error> {
.await?;
}
let auth = auth(rpc_ctx.clone());
let ctx = EitherContext::Rpc(rpc_ctx.clone());
let ctx = rpc_ctx.clone();
let server = rpc_server!({
command: embassy::main_api,
context: ctx,

View File

@@ -14,7 +14,7 @@ use serde_json::Value;
use crate::action::docker::DockerAction;
use crate::config::spec::PackagePointerSpecVariant;
use crate::context::{EitherContext, ExtendedContext};
use crate::context::RpcContext;
use crate::db::model::{CurrentDependencyInfo, InstalledPackageDataEntryModel};
use crate::db::util::WithRevision;
use crate::dependencies::{
@@ -137,24 +137,22 @@ pub enum MatchError {
}
#[command(subcommands(get, set))]
pub fn config(
#[context] ctx: EitherContext,
#[arg] id: PackageId,
) -> Result<ExtendedContext<EitherContext, PackageId>, Error> {
Ok(ExtendedContext::from(ctx).map(|_| id))
pub fn config(#[arg] id: PackageId) -> Result<PackageId, Error> {
Ok(id)
}
#[command(display(display_serializable))]
pub async fn get(
#[context] ctx: ExtendedContext<EitherContext, PackageId>,
#[context] ctx: RpcContext,
#[parent_data] id: PackageId,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<ConfigRes, Error> {
let mut db = ctx.base().as_rpc().unwrap().db.handle();
let mut db = ctx.db.handle();
let pkg_model = crate::db::DatabaseModel::new()
.package_data()
.idx_model(ctx.extension())
.idx_model(&id)
.and_then(|m| m.installed())
.expect(&mut db)
.await
@@ -166,12 +164,7 @@ pub async fn get(
.get(&mut db, true)
.await?
.to_owned()
.ok_or_else(|| {
Error::new(
anyhow!("{} has no config", ctx.extension()),
crate::ErrorKind::NotFound,
)
})?;
.ok_or_else(|| Error::new(anyhow!("{} has no config", id), crate::ErrorKind::NotFound))?;
let version = pkg_model
.clone()
.manifest()
@@ -179,40 +172,39 @@ pub async fn get(
.get(&mut db, true)
.await?;
let volumes = pkg_model.manifest().volumes().get(&mut db, true).await?;
action.get(ctx.extension(), &*version, &*volumes).await
action.get(&id, &*version, &*volumes).await
}
#[command(subcommands(self(set_impl(async)), set_dry), display(display_none))]
pub fn set(
#[context] ctx: ExtendedContext<EitherContext, PackageId>,
#[context] ctx: RpcContext,
#[parent_data] id: PackageId,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
#[arg(long = "timeout", parse(parse_duration))] timeout: Option<Duration>,
#[arg(stdin, parse(parse_stdin_deserializable))] config: Option<Config>,
#[arg(rename = "expire-id", long = "expire-id")] expire_id: Option<String>,
) -> Result<
ExtendedContext<EitherContext, (PackageId, Option<Config>, Option<Duration>, Option<String>)>,
Error,
> {
Ok(ctx.map(|id| (id, config, timeout, expire_id)))
) -> Result<(PackageId, Option<Config>, Option<Duration>, Option<String>), Error> {
Ok((id, config, timeout, expire_id))
}
#[command(display(display_serializable))]
pub async fn set_dry(
#[context] ctx: ExtendedContext<
EitherContext,
(PackageId, Option<Config>, Option<Duration>, Option<String>),
>,
#[context] ctx: RpcContext,
#[parent_data] (id, config, timeout, _): (
PackageId,
Option<Config>,
Option<Duration>,
Option<String>,
),
) -> Result<BreakageRes, Error> {
let (ctx, (id, config, timeout, _)) = ctx.split();
let rpc_ctx = ctx.as_rpc().unwrap();
let mut db = rpc_ctx.db.handle();
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut breakages = IndexMap::new();
configure(
&mut tx,
&rpc_ctx.docker,
&ctx.docker,
&id,
config,
&timeout,
@@ -240,19 +232,15 @@ pub async fn set_dry(
}
pub async fn set_impl(
ctx: ExtendedContext<
EitherContext,
(PackageId, Option<Config>, Option<Duration>, Option<String>),
>,
ctx: RpcContext,
(id, config, timeout, expire_id): (PackageId, Option<Config>, Option<Duration>, Option<String>),
) -> Result<WithRevision<()>, Error> {
let (ctx, (id, config, timeout, expire_id)) = ctx.split();
let rpc_ctx = ctx.as_rpc().unwrap();
let mut db = rpc_ctx.db.handle();
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut breakages = IndexMap::new();
configure(
&mut tx,
&rpc_ctx.docker,
&ctx.docker,
&id,
config,
&timeout,

View File

@@ -1,121 +1,30 @@
use rpc_toolkit::reqwest::Client;
use rpc_toolkit::url::{Host, Url};
use rpc_toolkit::Context;
mod cli;
mod rpc;
pub use cli::CliContext;
pub use rpc::RpcContext;
#[derive(Debug, Clone)]
pub struct ExtendedContext<T, U> {
base: T,
extension: U,
}
impl<T, U> ExtendedContext<T, U> {
pub fn map<F: FnOnce(U) -> V, V>(self, f: F) -> ExtendedContext<T, V> {
ExtendedContext {
base: self.base,
extension: f(self.extension),
}
}
pub fn split(self) -> (T, U) {
(self.base, self.extension)
}
pub fn base(&self) -> &T {
&self.base
}
pub fn extension(&self) -> &U {
&self.extension
impl From<CliContext> for () {
fn from(_: CliContext) -> Self {
()
}
}
impl<T> From<T> for ExtendedContext<T, ()> {
fn from(base: T) -> Self {
ExtendedContext {
base,
extension: (),
}
}
}
impl<T: Context, U> Context for ExtendedContext<T, U> {
fn host(&self) -> Host<&str> {
self.base.host()
}
fn port(&self) -> u16 {
self.base.port()
}
fn protocol(&self) -> &str {
self.base.protocol()
}
fn url(&self) -> Url {
self.base.url()
}
fn client(&self) -> &Client {
self.base.client()
impl From<RpcContext> for () {
fn from(_: RpcContext) -> Self {
()
}
}
#[derive(Clone)]
pub enum EitherContext {
Cli(CliContext),
Rpc(RpcContext),
}
impl EitherContext {
pub fn as_cli(&self) -> Option<&CliContext> {
match self {
EitherContext::Cli(a) => Some(a),
_ => None,
}
}
pub fn as_rpc(&self) -> Option<&RpcContext> {
match self {
EitherContext::Rpc(a) => Some(a),
_ => None,
}
}
pub fn to_cli(self) -> Option<CliContext> {
match self {
EitherContext::Cli(a) => Some(a),
_ => None,
}
}
pub fn to_rpc(self) -> Option<RpcContext> {
match self {
EitherContext::Rpc(a) => Some(a),
_ => None,
}
// TODO: these shouldn't be necessary
impl From<CliContext> for RpcContext {
fn from(_: CliContext) -> Self {
panic!("RPC Context used in CLI Handler")
}
}
impl Context for EitherContext {
fn host(&self) -> Host<&str> {
match self {
EitherContext::Cli(a) => a.host(),
EitherContext::Rpc(b) => b.host(),
}
}
fn port(&self) -> u16 {
match self {
EitherContext::Cli(a) => a.port(),
EitherContext::Rpc(b) => b.port(),
}
}
fn protocol(&self) -> &str {
match self {
EitherContext::Cli(a) => a.protocol(),
EitherContext::Rpc(b) => b.protocol(),
}
}
fn url(&self) -> Url {
match self {
EitherContext::Cli(a) => a.url(),
EitherContext::Rpc(b) => b.url(),
}
}
fn client(&self) -> &Client {
match self {
EitherContext::Cli(a) => a.client(),
EitherContext::Rpc(b) => b.client(),
}
impl From<RpcContext> for CliContext {
fn from(_: RpcContext) -> Self {
panic!("CLI Context used in RPC Handler")
}
}

View File

@@ -4,7 +4,7 @@ use indexmap::IndexMap;
use patch_db::DbHandle;
use rpc_toolkit::command;
use crate::context::EitherContext;
use crate::context::RpcContext;
use crate::db::util::WithRevision;
use crate::s9pk::manifest::PackageId;
use crate::status::MainStatus;
@@ -13,11 +13,10 @@ use crate::{Error, ResultExt};
#[command(display(display_none))]
pub async fn start(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[arg] id: PackageId,
) -> Result<WithRevision<()>, Error> {
let rpc_ctx = ctx.as_rpc().unwrap();
let mut db = rpc_ctx.db.handle();
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let installed = crate::db::DatabaseModel::new()
.package_data()
@@ -46,7 +45,7 @@ pub async fn start(
};
status
.synchronize(
&*rpc_ctx.managers.get(&(id, version)).await.ok_or_else(|| {
&*ctx.managers.get(&(id, version)).await.ok_or_else(|| {
Error::new(anyhow!("Manager not found"), crate::ErrorKind::Docker)
})?,
)
@@ -61,11 +60,10 @@ pub async fn start(
#[command(display(display_none))]
pub async fn stop(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[arg] id: PackageId,
) -> Result<WithRevision<()>, Error> {
let rpc_ctx = ctx.as_rpc().unwrap();
let mut db = rpc_ctx.db.handle();
let mut db = ctx.db.handle();
let mut tx = db.begin().await?;
let mut status = crate::db::DatabaseModel::new()

View File

@@ -6,7 +6,7 @@ use std::sync::Arc;
use futures::{SinkExt, StreamExt};
use patch_db::json_ptr::JsonPointer;
use patch_db::{DiffPatch, Dump, Revision};
use patch_db::{Dump, Revision};
use rpc_toolkit::command;
use rpc_toolkit::hyper::upgrade::Upgraded;
use rpc_toolkit::hyper::{Body, Error as HyperError, Request, Response};
@@ -19,8 +19,7 @@ use tokio_tungstenite::WebSocketStream;
pub use self::model::DatabaseModel;
use self::util::WithRevision;
use crate::context::{EitherContext, RpcContext};
use crate::middleware::auth::is_authed;
use crate::context::RpcContext;
use crate::util::{display_serializable, IoFormat};
use crate::{Error, ResultExt};
@@ -73,8 +72,8 @@ pub async fn subscribe(ctx: RpcContext, req: Request<Body>) -> Result<Response<B
}
#[command(subcommands(revisions, dump, put))]
pub fn db(#[context] ctx: EitherContext) -> Result<EitherContext, RpcError> {
Ok(ctx)
pub fn db() -> Result<(), RpcError> {
Ok(())
}
#[derive(Deserialize, Serialize)]
@@ -86,14 +85,13 @@ pub enum RevisionsRes {
#[command(display(display_serializable))]
pub async fn revisions(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[arg] since: u64,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<RevisionsRes, RpcError> {
let rpc_ctx = ctx.as_rpc().unwrap();
let cache = rpc_ctx.revision_cache.read().await;
let cache = ctx.revision_cache.read().await;
if cache
.front()
.map(|rev| rev.id <= since + 1)
@@ -108,28 +106,28 @@ pub async fn revisions(
))
} else {
drop(cache);
Ok(RevisionsRes::Dump(rpc_ctx.db.dump().await))
Ok(RevisionsRes::Dump(ctx.db.dump().await))
}
}
#[command(display(display_serializable))]
pub async fn dump(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<Dump, RpcError> {
Ok(ctx.as_rpc().unwrap().db.dump().await)
Ok(ctx.db.dump().await)
}
#[command(subcommands(ui))]
pub fn put(#[context] ctx: EitherContext) -> Result<EitherContext, RpcError> {
Ok(ctx)
pub fn put() -> Result<(), RpcError> {
Ok(())
}
#[command(display(display_serializable))]
pub async fn ui(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[arg] pointer: JsonPointer,
#[arg] value: Value,
#[allow(unused_variables)]
@@ -139,6 +137,6 @@ pub async fn ui(
let ptr = "/ui".parse::<JsonPointer>()? + &pointer;
Ok(WithRevision {
response: (),
revision: ctx.as_rpc().unwrap().db.put(&ptr, &value, None).await?,
revision: ctx.db.put(&ptr, &value, None).await?,
})
}

View File

@@ -5,13 +5,12 @@ use std::path::Path;
use ed25519_dalek::Keypair;
use rpc_toolkit::command;
use crate::context::EitherContext;
use crate::context::CliContext;
use crate::util::display_none;
use crate::{Error, ResultExt};
#[command(cli_only, blocking, display(display_none))]
pub fn init(#[context] ctx: EitherContext) -> Result<(), Error> {
let ctx = ctx.as_cli().unwrap();
pub fn init(#[context] ctx: CliContext) -> Result<(), Error> {
if !ctx.developer_key_path.exists() {
let parent = ctx.developer_key_path.parent().unwrap_or(Path::new("/"));
if !parent.exists() {

View File

@@ -2,14 +2,14 @@ use std::path::PathBuf;
use rpc_toolkit::command;
use crate::context::{CliContext, EitherContext};
use crate::context::CliContext;
use crate::s9pk::manifest::Manifest;
use crate::s9pk::reader::S9pkReader;
use crate::util::{display_none, display_serializable, IoFormat};
use crate::Error;
#[command(subcommands(hash, manifest, license, icon, instructions, docker_images))]
pub fn inspect(#[context] _ctx: EitherContext) -> Result<(), Error> {
pub fn inspect() -> Result<(), Error> {
Ok(())
}

View File

@@ -27,7 +27,7 @@ use tokio::fs::{File, OpenOptions};
use tokio::io::{AsyncRead, AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt};
use self::cleanup::cleanup_failed;
use crate::context::{EitherContext, ExtendedContext, RpcContext};
use crate::context::RpcContext;
use crate::db::model::{
CurrentDependencyInfo, InstalledPackageDataEntry, PackageDataEntry, StaticDependencyInfo,
StaticFiles,
@@ -50,17 +50,16 @@ pub const PKG_PUBLIC_DIR: &'static str = "/mnt/embassy-os/public/package-data";
#[command(display(display_none))]
pub async fn install(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[arg] id: String,
) -> Result<WithRevision<()>, Error> {
let rpc_ctx = ctx.to_rpc().unwrap();
let (pkg_id, version_str) = if let Some(split) = id.split_once("@") {
split
} else {
(id.as_str(), "*")
};
let version: VersionRange = version_str.parse()?;
let reg_url = rpc_ctx.package_registry_url().await?;
let reg_url = ctx.package_registry_url().await?;
let (man_res, s9pk) = tokio::try_join!(
reqwest::get(format!(
"{}/package/manifest/{}?version={}",
@@ -76,7 +75,7 @@ pub async fn install(
let progress = InstallProgress::new(s9pk.content_length());
let static_files = StaticFiles::remote(&man.id, &man.version, man.assets.icon_type());
let mut db_handle = rpc_ctx.db.handle();
let mut db_handle = ctx.db.handle();
let mut tx = db_handle.begin().await?;
let mut pde = crate::db::DatabaseModel::new()
.package_data()
@@ -115,7 +114,7 @@ pub async fn install(
drop(db_handle);
tokio::spawn(async move {
if let Err(e) = download_install_s9pk(&rpc_ctx, &man, s9pk).await {
if let Err(e) = download_install_s9pk(&ctx, &man, s9pk).await {
log::error!("Install of {}@{} Failed: {}", man.id, man.version, e);
}
});
@@ -128,10 +127,10 @@ pub async fn install(
#[command(display(display_none))]
pub async fn uninstall(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[arg] id: PackageId,
) -> Result<WithRevision<()>, Error> {
let mut handle = ctx.as_rpc().unwrap().db.handle();
let mut handle = ctx.db.handle();
let mut tx = handle.begin().await?;
let mut pde = crate::db::DatabaseModel::new()
@@ -161,8 +160,7 @@ pub async fn uninstall(
drop(handle);
tokio::spawn(async move {
let rpc_ctx = ctx.as_rpc().unwrap();
if let Err(e) = cleanup::uninstall(rpc_ctx, &mut rpc_ctx.db.handle(), &installed).await {
if let Err(e) = cleanup::uninstall(&ctx, &mut ctx.db.handle(), &installed).await {
log::error!("Uninstall of {} Failed: {}", id, e);
}
});

View File

@@ -46,14 +46,14 @@ pub mod version;
pub mod volume;
pub use config::Config;
use context::{CliContext, EitherContext};
use context::CliContext;
pub use error::{Error, ErrorKind, ResultExt};
use rpc_toolkit::command;
use rpc_toolkit::yajrc::RpcError;
pub use version::{init, self_update};
#[command(metadata(authenticated = false))]
pub fn echo(#[context] _ctx: EitherContext, #[arg] message: String) -> Result<String, RpcError> {
pub fn echo(#[arg] message: String) -> Result<String, RpcError> {
Ok(message)
}
@@ -68,8 +68,8 @@ pub fn echo(#[context] _ctx: EitherContext, #[arg] message: String) -> Result<St
auth::auth,
db::db,
))]
pub fn main_api(#[context] ctx: EitherContext) -> Result<EitherContext, RpcError> {
Ok(ctx)
pub fn main_api() -> Result<(), RpcError> {
Ok(())
}
#[command(subcommands(
@@ -79,8 +79,8 @@ pub fn main_api(#[context] ctx: EitherContext) -> Result<EitherContext, RpcError
control::start,
control::stop
))]
pub fn package(#[context] ctx: EitherContext) -> Result<EitherContext, RpcError> {
Ok(ctx)
pub fn package() -> Result<(), RpcError> {
Ok(())
}
#[command(subcommands(
@@ -90,6 +90,6 @@ pub fn package(#[context] ctx: EitherContext) -> Result<EitherContext, RpcError>
developer::init,
inspect::inspect
))]
pub fn portable_api(#[context] ctx: EitherContext) -> Result<EitherContext, RpcError> {
Ok(ctx)
pub fn portable_api() -> Result<(), RpcError> {
Ok(())
}

View File

@@ -6,18 +6,16 @@ use isocountry::CountryCode;
use rpc_toolkit::command;
use tokio::process::Command;
use crate::context::EitherContext;
use crate::util::{display_none, display_serializable, Invoke, IoFormat};
use crate::{Error, ErrorKind};
#[command(subcommands(add, connect, delete, get, set_country))]
pub async fn wifi(#[context] ctx: EitherContext) -> Result<EitherContext, Error> {
Ok(ctx)
pub async fn wifi() -> Result<(), Error> {
Ok(())
}
#[command(display(display_none))]
pub async fn add(
#[context] _ctx: EitherContext,
#[arg] ssid: String,
#[arg] password: String,
#[arg] priority: isize,
@@ -73,7 +71,7 @@ pub async fn add(
}
#[command(display(display_none))]
pub async fn connect(#[context] _ctx: EitherContext, #[arg] ssid: String) -> Result<(), Error> {
pub async fn connect(#[arg] ssid: String) -> Result<(), Error> {
if !ssid.is_ascii() {
return Err(Error::new(
anyhow::anyhow!("SSID may not have special characters"),
@@ -111,7 +109,7 @@ pub async fn connect(#[context] _ctx: EitherContext, #[arg] ssid: String) -> Res
}
#[command(display(display_none))]
pub async fn delete(#[context] _ctx: EitherContext, #[arg] ssid: String) -> Result<(), Error> {
pub async fn delete(#[arg] ssid: String) -> Result<(), Error> {
if !ssid.is_ascii() {
return Err(Error::new(
anyhow::anyhow!("SSID may not have special characters"),
@@ -195,7 +193,6 @@ fn display_wifi_info(info: WiFiInfo, matches: &ArgMatches<'_>) {
#[command(display(display_wifi_info))]
pub async fn get(
#[context] _ctx: EitherContext,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
@@ -239,7 +236,6 @@ pub async fn get(
#[command(display(display_none))]
pub async fn set_country(
#[context] _ctx: EitherContext,
#[arg(parse(country_code_parse))] country: CountryCode,
) -> Result<(), Error> {
let wpa_supplicant = WpaCli { interface: "wlan0" };

View File

@@ -5,7 +5,7 @@ use anyhow::anyhow;
use rpc_toolkit::command;
use rpc_toolkit::yajrc::RpcError;
use crate::context::{CliContext, EitherContext};
use crate::context::CliContext;
use crate::s9pk::builder::S9pkPacker;
use crate::s9pk::manifest::Manifest;
use crate::s9pk::reader::S9pkReader;
@@ -21,12 +21,10 @@ pub mod reader;
pub const SIG_CONTEXT: &'static [u8] = b"s9pk";
#[command(cli_only, display(display_none), blocking)]
pub fn pack(#[context] ctx: EitherContext, #[arg] path: Option<PathBuf>) -> Result<(), Error> {
pub fn pack(#[context] ctx: CliContext, #[arg] path: Option<PathBuf>) -> Result<(), Error> {
use std::fs::File;
use std::io::Read;
let ctx = ctx.as_cli().unwrap();
let path = if let Some(path) = path {
path
} else {
@@ -110,7 +108,7 @@ pub fn pack(#[context] ctx: EitherContext, #[arg] path: Option<PathBuf>) -> Resu
}
#[command(cli_only, display(display_none))]
pub async fn verify(#[context] _ctx: EitherContext, #[arg] path: PathBuf) -> Result<(), Error> {
pub async fn verify(#[arg] path: PathBuf) -> Result<(), Error> {
let mut s9pk = S9pkReader::open(path).await?;
s9pk.validate().await?;

View File

@@ -5,7 +5,7 @@ use clap::ArgMatches;
use rpc_toolkit::command;
use sqlx::{Pool, Sqlite};
use crate::context::EitherContext;
use crate::context::RpcContext;
use crate::util::{display_none, display_serializable, IoFormat};
use crate::Error;
@@ -48,13 +48,13 @@ impl std::str::FromStr for PubKey {
}
#[command(subcommands(add, remove, list,))]
pub fn ssh(#[context] ctx: EitherContext) -> Result<EitherContext, Error> {
Ok(ctx)
pub fn ssh() -> Result<(), Error> {
Ok(())
}
#[command(display(display_none))]
pub async fn add(#[context] ctx: EitherContext, #[arg] key: PubKey) -> Result<String, Error> {
let pool = &ctx.as_rpc().unwrap().secret_store;
pub async fn add(#[context] ctx: RpcContext, #[arg] key: PubKey) -> Result<String, Error> {
let pool = &ctx.secret_store;
// check fingerprint for duplicates
let fp = key.0.fingerprint_md5();
if sqlx::query!("SELECT * FROM ssh_keys WHERE fingerprint = ?", fp)
@@ -75,11 +75,8 @@ pub async fn add(#[context] ctx: EitherContext, #[arg] key: PubKey) -> Result<St
Ok(fp)
}
#[command(display(display_none))]
pub async fn remove(
#[context] ctx: EitherContext,
#[arg] fingerprint: String,
) -> Result<(), Error> {
let pool = &ctx.as_rpc().unwrap().secret_store;
pub async fn remove(#[context] ctx: RpcContext, #[arg] fingerprint: String) -> Result<(), Error> {
let pool = &ctx.secret_store;
// check if fingerprint is in DB
// if in DB, remove it from DB
let n = sqlx::query!("DELETE FROM ssh_keys WHERE fingerprint = ?", fingerprint)
@@ -128,12 +125,12 @@ fn display_all_ssh_keys(all: Vec<SshKeyResponse>, matches: &ArgMatches<'_>) {
#[command(display(display_all_ssh_keys))]
pub async fn list(
#[context] ctx: EitherContext,
#[context] ctx: RpcContext,
#[allow(unused_variables)]
#[arg(long = "format")]
format: Option<IoFormat>,
) -> Result<Vec<SshKeyResponse>, Error> {
let pool = &ctx.as_rpc().unwrap().secret_store;
let pool = &ctx.secret_store;
// list keys in DB and return them
let entries = sqlx::query!("SELECT fingerprint, openssh_pubkey, created_at FROM ssh_keys")
.fetch_all(pool)

View File

@@ -31,7 +31,7 @@ use tokio_compat_02::FutureExt;
// pub use v0_2_12::Version as Current;
pub type Current = ();
use crate::context::{CliContext, EitherContext, RpcContext};
use crate::context::{CliContext, RpcContext};
use crate::util::{to_yaml_async_writer, AsyncCompat};
use crate::{Error, ResultExt as _};
@@ -180,7 +180,7 @@ pub async fn self_update(requirement: emver::VersionRange) -> Result<(), Error>
}
#[command(rename = "git-info", local)]
pub fn git_info(#[context] _ctx: EitherContext) -> Result<String, Error> {
pub fn git_info() -> Result<String, Error> {
Ok(
git_version::git_version!(args = ["--always", "--abbrev=40", "--dirty=-modified"])
.to_owned(),

View File

@@ -1,21 +0,0 @@
use super::*;
const V0_2_14: emver::Version = emver::Version::new(0, 2, 14, 0);
pub struct Version;
#[async_trait]
impl VersionT for Version {
type Previous = v0_2_13::Version;
fn new() -> Self {
Version
}
fn semver(&self) -> &'static emver::Version {
&V0_2_14
}
async fn up(&self) -> Result<(), Error> {
Ok(())
}
async fn down(&self) -> Result<(), Error> {
Ok(())
}
}