Skip to content

Commit

Permalink
Push docker image to registry (#7)
Browse files Browse the repository at this point in the history
* push bootstrap to dockerhub registry. modify dockerconfig. create DockerImage struct

* address chido nit. reduce calls to RUN in dockerfile

* address jon's comments. next fetch-spl in rust

* build in fetch-spl.sh into rust. remove script
  • Loading branch information
gregcusack authored Apr 17, 2024
1 parent 044c9d2 commit e366862
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 211 deletions.
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>),
}?;

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

0 comments on commit e366862

Please sign in to comment.