Skip to content

Commit

Permalink
feat: NODE-1277 - Add ability to inject ipv4 info into SetupOS image
Browse files Browse the repository at this point in the history
  • Loading branch information
garym-dfinity committed Feb 10, 2024
1 parent 1e06007 commit ead28e2
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 4 deletions.
48 changes: 45 additions & 3 deletions ic-os/utils/bare_metal_deployment/deploy.py
Expand Up @@ -80,6 +80,18 @@ class Args:
# If present - decompress `upload_img` and inject this into config.ini
inject_image_ipv6_gateway: Optional[str] = None

# If present - decompress `upload_img` and inject this into config.ini
inject_image_ipv4_address: Optional[str] = None

# If present - decompress `upload_img` and inject this into config.ini
inject_image_ipv4_gateway: Optional[str] = None

# If present - decompress `upload_img` and inject this into config.ini
inject_image_ipv4_prefix_length: Optional[str] = None

# If present - decompress `upload_img` and inject this into config.ini
inject_image_domain_name: Optional[str] = None

# Path to the setupos-inject-configuration tool. Necessary if any inject* args are present
inject_configuration_tool: Optional[str] = None

Expand Down Expand Up @@ -112,6 +124,12 @@ def __post_init__(self):
if self.inject_image_ipv6_prefix:
assert self.inject_configuration_tool, \
"setupos_inject_configuration tool required to modify image"
ipv4_args = [self.inject_image_ipv4_address,
self.inject_image_ipv4_gateway,
self.inject_image_ipv4_prefix_length,
self.inject_image_domain_name]
assert all(ipv4_args) or not any(ipv4_args), \
"All ipv4 flags must be present or none"
assert self.file_share_ssh_key is None \
or Path(self.file_share_ssh_key).exists(), \
"File share ssh key path does not exist"
Expand Down Expand Up @@ -151,6 +169,14 @@ class OperationResult:
error_msg: Optional[str] = None


@dataclass(frozen=True)
class Ipv4Args:
address: str
gateway: str
prefix_length: str
domain_name: str


def parse_from_row(row: List[str], network_image_url: str) -> BMCInfo:
if len(row) == 3:
ip_address, username, password = row
Expand Down Expand Up @@ -451,7 +477,8 @@ def inject_config_into_image(setupos_inject_configuration_path: Path,
working_dir: Path,
compressed_image_path: Path,
ipv6_prefix: str,
ipv6_gateway: str) -> Path:
ipv6_gateway: str,
ipv4_args: Optional[Ipv4Args]) -> Path:
"""
Transform the compressed image.
* Decompress image into working_dir
Expand All @@ -475,7 +502,14 @@ def is_executable(p: Path) -> bool:
image_part = f"--image-path {img_path}"
prefix_part = f"--ipv6-prefix {ipv6_prefix}"
gateway_part = f"--ipv6-gateway {ipv6_gateway}"
invoke.run(f"{setupos_inject_configuration_path} {image_part} {prefix_part} {gateway_part}", echo=True)
ipv4_part = ""
if ipv4_args:
ipv4_part = f"--ipv4-address {ipv4_args.address} "
ipv4_part += f"--ipv4-gateway {ipv4_args.gateway} "
ipv4_part += f"--ipv4-prefix-length {ipv4_args.prefix_length} "
ipv4_part += f"--domain-name {ipv4_args.domain_name} "

invoke.run(f"{setupos_inject_configuration_path} {image_part} {prefix_part} {gateway_part} {ipv4_part}", echo=True)

# Reuse the name of the compressed image path in the working directory
result_filename = compressed_image_path.name
Expand Down Expand Up @@ -511,6 +545,13 @@ def main():
csv_filename: str = args.csv_filename
bmc_infos = parse_from_csv_file(csv_filename, network_image_url)

ipv4_args = None
if args.inject_image_ipv4_address:
ipv4_args = Ipv4Args(args.inject_image_ipv4_address,
args.inject_image_ipv4_gateway,
args.inject_image_ipv4_prefix_length,
args.inject_image_domain_name)

if args.upload_img or args.inject_image_ipv6_prefix:
file_share_endpoint = create_file_share_endpoint(args.file_share_url, args.file_share_username)
assert_ssh_connectivity(file_share_endpoint, args.file_share_ssh_key)
Expand All @@ -523,7 +564,8 @@ def main():
Path(tmpdir),
Path(args.upload_img),
args.inject_image_ipv6_prefix,
args.inject_image_ipv6_gateway)
args.inject_image_ipv6_gateway,
ipv4_args)

upload_to_file_share(
modified_image_path,
Expand Down
4 changes: 4 additions & 0 deletions ic-os/utils/bare_metal_deployment/zh2-dll01.yaml
Expand Up @@ -3,3 +3,7 @@ file_share_dir: /srv/images
file_share_image_filename: setupos.bmd.img
inject_image_ipv6_prefix: 2a00:fb01:400:200
inject_image_ipv6_gateway: 2a00:fb01:400:200::1
inject_image_ipv4_address: 212.71.124.178
inject_image_ipv4_gateway: 212.71.124.177
inject_image_ipv4_prefix_length: 28
inject_image_domain_name: bare_metal_deployment.icp5.io
27 changes: 26 additions & 1 deletion rs/ic_os/setupos-inject-configuration/src/main.rs
Expand Up @@ -3,7 +3,7 @@ use std::{
assert,
fs::{self, File, Permissions},
io::Write,
net::Ipv6Addr,
net::{Ipv4Addr, Ipv6Addr},
path::{Path, PathBuf},
};

Expand Down Expand Up @@ -44,6 +44,18 @@ struct NetworkConfig {
#[arg(long)]
ipv6_gateway: Option<Ipv6Addr>,

#[arg(long)]
ipv4_address: Option<Ipv4Addr>,

#[arg(long)]
ipv4_gateway: Option<Ipv4Addr>,

#[arg(long)]
ipv4_prefix_length: Option<u8>,

#[arg(long)]
domain_name: Option<String>,

#[arg(long)]
mgmt_mac: Option<String>,
}
Expand Down Expand Up @@ -169,6 +181,10 @@ async fn write_config(path: &Path, cfg: &NetworkConfig) -> Result<(), Error> {
ipv6_prefix,
ipv6_gateway,
mgmt_mac,
ipv4_address,
ipv4_gateway,
ipv4_prefix_length,
domain_name,
} = cfg;

if let (Some(ipv6_prefix), Some(ipv6_gateway)) = (ipv6_prefix, ipv6_gateway) {
Expand All @@ -178,6 +194,15 @@ async fn write_config(path: &Path, cfg: &NetworkConfig) -> Result<(), Error> {
writeln!(&mut f, "ipv6_gateway={}", ipv6_gateway)?;
}

if let (Some(ipv4_address), Some(ipv4_gateway), Some(ipv4_prefix_length), Some(domain_name)) =
(ipv4_address, ipv4_gateway, ipv4_prefix_length, domain_name)
{
writeln!(&mut f, "ipv4_address={}", ipv4_address)?;
writeln!(&mut f, "ipv4_gateway={}", ipv4_gateway)?;
writeln!(&mut f, "ipv4_prefix_length={}", ipv4_prefix_length)?;
writeln!(&mut f, "domain_name={}", domain_name)?;
}

if let Some(mgmt_mac) = mgmt_mac {
writeln!(&mut f, "mgmt_mac={}", mgmt_mac)?;
}
Expand Down

0 comments on commit ead28e2

Please sign in to comment.