Skip to content

Commit

Permalink
Handle cargo registry index lookup requests (#33681)
Browse files Browse the repository at this point in the history
  • Loading branch information
pgarg66 authored Oct 13, 2023
1 parent fd92977 commit 09e858d
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 136 deletions.
82 changes: 1 addition & 81 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ gag = "1.0.0"
generic-array = { version = "0.14.7", default-features = false }
gethostname = "0.2.3"
getrandom = "0.2.10"
git2 = "0.18.1"
goauth = "0.13.1"
hex = "0.4.3"
hidapi = { version = "2.4.1", default-features = false }
Expand All @@ -216,7 +215,6 @@ http = "0.2.9"
humantime = "2.0.1"
hyper = "0.14.27"
hyper-proxy = "0.9.1"
hyper-staticfile = "0.9.5"
im = "15.1.0"
index_list = "0.2.7"
indexmap = "2.0.2"
Expand Down
3 changes: 1 addition & 2 deletions cargo-registry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ edition = { workspace = true }
[dependencies]
clap = { workspace = true }
flate2 = { workspace = true }
git2 = { workspace = true }
hyper = { workspace = true, features = ["full"] }
hyper-staticfile = { workspace = true }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = { workspace = true }
solana-clap-utils = { workspace = true }
solana-cli = { workspace = true }
solana-cli-config = { workspace = true }
Expand Down
20 changes: 13 additions & 7 deletions cargo-registry/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use {
crate::{
client::Client,
publisher::{Error, Publisher},
sparse_index::RegistryIndex,
},
hyper::{
body,
Expand Down Expand Up @@ -30,15 +31,17 @@ impl CargoRegistryService {
async fn handle_publish_request(
request: hyper::Request<hyper::Body>,
client: Arc<Client>,
index: Arc<RegistryIndex>,
) -> hyper::Response<hyper::Body> {
info!("Handling request to publish the crate");
let bytes = body::to_bytes(request.into_body()).await;

match bytes {
Ok(data) => {
let Ok(result) =
tokio::task::spawn_blocking(move || Publisher::publish_crate(data, client))
.await
let Ok(result) = tokio::task::spawn_blocking(move || {
Publisher::publish_crate(data, client, index)
})
.await
else {
return response_builder::error_response(
hyper::StatusCode::INTERNAL_SERVER_ERROR,
Expand Down Expand Up @@ -218,7 +221,7 @@ impl CargoRegistryService {
}

async fn handler(
index: sparse_index::RegistryIndex,
index: Arc<sparse_index::RegistryIndex>,
request: hyper::Request<hyper::Body>,
client: Arc<Client>,
) -> Result<hyper::Response<hyper::Body>, Error> {
Expand Down Expand Up @@ -257,7 +260,7 @@ impl CargoRegistryService {
"Invalid length of the request.",
)
} else {
Self::handle_publish_request(request, client.clone()).await
Self::handle_publish_request(request, client.clone(), index.clone()).await
}
}
"unyank" => Self::handle_unyank_request(path, &request),
Expand Down Expand Up @@ -297,7 +300,10 @@ async fn main() {
let client = Arc::new(Client::new().expect("Failed to get RPC Client instance"));

let bind_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), client.port);
let index = sparse_index::RegistryIndex::new("/index", &client.server_url);
let index = Arc::new(sparse_index::RegistryIndex::new(
"/index",
&client.server_url,
));

let registry_service = make_service_fn(move |_| {
let client_inner = client.clone();
Expand All @@ -310,7 +316,7 @@ async fn main() {
});

let server = Server::bind(&bind_addr).serve(registry_service);
info!("Server running on on http://{}", bind_addr);
info!("Server running on http://{}", bind_addr);

let _ = server.await;
}
81 changes: 47 additions & 34 deletions cargo-registry/src/publisher.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use {
crate::client::{Client, ClientConfig},
crate::{
client::{Client, ClientConfig},
sparse_index::{IndexEntry, RegistryIndex},
},
flate2::read::GzDecoder,
hyper::body::Bytes,
log::*,
serde::{Deserialize, Serialize},
serde_json::from_slice,
sha2::{Digest, Sha256},
solana_cli::program_v4::{process_deploy_program, read_and_verify_elf},
solana_sdk::{
signature::{Keypair, Signer},
Expand All @@ -22,51 +26,51 @@ use {
tempfile::{tempdir, TempDir},
};

pub type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
pub(crate) type Error = Box<dyn std::error::Error + Send + Sync + 'static>;

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
enum DependencyType {
pub(crate) enum DependencyType {
Dev,
Build,
Normal,
}

#[allow(dead_code)]
#[derive(Debug, Deserialize)]
struct Dependency {
name: String,
version_req: String,
features: Vec<String>,
optional: bool,
default_features: bool,
target: Option<String>,
kind: DependencyType,
registry: Option<String>,
explicit_name_in_toml: Option<String>,
pub(crate) struct Dependency {
pub name: String,
pub version_req: String,
pub features: Vec<String>,
pub optional: bool,
pub default_features: bool,
pub target: Option<String>,
pub kind: DependencyType,
pub registry: Option<String>,
pub explicit_name_in_toml: Option<String>,
}

#[derive(Debug, Deserialize)]
#[allow(unused)]
struct PackageMetaData {
name: String,
vers: String,
deps: Vec<Dependency>,
features: BTreeMap<String, Vec<String>>,
authors: Vec<String>,
description: Option<String>,
documentation: Option<String>,
homepage: Option<String>,
readme: Option<String>,
readme_file: Option<String>,
keywords: Vec<String>,
categories: Vec<String>,
license: Option<String>,
license_file: Option<String>,
repository: Option<String>,
badges: BTreeMap<String, BTreeMap<String, String>>,
links: Option<String>,
rust_version: Option<String>,
pub(crate) struct PackageMetaData {
pub name: String,
pub vers: String,
pub deps: Vec<Dependency>,
pub features: BTreeMap<String, Vec<String>>,
pub authors: Vec<String>,
pub description: Option<String>,
pub documentation: Option<String>,
pub homepage: Option<String>,
pub readme: Option<String>,
pub readme_file: Option<String>,
pub keywords: Vec<String>,
pub categories: Vec<String>,
pub license: Option<String>,
pub license_file: Option<String>,
pub repository: Option<String>,
pub badges: BTreeMap<String, BTreeMap<String, String>>,
pub links: Option<String>,
pub rust_version: Option<String>,
}

impl PackageMetaData {
Expand All @@ -86,7 +90,7 @@ impl PackageMetaData {
}
}

pub struct Publisher {}
pub(crate) struct Publisher {}

impl Publisher {
fn make_path<P: AsRef<Path>>(tempdir: &TempDir, meta: &PackageMetaData, append: P) -> PathBuf {
Expand All @@ -107,12 +111,17 @@ impl Publisher {
Ok(library_name.to_string())
}

pub(crate) fn publish_crate(bytes: Bytes, client: Arc<Client>) -> Result<(), Error> {
pub(crate) fn publish_crate(
bytes: Bytes,
client: Arc<Client>,
index: Arc<RegistryIndex>,
) -> Result<(), Error> {
let (meta_data, offset) = PackageMetaData::new(&bytes)?;

let (_crate_file_length, length_size) =
PackageMetaData::read_u32_length(&bytes.slice(offset..))?;
let crate_bytes = bytes.slice(offset.saturating_add(length_size)..);
let crate_cksum = format!("{:x}", Sha256::digest(&crate_bytes));

let decoder = GzDecoder::new(crate_bytes.as_ref());
let mut archive = Archive::new(decoder);
Expand Down Expand Up @@ -154,6 +163,10 @@ impl Publisher {
format!("Failed to deploy the program: {}", e)
})?;

let mut entry: IndexEntry = meta_data.into();
entry.cksum = crate_cksum;
index.insert_entry(entry)?;

info!("Successfully deployed the program");
Ok(())
}
Expand Down
Loading

0 comments on commit 09e858d

Please sign in to comment.