2

I get the following error when i run the following code.

Version info:

Python 3.6.5 (default, May 11 2018, 04:00:52) [GCC 8.1.0] on linux

Code:

Proper format at https://gist.github.com/Drunkenpanda2000/31f76521ce1166b804a539f40ec21c60

#!/usr/bin/env python

import subprocess

#will be replaced with inputs from Chef

name='test' 
vcpus=1 
memory=2048 
iso='/var/lib/libvirt/images/Centos.iso' 
discsize= 80 
os_type='linux' 
os_variant='centos7' 
network_bridge='default'

#setting up the command

args = (
    'virt-install' + 
    ' --name=' + name + 
    ' --vcpus=' + vcpus + 
    ' --memory=' + memory + 
    ' --cdrom=' + iso + 
    ' --disk size=' + discsize + 
    ' --os-type=' + os_type + 
    ' --os-varient=' + os_variant +
    ' --network bridge=' + network_bridge +
    " --extra-args 'console=ttyS0,115200n8 serial'" )

#execute the commands in bash

subprocess.call(args, shell=True)

Error

[drunkenpanda@Diablo Scripts]$ ./createvm.py  Traceback (most recent call last):   File "./createvm.py", line 27, in <module>
    ' --network bridge=' + network_bridge + TypeError: must be str, not int

New code

    args = ['virt-install',
    ' --name',name,
    ' --vcpus',str(vcpus),
    ' --memory',str(memory),
    ' --cdrom',iso,
    ' --disk-size',str(discsize),
    ' --os-variant',os_variant,
    ' --os-type',os_type,
    ' --network bridge',network_bridge]


    # " --extra-args 'console=ttyS0,115200n8 serial'"\


#execute the commands in bash

subprocess.call(args, shell=False)

New error

./createvmattend.1.py 
usage: virt-install --name NAME --memory MB STORAGE INSTALL [options]
virt-install: error: unrecognized arguments:  --name bob  --vcpus 1  --memory 2048  --cdrom /var/lib/libvirt/images/Centos.iso  --disk-size 80  --os-variant centos7.0  --os-type linux  --network bridge virbr0
Nic Tanghe
  • 39
  • 8
  • Probably want `--os-variant` instead of `--os-varient`, too. – Ry- Jun 05 '18 at 21:15
  • 1
    When concatenating strings, you cannot mix in integers. replace any integer with its stringyfied version: `str(vcpus)`,`str(memory)`,`str(discsize)`. Look into Literal String Interpolation [PEP-498](https://www.python.org/dev/peps/pep-0498/) if you are on 3.6 and into [`.format()`](https://docs.python.org/3.4/library/functions.html#format) if not yet on 3.6 for better ways of string formatting. – Patrick Artner Jun 05 '18 at 21:28
  • @Ry- did'T look for the dupe, my bad. – Patrick Artner Jun 05 '18 at 21:28
  • @PatrickArtner: No problem, question-specific answers are usually helpful too (although maybe the right question-specific answer is to avoid `shell=True`, @NicTanghe – you can pass a list of arguments) – Ry- Jun 05 '18 at 21:37
  • In the specific case of a command line for use with `subprocess.call()`, the correct answer is *none of the above*: instead of building up one long string you should pass a list of strings for each argument, so you can avoid `shell=True` which is a security bug. – Daniel Pryden Jun 05 '18 at 22:01
  • Ok i have been looking at examples of what you are saying but i do not see the logic in how the code is build when passing a list of arguments, how whould you pas 2 commands with diferent arguments ? could someone give me the example with my code as an example? – Nic Tanghe Jun 07 '18 at 14:23
  • If i sum up my arguments in a list and replace with shell=false ,i get the following error. ./createvmattend.1.py usage: virt-install --name NAME --memory MB STORAGE INSTALL [options] virt-install: error: unrecognized arguments: --name bob --vcpus 1 --memory 2048 --cdrom /var/lib/libvirt/images/Centos.iso --disk size 80 --os-variant centos7.0 --os-type linux --network bridge virbr0 – Nic Tanghe Jun 07 '18 at 14:45
  • the `--disk size=` looks fishy, you shouldnt have spaces in command line params. – Patrick Artner Jun 07 '18 at 16:08
  • Ok i changed the disk size= and it diden't fix anything i'll edit the original post to include the new code. – Nic Tanghe Jun 07 '18 at 17:49

1 Answers1

1

You can only string-concatenate strings, not integers.

Crude but should work:

args = (
    'virt-install' + 
    ' --name=' + name + 
    ' --vcpus=' + str(vcpus) +     # fix
    ' --memory=' + str(memory) +    # fix
    ' --cdrom=' + iso + 
    ' --disk size=' + str(discsize) +  # fix
    ' --os-type=' + os_type + 
    ' --os-varient=' + os_variant +
    ' --network bridge=' + network_bridge +
    " --extra-args 'console=ttyS0,115200n8 serial'" )

If you are on python 3.6 you might want to switch to Literal String Interpolation PEP-498:

someValue = 22
c = f"This text contains {someValue}"

or you can use .format()

someValue = 22
c = "This text contains {}".format(someValue) # positional replacement of {} by var
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • thank you i will test it now. I was however perticularry confuzed as it poinet to the network bridge line in particular wich does no contain a string. – Nic Tanghe Jun 06 '18 at 16:24