Skip to content

Commit 7a3b942

Browse files
authored
Merge pull request #950 from Pacho20/ibm-cloud-support
ibmcloud: initial support for IBM Cloud as a provider
2 parents 3bd3ef3 + ddf60f4 commit 7a3b942

8 files changed

+267
-13
lines changed

config/peerpods/podvm/Dockerfile.podvm-builder

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ ARG ACTIVATION_KEY
2424

2525
RUN mkdir -p /scripts
2626

27-
ADD ami-helper.sh lib.sh libvirt-podvm-image-handler.sh aws-podvm-image-handler.sh azure-podvm-image-handler.sh gcp-podvm-image-handler.sh /scripts/
27+
ADD ami-helper.sh lib.sh libvirt-podvm-image-handler.sh aws-podvm-image-handler.sh azure-podvm-image-handler.sh gcp-podvm-image-handler.sh ibmcloud-podvm-image-handler.sh /scripts/
2828

2929
RUN mkdir -p /scripts/bootc
3030
ADD bootc/config.toml /scripts/bootc/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: ibmcloud-podvm-image-cm
5+
namespace: openshift-sandboxed-containers-operator
6+
# these are just placeholders for now
7+
data:
8+
# Booleans
9+
INSTALL_PACKAGES: "no"
10+
DOWNLOAD_SOURCES: "no"
11+
CONFIDENTIAL_COMPUTE_ENABLED: "no"
12+
DISABLE_CLOUD_CONFIG: "true"
13+
ENABLE_NVIDIA_GPU: "no"
14+
UPDATE_PEERPODS_CM: "yes"
15+
BOOT_FIPS: "no"
16+
17+
# precreated artifacts
18+
#COS_BUCKET_NAME: existing-bucket-name
19+
PODVM_IMAGE_URI: bootc::image-registry.openshift-image-registry.svc:5000/openshift-sandboxed-containers-operator/podvm-bootc
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/bin/bash
2+
# FILEPATH: ibmcloud-podvm-image-handler.sh
3+
4+
# This script is used to import PodVM images to IBM Cloud
5+
# The basic assumption is that the required variables are set as environment variables in the pod
6+
# Typically the variables are read from configmaps and set as environment variables in the pod
7+
# The script will be called with one of the following options:
8+
# Create image (-c)
9+
# Delete image (-C)
10+
11+
# include common functions from lib.sh
12+
# shellcheck source=/dev/null
13+
# The directory is where ibmcloud-podvm-image-handler.sh is located
14+
source "$(dirname "$0")"/lib.sh
15+
16+
# function to download and install ibmcloud cli
17+
18+
function install_ibmcloud_cli() {
19+
# Install ibmcloud cli
20+
# If any error occurs, exit the script with an error message
21+
22+
# Check if ibmcloud cli is already installed
23+
if command -v ibmcloud &>/dev/null; then
24+
echo "ibmcloud cli is already installed"
25+
return
26+
fi
27+
28+
# Download ibmcloud cli
29+
curl -fsSL https://clis.cloud.ibm.com/install/linux -o /tmp/ibmcloud_install.sh ||
30+
error_exit "Failed to download ibmcloud cli"
31+
32+
# Install ibmcloud cli
33+
sh /tmp/ibmcloud_install.sh ||
34+
error_exit "Failed to execute ibmcloud cli installer"
35+
36+
# Install ibmcloud cli plugins
37+
ibmcloud plugin install -a ||
38+
error_exit "Failed to install ibmcloud cli plugins"
39+
40+
# Clean up temporary files
41+
rm -f "/tmp/ibmcloud_install.sh"
42+
}
43+
44+
function create_image() {
45+
error_exit "currently not supported"
46+
}
47+
48+
function delete_image() {
49+
error_exit "currently not supported"
50+
}
51+
52+
# display help message
53+
54+
function display_help() {
55+
echo "This script is used to import PodVM images to IBM Cloud"
56+
echo "Usage: $0 [-c|-C] [-- install_binaries|install_rpms|install_cli]"
57+
echo "Options:"
58+
echo "-c Create image"
59+
echo "-C Delete image"
60+
}
61+
62+
# main function
63+
64+
if [ "$#" -eq 0 ]; then
65+
display_help
66+
exit 1
67+
fi
68+
69+
if [ "$1" = "--" ]; then
70+
shift
71+
# Handle positional parameters
72+
case "$1" in
73+
74+
install_binaries)
75+
install_binary_packages
76+
;;
77+
install_rpms)
78+
install_rpm_packages
79+
;;
80+
install_cli)
81+
install_ibmcloud_cli
82+
;;
83+
*)
84+
echo "Unknown argument: $1"
85+
exit 1
86+
;;
87+
esac
88+
else
89+
while getopts "cCh" opt; do
90+
verify_vars
91+
case ${opt} in
92+
c)
93+
create_image
94+
;;
95+
C)
96+
delete_image
97+
;;
98+
h)
99+
# Display help
100+
display_help
101+
exit 0
102+
;;
103+
*)
104+
# Invalid option
105+
display_help
106+
exit 1
107+
;;
108+
esac
109+
done
110+
fi

config/peerpods/podvm/osc-podvm-create-job.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ spec:
3434
# azure-podvm-image-handler.sh script under /scripts/azure-podvm-image-handler.sh
3535
# aws-podvm-image-handler.sh script under /scripts/aws-podvm-image-handler.sh
3636
# gcp-podvm-image-handler.sh script under /scripts/gcp-podvm-image-handler.sh
37+
# ibmcloud-podvm-image-handler.sh script under /scripts/ibmcloud-podvm-image-handler.sh
3738
# sources for cloud-api-adaptor under /src/cloud-api-adaptor
3839
lifecycle:
3940
preStop:
@@ -67,6 +68,9 @@ spec:
6768
- configMapRef:
6869
name: gcp-podvm-image-cm
6970
optional: true
71+
- configMapRef:
72+
name: ibmcloud-podvm-image-cm
73+
optional: true
7074
- configMapRef:
7175
name: libvirt-podvm-image-cm
7276
optional: true

config/peerpods/podvm/osc-podvm-delete-job.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ spec:
1818
# azure-podvm-image-handler.sh script under /scripts/azure-podvm-image-handler.sh
1919
# aws-podvm-image-handler.sh script under /scripts/aws-podvm-image-handler.sh
2020
# gcp-podvm-image-handler.sh script under /scripts/gcp-podvm-image-handler.sh
21+
# ibmcloud-podvm-image-handler.sh script under /scripts/ibmcloud-podvm-image-handler.sh
2122
# sources for cloud-api-adaptor under /src/cloud-api-adaptor
2223
# Binaries like kubectl, packer and yq under /usr/local/bin
2324
image: registry.redhat.io/openshift-sandboxed-containers/osc-podvm-builder-rhel9:1.10.1 ## OSC_VERSION
@@ -47,6 +48,9 @@ spec:
4748
- configMapRef:
4849
name: gcp-podvm-image-cm
4950
optional: true
51+
- configMapRef:
52+
name: ibmcloud-podvm-image-cm
53+
optional: true
5054
- configMapRef:
5155
name: libvirt-podvm-image-cm
5256
optional: true

config/peerpods/podvm/podvm-builder.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ function install_gcp_deps() {
3131
/scripts/gcp-podvm-image-handler.sh -- install_binaries
3232
}
3333

34+
# Function to install IBM Cloud deps
35+
function install_ibmcloud_deps() {
36+
/scripts/ibmcloud-podvm-image-handler.sh -- install_cli
37+
/scripts/ibmcloud-podvm-image-handler.sh -- install_binaries
38+
}
3439

3540
# Function to check if peer-pods-cm configmap exists
3641
function check_peer_pods_cm_exists() {
@@ -382,6 +387,10 @@ libvirt)
382387
gcp)
383388
install_gcp_deps
384389
;;
390+
ibmcloud)
391+
echo "IBM Cloud doesn't support this feature, please provide IBMCLOUD_PODVM_IMAGE_ID in your peer-pods-cm"
392+
exit 1
393+
;;
385394
*)
386395
echo "CLOUD_PROVIDER is not set to azure or aws or libvirt"
387396
display_usage

controllers/image_generator.go

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ const (
5454
peerpodsCMAzureImageKey = "AZURE_IMAGE_ID"
5555
peerpodsCMGCPImageKey = "PODVM_IMAGE_NAME"
5656
peerpodsLibvirtImageKey = "LIBVIRT_IMAGE_ID"
57+
peerpodsCMIBMCloudImageKey = "IBMCLOUD_PODVM_IMAGE_ID"
5758
fipsCMKey = "BOOT_FIPS"
5859
procFIPS = "/proc/sys/crypto/fips_enabled"
5960
AWSProvider = "aws"
6061
AzureProvider = "azure"
6162
GCPProvider = "gcp"
6263
LibvirtProvider = "libvirt"
64+
IBMCloudProvider = "ibmcloud"
6365
peerpodsImageJobsPathLocation = "/config/peerpods/podvm"
6466
azureImageGalleryPrefix = "PodVMGallery"
6567
)
@@ -259,6 +261,9 @@ func newImageGenerator(client client.Client) (*ImageGenerator, error) {
259261
igLogger.Info("libvirt is our provider", "provider", provider)
260262
ig.CMimageIDKey = peerpodsLibvirtImageKey
261263
ig.provider = provider
264+
case IBMCloudProvider:
265+
ig.provider = provider
266+
ig.CMimageIDKey = peerpodsCMIBMCloudImageKey
262267
default:
263268
igLogger.Info("unsupported cloud provider, image creation/deletion will be disabled", "provider", ig.provider)
264269
ig.provider = unsupportedCloudProvider
@@ -415,6 +420,7 @@ func (r *ImageGenerator) getPeerPodsCM() (*corev1.ConfigMap, error) {
415420
// azure-podvm-image-cm.yaml for Azure
416421
// aws-podvm-image-cm.yaml for AWS
417422
// libvirt-podvm-image-cm.yaml for Libvirt
423+
// ibmcloud-podvm-image-cm.yaml for IBM Cloud
418424

419425
func (r *ImageGenerator) imageCreateJobRunner() (int, error) {
420426
igLogger.Info("imageCreateJobRunner: Start")
@@ -617,6 +623,10 @@ func (r *ImageGenerator) validatePeerPodsConfigs() error {
617623
libvirtSecretKeys := []string{"CLOUD_PROVIDER", "LIBVIRT_URI"}
618624
// libvirt ConfigMap Keys
619625
libvirtConfigMapKeys := []string{"CLOUD_PROVIDER", "LIBVIRT_POOL", "LIBVIRT_VOL_NAME", "LIBVIRT_DIR_NAME"}
626+
// ibmcloud Secret Keys
627+
ibmcloudSecretKeys := []string{"IBMCLOUD_IAM_PROFILE_ID", "IBMCLOUD_API_KEY"}
628+
// ibmcloud ConfigMap Keys
629+
ibmcloudConfigMapKeys := []string{"CLOUD_PROVIDER"}
620630

621631
// Check for each cloud provider if respective ConfigMap keys are present in the peerPodsConfigMap
622632
switch r.provider {
@@ -665,6 +675,16 @@ func (r *ImageGenerator) validatePeerPodsConfigs() error {
665675
return fmt.Errorf("validatePeerPodsConfigs: cannot find the required keys in peer-pods-cm ConfigMap")
666676
}
667677

678+
case IBMCloudProvider:
679+
// Check if ibmcloud Secret Keys are present in the peerPodsSecret
680+
if !checkAnyKeyPresentWithValue(peerPodsSecret.Data, ibmcloudSecretKeys) {
681+
return fmt.Errorf("validatePeerPodsConfigs: cannot find the required keys in peer-pods-secret Secret")
682+
}
683+
684+
// Check if ibmcloud ConfigMap Keys are present in the peerPodsConfigMap
685+
if !checkKeysPresentAndNotEmpty(peerPodsCM.Data, ibmcloudConfigMapKeys) {
686+
return fmt.Errorf("validatePeerPodsConfigs: cannot find the required keys in peer-pods-cm ConfigMap")
687+
}
668688
default:
669689
return fmt.Errorf("validatePeerPodsConfigs: unsupported cloud provider %s", r.provider)
670690
}
@@ -680,18 +700,8 @@ func (r *ImageGenerator) validatePeerPodsConfigs() error {
680700

681701
func checkKeysPresentAndNotEmpty(data interface{}, keys []string) bool {
682702
// Convert the input map to a map[string]string
683-
var strMap map[string]string
684-
685-
switch v := data.(type) {
686-
case map[string]string:
687-
strMap = v
688-
case map[string][]byte:
689-
strMap = make(map[string]string)
690-
for key, value := range v {
691-
strMap[key] = string(value)
692-
}
693-
default:
694-
// Unsupported type
703+
strMap := toStrMap(data)
704+
if strMap == nil {
695705
return false
696706
}
697707

@@ -708,6 +718,49 @@ func checkKeysPresentAndNotEmpty(data interface{}, keys []string) bool {
708718
return true
709719
}
710720

721+
// checkAnyKeyPresentWithValue checks if any of the specified keys are present in the input map
722+
// and have non-empty string values.
723+
// It accepts a map of type map[string][]byte or map[string]string as `data`,
724+
// and a slice of keys to search for.
725+
// Returns true if any key exists in the map and its value is not an empty string.
726+
func checkAnyKeyPresentWithValue(data interface{}, keys []string) bool {
727+
// Convert the input to a map[string]string using a helper function.
728+
strMap := toStrMap(data)
729+
if strMap == nil {
730+
return false // Return false if conversion fails.
731+
}
732+
733+
// Iterate over the list of keys and check if any key exists with a non-empty value.
734+
for _, key := range keys {
735+
value, ok := strMap[key]
736+
if ok && value != "" {
737+
return true // Found a key with a non-empty value.
738+
}
739+
}
740+
741+
igLogger.Info("checkAnyKeyPresentWithValue: no key is present or has non-empty value", "searchedKeys", keys)
742+
743+
return false // No matching key with a non-empty value found.
744+
}
745+
746+
func toStrMap(data interface{}) map[string]string {
747+
var strMap map[string]string
748+
749+
switch v := data.(type) {
750+
case map[string]string:
751+
strMap = v
752+
case map[string][]byte:
753+
strMap = make(map[string]string)
754+
for key, value := range v {
755+
strMap[key] = string(value)
756+
}
757+
default:
758+
// Unsupported type
759+
return nil
760+
}
761+
return strMap
762+
}
763+
711764
func (r *ImageGenerator) getImageConfigMapName() string {
712765
return r.provider + "-podvm-image-cm"
713766
}
@@ -716,6 +769,7 @@ func (r *ImageGenerator) getImageConfigMapName() string {
716769
// azure-podvm-image-cm.yaml for Azure
717770
// aws-podvm-image-cm.yaml for AWS
718771
// libvirt-podvm-image-cm.yaml for Libvirt
772+
// ibmcloud-podvm-image-cm.yaml for IBM Cloud
719773
// Returns error if the ConfigMap creation fails
720774

721775
func (r *ImageGenerator) createImageConfigMapFromFile() error {

0 commit comments

Comments
 (0)