skip to Main Content

I need help with bash and systemctl service…

My problem is that my company requires me to automate the boot of all virtual machines running on our KVM server (CentOS), we have 5 physical hosts in total; however, I came across an issue on one of them, which I recently updated my VM versions, where my service <vmx.service> located under /etc/systemd/system does not run my ExecStart=/bin/bash -c ‘./vmx.sh -lv –start –cfg config/pod8/vmx1.conf’ bash script.

file: vmx.service
[Unit]
Description=Juniper vMX Router
Wants=network-online.target
After=network-online.target
After=libvirtd.service

[Service]
WorkingDirectory=/home/vMX-21.1R1/
Environment="PATH=/opt/rh/python27/root/usr/bin:/usr/lib64/qt3.3/bin:/usr/local/sbin:/usr/local/bin:/$

Type=oneshot
User=root
Group=root
RemainAfterExit=true

## Commands used to stop/start/restart the vMX
ExecStart=/bin/bash -c './path-python.sh'

ExecStart=/bin/bash -c './vmx.sh -lv --start --cfg config/pod8/vmx1.conf' <<<<<<<<<<<<<<<<<<<<<<<
ExecStart=/bin/bash -c './vmx.sh -lv --start --cfg config/pod8/vmx2.conf'
ExecStart=/bin/bash -c './vmx.sh -lv --start --cfg config/pod8/vr-device.conf'

[Install]
WantedBy=multi-user.target

Here is my service status:

   Loaded: loaded (/etc/systemd/system/vmx.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Mon 2021-11-29 14:04:37 AEST; 2h 4min ago
  Process: 2324 ExecStart=/bin/bash -c ./vmx.sh -lv --start --cfg config/pod8/vmx1.conf (code=exited, status=2)
  Process: 1877 ExecStart=/bin/bash -c ./path-python.sh (code=exited, status=0/SUCCESS)
 Main PID: 2324 (code=exited, status=2)

Nov 29 14:04:37 Juniper-KVM3 bash[2324]: import netifaces as ni
Nov 29 14:04:37 Juniper-KVM3 bash[2324]: ImportError: No module named netifaces
Nov 29 14:04:37 Juniper-KVM3 bash[2324]: Log file........................................../home....log
Nov 29 14:04:37 Juniper-KVM3 bash[2324]: ==================================================
Nov 29 14:04:37 Juniper-KVM3 bash[2324]:  Aborted!. 1 error(s) and 0 warning(s)
Nov 29 14:04:37 Juniper-KVM3 bash[2324]: ==================================================
Nov 29 14:04:37 Juniper-KVM3 systemd[1]: vmx.service: main process exited, code=exited, status=2...MENT
Nov 29 14:04:37 Juniper-KVM3 systemd[1]: Failed to start Juniper vMX Router.
Nov 29 14:04:37 Juniper-KVM3 systemd[1]: Unit vmx.service entered failed state.
Nov 29 14:04:37 Juniper-KVM3 systemd[1]: vmx.service failed.

I thought that the error: ImportError: No module named netifaces would be fixed by running
pip uninstall netifaces && pip install netifaces as read in this article.
However, it did not work either, Regardless, the weirdest thing is that when I run the same script in my terminal, it works:

[root@system]# ./vmx.sh -lv --stop --cfg config/pod8/vmx1.conf
[...]
==================================================
    VMX Status Verification Completed.
==================================================
Log file........................................../home/vMX-21.1R1/build/8m1/logs/vmx_1638166233.log
==================================================
    Thank you for using VMX
==================================================

I made sure that SElinux is disabled:

SELinux status:                 disabled

It is worth noting that ./path-python.sh script runs without a problem, this script allows me to change my python27 path, otherwise my VM Installation would fail, but I can certainly say that this problem has nothing to do with python itself, as the script works only when I run it within my terminal. (My Other servers works as expected using the same scripts and bash, I have no clue what is wrong).

2

Answers


  1. Chosen as BEST ANSWER

    So, after playing around with virtualenv I finally made it work! Previously, when running ./vmx.sh script, it would require the system to use Python2.7; however, every time my host would reboot, if I wanted to fully automate the boot of all of my VMs, I would require to change the PATH of Python by running manually the following command onto my terminal:

    echo 'export PATH=/opt/rh/python27/root/usr/bin:$PATH' >> /etc/profile
    PATH=/opt/rh/python27/root/usr/bin:$PATH
    export PATH
    cd /opt/rh/python27/ && . enable && pip install netifaces pyyaml 
    

    Instead of running the previous commands from a .sh script, which ended up not working for me, It was pointed out that "Python-related path tweaks, will not be available for the subsequent ExecStart commands". For that reason, I did the following:

    1. Instead of running scl enable python27 bash (which would make as default my Python Version until you logout), I decided to keep the changes by creating a script under /etc/profile.d/
    #!/bin/bash
    source scl_source enable python27
    
    1. I installed virtualenv pip install virtualenv

    2. Created a virtual environment virtualenv --python=/usr/bin/python2.7 vMX-ENV which I would use to install all my packages and scripts to install my VMs

    3. Activated my Virtual Environment source /home/vMX-ENV/bin/activate

    4. Created a Directory (vMX-*) where ./vmx.sh script will be located.

    # ls
    bin  lib  lib64  pyvenv.cfg  vMX-21.1R1 
    
    1. Inside of that Directory, I created a bash script that will be initiated by the service when on boot, I called it: pyrun.sh, this script runs the ./vmx.sh script "Credit: AKX"
    #!/bin/bash
    
    source /home/vMX-ENV/bin/activate
    ./vmx.sh -lv --start --cfg config/pod17/vmx1.conf
    # ...
    
    1. Created the vmxd.service and ExecStart=/bin/bash -c './pyrun.sh'

    By creating a virtualenv I was able to isolate my Python project by only creating a unique environment with all the needed packages and running only Python2.7 which is required to run ./vmx.sh

    After rebooting the host, here is the journalctl -u vmxd.service successful output as a result:

    Starting Juniper vMX Router...
    ==================================================
    Welcome to VMX
    ==================================================
    [...]
    

  2. The ExecStart commands are run separately, not in the same shell or somesuch.

    In other words, if

    ExecStart=/bin/bash -c './path-python.sh'
    

    sets up some Python-related path tweaks, they will not be available for the subsequent ExecStart commands.

    Instead of a script that "changes your python27 path" I would recommend you to set up a virtualenv for that Python environment with the packages you require installed in it, so you could just use that virtualenv’s interpreter in your vmx.sh. If you can’t edit vmx.sh, you could set up a script that does something like

    #!/bin/bash
    
    source /opt/myvirtualenv/bin/activate
    ./vmx.sh -lv --start --cfg config/pod8/vmx1.conf
    # ...
    

    and run that instead; the activate script ensures that virtualenv’s Python is the primary one for that shell session.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search