Search code examples
pythonbashkubernetesansiblekubespray

How do I pass the config var to python for kubespray dynamic inventory in a bash file?


So I'm trying to create a bash script to pass the IP array needed to make inventory file for ansible the official docs say that this is achieved through

declare -a IPS=(10.10.1.3 10.10.1.4 10.10.1.5)
CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}

however in a bash script CONFIG_FILE is set up as variable so it stop the inventory file being created as the variable is not passed into the python file

i have tried the following to try and pass the varible to the python file in an attempt to create the inventory file

declare -a IPS=(10.10.1.3 10.10.1.4 10.10.1.5)
CONFIG_FILE=kubespray/inventory/mycluster/hosts.yaml
python3 kubespray/contrib/inventory_builder/inventory.py ${IPS[@]}

which results in

DEBUG: Adding group all
DEBUG: Adding group kube-master
DEBUG: Adding group kube-node
DEBUG: Adding group etcd
DEBUG: Adding group k8s-cluster
DEBUG: Adding group calico-rr
DEBUG: adding host node1 to group all
DEBUG: adding host node2 to group all
DEBUG: adding host node3 to group all
DEBUG: adding host node1 to group etcd
DEBUG: adding host node2 to group etcd
DEBUG: adding host node3 to group etcd
DEBUG: adding host node1 to group kube-master
DEBUG: adding host node2 to group kube-master
DEBUG: adding host node1 to group kube-node
DEBUG: adding host node2 to group kube-node
DEBUG: adding host node3 to group kube-node
Traceback (most recent call last):
  File "kubespray/contrib/inventory_builder/inventory.py", line 431, in <module>
    sys.exit(main())
  File "kubespray/contrib/inventory_builder/inventory.py", line 427, in main
    KubesprayInventory(argv, CONFIG_FILE)
  File "kubespray/contrib/inventory_builder/inventory.py", line 116, in __init__
    self.write_config(self.config_file)
  File "kubespray/contrib/inventory_builder/inventory.py", line 120, in write_config
    with open(self.config_file, 'w') as f:
FileNotFoundError: [Errno 2] No such file or directory: './inventory/sample/hosts.yaml'

I have also tried

declare -a IPS=(10.10.1.3 10.10.1.4 10.10.1.5)
CONFIG_FILE=kubespray/inventory/mycluster/hosts.yaml
${CONFIG_FILE} python3 kubespray/contrib/inventory_builder/inventory.py ${IPS[@]}

which results in

-bash: kubespray/inventory/mycluster/hosts.yaml: No such file or directory

which is understandable but the idea is to have the file created by the python script

is is possible to get the bash script working so that it performs the actions set out by

CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}

?

UPDATE

So after some tinkering I came to the conclusion that this is probably due to my pip virtual environment as my script tries to create one before running the commands so for more context

#!/bin/bash

echo "setting up virtual environment"
sleep 2

sudo apt-get install python3-venv -y

python3 -m venv tutorial-env
source tutorial-env/bin/activate
echo "installing pip requirements"
sudo pip3 install -r kubespray/requirements.txt
cp -rfp kubespray/inventory/sample kubespray/inventory/mycluster
declare -a IPS=(IP1 IP2 IP3)
echo "${IPS[@]}"
CONFIG_FILE=kubespray/inventory/mycluster/hosts.yaml python3  kubespray/contrib/inventory_builder/inventory.py ${IPS[@]}
cat kubespray/inventory/mycluster/hosts.yaml
sudo ansible-playbook -i kubespray/inventory/mycluster/hosts.yaml --ssh-extra-args="-oStrictHostKeyChecking=no" --key-file "~/.ssh/id_rsa" --become-user="provision" kubespray/cluster.yml

if I remove the lines

python3 -m venv tutorial-env
source tutorial-env/bin/activate

Then the script works as intended, well to some degree as ideally it should be in the virtual env, apologies for the badly worded question


Solution

  • The issue comes from the sudo in your script.

    You create a virtualenv and activate it for the local session.
    But then you change to root context to install the requirements, which are installed at system-level, not virtualenv level.
    Then you execute back python in the virtualenv context without the requirements installed and it fails.

    It explains why it works without virtualenv as you use the system-level installed requirements.

    To solve the problem, just install the requirements without the sudo when you are working in the virtualenv: to install requirements and to execute ansible.