Skip to content

Commit

Permalink
[wicketd] add stub API for fetching artifacts (#1998)
Browse files Browse the repository at this point in the history
Add a basic stub API for fetching artifacts, and update the OpenAPI
schema.

The implementation hasn't been filled out yet.
  • Loading branch information
sunshowers authored Dec 1, 2022
1 parent 41d0fed commit 3257446
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 2 deletions.
54 changes: 54 additions & 0 deletions openapi/wicketd.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,60 @@
"version": "0.0.1"
},
"paths": {
"/artifacts/{name}/{version}/{hash}": {
"get": {
"summary": "Fetch an artifact from the in-memory cache.",
"operationId": "get_artifact",
"parameters": [
{
"in": "path",
"name": "hash",
"description": "A hash of the artifact. TODO: is there a hash type?",
"required": true,
"schema": {
"type": "string"
},
"style": "simple"
},
{
"in": "path",
"name": "name",
"description": "The artifact's name.",
"required": true,
"schema": {
"type": "string"
},
"style": "simple"
},
{
"in": "path",
"name": "version",
"description": "The version of the artifact.",
"required": true,
"schema": {
"type": "string"
},
"style": "simple"
}
],
"responses": {
"200": {
"description": "",
"content": {
"*/*": {
"schema": {}
}
}
},
"4XX": {
"$ref": "#/components/responses/Error"
},
"5XX": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/inventory": {
"get": {
"summary": "A status endpoint used to report high level information known to wicketd.",
Expand Down
40 changes: 40 additions & 0 deletions wicketd/src/artifacts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

// Copyright 2022 Oxide Computer Company

use hyper::body::Bytes;
use schemars::JsonSchema;
use serde::Deserialize;
use slog::Logger;

/// Path parameters for Silo requests
#[derive(Clone, Debug, Deserialize, JsonSchema)]
#[allow(dead_code)]
pub(crate) struct ArtifactId {
/// The artifact's name.
pub(crate) name: String,

/// The version of the artifact.
pub(crate) version: String,
}

/// The artifact store, used to cache artifacts.
pub struct ArtifactStore {
log: Logger,
// TODO: implement this
}

impl ArtifactStore {
pub(crate) fn new(log: &Logger) -> Self {
let log = log.new(slog::o!("component" => "wicketd artifact store"));
Self { log }
}

pub(crate) fn get_artifact(&self, id: &ArtifactId) -> Option<Bytes> {
slog::debug!(self.log, "Artifact requested (this is a stub implementation which always 404s): {:?}", id);
// TODO: implement this
None
}
}
3 changes: 2 additions & 1 deletion wicketd/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

//! User provided dropshot server context
use crate::MgsHandle;
use crate::{artifacts::ArtifactStore, MgsHandle};

/// Shared state used by API handlers
pub struct ServerContext {
pub artifact_store: ArtifactStore,
pub mgs_handle: MgsHandle,
}
24 changes: 24 additions & 0 deletions wicketd/src/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@

//! HTTP entrypoint functions for wicketd
use crate::artifacts::ArtifactId;
use crate::RackV1Inventory;
use dropshot::endpoint;
use dropshot::ApiDescription;
use dropshot::FreeformBody;
use dropshot::HttpError;
use dropshot::HttpResponseOk;
use dropshot::Path;
use dropshot::RequestContext;
use hyper::Body;
use std::sync::Arc;

use crate::ServerContext;
Expand All @@ -22,6 +26,7 @@ pub fn api() -> WicketdApiDescription {
api: &mut WicketdApiDescription,
) -> Result<(), String> {
api.register(get_inventory)?;
api.register(get_artifact)?;
Ok(())
}

Expand Down Expand Up @@ -53,3 +58,22 @@ async fn get_inventory(
}
}
}

/// Fetch an artifact from the in-memory cache.
#[endpoint {
method = GET,
path = "/artifacts/{name}/{version}"
}]
async fn get_artifact(
rqctx: Arc<RequestContext<ServerContext>>,
path: Path<ArtifactId>,
) -> Result<HttpResponseOk<FreeformBody>, HttpError> {
match rqctx.context().artifact_store.get_artifact(&path.into_inner()) {
Some(bytes) => Ok(HttpResponseOk(Body::from(bytes).into())),
None => {
Err(HttpError::for_not_found(None, "Artifact not found".into()))
}
}
}

// TODO: hash verification/fetch artifact by hash?
6 changes: 5 additions & 1 deletion wicketd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

mod artifacts;
mod config;
mod context;
mod http_entrypoints;
mod inventory;
mod mgs;

use artifacts::ArtifactStore;
pub use config::Config;
pub(crate) use context::ServerContext;
pub use inventory::{RackV1Inventory, SpInventory};
Expand Down Expand Up @@ -58,6 +60,8 @@ pub async fn run_server(config: Config, args: Args) -> Result<(), String> {
..Default::default()
};

let artifact_store = ArtifactStore::new(&log);

let mgs_manager = MgsManager::new(&log, config.mgs_addr);
let mgs_handle = mgs_manager.get_handle();
tokio::spawn(async move {
Expand All @@ -67,7 +71,7 @@ pub async fn run_server(config: Config, args: Args) -> Result<(), String> {
let server = dropshot::HttpServerStarter::new(
&dropshot_config,
http_entrypoints::api(),
ServerContext { mgs_handle },
ServerContext { artifact_store, mgs_handle },
&log.new(o!("component" => "dropshot (wicketd)")),
)
.map_err(|err| format!("initializing http server: {}", err))?
Expand Down

0 comments on commit 3257446

Please sign in to comment.