Skip to content

Commit

Permalink
add credentials for pushing and pulling from docker repo. some refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
greg committed Sep 6, 2023
1 parent cecd244 commit 6a220ff
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 104 deletions.
3 changes: 3 additions & 0 deletions net/k8s-cluster/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Run this thing
```
export REGISTRY_USERNAME=<docker-registry-username> REGISTRY_PASSWORD=<docker-registry-password>
```
```
kubectl create ns greg
```
```
Expand Down
148 changes: 99 additions & 49 deletions net/k8s-cluster/src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use {
crate::{boxed_error, initialize_globals, SOLANA_ROOT},
crate::{
boxed_error, initialize_globals, load_env_variable_by_name, new_spinner_progress_bar,
DOCKER_WHALE, SOLANA_ROOT,
},
docker_api::{self, opts, Docker},
log::*,
std::{
Expand All @@ -16,12 +19,46 @@ const URI_ENV_VAR: &str = "unix:///var/run/docker.sock";
#[derive(Clone, Debug)]
pub struct DockerImageConfig<'a> {
pub base_image: &'a str,
pub image_name: &'a str,
pub tag: &'a str,
pub registry: &'a str,
}

pub struct DockerConfig<'a> {
image_config: DockerImageConfig<'a>,
deploy_method: &'a str,
docker: Docker,
registry_username: Option<String>,
registry_password: Option<String>,
}

fn init_runtime() -> Docker {
let _ = env_logger::try_init();
if let Ok(uri) = env::var(URI_ENV_VAR) {
Docker::new(uri).unwrap()
} else {
#[cfg(unix)]
{
let uid = nix::unistd::Uid::effective();
let docker_dir = PathBuf::from(format!("/run/user/{uid}/docker"));
let docker_root_dir = PathBuf::from("/var/run");
if docker_dir.exists() {
Docker::unix(docker_dir.join("docker.sock"))
} else if docker_root_dir.exists() {
Docker::unix(docker_root_dir.join("docker.sock"))
} else {
panic!(
"Docker socket not found. Tried {URI_ENV_VAR} env variable, {} and {}",
docker_dir.display(),
docker_root_dir.display()
);
}
}
#[cfg(not(unix))]
{
panic!("Docker socket not found. Try setting the {URI_ENV_VAR} env variable",);
}
}
}

impl<'a> DockerConfig<'a> {
Expand All @@ -30,41 +67,27 @@ impl<'a> DockerConfig<'a> {
DockerConfig {
image_config,
deploy_method,
docker: init_runtime(),
registry_username: match load_env_variable_by_name("REGISTRY_USERNAME") {
Ok(username) => Some(username),
Err(_) => None,
},
registry_password: match load_env_variable_by_name("REGISTRY_PASSWORD") {
Ok(password) => Some(password),
Err(_) => None,
},
}
}

pub fn init_runtime(&self) -> Docker {
let _ = env_logger::try_init();
if let Ok(uri) = env::var(URI_ENV_VAR) {
Docker::new(uri).unwrap()
} else {
#[cfg(unix)]
{
let uid = nix::unistd::Uid::effective();
let docker_dir = PathBuf::from(format!("/run/user/{uid}/docker"));
let docker_root_dir = PathBuf::from("/var/run");
if docker_dir.exists() {
Docker::unix(docker_dir.join("docker.sock"))
} else if docker_root_dir.exists() {
Docker::unix(docker_root_dir.join("docker.sock"))
} else {
panic!(
"Docker socket not found. Tried {URI_ENV_VAR} env variable, {} and {}",
docker_dir.display(),
docker_root_dir.display()
);
}
}
#[cfg(not(unix))]
{
panic!("Docker socket not found. Try setting the {URI_ENV_VAR} env variable",);
}
pub fn registry_credentials_set(&self) -> bool {
if self.registry_username.is_none() || self.registry_username.is_none() {
return false;
}
true
}

pub async fn build_image(&self, validator_type: &str) -> Result<(), Box<dyn Error>> {
let docker = self.init_runtime();
match self.create_base_image(&docker, validator_type).await {
match self.create_base_image(validator_type).await {
Ok(res) => {
if res.status.success() {
info!("Successfully created base Image");
Expand All @@ -78,24 +101,8 @@ impl<'a> DockerConfig<'a> {
};
}

pub async fn create_base_image(
&self,
docker: &Docker,
validator_type: &str,
) -> Result<Output, Box<dyn Error>> {
let tag = format!("{}-{}", validator_type, self.image_config.tag);

let images = docker.images();
let _ = images
.get(tag.as_str())
.remove(
&opts::ImageRemoveOpts::builder()
.force(true)
.noprune(true)
.build(),
)
.await;

pub async fn create_base_image(&self, validator_type: &str) -> Result<Output, Box<dyn Error>> {
let image_name = format!("{}-{}", validator_type, self.image_config.image_name);
let docker_path = SOLANA_ROOT.join(format!("{}/{}", "docker-build", validator_type));

let dockerfile_path = match self.create_dockerfile(validator_type, docker_path, None) {
Expand All @@ -112,8 +119,8 @@ impl<'a> DockerConfig<'a> {
let dockerfile = dockerfile_path.join("Dockerfile");
let context_path = SOLANA_ROOT.display().to_string();
let command = format!(
"docker build -t {}/{} -f {:?} {}",
"gregcusack", tag, dockerfile, context_path
"docker build -t {}/{}:{} -f {:?} {}",
self.image_config.registry, image_name, self.image_config.tag, dockerfile, context_path
);
match Command::new("sh")
.arg("-c")
Expand Down Expand Up @@ -189,6 +196,49 @@ WORKDIR /home/solana
.expect("saved Dockerfile");
Ok(docker_path)
}

pub async fn push_image(&self, validator_type: &str) -> Result<(), Box<dyn Error>> {
let username = match &self.registry_username {
Some(username) => username,
None => {
return Err(boxed_error!(
"No username set for registry! Is REGISTRY_USERNAME set?"
))
}
};
let password = match &self.registry_password {
Some(password) => password,
None => {
return Err(boxed_error!(
"No password set for registry! Is REGISTRY_PASSWORD set?"
))
}
};

// self.docker
let image = format!(
"{}/{}-{}",
self.image_config.registry, validator_type, self.image_config.image_name
);
let auth = opts::RegistryAuth::Password {
username: password.to_string(),
password: username.to_string(),
email: None,
server_address: None,
};

let options = opts::ImagePushOpts::builder()
.tag(self.image_config.tag)
.auth(auth)
.build();
let progress_bar = new_spinner_progress_bar();
progress_bar.set_message(format!("{DOCKER_WHALE}Pushing image {} to registry", image));

match self.docker.images().push(image, &options).await {
Ok(res) => Ok(res),
Err(err) => Err(boxed_error!(format!("{}", err))),
}
}
}

// RUN apt install -y iputils-ping curl vim bzip2 psmisc \
Expand Down
37 changes: 19 additions & 18 deletions net/k8s-cluster/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,13 @@ use {
native_token::sol_to_lamports,
poh_config::PohConfig,
rent::Rent,
signature::{
keypair_from_seed, write_keypair, write_keypair_file, Keypair,
Signer,
},
signature::{keypair_from_seed, write_keypair, write_keypair_file, Keypair, Signer},
stake::state::StakeStateV2,
system_program, timing,
},
solana_stake_program::stake_state,
solana_vote_program::vote_state::{self, VoteState},
std::{
error::Error,
fs::File,
io::Read,
path::PathBuf,
time::Duration,
},
std::{error::Error, fs::File, io::Read, path::PathBuf, time::Duration},
};

pub const DEFAULT_WORD_COUNT: usize = 12;
Expand Down Expand Up @@ -106,28 +97,35 @@ impl<'a> Genesis<'a> {
}

pub fn generate_accounts(
&mut self,
validator_type: &str,
number_of_accounts: i32
&mut self,
validator_type: &str,
number_of_accounts: i32,
) -> Result<(), Box<dyn Error>> {
let mut filename_prefix = "validator".to_string();
if validator_type == "bootstrap" {
filename_prefix = format!("{}-{}", validator_type, filename_prefix);
} else if validator_type == "validator" {
filename_prefix = "validator".to_string();
} else {
return Err(boxed_error!(format!("Invalid validator type: {}", validator_type)));
return Err(boxed_error!(format!(
"Invalid validator type: {}",
validator_type
)));
}

for i in 0..number_of_accounts {
self.generate_account(validator_type, filename_prefix.as_str(), i)?;
}


Ok(())
}

fn generate_account(&mut self, validator_type: &str, filename_prefix: &str, i: i32) -> Result<(), Box<dyn Error>> {
fn generate_account(
&mut self,
validator_type: &str,
filename_prefix: &str,
i: i32,
) -> Result<(), Box<dyn Error>> {
let account_types = vec!["identity", "vote-account", "stake-account"];
let mut identity: Option<Keypair> = None;
let mut vote: Option<Keypair> = None;
Expand All @@ -139,7 +137,10 @@ impl<'a> Genesis<'a> {
} else if validator_type == "validator" {
filename = format!("{}-{}-{}.json", filename_prefix, account, i);
} else {
return Err(boxed_error!(format!("Invalid validator type: {}", validator_type)));
return Err(boxed_error!(format!(
"Invalid validator type: {}",
validator_type
)));
}

let outfile = self.config_dir.join(filename);
Expand Down
Loading

0 comments on commit 6a220ff

Please sign in to comment.