-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from cloudflavor/feature/introduce-sdk-concept
Feature/introduce sdk concept
- Loading branch information
Showing
20 changed files
with
344 additions
and
28 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
[workspace] | ||
resolver = "2" | ||
members = ["plugins/hetzner"] | ||
members = [ | ||
"crates/plugins/hetzner", | ||
"crates/sdk/skyforge-sdk", | ||
"crates/sdk/skyforge-sdk-macros", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,21 @@ | ||
# Skyforge | ||
|
||
A registry of WASI plugins for infrastructure provisioning | ||
|
||
## Building | ||
|
||
All plugins are built using the wasm component of the Rust toolchain. To build the plugins, run the following command: | ||
|
||
e.g. for the Hetzner plugin: | ||
|
||
```sh | ||
$ cargo install cargo-component --locked | ||
... | ||
$ cargo component build && cp ../../../target/wasm32-wasi/debug/hetzner.wasm ~/.config/skycrane/plugins/ | ||
... | ||
``` | ||
|
||
This will build the plugin and copy the resulting wasm file to the | ||
`~/.config/skycrane/plugins/` directory. The manual copy is necessary because we don't | ||
have a registry in place at the moment. Once the registry is in place, skycrane will | ||
download the plugin automatically. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module( | ||
name = "hetzner", | ||
version = "v0.1.0", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
network( | ||
name = "network", | ||
cidr = "10.0.0.1/16", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,224 @@ | ||
// Generated by `wit-bindgen` 0.25.0. DO NOT EDIT! | ||
// Options used: | ||
#[allow(dead_code)] | ||
pub mod exports { | ||
#[allow(dead_code)] | ||
pub mod cloudflavor { | ||
#[allow(dead_code)] | ||
pub mod skyforge { | ||
#[allow(dead_code, clippy::all)] | ||
pub mod plugin_api { | ||
#[used] | ||
#[doc(hidden)] | ||
#[cfg(target_arch = "wasm32")] | ||
static __FORCE_SECTION_REF: fn() = | ||
super::super::super::super::__link_custom_section_describing_imports; | ||
use super::super::super::super::_rt; | ||
#[derive(Clone)] | ||
pub struct Config { | ||
pub name: _rt::String, | ||
} | ||
impl ::core::fmt::Debug for Config { | ||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { | ||
f.debug_struct("Config").field("name", &self.name).finish() | ||
} | ||
} | ||
#[repr(u8)] | ||
#[derive(Clone, Copy, Eq, PartialEq)] | ||
pub enum Error { | ||
InvalidFormat, | ||
MissingField, | ||
Other, | ||
} | ||
impl Error { | ||
pub fn name(&self) -> &'static str { | ||
match self { | ||
Error::InvalidFormat => "invalid-format", | ||
Error::MissingField => "missing-field", | ||
Error::Other => "other", | ||
} | ||
} | ||
pub fn message(&self) -> &'static str { | ||
match self { | ||
Error::InvalidFormat => "", | ||
Error::MissingField => "", | ||
Error::Other => "", | ||
} | ||
} | ||
} | ||
impl ::core::fmt::Debug for Error { | ||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { | ||
f.debug_struct("Error") | ||
.field("code", &(*self as i32)) | ||
.field("name", &self.name()) | ||
.field("message", &self.message()) | ||
.finish() | ||
} | ||
} | ||
impl ::core::fmt::Display for Error { | ||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { | ||
write!(f, "{} (error {})", self.name(), *self as i32) | ||
} | ||
} | ||
|
||
impl std::error::Error for Error {} | ||
|
||
impl Error { | ||
#[doc(hidden)] | ||
pub unsafe fn _lift(val: u8) -> Error { | ||
if !cfg!(debug_assertions) { | ||
return ::core::mem::transmute(val); | ||
} | ||
|
||
match val { | ||
0 => Error::InvalidFormat, | ||
1 => Error::MissingField, | ||
2 => Error::Other, | ||
|
||
_ => panic!("invalid enum discriminant"), | ||
} | ||
} | ||
} | ||
|
||
#[doc(hidden)] | ||
#[allow(non_snake_case)] | ||
pub unsafe fn _export_deserialize_config_cabi<T: Guest>( | ||
arg0: *mut u8, | ||
arg1: usize, | ||
) -> *mut u8 { | ||
#[cfg(target_arch = "wasm32")] | ||
_rt::run_ctors_once(); | ||
let len0 = arg1; | ||
let bytes0 = _rt::Vec::from_raw_parts(arg0.cast(), len0, len0); | ||
let result1 = T::deserialize_config(_rt::string_lift(bytes0)); | ||
let ptr2 = _RET_AREA.0.as_mut_ptr().cast::<u8>(); | ||
match result1 { | ||
Ok(e) => { | ||
*ptr2.add(0).cast::<u8>() = (0i32) as u8; | ||
let Config { name: name3 } = e; | ||
let vec4 = (name3.into_bytes()).into_boxed_slice(); | ||
let ptr4 = vec4.as_ptr().cast::<u8>(); | ||
let len4 = vec4.len(); | ||
::core::mem::forget(vec4); | ||
*ptr2.add(8).cast::<usize>() = len4; | ||
*ptr2.add(4).cast::<*mut u8>() = ptr4.cast_mut(); | ||
} | ||
Err(e) => { | ||
*ptr2.add(0).cast::<u8>() = (1i32) as u8; | ||
*ptr2.add(4).cast::<u8>() = (e.clone() as i32) as u8; | ||
} | ||
}; | ||
ptr2 | ||
} | ||
#[doc(hidden)] | ||
#[allow(non_snake_case)] | ||
pub unsafe fn __post_return_deserialize_config<T: Guest>(arg0: *mut u8) { | ||
let l0 = i32::from(*arg0.add(0).cast::<u8>()); | ||
match l0 { | ||
0 => { | ||
let l1 = *arg0.add(4).cast::<*mut u8>(); | ||
let l2 = *arg0.add(8).cast::<usize>(); | ||
_rt::cabi_dealloc(l1, l2, 1); | ||
} | ||
_ => (), | ||
} | ||
} | ||
pub trait Guest { | ||
fn deserialize_config(config_str: _rt::String) -> Result<Config, Error>; | ||
} | ||
#[doc(hidden)] | ||
|
||
macro_rules! __export_cloudflavor_skyforge_plugin_api_0_1_0_cabi{ | ||
($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { | ||
|
||
#[export_name = "cloudflavor:skyforge/plugin-api@0.1.0#deserialize-config"] | ||
unsafe extern "C" fn export_deserialize_config(arg0: *mut u8,arg1: usize,) -> *mut u8 { | ||
$($path_to_types)*::_export_deserialize_config_cabi::<$ty>(arg0, arg1) | ||
} | ||
#[export_name = "cabi_post_cloudflavor:skyforge/plugin-api@0.1.0#deserialize-config"] | ||
unsafe extern "C" fn _post_return_deserialize_config(arg0: *mut u8,) { | ||
$($path_to_types)*::__post_return_deserialize_config::<$ty>(arg0) | ||
} | ||
};); | ||
} | ||
#[doc(hidden)] | ||
pub(crate) use __export_cloudflavor_skyforge_plugin_api_0_1_0_cabi; | ||
#[repr(align(4))] | ||
struct _RetArea([::core::mem::MaybeUninit<u8>; 12]); | ||
static mut _RET_AREA: _RetArea = _RetArea([::core::mem::MaybeUninit::uninit(); 12]); | ||
} | ||
} | ||
} | ||
} | ||
mod _rt { | ||
pub use alloc_crate::string::String; | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
pub fn run_ctors_once() { | ||
wit_bindgen_rt::run_ctors_once(); | ||
} | ||
pub use alloc_crate::vec::Vec; | ||
pub unsafe fn string_lift(bytes: Vec<u8>) -> String { | ||
if cfg!(debug_assertions) { | ||
String::from_utf8(bytes).unwrap() | ||
} else { | ||
String::from_utf8_unchecked(bytes) | ||
} | ||
} | ||
pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) { | ||
if size == 0 { | ||
return; | ||
} | ||
let layout = alloc::Layout::from_size_align_unchecked(size, align); | ||
alloc::dealloc(ptr as *mut u8, layout); | ||
} | ||
extern crate alloc as alloc_crate; | ||
pub use alloc_crate::alloc; | ||
} | ||
|
||
/// Generates `#[no_mangle]` functions to export the specified type as the | ||
/// root implementation of all generated traits. | ||
/// | ||
/// For more information see the documentation of `wit_bindgen::generate!`. | ||
/// | ||
/// ```rust | ||
/// # macro_rules! export{ ($($t:tt)*) => (); } | ||
/// # trait Guest {} | ||
/// struct MyType; | ||
/// | ||
/// impl Guest for MyType { | ||
/// // ... | ||
/// } | ||
/// | ||
/// export!(MyType); | ||
/// ``` | ||
#[allow(unused_macros)] | ||
#[doc(hidden)] | ||
|
||
macro_rules! __export_skyforge_api_impl { | ||
($ty:ident) => (self::export!($ty with_types_in self);); | ||
($ty:ident with_types_in $($path_to_types_root:tt)*) => ( | ||
$($path_to_types_root)*::exports::cloudflavor::skyforge::plugin_api::__export_cloudflavor_skyforge_plugin_api_0_1_0_cabi!($ty with_types_in $($path_to_types_root)*::exports::cloudflavor::skyforge::plugin_api); | ||
) | ||
} | ||
#[doc(inline)] | ||
pub(crate) use __export_skyforge_api_impl as export; | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
#[link_section = "component-type:wit-bindgen:0.25.0:skyforge-api:encoded world"] | ||
#[doc(hidden)] | ||
pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 342] = *b"\ | ||
\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xd3\x01\x01A\x02\x01\ | ||
A\x02\x01B\x07\x01r\x01\x04names\x04\0\x06config\x03\0\0\x01m\x03\x0einvalid-for\ | ||
mat\x0dmissing-field\x05other\x04\0\x05error\x03\0\x02\x01j\x01\x01\x01\x03\x01@\ | ||
\x01\x0aconfig-strs\0\x04\x04\0\x12deserialize-config\x01\x05\x04\x01%cloudflavo\ | ||
r:skyforge/plugin-api@0.1.0\x05\0\x04\x01'cloudflavor:skyforge/skyforge-api@0.1.\ | ||
0\x04\0\x0b\x12\x01\0\x0cskyforge-api\x03\0\0\0G\x09producers\x01\x0cprocessed-b\ | ||
y\x02\x0dwit-component\x070.208.1\x10wit-bindgen-rust\x060.25.0"; | ||
|
||
#[inline(never)] | ||
#[doc(hidden)] | ||
#[cfg(target_arch = "wasm32")] | ||
pub fn __link_custom_section_describing_imports() { | ||
wit_bindgen_rt::maybe_link_cabi_realloc(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use skyforge_sdk::skyforge_plugin; | ||
|
||
struct Hetzner; | ||
|
||
#[skyforge_plugin] | ||
impl SkyforgePlugin for Hetzner { | ||
fn deserialize_config_impl(config: String) -> Result<Config, Error> { | ||
println!("Hetzner config: {}", config); | ||
Ok(Config { name: config }) | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../spec/wit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "skyforge-sdk-macros" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
proc-macro2 = "1.0" | ||
quote = "1.0" | ||
syn = "2.0" | ||
|
||
[lib] | ||
proc-macro = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use proc_macro::TokenStream; | ||
use quote::quote; | ||
use syn::{parse_macro_input, ItemImpl}; | ||
|
||
#[proc_macro_attribute] | ||
pub fn skyforge_plugin(_: TokenStream, input: TokenStream) -> TokenStream { | ||
let impl_trait = parse_macro_input!(input as ItemImpl); | ||
let name = impl_trait.self_ty; | ||
if let Some((_, path, _)) = &impl_trait.trait_ { | ||
let trait_name = path.get_ident().unwrap(); | ||
if trait_name != "SkyforgePlugin" { | ||
panic!("Expected trait name to be `SkyforgePlugin`"); | ||
} | ||
} | ||
|
||
let trait_items = &impl_trait.items; | ||
|
||
let expanded = quote! { | ||
|
||
wit_bindgen::generate!({path: "wit", world: "skyforge-api"}); | ||
|
||
use exports::cloudflavor::skyforge::plugin_api::{Guest, Config,Error}; | ||
|
||
impl Guest for #name { | ||
fn deserialize_config(config: String) -> Result<Config, Error> { | ||
let config = Self::deserialize_config_impl(config).unwrap(); | ||
Ok(config) | ||
} | ||
} | ||
|
||
export!(#name); | ||
|
||
impl #name { | ||
#(#trait_items)* | ||
} | ||
}; | ||
|
||
TokenStream::from(expanded) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[package] | ||
name = "skyforge-sdk" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
wit-bindgen = "0.28.0" | ||
skyforge-sdk-macros = { path = "../skyforge-sdk-macros" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
pub use skyforge_sdk_macros::skyforge_plugin; | ||
|
||
wit_bindgen::generate!({ | ||
path: "wit", | ||
world: "skyforge-api", | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../spec/wit |
Oops, something went wrong.