Skip to content

Commit

Permalink
moss: Add basic scaffolding for upcoming varlink integration
Browse files Browse the repository at this point in the history
While not currently used, this now adds relevant build + cargo changes to
integrate varlink with moss, such that when the time is right we can add
RPC over varlink to moss for integration into packagekitd, lichen, etc.

This change is landing early as multiple ongoing large PRs would constantly
need rebasing thanks to lockfile cruft.

Signed-off-by: Ikey Doherty <[email protected]>
  • Loading branch information
ikeycode committed Nov 9, 2024
1 parent b589c83 commit e156603
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 47 deletions.
216 changes: 169 additions & 47 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ rayon = "1.10.0"
regex = "1.10.5"
reqwest = { version = "0.12.5", default-features = false, features = ["brotli", "charset", "deflate", "gzip", "http2", "rustls-tls", "stream", "zstd"] }
serde = { version = "1.0.204", features = ["derive"] }
serde_derive = "1.0.204"
serde_json = "1.0.120"
serde_yaml = "0.9.34"
sha2 = "0.10.8"
Expand All @@ -55,6 +56,8 @@ tokio = { version = "1.38.0", features = ["full"] }
tokio-stream = { version = "0.1.15", features = ["time"] }
tokio-util = { version = "0.7.11", features = ["io"] }
url = { version = "2.5.2", features = ["serde"] }
varlink = "11.0.1"
varlink_generator = "10.1.0"
xxhash-rust = { version = "0.8.11", features = ["xxh3"] }
zstd = { version = "0.13.2", features = ["zstdmt"] }
mailparse = "0.15.0"
Expand Down
5 changes: 5 additions & 0 deletions moss/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ edition.workspace = true
version.workspace = true
rust-version.workspace = true

[build-dependencies]
varlink_generator.workspace = true

[dependencies]
config = { path = "../crates/config" }
container = { path = "../crates/container" }
Expand Down Expand Up @@ -34,12 +37,14 @@ nix.workspace = true
rayon.workspace = true
reqwest.workspace = true
serde.workspace = true
serde_derive.workspace = true
sha2.workspace = true
strum.workspace = true
tokio.workspace = true
tokio-util.workspace = true
thiserror.workspace = true
url.workspace = true
varlink.workspace = true
xxhash-rust.workspace = true
zbus.workspace = true

Expand Down
6 changes: 6 additions & 0 deletions moss/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extern crate varlink_generator;

fn main() {
println!("cargo:rerun-if-changed=src/varlink/com.serpentos.moss.varlink");
varlink_generator::cargo_build_tosource("src/varlink/com.serpentos.moss.varlink", true);
}
2 changes: 2 additions & 0 deletions moss/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ pub mod request;
pub mod runtime;
pub mod signal;
pub mod state;

mod varlink;
4 changes: 4 additions & 0 deletions moss/src/varlink/com.serpentos.moss.varlink
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface com.serpentos.moss

# Placeholder until we add real varlink API
method Version() -> (version: string)
177 changes: 177 additions & 0 deletions moss/src/varlink/com_serpentos_moss.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
#![doc = "This file was automatically generated by the varlink rust generator"]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
use serde_derive::{Deserialize, Serialize};
use std::io::BufRead;
use std::sync::{Arc, RwLock};
use varlink::{self, CallTrait};
#[allow(dead_code)]
#[derive(Clone, PartialEq, Debug)]
#[allow(clippy::enum_variant_names)]
pub enum ErrorKind {
Varlink_Error,
VarlinkReply_Error,
}
impl ::std::fmt::Display for ErrorKind {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match self {
ErrorKind::Varlink_Error => write!(f, "Varlink Error"),
ErrorKind::VarlinkReply_Error => write!(f, "Varlink error reply"),
}
}
}
pub struct Error(
pub ErrorKind,
pub Option<Box<dyn std::error::Error + 'static + Send + Sync>>,
pub Option<&'static str>,
);
impl Error {
#[allow(dead_code)]
pub fn kind(&self) -> &ErrorKind {
&self.0
}
}
impl From<ErrorKind> for Error {
fn from(e: ErrorKind) -> Self {
Error(e, None, None)
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.1
.as_ref()
.map(|e| e.as_ref() as &(dyn std::error::Error + 'static))
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(&self.0, f)
}
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use std::error::Error as StdError;
if let Some(ref o) = self.2 {
std::fmt::Display::fmt(o, f)?;
}
std::fmt::Debug::fmt(&self.0, f)?;
if let Some(e) = self.source() {
std::fmt::Display::fmt("\nCaused by:\n", f)?;
std::fmt::Debug::fmt(&e, f)?;
}
Ok(())
}
}
#[allow(dead_code)]
pub type Result<T> = std::result::Result<T, Error>;
impl From<varlink::Error> for Error {
fn from(e: varlink::Error) -> Self {
match e.kind() {
varlink::ErrorKind::VarlinkErrorReply(r) => Error(
ErrorKind::from(r),
Some(Box::from(e)),
Some(concat!(file!(), ":", line!(), ": ")),
),
_ => Error(
ErrorKind::Varlink_Error,
Some(Box::from(e)),
Some(concat!(file!(), ":", line!(), ": ")),
),
}
}
}
#[allow(dead_code)]
impl Error {
pub fn source_varlink_kind(&self) -> Option<&varlink::ErrorKind> {
use std::error::Error as StdError;
let mut s: &dyn StdError = self;
while let Some(c) = s.source() {
let k = self
.source()
.and_then(|e| e.downcast_ref::<varlink::Error>())
.map(|e| e.kind());
if k.is_some() {
return k;
}
s = c;
}
None
}
}
impl From<&varlink::Reply> for ErrorKind {
#[allow(unused_variables)]
fn from(e: &varlink::Reply) -> Self {
match e {

Check warning on line 104 in moss/src/varlink/com_serpentos_moss.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] moss/src/varlink/com_serpentos_moss.rs#L104

warning: this match could be replaced by its body itself --> moss/src/varlink/com_serpentos_moss.rs:104:9 | 104 | / match e { 105 | | _ => ErrorKind::VarlinkReply_Error, 106 | | } | |_________^ help: consider using the match body instead: `ErrorKind::VarlinkReply_Error` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_single_binding = note: `#[warn(clippy::match_single_binding)]` on by default
Raw output
moss/src/varlink/com_serpentos_moss.rs:104:9:w:warning: this match could be replaced by its body itself
   --> moss/src/varlink/com_serpentos_moss.rs:104:9
    |
104 | /         match e {
105 | |             _ => ErrorKind::VarlinkReply_Error,
106 | |         }
    | |_________^ help: consider using the match body instead: `ErrorKind::VarlinkReply_Error`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_single_binding
    = note: `#[warn(clippy::match_single_binding)]` on by default


__END__
_ => ErrorKind::VarlinkReply_Error,
}
}
}
pub trait VarlinkCallError: varlink::CallTrait {}
impl<'a> VarlinkCallError for varlink::Call<'a> {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct Version_Reply {
pub r#version: String,
}
impl varlink::VarlinkReply for Version_Reply {}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct Version_Args {}
pub trait Call_Version: VarlinkCallError {
fn reply(&mut self, r#version: String) -> varlink::Result<()> {
self.reply_struct(Version_Reply { r#version }.into())
}
}
impl<'a> Call_Version for varlink::Call<'a> {}
pub trait VarlinkInterface {
fn version(&self, call: &mut dyn Call_Version) -> varlink::Result<()>;
fn call_upgraded(&self, _call: &mut varlink::Call, _bufreader: &mut dyn BufRead) -> varlink::Result<Vec<u8>> {
Ok(Vec::new())
}
}
pub trait VarlinkClientInterface {
fn version(&mut self) -> varlink::MethodCall<Version_Args, Version_Reply, Error>;
}
#[allow(dead_code)]
pub struct VarlinkClient {
connection: Arc<RwLock<varlink::Connection>>,
}
impl VarlinkClient {
#[allow(dead_code)]
pub fn new(connection: Arc<RwLock<varlink::Connection>>) -> Self {
VarlinkClient { connection }
}
}
impl VarlinkClientInterface for VarlinkClient {
fn version(&mut self) -> varlink::MethodCall<Version_Args, Version_Reply, Error> {
varlink::MethodCall::<Version_Args, Version_Reply, Error>::new(
self.connection.clone(),
"com.serpentos.moss.Version",
Version_Args {},
)
}
}
#[allow(dead_code)]
pub struct VarlinkInterfaceProxy {
inner: Box<dyn VarlinkInterface + Send + Sync>,
}
#[allow(dead_code)]
pub fn new(inner: Box<dyn VarlinkInterface + Send + Sync>) -> VarlinkInterfaceProxy {
VarlinkInterfaceProxy { inner }
}
impl varlink::Interface for VarlinkInterfaceProxy {
fn get_description(&self) -> &'static str {
"interface com.serpentos.moss\n\n# Placeholder until we add real varlink API\nmethod Version() -> (version: string)"
}
fn get_name(&self) -> &'static str {
"com.serpentos.moss"
}
fn call_upgraded(&self, call: &mut varlink::Call, bufreader: &mut dyn BufRead) -> varlink::Result<Vec<u8>> {
self.inner.call_upgraded(call, bufreader)
}
fn call(&self, call: &mut varlink::Call) -> varlink::Result<()> {
let req = call.request.unwrap();
match req.method.as_ref() {
"com.serpentos.moss.Version" => self.inner.version(call as &mut dyn Call_Version),
m => call.reply_method_not_found(String::from(m)),
}
}
}
6 changes: 6 additions & 0 deletions moss/src/varlink/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-FileCopyrightText: Copyright © 2020-2024 Serpent OS Developers
//
// SPDX-License-Identifier: MPL-2.0

#[allow(dead_code)]
mod com_serpentos_moss;

0 comments on commit e156603

Please sign in to comment.