diff --git a/tools/testsys-config/src/lib.rs b/tools/testsys-config/src/lib.rs index a9134e36bed..1794cb21d3a 100644 --- a/tools/testsys-config/src/lib.rs +++ b/tools/testsys-config/src/lib.rs @@ -197,6 +197,8 @@ pub struct GenericVariantConfig { pub conformance_registry: Option, /// The endpoint IP to reserve for the vSphere control plane VMs when creating a K8s cluster pub control_plane_endpoint: Option, + /// The path to userdata that should be used for Bottlerocket launch + pub userdata: Option, } impl GenericVariantConfig { @@ -222,6 +224,7 @@ impl GenericVariantConfig { conformance_image: self.conformance_image.or(other.conformance_image), conformance_registry: self.conformance_registry.or(other.conformance_registry), control_plane_endpoint: self.control_plane_endpoint.or(other.control_plane_endpoint), + userdata: self.userdata.or(other.userdata), } } } diff --git a/tools/testsys/src/aws_resources.rs b/tools/testsys/src/aws_resources.rs index 285f91e45ee..45edfca9bd0 100644 --- a/tools/testsys/src/aws_resources.rs +++ b/tools/testsys/src/aws_resources.rs @@ -2,7 +2,7 @@ use crate::crds::BottlerocketInput; use crate::error::{self, Result}; use aws_sdk_ec2::model::{Filter, Image}; use aws_sdk_ec2::Region; -use bottlerocket_types::agent_config::{ClusterType, Ec2Config}; +use bottlerocket_types::agent_config::{ClusterType, CustomUserData, Ec2Config}; use maplit::btreemap; use model::{DestructionPolicy, Resource}; use serde::Deserialize; @@ -146,6 +146,12 @@ pub(crate) async fn ec2_crd<'a>( .cloned() .collect(), ) + .custom_user_data( + bottlerocket_input + .crd_input + .encoded_userdata()? + .map(|encoded_userdata| CustomUserData::Merge { encoded_userdata }), + ) .cluster_name_template(cluster_name, "clusterName") .region_template(cluster_name, "region") .instance_profile_arn_template(cluster_name, "iamInstanceProfileArn") diff --git a/tools/testsys/src/crds.rs b/tools/testsys/src/crds.rs index 7a989a80e9a..7f6e137cabc 100644 --- a/tools/testsys/src/crds.rs +++ b/tools/testsys/src/crds.rs @@ -98,6 +98,20 @@ impl<'a> CrdInput<'a> { .collect()) } + /// Use the provided userdata path to create the encoded userdata. + pub fn encoded_userdata(&self) -> Result> { + let userdata_path = match self.config.userdata.as_ref() { + Some(path) => path, + None => return Ok(None), + }; + + let userdata = std::fs::read_to_string(userdata_path).context(error::FileSnafu { + path: userdata_path, + })?; + + Ok(Some(base64::encode(userdata))) + } + /// Fill in the templated cluster name with `arch` and `variant`. fn rendered_cluster_name(&self, raw_cluster_name: String) -> Result { Ok(rendered_cluster_name( diff --git a/tools/testsys/src/run.rs b/tools/testsys/src/run.rs index f0cd51a9ded..2a151cd6380 100644 --- a/tools/testsys/src/run.rs +++ b/tools/testsys/src/run.rs @@ -142,6 +142,10 @@ struct CliConfig { /// The endpoint IP to reserve for the vSphere control plane VMs when creating a K8s cluster #[clap(long, env = "TESTSYS_CONTROL_PLANE_ENDPOINT")] pub control_plane_endpoint: Option, + + /// Specify the path to the userdata that should be added for Bottlerocket launch + #[clap(long, env = "TESTSYS_USERDATA")] + pub userdata: Option, } impl From for GenericVariantConfig { @@ -154,6 +158,7 @@ impl From for GenericVariantConfig { conformance_image: val.conformance_image, conformance_registry: val.conformance_registry, control_plane_endpoint: val.control_plane_endpoint, + userdata: val.userdata, } } } diff --git a/tools/testsys/src/vmware_k8s.rs b/tools/testsys/src/vmware_k8s.rs index 59f9e9aafde..db391fcaaf1 100644 --- a/tools/testsys/src/vmware_k8s.rs +++ b/tools/testsys/src/vmware_k8s.rs @@ -6,7 +6,8 @@ use crate::error::{self, Result}; use crate::migration::migration_crd; use crate::sonobuoy::sonobuoy_crd; use bottlerocket_types::agent_config::{ - CreationPolicy, K8sVersion, VSphereK8sClusterConfig, VSphereK8sClusterInfo, VSphereVmConfig, + CreationPolicy, CustomUserData, K8sVersion, VSphereK8sClusterConfig, VSphereK8sClusterInfo, + VSphereVmConfig, }; use maplit::btreemap; use model::{Crd, DestructionPolicy, SecretName}; @@ -198,6 +199,12 @@ impl CrdCreator for VmwareK8sCreator { control_plane_endpoint_ip: format!("${{{}.endpoint}}", cluster_name), kubeconfig_base64: format!("${{{}.encodedKubeconfig}}", cluster_name), }) + .custom_user_data( + bottlerocket_input + .crd_input + .encoded_userdata()? + .map(|encoded_userdata| CustomUserData::Merge { encoded_userdata }), + ) .assume_role(bottlerocket_input.crd_input.config.agent_role.clone()) .set_labels(Some(labels)) .set_conflicts_with(Some(existing_clusters))