Skip to content
This repository was archived by the owner on Feb 23, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ log = "0.4.21"
rand = "0.8.5"
reqwest = { version = "0.11.23", features = ["blocking", "brotli", "deflate", "gzip", "rustls-tls", "json"] }
rustls = { version = "0.21.11", default-features = false, features = ["quic"] }
solana-accounts-db = "1.18.8"
solana-core = "1.18.8"
solana-ledger = "1.18.8"
solana-logger = "1.18.8"
Expand Down
18 changes: 10 additions & 8 deletions PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,24 @@
- [x] Create Genesis
- [x] Generate faucet and bootstrap accounts
- [x] Build genesis
- [x] Docker Build
- [x] Build Bootstrap Image
- [x] Push Image to registry
- [x] Docker Build & Push
- [x] Bootstrap
- [x] Validator (regular)
- [ ] RPC nodes
- [ ] Client
- [ ] Create & Deploy Secrets
- [x] Bootstrap
- [ ] Validator (regular)
- [x] Validator (regular)
- [ ] RPC nodes
- [ ] Client
- [ ] Create & Deploy Selector
- [x] Bootstrap
- [ ] Validator (regular)
- [x] Validator (regular)
- [ ] RPC nodes
- [ ] Client
- [ ] Create & Deploy Replica Set
- [x] Bootstrap
- [ ] Validator (regular)
- [x] Validator (regular)
- [ ] RPC nodes
- [ ] Client
- [ ] Create & Deploy Services
Expand All @@ -42,11 +44,11 @@
- [x] Build and deploy Load Balancer (sits in front of bootstrap and RPC nodes)
- [ ] Add metrics
- [x] Bootstrap
- [ ] Validator (regular)
- [x] Validator (regular)
- [ ] RPC nodes
- [ ] Client
- [ ] Create accounts
- [ ] Validator (regular)
- [x] Validator (regular)
- [ ] RPC
- [ ] Client
- [ ] Add feature flags to configure:
Expand Down
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,22 @@ kubectl create ns <namespace>
cargo run --bin cluster --
-n <namespace>
--local-path <path-to-local-agave-monorepo>
--validator-lab-dir <path-to-validator-lab-directory>
```

#### Build specific Agave release
```
cargo run --bin cluster --
-n <namespace>
--release-channel <agave-version: e.g. v1.17.28> # note: MUST include the "v"
--validator-lab-dir <path-to-validator-lab-directory>
```

#### Build from Local Repo and Configure Genesis and Bootstrap Validator Image
#### Build from Local Repo and Configure Genesis and Bootstrap and Validator Image
Example:
```
cargo run --bin cluster --
-n <namespace>
--local-path /home/sol/solana
--validator-lab-dir /home/sol/validator-lab
--num_validators <number-of-non-bootstrap-voting-validators>
# genesis config. Optional: Many of these have defaults
--hashes-per-tick <hashes-per-tick>
--enable-warmup-epochs <true|false>
Expand All @@ -59,14 +57,20 @@ cargo run --bin cluster --
--tag <docker-image-tag> # e.g. v1
--base-image <base-image> # e.g. ubuntu:20.04
--image-name <docker-image-name> # e.g. cluster-image
# validator config
--full-rpc
--internal-node-sol <Sol>
--internal-node-stake-sol <Sol>
# kubernetes config
--cpu-requests <cores>
--memory-requests <memory>
```

## Metrics
1) Setup metrics database:
```
cd scripts/
./init-metrics -c <database-name> <metrics-username>
# enter password when promted
./init-metrics -c <database-name> -u <metrics-username>
# enter password when prompted
```
2) add the following to your `cluster` command from above
```
Expand Down
Binary file added init-metrics
Binary file not shown.
102 changes: 0 additions & 102 deletions scripts/init-metrics.sh

This file was deleted.

11 changes: 9 additions & 2 deletions src/cluster_images.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use {
#[derive(Default)]
pub struct ClusterImages {
bootstrap: Option<Validator>,
_validator: Option<Validator>,
validator: Option<Validator>,
_rpc: Option<Validator>,
_clients: Vec<Validator>,
}
Expand All @@ -21,6 +21,7 @@ impl ClusterImages {
pub fn set_item(&mut self, item: Validator, validator_type: ValidatorType) {
match validator_type {
ValidatorType::Bootstrap => self.bootstrap = Some(item),
ValidatorType::Standard => self.validator = Some(item),
_ => panic!("{validator_type} not implemented yet!"),
}
}
Expand All @@ -31,10 +32,16 @@ impl ClusterImages {
.ok_or_else(|| "Bootstrap validator is not available".into())
}

pub fn validator(&mut self) -> Result<&mut Validator, Box<dyn Error>> {
self.validator
.as_mut()
.ok_or_else(|| "Validator is not available".into())
}

pub fn get_validators(&self) -> impl Iterator<Item = &Validator> {
self.bootstrap
.iter()
.chain(self._validator.iter())
.chain(self.validator.iter())
.chain(self._rpc.iter())
.filter_map(Some)
}
Expand Down
28 changes: 20 additions & 8 deletions src/docker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ impl DockerConfig {
) -> Result<(), Box<dyn Error>> {
let validator_type = docker_image.validator_type();
match validator_type {
ValidatorType::Bootstrap => (),
ValidatorType::Standard | ValidatorType::RPC | ValidatorType::Client => {
ValidatorType::Bootstrap | ValidatorType::Standard => (),
ValidatorType::RPC | ValidatorType::Client => {
return Err(format!(
"Build docker image for validator type: {validator_type} not supported yet"
)
Expand Down Expand Up @@ -138,9 +138,11 @@ impl DockerConfig {
fn write_startup_script_to_docker_directory(
file_name: &str,
docker_dir: &Path,
) -> std::io::Result<()> {
validator_type: &ValidatorType,
) -> Result<(), Box<dyn Error>> {
let script_path = docker_dir.join(file_name);
StartupScripts::write_script_to_file(StartupScripts::bootstrap(), &script_path)
let script_content = validator_type.script()?;
StartupScripts::write_script_to_file(script_content, &script_path).map_err(|e| e.into())
}

fn create_dockerfile(
Expand All @@ -154,11 +156,21 @@ impl DockerConfig {
}
fs::create_dir_all(docker_path)?;

if validator_type == &ValidatorType::Bootstrap {
let files_to_copy = ["bootstrap-startup-script.sh", "common.sh"];
for file_name in files_to_copy.iter() {
Self::write_startup_script_to_docker_directory(file_name, docker_path)?;
match validator_type {
ValidatorType::Bootstrap | ValidatorType::Standard => {
let files_to_copy = [
format!("{validator_type}-startup-script.sh"),
"common.sh".to_string(),
];
for file_name in files_to_copy.iter() {
Self::write_startup_script_to_docker_directory(
file_name,
docker_path,
validator_type,
)?;
}
}
ValidatorType::RPC | ValidatorType::Client => todo!(),
}

let startup_script_directory = format!("./docker-build/{validator_type}");
Expand Down
35 changes: 30 additions & 5 deletions src/k8s_helpers.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use {
crate::{docker::DockerImage, ValidatorType},
crate::docker::DockerImage,
k8s_openapi::{
api::{
apps::v1::{ReplicaSet, ReplicaSetSpec},
core::v1::{
Container, EnvVar, PodSecurityContext, PodSpec, PodTemplateSpec, Probe,
ResourceRequirements, Secret, Service, ServicePort, ServiceSpec, Volume,
VolumeMount,
Container, EnvVar, EnvVarSource, ObjectFieldSelector, PodSecurityContext, PodSpec,
PodTemplateSpec, Probe, ResourceRequirements, Secret, Service, ServicePort,
ServiceSpec, Volume, VolumeMount,
},
},
apimachinery::pkg::{api::resource::Quantity, apis::meta::v1::LabelSelector},
Expand Down Expand Up @@ -59,7 +59,7 @@ pub fn create_selector(key: &str, value: &str) -> BTreeMap<String, String> {

#[allow(clippy::too_many_arguments)]
pub fn create_replica_set(
name: ValidatorType,
name: String,
namespace: String,
label_selector: BTreeMap<String, String>,
image_name: DockerImage,
Expand Down Expand Up @@ -167,3 +167,28 @@ pub fn create_service(
..Default::default()
}
}

pub fn create_environment_variable(
name: String,
value: Option<String>,
field_path: Option<String>,
) -> EnvVar {
match field_path {
Some(path) => EnvVar {
name,
value_from: Some(EnvVarSource {
field_ref: Some(ObjectFieldSelector {
field_path: path,
..Default::default()
}),
..Default::default()
}),
..Default::default()
},
None => EnvVar {
name,
value,
..Default::default()
},
}
}
Loading