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
4 changes: 2 additions & 2 deletions PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
- [x] Create Genesis
- [x] Generate faucet and bootstrap accounts
- [x] Build genesis
- [ ] Docker Build
- [x] Docker Build
- [x] Build Bootstrap Image
- [ ] Push Image to registry
- [x] Push Image to registry
- [ ] Create & Deploy Secrets
- [ ] Bootstrap
- [ ] Validator (regular)
Expand Down
62 changes: 0 additions & 62 deletions fetch-spl.sh

This file was deleted.

155 changes: 97 additions & 58 deletions src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1,74 @@
use {
crate::{new_spinner_progress_bar, release::DeployMethod, ValidatorType, BUILD},
crate::{new_spinner_progress_bar, release::DeployMethod, ValidatorType, BUILD, ROCKET},
log::*,
std::{
env,
error::Error,
fmt::{self, Display, Formatter},
fs,
path::{Path, PathBuf},
process::{Command, Output, Stdio},
process::{Command, Stdio},
},
};

pub struct DockerConfig {
pub base_image: String,
pub image_name: String,
pub tag: String,
pub registry: String,
deploy_method: DeployMethod,
pub struct DockerImage {
registry: String,
validator_type: ValidatorType,
image_name: String,
tag: String,
}

impl DockerConfig {
impl DockerImage {
// Constructor to create a new instance of DockerImage
pub fn new(
base_image: String,
registry: String,
validator_type: ValidatorType,
image_name: String,
tag: String,
registry: String,
deploy_method: DeployMethod,
) -> Self {
DockerConfig {
base_image,
DockerImage {
registry,
validator_type,
image_name,
tag,
registry,
}
}

pub fn validator_type(&self) -> ValidatorType {
self.validator_type
}
}

// Put DockerImage in format for building, pushing, and pulling
impl Display for DockerImage {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(
f,
"{}/{}-{}:{}",
self.registry, self.validator_type, self.image_name, self.tag
)
}
}

pub struct DockerConfig {
pub base_image: String,
deploy_method: DeployMethod,
}

impl DockerConfig {
pub fn new(base_image: String, deploy_method: DeployMethod) -> Self {
DockerConfig {
base_image,
deploy_method,
}
}

pub fn build_image(
&self,
solana_root_path: &Path,
validator_type: &ValidatorType,
docker_image: &DockerImage,
) -> Result<(), Box<dyn Error>> {
let validator_type = docker_image.validator_type();
match validator_type {
ValidatorType::Bootstrap => (),
ValidatorType::Standard | ValidatorType::RPC | ValidatorType::Client => {
Expand All @@ -49,34 +78,27 @@ impl DockerConfig {
.into());
}
}
let image_name = format!("{validator_type}-{}", self.image_name);

let docker_path = solana_root_path.join(format!("docker-build/{validator_type}"));
match self.create_base_image(solana_root_path, image_name, &docker_path, validator_type) {
Ok(res) => {
if res.status.success() {
info!("Successfully created base Image");
Ok(())
} else {
error!("Failed to build base image");
Err(String::from_utf8_lossy(&res.stderr).into())
}
}
Err(err) => Err(err),
}
self.create_base_image(
solana_root_path,
docker_image,
&docker_path,
&validator_type,
)?;

Ok(())
}

fn create_base_image(
&self,
solana_root_path: &Path,
image_name: String,
docker_image: &DockerImage,
docker_path: &PathBuf,
validator_type: &ValidatorType,
) -> Result<Output, Box<dyn Error>> {
) -> Result<(), Box<dyn Error>> {
self.create_dockerfile(validator_type, docker_path, None)?;

trace!("Tmp: {}", docker_path.as_path().display());
trace!("Exists: {}", docker_path.as_path().exists());

// We use std::process::Command here because Docker-rs is very slow building dockerfiles
// when they are in large repos. Docker-rs doesn't seem to support the `--file` flag natively.
// so we result to using std::process::Command
Expand All @@ -86,10 +108,7 @@ impl DockerConfig {
let progress_bar = new_spinner_progress_bar();
progress_bar.set_message(format!("{BUILD}Building {validator_type} docker image...",));

let command = format!(
"docker build -t {}/{image_name}:{} -f {dockerfile:?} {context_path}",
self.registry, self.tag,
);
let command = format!("docker build -t {docker_image} -f {dockerfile:?} {context_path}");

let output = match Command::new("sh")
.arg("-c")
Expand All @@ -102,11 +121,15 @@ impl DockerConfig {
{
Ok(res) => Ok(res),
Err(err) => Err(Box::new(err) as Box<dyn Error>),
};
}?;

if !output.status.success() {
return Err(output.status.to_string().into());
}
progress_bar.finish_and_clear();
info!("{validator_type} image build complete");

output
Ok(())
}

fn copy_file_to_docker(
Expand Down Expand Up @@ -152,30 +175,19 @@ impl DockerConfig {
let dockerfile = format!(
r#"
FROM {}
RUN apt-get update
RUN apt-get install -y iputils-ping curl vim bzip2
RUN apt-get update && apt-get install -y iputils-ping curl vim && \
rm -rf /var/lib/apt/lists/* && \
useradd -ms /bin/bash solana && \
adduser solana sudo

RUN useradd -ms /bin/bash solana
RUN adduser solana sudo
USER solana

RUN mkdir -p /home/solana/k8s-cluster-scripts
# TODO: this needs to be changed for non bootstrap, this should be ./src/scripts/<validator-type>-startup-scripts.sh
COPY {startup_script_directory}/bootstrap-startup-script.sh /home/solana/k8s-cluster-scripts

RUN mkdir -p /home/solana/ledger
COPY --chown=solana:solana {startup_script_directory} /home/solana/k8s-cluster-scripts
COPY --chown=solana:solana ./config-k8s/bootstrap-validator /home/solana/ledger

RUN mkdir -p /home/solana/.cargo/bin

COPY ./{solana_build_directory}/bin/ /home/solana/.cargo/bin/
COPY ./{solana_build_directory}/version.yml /home/solana/

RUN mkdir -p /home/solana/config
COPY --chown=solana:solana ./{solana_build_directory}/bin/ /home/solana/.cargo/bin/
COPY --chown=solana:solana ./{solana_build_directory}/version.yml /home/solana/
ENV PATH="/home/solana/.cargo/bin:${{PATH}}"

WORKDIR /home/solana

"#,
self.base_image
);
Expand All @@ -187,4 +199,31 @@ WORKDIR /home/solana
)?;
Ok(())
}

pub fn push_image(docker_image: &DockerImage) -> Result<(), Box<dyn Error>> {
let progress_bar = new_spinner_progress_bar();
progress_bar.set_message(format!(
"{ROCKET}Pushing {} image to registry...",
docker_image.validator_type()
));
let command = format!("docker push '{}'", docker_image);
let output = match Command::new("sh")
.arg("-c")
.arg(&command)
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.expect("Failed to execute command")
.wait_with_output()
{
Ok(res) => Ok(res),
Err(err) => Err(Box::new(err) as Box<dyn Error>),
}?;
Comment on lines +210 to +221
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: you should be able to simplify this to something like:

        let output = match Command::new("sh")
            .arg("-c")
            .arg(&command)
            .stdout(Stdio::null())
            .stderr(Stdio::null())
            .spawn()
            .expect("Failed to execute command")
            .wait_with_output()
            .map_err(Box::new)?;

with maybe some trickery on the Box::new bit


if !output.status.success() {
return Err(output.status.to_string().into());
}
progress_bar.finish_and_clear();
Ok(())
}
}
Loading