Trouble scripting container launch

Has anyone had luck making a provisioning script that pulls hostname and IP address from a csv file and looping through the file to launch containers?

Here is my rudimentary script trying to do just that, my csv file is “host-list” formatted as such

c1,192.168.0.222
c2,192.168.0.221
c3,192.168.0.220
c4,192.168.0.219
.......

My bash script:

#! /bin/bash -vx
while IFS=',' read -r name_c1 ip_c2
do
  file=v1-$ip_c2.yaml
  # cat $file
   echo "File" $file
incus launch images:debian/12/cloud "$name_c1" -p prod-mgt --config=cloud-init.network-config="$(cat $file)"

done <  host-list

Gives me this error:
Error: yaml: unmarshal errors:
line 1: cannot unmarshal !!str c2,192.... into api.InstancePut

Seems to struggle with the --config=cloud-init.network-config=“$(cat $file)” section, yet it does render and expand $file. Have used shellcheck to check syntax, but it finds no errors.

Thought I would ask, as others may do the same thing for rapid container deployment.

Thank you

incus launch reads from stdin by default so that’s likely the issue here.
Try to do incus launch ... < /dev/null to force stdin to be closed to avoid this issue.

Ah ok. Thanks for that info Stéphane.

This is a little cleaner:

#! /bin/bash
while IFS=',' read -r name_c1 ip_c2
do
    file=v1-$ip_c2.yaml

    cat >> "$file" << EOF
network:
  version: 1
  config:
    - type: physical
      name: eth0
      subnets:
        - type: static
          address: $ip_c2/24
          gateway: 192.168.0.1
          dns_nameservers:
            - 192.168.50.50
            - 192.168.0.1
          dns_search:
            - example.com
EOF
# provision containers
incus launch images:debian/12/cloud "$name_c1" -p prod-mgt --config=cloud-init.network-config="$(cat $file)" < /dev/null
done <  host-list

rm v1-*
exit

Edited…

I prefer to avoid the temporary files by putting the config inline: example here. Care is needed if you need inner double quotes, or dollar literals.

Another way might be something bash-specific, like:

( incus launch ... -c user.network-config="$(cat <&3)" -c user.user-data="$(cat <&4)" ) 3<<EOS1 4<<EOS2
version: 2
foo...
EOS1
#cloud-config
bar...
EOS2
1 Like

Thanks Brian! I was thinking I could do something like this to save on disk I/O, just needed some examples. Just what I was looking for.

Here is what is working for me:

incus launch images:$image_c4 "$name_c1" -p $prof_c3 -c cloud-init.network-config="version: 1
config:
  - type: physical
    name: eth0
    subnets:
      - type: static
        address: $ip_c2/24
        gateway: 192.168.0.1
     - type: nameserver
       address:
         - 192.168.0.1
         - 192.168.50.50
       search:
         - example.lan
" < /dev/null

Tested on several distros with no issues.

Thanks again for all the input!