Skip to content

Commit 451af70

Browse files
committed
Merge remote-tracking branch 'origin/k-dev' into development
2 parents 23f8f3f + 38f3d45 commit 451af70

4 files changed

Lines changed: 199 additions & 77 deletions

File tree

‎image-factory/start.sh‎

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,13 @@ if [[ ! -f "${CONFIG_PATH}" ]]; then
2828
exit 1
2929
fi
3030

31-
OS_ARCH="${2:-"$(arch)"}"
31+
if command -v arch >/dev/null 2>&1; then
32+
default_arch=$(arch)
33+
else
34+
default_arch=$(uname -m)
35+
fi
36+
37+
OS_ARCH="${2:-$default_arch}"
3238

3339
OS_VERSION="${2:-"$(jq -r '.os_image_version // "latest"' "${CONFIG_PATH}")"}"
3440

@@ -40,8 +46,22 @@ dockerlogin
4046

4147
if [[ "${VERSION}" == "build" ]]; then
4248
IMAGE_VERSION="cuos_imagebuilder"
43-
docker build -f "Dockerfile" -t "${IMAGE_VERSION}" .. \
44-
|| raise "Failed to build image"
49+
BUILD_CONTEXT="${SCRIPT_DIR}/.."
50+
if docker buildx version >/dev/null 2>&1; then
51+
echo "🔧 Using docker buildx …"
52+
docker buildx build \
53+
-f "${SCRIPT_DIR}/Dockerfile" \
54+
-t "${IMAGE_VERSION}" \
55+
"${BUILD_CONTEXT}" \
56+
|| raise "Failed to build image with buildx"
57+
else
58+
echo "⚠️ buildx not available – falling back to legacy docker build"
59+
docker build \
60+
-f "${SCRIPT_DIR}/Dockerfile" \
61+
-t "${IMAGE_VERSION}" \
62+
"${BUILD_CONTEXT}" \
63+
|| raise "Failed to build image with legacy docker"
64+
fi
4565
else
4666
IMAGE_VERSION="${UPDATE_REGISTRY}${OS_IMAGE_FACTORY}:${OS_VERSION}"
4767
docker image pull "${IMAGE_VERSION}" \

‎installer-factory/start.sh‎

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,38 @@
11
#!/bin/bash
2+
set -euo pipefail
3+
4+
raise() {
5+
echo "Error: $*" >&2
6+
exit "${2:-1}"
7+
}
28

39
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
410

511
if [[ "${1:-}" != "" ]]; then
6-
"${SCRIPT_DIR}/../image-factory/start.sh" "$@" || exit "$?"
12+
"${SCRIPT_DIR}/../image-factory/start.sh" "$@" || exit "$?"
13+
fi
14+
15+
IMAGE_NAME="minimal-installer"
16+
BUILD_CTX="${SCRIPT_DIR}"
17+
18+
if docker buildx version >/dev/null 2>&1; then
19+
echo "🔧 Buildx detected – building with BuildKit"
20+
docker buildx build \
21+
-f "${SCRIPT_DIR}/Dockerfile" \
22+
-t "${IMAGE_NAME}" \
23+
"${BUILD_CTX}" \
24+
|| raise "Buildx build failed"
25+
else
26+
echo "⚠️ Buildx not available – using legacy docker build"
27+
docker build \
28+
-f "${SCRIPT_DIR}/Dockerfile" \
29+
-t "${IMAGE_NAME}" \
30+
"${BUILD_CTX}" \
31+
|| raise "Legacy docker build failed"
732
fi
833

9-
docker build -t minimal-installer . || exit "$?"
1034
docker run --rm \
1135
-v "${SCRIPT_DIR}/../output/:/output/" \
1236
minimal-installer || exit "$?"
1337

1438
echo "ISO created at ../output/installer.iso"
15-

‎system/build.sh‎

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
#!/bin/bash
2+
set -euo pipefail
23

3-
IMAGE="cuos-system"
4-
docker build -t "${IMAGE}" .
4+
raise() {
5+
echo "Error: $*" >&2
6+
exit 1
7+
}
8+
9+
IMAGE="${IMAGE:-cuos-system}"
10+
BUILD_CONTEXT="${BUILD_CONTEXT:-.}"
11+
12+
if docker buildx version >/dev/null 2>&1; then
13+
echo "🔧 Buildx detected – building with BuildKit"
14+
docker buildx build \
15+
-t "${IMAGE}" \
16+
"${BUILD_CONTEXT}" \
17+
|| raise "Buildx build failed"
18+
else
19+
echo "⚠️ Buildx not available – falling back to legacy docker build"
20+
docker build \
21+
-t "${IMAGE}" \
22+
"${BUILD_CONTEXT}" \
23+
|| raise "Legacy docker build failed"
24+
fi

‎system/cuos/init.sh‎

Lines changed: 128 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -209,20 +209,75 @@ configure_network() {
209209
# For lxc the network is configured from outside
210210
return
211211
fi
212+
212213
# Gather all non-lo, non-docker0 interfaces and sort them alphabetically
213214
shopt -s nullglob
214-
local interfaces=()
215+
declare -a interfaces=()
216+
declare -A interfaces_mac=()
217+
215218
# only ethernet interfaces, so not lo, docker0, wlan, bonds, br, veth, etc.
216219
for interface in /sys/class/net/e*; do
217220
local name
218221
name="$(basename "$interface")"
219222
interfaces+=("$name")
223+
if [[ -r "$interface/address" ]]; then
224+
mac=$(<"$interface/address")
225+
interfaces_mac["$name"]=$(echo "$mac" | tr '[:upper:]' '[:lower:]')
226+
else
227+
interfaces_mac["$name"]=""
228+
fi
220229
done
221230

222231
# Read network config array from system.json using jq_config
223232
local configs_length
224233
configs_length="$(jq_config '.network | length')"
225234

235+
declare -A used_json=() # json_index → 1 when already assigned
236+
declare -A iface_to_json=() # interface name → json_index
237+
declare -a remaining_json=() # indices that are still free (preserve order)
238+
declare -a pending_ifaces=() # interfaces that did NOT match name/MAC
239+
240+
for ((i=0; i<${#interfaces[@]}; i++)); do
241+
local iface="${interfaces[$i]}"
242+
local match_idx=-1
243+
244+
for ((j=0; j<configs_length; j++)); do
245+
(( used_json[$j] )) && continue # already taken
246+
247+
local entry entry_name entry_mac
248+
entry=$(jq_config -r ".network[$j]")
249+
entry_name=$(echo "$entry" | jq -r '.name // empty')
250+
entry_mac=$(echo "$entry" | jq -r '."mac-address" // empty' | tr '[:upper:]' '[:lower:]')
251+
252+
if [[ -n "$entry_name" && "$entry_name" == "$iface" ]]; then
253+
match_idx=$j; break
254+
elif [[ -n "$entry_mac" && "$entry_mac" == "${interfaces_mac[$iface]}" ]]; then
255+
match_idx=$j; break
256+
fi
257+
done
258+
259+
if (( match_idx != -1 )); then
260+
used_json[$match_idx]=1
261+
# store the association for later stanza generation
262+
iface_to_json["$iface"]=$match_idx
263+
else
264+
# remember that this iface still needs a config (positional fallback)
265+
pending_ifaces+=("$iface")
266+
fi
267+
done
268+
269+
# collect the indices that were not used
270+
for ((j=0; j<configs_length; j++)); do
271+
(( used_json[$j] )) || remaining_json+=("$j")
272+
done
273+
274+
# assign them in order
275+
for ((k=0; k<${#pending_ifaces[@]}; k++)); do
276+
local iface="${pending_ifaces[$k]}"
277+
local idx="${remaining_json[$k]:-}" # may be empty if JSON shorter
278+
(( idx != "" )) && iface_to_json["$iface"]=$idx
279+
done
280+
226281
{
227282
echo "auto lo"
228283
echo "iface lo inet loopback"
@@ -231,88 +286,92 @@ configure_network() {
231286
# Configure each interface with corresponding config if present
232287
for ((i=0; i<${#interfaces[@]}; i++)); do
233288
local IFACE="${interfaces[$i]}"
234-
local METRIC
235-
METRIC=$((100 * (i+1)))
236-
if [ "$i" -lt "$configs_length" ]; then
237-
# Extract config for this interface
238-
local config
239-
config=$(jq_config -r ".network[$i]")
240-
local DHCP
241-
DHCP=$(echo "$config" | jq -r '.dhcp // empty')
242-
local IP
243-
IP=$(echo "$config" | jq -r '."ip-address" // empty')
244-
local MASK
245-
MASK=$(echo "$config" | jq -r '."network-mask" // empty')
246-
local GW
247-
GW=$(echo "$config" | jq -r '.gateway // empty')
248-
local DNS
249-
DNS=$(echo "$config" | jq -r '
250-
if (."dns-server" | type == "array") then
251-
."dns-server" | join(" ")
252-
else
253-
."dns-server" // empty
254-
end')
255-
local NTP
256-
NTP=$(echo "$config" | jq -r '
257-
if (."ntp-server" | type == "array") then
258-
."ntp-server" | join(" ")
259-
else
260-
."ntp-server" // empty
261-
end')
262-
if [ -z "$DHCP" ] && [ -z "$IP" ] && [ -z "$MASK" ]; then
263-
# No config for this interface, skip it
264-
echo "iface $IFACE inet manual"
265-
echo
266-
continue
267-
fi
268-
if [ "$DHCP" = "true" ]; then
269-
# DHCP configuration with metric
289+
local METRIC=$((100 * (i+1)))
290+
291+
local json_idx="${iface_to_json[$iface]:-}"
292+
293+
# No JSON entry at all → original defaults (first iface DHCP, rest manual)
294+
if [[ -z "$json_idx" ]]; then
295+
if [[ "$IFACE" == "${interfaces[0]}" ]]; then
270296
echo "auto $IFACE"
271297
echo "iface $IFACE inet dhcp"
272298
echo " metric $METRIC"
273299
echo
274300
else
275-
# Static configuration
276-
echo "auto $IFACE"
277-
echo "iface $IFACE inet static"
278-
[ -n "$IP" ] && echo " address $IP"
279-
[ -n "$MASK" ] && echo " netmask $MASK"
280-
[ -n "$GW" ] && echo " gateway $GW"
281-
[ -n "$DNS" ] && echo " dns-nameservers $DNS"
282-
[ -n "$NTP" ] && echo " ntp-servers $NTP"
301+
echo "iface $IFACE inet manual"
283302
echo
284303
fi
285-
# Static routes
286-
if echo "$config" | jq -e 'has("routes")' >/dev/null 2>&1; then
287-
echo "$config" | jq -r '
288-
.routes // empty |
289-
(if type=="array" then .[] else . end) |
290-
(.network // "") as $d |
291-
(.gateway // "") as $g |
292-
(.netmask // "") as $m |
293-
[$d, $g, $m] | @tsv' |
294-
while IFS=$'\t' read -r RDEST RGW RMASK; do
295-
if [ -z "$RDEST" ] || [ -z "$RGW" ]; then
296-
echo "IGNORE: invalid route with empty destination or gateway" >&2
297-
continue
298-
fi
299-
PREFIX=$(mask_to_prefix "$RMASK")
300-
RDEST="$RDEST${PREFIX:+"/$PREFIX"}"
301-
echo " up ip route add $RDEST via $RGW dev $IFACE"
302-
echo " down ip route del $RDEST via $RGW dev $IFACE"
303-
done
304-
fi
305-
elif [ "$i" -eq 0 ]; then
306-
# No config for the first interface, set to DHCP with metric
304+
continue
305+
fi
306+
307+
# Extract config for this interface
308+
local config
309+
config=$(jq_config -r ".network[$json_idx]")
310+
local DHCP
311+
DHCP=$(echo "$config" | jq -r '.dhcp // empty')
312+
local IP
313+
IP=$(echo "$config" | jq -r '."ip-address" // empty')
314+
local MASK
315+
MASK=$(echo "$config" | jq -r '."network-mask" // empty')
316+
local GW
317+
GW=$(echo "$config" | jq -r '.gateway // empty')
318+
local DNS
319+
DNS=$(echo "$config" | jq -r '
320+
if (."dns-server" | type == "array") then
321+
."dns-server" | join(" ")
322+
else
323+
."dns-server" // empty
324+
end')
325+
local NTP
326+
NTP=$(echo "$config" | jq -r '
327+
if (."ntp-server" | type == "array") then
328+
."ntp-server" | join(" ")
329+
else
330+
."ntp-server" // empty
331+
end')
332+
if [ -z "$DHCP" ] && [ -z "$IP" ] && [ -z "$MASK" ]; then
333+
# No config for this interface, skip it
334+
echo "iface $IFACE inet manual"
335+
echo
336+
continue
337+
fi
338+
if [ "$DHCP" = "true" ]; then
339+
# DHCP configuration with metric
307340
echo "auto $IFACE"
308341
echo "iface $IFACE inet dhcp"
309342
echo " metric $METRIC"
310343
echo
311344
else
312-
# No config for this interface, set to manual
313-
echo "iface $IFACE inet manual"
345+
# Static configuration
346+
echo "auto $IFACE"
347+
echo "iface $IFACE inet static"
348+
[ -n "$IP" ] && echo " address $IP"
349+
[ -n "$MASK" ] && echo " netmask $MASK"
350+
[ -n "$GW" ] && echo " gateway $GW"
351+
[ -n "$DNS" ] && echo " dns-nameservers $DNS"
352+
[ -n "$NTP" ] && echo " ntp-servers $NTP"
314353
echo
315354
fi
355+
# Static routes
356+
if echo "$config" | jq -e 'has("routes")' >/dev/null 2>&1; then
357+
echo "$config" | jq -r '
358+
.routes // empty |
359+
(if type=="array" then .[] else . end) |
360+
(.network // "") as $d |
361+
(.gateway // "") as $g |
362+
(.netmask // "") as $m |
363+
[$d, $g, $m] | @tsv' |
364+
while IFS=$'\t' read -r RDEST RGW RMASK; do
365+
if [ -z "$RDEST" ] || [ -z "$RGW" ]; then
366+
echo "IGNORE: invalid route with empty destination or gateway" >&2
367+
continue
368+
fi
369+
PREFIX=$(mask_to_prefix "$RMASK")
370+
RDEST="$RDEST${PREFIX:+"/$PREFIX"}"
371+
echo " up ip route add $RDEST via $RGW dev $IFACE"
372+
echo " down ip route del $RDEST via $RGW dev $IFACE"
373+
done
374+
fi
316375
done
317376
} > "${interfaces_file}.new"
318377

0 commit comments

Comments
 (0)