Skip to content

Commit

Permalink
impl: initial ImageHandle request extractor
Browse files Browse the repository at this point in the history
  • Loading branch information
cilki committed Mar 17, 2024
1 parent 639fcac commit f82271f
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 7 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ jobs:
runs-on: ubuntu-latest
name: nightly / doc
steps:
- run: apt-get install -y libpango-1.0-0
- uses: actions/checkout@v4
with:
submodules: true
Expand Down Expand Up @@ -99,7 +100,7 @@ jobs:
# https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
strategy:
matrix:
msrv: ["1.59.0"]
msrv: ["1.70.0"]
name: ubuntu / ${{ matrix.msrv }}
steps:
- uses: actions/checkout@v4
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
# toolchain
toolchain: [stable, beta]
steps:
- run: apt-get install -y libpango-1.0-0
- uses: actions/checkout@v4
with:
submodules: true
Expand Down Expand Up @@ -69,6 +70,7 @@ jobs:
runs-on: ubuntu-latest
name: ubuntu / stable / minimal-versions
steps:
- run: apt-get install -y libpango-1.0-0
- uses: actions/checkout@v4
with:
submodules: true
Expand Down Expand Up @@ -132,6 +134,7 @@ jobs:
runs-on: ubuntu-latest
name: ubuntu / stable / coverage
steps:
- run: apt-get install -y libpango-1.0-0
- uses: actions/checkout@v4
with:
submodules: true
Expand Down
2 changes: 1 addition & 1 deletion goldboot-image/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license = "AGPL-3.0-only"
authors = ["Tyler Cook"]
homepage = "https://goldboot.fossable.org"
repository = "https://github.com/fossable/goldboot"
rust-version = "1.59"
rust-version = "1.70"

[dependencies]
aes-gcm = { version = "0.10.3", features = ["std"] }
Expand Down
15 changes: 15 additions & 0 deletions goldboot-image/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ pub struct PrimaryHeader {

/// The size of the directory in bytes
pub directory_size: u32,

/// Whether the image is public
pub public: u8,

/// Extra space for the future
pub reserved: [u8; 64],
}

impl PrimaryHeader {
Expand All @@ -183,6 +189,10 @@ impl PrimaryHeader {
.to_string_lossy()
.into_owned()
}

pub fn is_public(&self) -> bool {
return self.public == 1u8;
}
}

/// Contains metadata which may be encrypted.
Expand Down Expand Up @@ -447,6 +457,7 @@ impl ImageHandle {
name: String,
config: Vec<u8>,
password: Option<String>,
public: bool,
dest: impl AsRef<Path>,
progress: F,
) -> Result<ImageHandle> {
Expand Down Expand Up @@ -485,7 +496,9 @@ impl ImageHandle {
} else {
HeaderEncryptionType::None
},
public: if public { 1u8 } else { 0u8 },
name: [0u8; 64],
reserved: [0u8; 64],
};

primary_header.name[0..name.len()].copy_from_slice(&name.clone().as_bytes()[..]);
Expand Down Expand Up @@ -792,6 +805,7 @@ mod tests {
String::from("Test"),
vec![],
None,
true,
tmp.path().join("small.gb"),
|_, _| {},
)?;
Expand Down Expand Up @@ -830,6 +844,7 @@ mod tests {
String::from("Test"),
vec![],
Some(String::from("1234")),
true,
tmp.path().join("small.gb"),
|_, _| {},
)?;
Expand Down
2 changes: 1 addition & 1 deletion goldboot-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "goldboot-macros"
version = "0.0.1"
edition = "2021"
rust-version = "1.59"
rust-version = "1.70"

[lib]
proc-macro = true
Expand Down
2 changes: 1 addition & 1 deletion goldboot-uefi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
name = "goldboot-uefi"
version = "0.1.0"
edition = "2021"
rust-version = "1.59"
rust-version = "1.70"

[dependencies]
2 changes: 1 addition & 1 deletion goldboot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ authors = ["Tyler Cook"]
readme = "README.md"
homepage = "https://goldboot.org"
repository = "https://github.com/goldboot/goldboot/"
rust-version = "1.59"
rust-version = "1.70"

[dependencies]
anyhow = "1.0.76"
Expand Down
5 changes: 5 additions & 0 deletions goldboot/src/foundry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ pub struct Foundry {
/// Whether screenshots will be generated during the run for debugging
pub record: bool,

/// Whether the image is public
pub public: bool,

pub size: String,
}

Expand Down Expand Up @@ -198,6 +201,7 @@ impl Foundry {
self.name.clone(),
ron::ser::to_string_pretty(&self, PrettyConfig::new())?.into_bytes(),
self.password.clone(),
self.public,
output,
ProgressBar::Convert.new_empty(),
)?;
Expand All @@ -208,6 +212,7 @@ impl Foundry {
self.name.clone(),
ron::ser::to_string_pretty(&self, PrettyConfig::new())?.into_bytes(),
self.password.clone(),
self.public,
&tmp,
ProgressBar::Convert.new_empty(),
)?;
Expand Down
44 changes: 42 additions & 2 deletions goldboot/src/registry/api/image.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,47 @@
use axum::extract::Path;
use crate::registry::extract;
use axum::{
extract::{Path, State},
http::StatusCode,
Json,
};
use goldboot_image::{ImageArch, ImageHandle};
use serde::{Deserialize, Serialize};

use crate::library::ImageLibrary;

#[derive(Serialize, Deserialize)]
pub struct ImageInfoResponse {
pub version: u8,

/// The total size of all blocks combined in bytes
pub size: u64,

/// Image creation time
pub timestamp: u64,

/// A copy of the name field from the config
pub name: String,

/// System architecture
pub arch: ImageArch,
}

impl From<ImageHandle> for ImageInfoResponse {
fn from(value: ImageHandle) -> Self {
Self {
version: value.primary_header.version,
size: value.primary_header.size,
timestamp: value.primary_header.timestamp,
name: value.primary_header.name(),
arch: value.primary_header.arch,
}
}
}

/// Get image info
pub async fn info(Path(_id): Path<String>) {}
pub async fn info(image: extract::ImageHandle) -> Json<ImageInfoResponse> {
Json(image.0.into())
}

/// Get image list
pub async fn list() {}
Expand Down
1 change: 1 addition & 0 deletions goldboot/src/registry/api/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod image;
59 changes: 59 additions & 0 deletions goldboot/src/registry/extract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::collections::HashMap;

use axum::{
async_trait,
extract::{rejection::JsonRejection, FromRequest, MatchedPath, Path, Request},
http::StatusCode,
response::IntoResponse,
RequestPartsExt,
};
use tracing::error;

use crate::library::ImageLibrary;

use super::RegistryState;

/// Newtype wrapper for ImageHandle.
pub struct ImageHandle(pub goldboot_image::ImageHandle);

#[async_trait]
impl FromRequest<RegistryState> for ImageHandle {
type Rejection = StatusCode;

async fn from_request(req: Request, state: &RegistryState) -> Result<Self, Self::Rejection> {
let (mut parts, body) = req.into_parts();

// We can use other extractors to provide better rejection messages.
// For example, here we are using `axum::extract::MatchedPath` to
// provide a better error message.
//
// Have to run that first since `Json` extraction consumes the request.
let path = parts
.extract::<MatchedPath>()
.await
.map(|path| path.as_str().to_owned())
.ok();

let req = Request::from_parts(parts, body);

match Path::<HashMap<String, String>>::from_request(req, state).await {
Ok(value) => match value.get("image_id") {
Some(image_id) => match ImageLibrary::find_by_id(image_id) {
Ok(image_handle) => {
if image_handle.primary_header.is_public() {
Ok(ImageHandle(image_handle))
} else {
todo!()
}
}
Err(_) => Err(StatusCode::NOT_FOUND),
},
None => {
error!("No image id");
Err(StatusCode::INTERNAL_SERVER_ERROR)
}
},
Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR),
}
}
}
21 changes: 21 additions & 0 deletions goldboot/src/registry/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
use axum::{routing::get, Router};

pub mod api;
pub mod extract;
pub mod media;

pub struct RegistryTokenPermissions {
Expand All @@ -23,3 +27,20 @@ pub struct RegistryToken {
/// The token's associated permissions
pub permissions: RegistryTokenPermissions,
}

#[derive(Clone)]
pub struct RegistryState {}

pub async fn run(address: String, port: u16) {
let state = RegistryState {};

let app = Router::new()
.route("/image/list", get(api::image::list))
.route("/image/info/:image_id", get(api::image::info))
.with_state(state);

let listener = tokio::net::TcpListener::bind(format!("{address}:{port}"))
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}

0 comments on commit f82271f

Please sign in to comment.