1
+ #! /bin/bash
2
+
3
+ set -e
4
+ set -o pipefail
5
+
6
+ SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
7
+
8
+ # AWS wrapper with region
9
+ AWS () {
10
+ if [ -z " $AWS_PROFILE " ]; then
11
+ aws --region " $AWS_REGION " " $@ "
12
+ else
13
+ aws --region " $AWS_REGION " --profile " $AWS_PROFILE " " $@ "
14
+ fi
15
+ }
16
+
17
+ checkEnvVars () {
18
+ if [ -z " $AWS_REGION " ]; then
19
+ echo " Error: AWS_REGION environment variable must be set."
20
+ exit 1
21
+ fi
22
+ }
23
+
24
+ waitForInstanceStatus () {
25
+ local instance_id=" $1 "
26
+ local target_state=" $2 "
27
+ local status=" "
28
+
29
+ echo " Waiting for instance $instance_id to reach state $target_state ..."
30
+ while true ; do
31
+ status=$( AWS ec2 describe-instances --instance-ids " $instance_id " \
32
+ --query ' Reservations[0].Instances[0].State.Name' --output text)
33
+
34
+ if [ " $status " == " $target_state " ]; then
35
+ echo " Instance reached state: $target_state "
36
+ break
37
+ elif [ " $status " == " terminated" ] || [ " $status " == " shutting-down" ]; then
38
+ if [ " $target_state " == " terminated" ] && [ " $status " == " shutting-down" ]; then
39
+ echo " Instance is shutting down, waiting for full termination..."
40
+ sleep 10
41
+ continue
42
+ elif [ " $status " != " $target_state " ]; then
43
+ echo " Instance reached terminal state '$status ' while waiting for '$target_state '"
44
+ exit 1
45
+ fi
46
+ else
47
+ echo " Current instance state: $status "
48
+ sleep 10
49
+ fi
50
+ done
51
+ }
52
+
53
+ waitForSystemStatus () {
54
+ local instance_id=" $1 "
55
+ local status=" "
56
+
57
+ echo " Waiting for instance system status checks..."
58
+ while true ; do
59
+ status=$( AWS ec2 describe-instance-status --instance-ids " $instance_id " \
60
+ --query ' InstanceStatuses[0].SystemStatus.Status' --output text)
61
+
62
+ if [ " $status " == " ok" ]; then
63
+ echo " System status checks passed"
64
+ break
65
+ elif [ " $status " == " impaired" ]; then
66
+ echo " Instance system status failed - status: $status "
67
+ exit 1
68
+ else
69
+ echo " Current system status: $status "
70
+ sleep 10
71
+ fi
72
+ done
73
+ }
74
+
75
+ waitForKairosActiveBoot () {
76
+ local public_ip=" $1 "
77
+ local key_file=" $2 "
78
+ local max_attempts=60 # 10 minutes (60 * 10 seconds)
79
+ local attempt=0
80
+ local boot_state=" "
81
+ local ssh_error=" "
82
+
83
+ echo " Waiting for Kairos to reach active_boot state..."
84
+ while [ $attempt -lt $max_attempts ]; do
85
+ # Try to get the boot state via SSH with host key checking disabled
86
+ if boot_state=$( ssh -i " $key_file " \
87
+ -o StrictHostKeyChecking=no \
88
+ -o UserKnownHostsFile=/dev/null \
89
+ -o ConnectTimeout=5 \
90
+ -o BatchMode=yes \
91
+ -o LogLevel=ERROR \
92
+ kairos@" $public_ip " \
93
+ kairos-agent state get boot 2>&1 ) ; then
94
+ # Clean the output to get just the boot state
95
+ boot_state=$( echo " $boot_state " | grep -v " WARNING" | grep -v " Offending" | grep -v " authentication" | grep -v " host key" | tr -d ' [:space:]' )
96
+ if [ " $boot_state " == " active_boot" ]; then
97
+ echo " Kairos has successfully reached active_boot state!"
98
+ return 0
99
+ else
100
+ echo " Current Kairos boot state: $boot_state "
101
+ fi
102
+ else
103
+ ssh_error=$boot_state
104
+ echo " SSH connection attempt failed. Error: $ssh_error "
105
+ fi
106
+
107
+ attempt=$(( attempt + 1 ))
108
+ sleep 10
109
+ done
110
+
111
+ echo " Timeout waiting for Kairos to reach active_boot state"
112
+ if [ -n " $ssh_error " ]; then
113
+ echo " Last SSH error: $ssh_error "
114
+ fi
115
+ return 1
116
+ }
117
+
118
+ testKairosImage () {
119
+ local ami_id=" $1 "
120
+ local instance_type=" t3.small"
121
+ local test_name=" kairos-test-$( date +%s) "
122
+ local temp_key_file=" /tmp/${test_name} .pem"
123
+
124
+ # Generate temporary SSH key pair
125
+ echo " Generating temporary SSH key pair..."
126
+ ssh-keygen -t rsa -b 2048 -f " $temp_key_file " -N " " -q
127
+
128
+ # Create a security group for testing
129
+ echo " Creating security group..."
130
+ sg_id=$( AWS ec2 create-security-group \
131
+ --group-name " $test_name " \
132
+ --description " Temporary security group for Kairos testing" \
133
+ --query ' GroupId' --output text)
134
+
135
+ # Allow SSH access for testing
136
+ AWS ec2 authorize-security-group-ingress \
137
+ --group-id " $sg_id " \
138
+ --protocol tcp \
139
+ --port 22 \
140
+ --cidr 0.0.0.0/0
141
+
142
+ # Create test userdata for Kairos with SSH key
143
+ userdata=$( cat << EOF
144
+ #cloud-config
145
+ install:
146
+ auto: true
147
+ reboot: true
148
+ device: auto
149
+ poweroff: false
150
+ users:
151
+ - name: kairos
152
+ ssh_authorized_keys:
153
+ - $( cat " ${temp_key_file} .pub" )
154
+ groups:
155
+ - admin
156
+ EOF
157
+ )
158
+
159
+ echo " Launching test instance..."
160
+ instance_id=$( AWS ec2 run-instances \
161
+ --image-id " $ami_id " \
162
+ --instance-type " $instance_type " \
163
+ --security-group-ids " $sg_id " \
164
+ --user-data " $userdata " \
165
+ --tag-specifications " ResourceType=instance,Tags=[{Key=Name,Value=$test_name }]" \
166
+ --block-device-mappings " [{\" DeviceName\" :\" /dev/xvda\" ,\" Ebs\" :{\" VolumeSize\" :40}}]" \
167
+ --query ' Instances[0].InstanceId' \
168
+ --output text)
169
+
170
+ echo " Test instance $instance_id launched"
171
+
172
+ # Wait for instance to be running
173
+ waitForInstanceStatus " $instance_id " " running"
174
+
175
+ # Wait for system status checks to pass
176
+ waitForSystemStatus " $instance_id "
177
+
178
+ # Get instance public IP
179
+ public_ip=$( AWS ec2 describe-instances --instance-ids " $instance_id " \
180
+ --query ' Reservations[0].Instances[0].PublicIpAddress' --output text)
181
+
182
+ echo " Testing Kairos installation and boot state..."
183
+ if ! waitForKairosActiveBoot " $public_ip " " $temp_key_file " ; then
184
+ echo " Failed to verify Kairos active_boot state"
185
+ AWS ec2 terminate-instances --instance-ids " $instance_id "
186
+ AWS ec2 delete-security-group --group-id " $sg_id "
187
+ rm -f " $temp_key_file " " ${temp_key_file} .pub"
188
+ exit 1
189
+ fi
190
+
191
+ # Cleanup
192
+ echo " Test successful! Cleaning up resources..."
193
+ AWS ec2 terminate-instances --instance-ids " $instance_id "
194
+
195
+ # Wait for instance termination
196
+ waitForInstanceStatus " $instance_id " " terminated"
197
+
198
+ # Delete security group
199
+ AWS ec2 delete-security-group --group-id " $sg_id "
200
+
201
+ # Remove temporary SSH key
202
+ rm -f " $temp_key_file " " ${temp_key_file} .pub"
203
+
204
+ echo " Cleanup complete"
205
+ }
206
+
207
+ main () {
208
+ if [ $# -ne 1 ]; then
209
+ echo " Error: You need to specify the AMI ID to test."
210
+ echo " Usage: $0 <ami-id>"
211
+ exit 1
212
+ fi
213
+
214
+ checkEnvVars
215
+
216
+ local ami_id=" $1 "
217
+ testKairosImage " $ami_id "
218
+ }
219
+
220
+ # Run main if script is not sourced
221
+ if [ " ${BASH_SOURCE[0]} " -ef " $0 " ]; then
222
+ main " $@ "
223
+ fi
0 commit comments