From efbfbbace85feef68e446388d211ec33dbcfcd5e Mon Sep 17 00:00:00 2001 From: Emile 'iMil' Heitor Date: Wed, 22 May 2013 16:12:09 +0200 Subject: [PATCH 01/19] Nasty loop for wheezy XenAPI location --- salt/modules/xapi.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/salt/modules/xapi.py b/salt/modules/xapi.py index 7740ef5aae..687378eb93 100644 --- a/salt/modules/xapi.py +++ b/salt/modules/xapi.py @@ -9,13 +9,26 @@ XCP is not taking precedence on Xen Source on many platforms, please keep compatibility in mind. ''' +import os import sys from contextlib import contextmanager + +import salt.utils + # This module has only been tested on Debian GNU/Linux and NetBSD, it # probably needs more path appending for other distributions. # The path to append is the path to python Xen libraries, where resides # XenAPI. -sys.path.append('/usr/lib/xen-default/lib/python') # Debian +# +# FIXME: +# Debian wheezy made it more difficult by removing /usr/lib/xen-default which +# was a link to the used version, and does not publish those modules in +# /usr/lib/pyshared, thus that nasty loop. Choose higher version by default +for xenversion in ['4.2', '4.1', '4.0']: # known to work on Debian xend XenAPI + xapipath = '/usr/lib/xen-{0}/lib/python'.format(xenversion) + if os.path.isdir(xapipath): + sys.path.append(xapipath) + break try: import xen.xm.XenAPI as XenAPI @@ -23,8 +36,6 @@ try: except ImportError: HAS_XENAPI = False -import salt.utils - def __virtual__(): if HAS_XENAPI is False: From 4a06a0b54b558ac2eb67cc0b73cea8f11656895f Mon Sep 17 00:00:00 2001 From: Emile 'iMil' Heitor Date: Wed, 22 May 2013 16:12:29 +0200 Subject: [PATCH 02/19] useless else --- salt/modules/pkgin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/modules/pkgin.py b/salt/modules/pkgin.py index 6422fd5fb3..048d92a310 100644 --- a/salt/modules/pkgin.py +++ b/salt/modules/pkgin.py @@ -28,8 +28,8 @@ def __virtual__(): if __grains__['os'] in supported and _check_pkgin(): return 'pkg' - else: - return False + + return False def _splitpkg(name): From 3c06d50dbe0833c6cd3c2ab353bcbcb2208dc01f Mon Sep 17 00:00:00 2001 From: Emile 'iMil' Heitor Date: Wed, 22 May 2013 23:23:00 +0200 Subject: [PATCH 03/19] Cleaner approach to find out XenAPI on Debian systems --- salt/modules/xapi.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/salt/modules/xapi.py b/salt/modules/xapi.py index bd2d932bb4..aa8dd508a4 100644 --- a/salt/modules/xapi.py +++ b/salt/modules/xapi.py @@ -14,21 +14,18 @@ import sys import contextlib import salt.utils - +import salt.modules.cmdmod # This module has only been tested on Debian GNU/Linux and NetBSD, it # probably needs more path appending for other distributions. # The path to append is the path to python Xen libraries, where resides # XenAPI. -# -# FIXME: -# Debian wheezy made it more difficult by removing /usr/lib/xen-default which -# was a link to the used version, and does not publish those modules in -# /usr/lib/pyshared, thus that nasty loop. Choose higher version by default -for xenversion in ['4.2', '4.1', '4.0']: # known to work on Debian xend XenAPI +debian_xen_version = '/usr/lib/xen-common/bin/xen-version' +if os.path.isfile(debian_xen_version): + xenversion = salt.modules.cmdmod._run_quiet(debian_xen_version) xapipath = '/usr/lib/xen-{0}/lib/python'.format(xenversion) if os.path.isdir(xapipath): sys.path.append(xapipath) - break + try: import xen.xm.XenAPI as XenAPI From bd5add027f54b5996d370bc5bef677c4310a2d0c Mon Sep 17 00:00:00 2001 From: Emile 'iMil' Heitor Date: Thu, 23 May 2013 18:54:47 +0200 Subject: [PATCH 04/19] Removed salt.modules.cmdmod import, use os.popen() instead as we don't have access to __salt__ here --- salt/modules/xapi.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/salt/modules/xapi.py b/salt/modules/xapi.py index aa8dd508a4..28d8159497 100644 --- a/salt/modules/xapi.py +++ b/salt/modules/xapi.py @@ -14,14 +14,13 @@ import sys import contextlib import salt.utils -import salt.modules.cmdmod # This module has only been tested on Debian GNU/Linux and NetBSD, it # probably needs more path appending for other distributions. # The path to append is the path to python Xen libraries, where resides # XenAPI. debian_xen_version = '/usr/lib/xen-common/bin/xen-version' if os.path.isfile(debian_xen_version): - xenversion = salt.modules.cmdmod._run_quiet(debian_xen_version) + xenversion = os.popen(debian_xen_version).readlines()[0].rstrip() xapipath = '/usr/lib/xen-{0}/lib/python'.format(xenversion) if os.path.isdir(xapipath): sys.path.append(xapipath) From 26342801aa8bf41f926590184dacc961fa8b2696 Mon Sep 17 00:00:00 2001 From: Emile 'iMil' Heitor Date: Sat, 25 May 2013 14:43:16 +0200 Subject: [PATCH 05/19] Got rid of os.popen() by calling a helper function from __virtual__ --- salt/modules/xapi.py | 71 +++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/salt/modules/xapi.py b/salt/modules/xapi.py index 28d8159497..6915aad1dc 100644 --- a/salt/modules/xapi.py +++ b/salt/modules/xapi.py @@ -12,31 +12,32 @@ compatibility in mind. import os import sys import contextlib +import importlib import salt.utils # This module has only been tested on Debian GNU/Linux and NetBSD, it # probably needs more path appending for other distributions. # The path to append is the path to python Xen libraries, where resides # XenAPI. -debian_xen_version = '/usr/lib/xen-common/bin/xen-version' -if os.path.isfile(debian_xen_version): - xenversion = os.popen(debian_xen_version).readlines()[0].rstrip() - xapipath = '/usr/lib/xen-{0}/lib/python'.format(xenversion) - if os.path.isdir(xapipath): - sys.path.append(xapipath) - - -try: - import xen.xm.XenAPI as XenAPI - HAS_XENAPI = True -except ImportError: - HAS_XENAPI = False +def _check_xenapi(): + if __grains__['os'] == 'Debian': + debian_xen_version = '/usr/lib/xen-common/bin/xen-version' + if os.path.isfile(debian_xen_version): + # __salt__ is not available in __virtual__ + xenversion = salt.modules.cmdmod._run_quiet(debian_xen_version) + xapipath = '/usr/lib/xen-{0}/lib/python'.format(xenversion) + if os.path.isdir(xapipath): + sys.path.append(xapipath) + try: + return importlib.import_module('xen.xm.XenAPI') + except ImportError: + return False def __virtual__(): - if HAS_XENAPI is False: - return False - return 'virt' + if _check_xenapi() is not False: + return 'virt' + return False @contextlib.contextmanager @@ -44,6 +45,8 @@ def _get_xapi_session(): ''' Get a session to XenAPI. By default, use the local UNIX socket. ''' + _xenapi = _check_xenapi() + xapi_uri = __salt__['config.option']('xapi.uri') xapi_login = __salt__['config.option']('xapi.login') xapi_password = __salt__['config.option']('xapi.password') @@ -57,7 +60,7 @@ def _get_xapi_session(): xapi_password = '' try: - session = XenAPI.Session(xapi_uri) + session = _xenapi.Session(xapi_uri) session.xenapi.login_with_password(xapi_login, xapi_password) yield session.xenapi @@ -204,7 +207,7 @@ def vm_state(vm_=None): ''' with _get_xapi_session() as xapi: info = {} - + if vm_: info[vm_] = _get_record_by_label(xapi, 'VM', vm_)['power_state'] else: @@ -228,7 +231,7 @@ def node_info(): host_cpu_rec = _get_record(xapi, 'host_cpu', host_rec['host_CPUs'][0]) # get related metrics host_metrics_rec = _get_metrics_record(xapi, 'host', host_rec) - + # adapted / cleaned up from Xen's xm def getCpuMhz(): cpu_speeds = [int(host_cpu_rec["speed"]) @@ -238,18 +241,18 @@ def node_info(): return sum(cpu_speeds) / len(cpu_speeds) else: return 0 - + def getCpuFeatures(): if len(host_cpu_rec) > 0: return host_cpu_rec['features'] - + def getFreeCpuCount(): cnt = 0 for host_cpu_it in host_cpu_rec: if len(host_cpu_rec['cpu_pool']) == 0: cnt += 1 return cnt - + info = { 'cpucores': _get_val(host_rec, ["cpu_configuration", "nr_cpus"]), @@ -292,9 +295,9 @@ def node_info(): 'xend_config_format': _get_val(host_rec, ["software_version", "xend_config_format"]) } - + return info - + def get_nics(vm_): ''' @@ -306,7 +309,7 @@ def get_nics(vm_): ''' with _get_xapi_session() as xapi: nic = {} - + vm_rec = _get_record_by_label(xapi, 'VM', vm_) if vm_rec is False: return False @@ -317,7 +320,7 @@ def get_nics(vm_): 'device': vif_rec['device'], 'mtu': vif_rec['MTU'] } - + return nic @@ -348,9 +351,9 @@ def get_disks(vm_): salt '*' virt.get_disks ''' with _get_xapi_session() as xapi: - + disk = {} - + vm_uuid = _get_label_uuid(xapi, 'VM', vm_) if vm_uuid is False: return False @@ -364,7 +367,7 @@ def get_disks(vm_): 'type': prop['device-type'], 'protocol': prop['protocol'] } - + return disk @@ -380,7 +383,7 @@ def setmem(vm_, memory): ''' with _get_xapi_session() as xapi: mem_target = int(memory) * 1024 * 1024 - + vm_uuid = _get_label_uuid(xapi, 'VM', vm_) if vm_uuid is False: return False @@ -729,9 +732,9 @@ def vm_netstats(vm_=None): ret[vif_rec['device']] = _get_metrics_record(xapi,'VIF', vif_rec) del ret[vif_rec['device']]['last_updated'] - + return ret - + info = {} if vm_: info[vm_] = _info(vm_) @@ -772,9 +775,9 @@ def vm_diskstats(vm_=None): ret[vbd_rec['device']] = _get_metrics_record(xapi, 'VBD', vbd_rec) del ret[vbd_rec['device']]['last_updated'] - + return ret - + info = {} if vm_: info[vm_] = _info(vm_) From 9cff2a03d7341bf1fde76a6d6112f4c93b401af5 Mon Sep 17 00:00:00 2001 From: Matthew Williams Date: Sat, 25 May 2013 09:39:56 -0700 Subject: [PATCH 06/19] modules/virt.py: use qemu-img to detect image type; allow emulator type (e.g., kvm, qemu) to be passed as an arg to init --- salt/modules/virt.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/salt/modules/virt.py b/salt/modules/virt.py index 084e908f39..71cce75e5e 100644 --- a/salt/modules/virt.py +++ b/salt/modules/virt.py @@ -109,13 +109,14 @@ def _get_target(target, ssh): return ' %s://%s/%s' % (proto, target, 'system') -def _gen_xml(name, cpu, mem, vda, nicp, **kwargs): +def _gen_xml(name, cpu, mem, vda, nicp, emulator, **kwargs): ''' Generate the XML string to define a libvirt vm ''' mem = mem * 1024 + print 'emulator: {}'.format(emulator) data = ''' - + %%NAME%% %%CPU%% %%MEM%% @@ -137,6 +138,7 @@ def _gen_xml(name, cpu, mem, vda, nicp, **kwargs): ''' + data = data.replace('%%EMULATOR%%', emulator) data = data.replace('%%NAME%%', name) data = data.replace('%%CPU%%', str(cpu)) data = data.replace('%%MEM%%', str(mem)) @@ -173,8 +175,8 @@ def _image_type(vda): ''' Detect what driver needs to be used for the given image ''' - out = __salt__['cmd.run']('file {0}'.format(vda)) - if 'Qcow' in out and 'Version: 2' in out: + out = __salt__['cmd.run']('qemu-img {0}'.format(vda)) + if 'qcow2' in out: return 'qcow2' else: return 'raw' @@ -188,7 +190,7 @@ def _nic_profile(nic): return __salt__['config.option']('virt.nic', {}).get(nic, default) -def init(name, cpu, mem, image, nic='default', **kwargs): +def init(name, cpu, mem, image, nic='default', emulator='kvm', **kwargs): ''' Initialize a new vm @@ -206,7 +208,7 @@ def init(name, cpu, mem, image, nic='default', **kwargs): os.makedirs(img_dir) nicp = _nic_profile(nic) salt.utils.copyfile(sfn, img_dest) - xml = _gen_xml(name, cpu, mem, img_dest, nicp, **kwargs) + xml = _gen_xml(name, cpu, mem, img_dest, nicp, emulator, **kwargs) define_xml_str(xml) if kwargs.get('seed'): __salt__['img.seed'](img_dest, name, kwargs.get('config')) From 11df856bba55f39e1d1ca8269568a7315e208f30 Mon Sep 17 00:00:00 2001 From: Niels Abspoel Date: Sat, 25 May 2013 22:27:21 +0200 Subject: [PATCH 07/19] Updated salt-git package with new features feautures: - during installation a salt system user is created - Creation of '/etc/salt/master.d/' for enhanced configuration - salt-master run under own user 'salt' - salt-user.conf created to set salt-master up for using salt system user - added logrotate config files in appropriate place - added bash-completion config files in appropriate place. - Check if salt-master/salt-minion is running when upgrading and reexec / reload daemons accordingly - Updated removal of salt package to remove 'cache' and 'log' dirs. and removal of salt system user. - Made installation more verbose to communicate what happens. --- pkg/arch/git/PKGBUILD | 88 ++++++++++++++++++++++++++++++++ pkg/arch/git/salt.install | 104 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100755 pkg/arch/git/PKGBUILD create mode 100644 pkg/arch/git/salt.install diff --git a/pkg/arch/git/PKGBUILD b/pkg/arch/git/PKGBUILD new file mode 100755 index 0000000000..7073739ced --- /dev/null +++ b/pkg/arch/git/PKGBUILD @@ -0,0 +1,88 @@ +# Maintainer: Christer Edwards +pkgname=salt-git +_gitname="salt" +pkgver=v0.15.0.786.g0a800ec +pkgrel=1 +pkgdesc="A remote execution and communication system built on zeromq" +arch=('any') +url="https://github.com/saltstack/salt" +license=('APACHE') +groups=() +depends=('python2' + 'python2-yaml' + 'python2-jinja' + 'python2-pyzmq' + 'python2-crypto' + 'python2-psutil' + 'python2-msgpack' + 'python2-m2crypto' + 'logrotate' + 'bash-completion') + +backup=('etc/salt/master' + 'etc/salt/minion') + +makedepends=('git') +conflicts=('salt') +provides=('salt' 'bash-completion-salt') +install="salt.install" + +# makepkg 4.1 knows about git and will pull main branch +source=("git://github.com/saltstack/salt.git") + +# makepkg knows it's a git repo because the url starts with 'git' +# it then knows to checkout the branch upon cloning, expediating versioning. +#branch="develop" +#source=("git://github.com/saltstack/salt.git#branch=$branch") + +# makepkg also knows about tags +#tags="v0.14.1" +#source=("git://github.com/saltstack/salt.git#tag=$tag") + +# because the sources are not static, skip checksums +md5sums=('SKIP') + +pkgver() { + cd "$srcdir/$_gitname" + echo $(git describe --always | sed 's/-/./g') + # for git, if the repo has no tags, comment out the above and uncomment the next line: + #echo "0.$(git rev-list --count $branch).$(git describe --always)" + # This will give you a count of the total commits and the hash of the commit you are on. + # Useful if you're making a repository with git packages so that they can have sequential + # version numbers. (Else a pacman -Syu may not update the package) +} + +#build() { +# cd "${srcdir}/${_gitname}" +# python2 setup.py build + # no need to build setup.py install will do this +#} + +package() { + cd "${srcdir}/${_gitname}" + + ## build salt + python2 setup.py install --root=${pkgdir}/ --optimize=1 + + ## install salt systemd service files + install -Dm644 ${srcdir}/salt/pkg/arch/salt-master.service ${pkgdir}/usr/lib/systemd/system/salt-master.service + install -Dm644 ${srcdir}/salt/pkg/arch/salt-syndic.service ${pkgdir}/usr/lib/systemd/system/salt-syndic.service + install -Dm644 ${srcdir}/salt/pkg/arch/salt-minion.service ${pkgdir}/usr/lib/systemd/system/salt-minion.service + + ## install salt config files + mkdir -p ${pkgdir}/etc/salt/master.d + mkdir -p ${pkgdir}/etc/salt/minion.d + cp ${srcdir}/salt/conf/master ${pkgdir}/etc/salt/ + cp ${srcdir}/salt/conf/minion ${pkgdir}/etc/salt/ + + ## install logrotate: + mkdir -p ${pkgdir}/etc/logrotate.d/ + install -Dm644 ${srcdir}/salt/pkg/salt-common.logrotate ${pkgdir}/etc/logrotate.d/salt + + ## install bash-completion + mkdir -p ${pkgdir}usr/share/bash-completion/completion/ + install -Dm644 ${srcdir}/salt/pkg/salt.bash ${pkgdir}usr/share/bash-completion/completion/salt + + # remove vcs leftovers + find "$pkgdir" -type d -name .git -exec rm -r '{}' + +} diff --git a/pkg/arch/git/salt.install b/pkg/arch/git/salt.install new file mode 100644 index 0000000000..2b513bdadf --- /dev/null +++ b/pkg/arch/git/salt.install @@ -0,0 +1,104 @@ +# Salt: Installer: Arch +# Maintainer: Niels Abspoel + +pre_install(){ + # create salt user + getent passwd salt &>/dev/null || \ + echo "salt master user doesn't exist, creating..."; \ + useradd -r -d /srv/salt -s /sbin/nologin -c "Salt" salt &>/dev/null || : +} + +pre_upgrade () { + pre_install + salthomedir=`getent passwd salt | cut -d: -f6` + saltdir=/srv/salt/ + if [[ $salthomedir != $saltdir ]]; then + echo "setting salt master user homedir to /srv/salt/" + usermod -d /srv/salt/ salt &>/dev/null || : + fi +} + +post_install() { + # set user permissions on directories needed for salt + getent passwd salt &>/dev/null && chown -R salt /var/cache/salt + getent passwd salt &>/dev/null && chown -R salt /var/log/salt + getent passwd salt &>/dev/null && chown -R salt /etc/salt/pki + getent passwd salt &>/dev/null && chown -R salt /srv/salt + + # set salt master user in config + # and verify environment + if [[ ! -f /etc/salt/master.d/salt-user.conf ]]; then + if [[ ! -d /etc/salt/master.d ]]; then + mkdir -p /etc/salt/master.d + fi + echo "configure salt-master to run as salt master user" + cat << EOF1 > /etc/salt/master.d/salt-user.conf +user: salt +verify_env: True +EOF1 + fi + + # set salt user limits + if [[ ! -f /etc/security/limits.d/20-salt.conf ]]; then + echo "raising file limits for salt master user" + cat << EOF2 > /etc/security/limits.d/20-salt.conf +salt soft nofile 100000 +salt hard nofile 100000 +EOF2 + fi +} + +post_upgrade () { + # if salt-master/salt-minion daemon is running reinitialise + if [[ -f /var/run/salt-master.pid ]]; then + if [ "`systemctl is-active salt-master`" == "active" ]; then + echo "salt-master is running system daemons are reloaded" + getent passwd salt &>/dev/null && systemctl daemon-reexec + getent passwd salt &>/dev/null && systemctl daemon-reload + fi + fi + if [[ -f /var/run/salt-minion.pid ]]; then + if [ "`systemctl is-active salt-minion`" == "active" ]; then + echo "salt-minion was running system daemons are reloaded" + getent passwd salt &>/dev/null && systemctl daemon-reexec + getent passwd salt &>/dev/null && systemctl daemon-reload + fi + fi +} + +pre_remove (){ + # Stop salt-master daemon and remove it + if [[ -f /var/run/salt-master.pid ]]; then + if [ "`systemctl is-active salt-master`" == "active" ]; then + echo "stopping salt-master and removing it" + systemctl stop salt-master + systemctl disable salt-master + fi + fi + + # Stop salt-minion daemon and remove it + if [[ -f /var/run/salt-minion.pid ]]; then + if [ "`systemctl is-active salt-minion`" == "active" ]; then + echo "stopping salt-minion and removing it" + systemctl stop salt-minion + systemctl disable salt-minion + fi + fi +} + +post_remove (){ + # remove shared job cache and other runtime directories + rm -rf \ + /var/cache/salt \ + /var/log/salt \ + 2> /dev/null + echo "shared job cache and runtime directories removed" + # remove salt user and group but leave /srv/salt + getent passwd salt &>/dev/null && userdel salt && echo "salt master user removed" + echo "salt has been removed but /srv/salt is still available" +} + +op=$1 +shift + +$op "$@" From a02d5488c9e692e051a8c39a4c00ee43b472c86b Mon Sep 17 00:00:00 2001 From: Emile 'iMil' Heitor Date: Sun, 26 May 2013 11:39:23 +0200 Subject: [PATCH 08/19] Added vcpu_pin: sets which CPUs a VCPU can use --- salt/modules/xapi.py | 81 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/salt/modules/xapi.py b/salt/modules/xapi.py index 6915aad1dc..cfa208d7aa 100644 --- a/salt/modules/xapi.py +++ b/salt/modules/xapi.py @@ -7,6 +7,13 @@ Xen Source, NOT XenServer nor Xen Cloud Platform. As a matter of fact it to adapt this code to XS/XCP, mostly playing with XenAPI version, but as XCP is not taking precedence on Xen Source on many platforms, please keep compatibility in mind. + +Useful documentation: + +. http://downloads.xen.org/Wiki/XenAPI/xenapi-1.0.6.pdf +. http://docs.vmd.citrix.com/XenServer/6.0.0/1.0/en_gb/api/ +. https://github.com/xen-org/xen-api/tree/master/scripts/examples/python +. http://xenbits.xen.org/gitweb/?p=xen.git;a=tree;f=tools/python/xen/xm;hb=HEAD ''' import os @@ -52,7 +59,7 @@ def _get_xapi_session(): xapi_password = __salt__['config.option']('xapi.password') if not xapi_uri: - # "old" xend method + # xend local UNIX socket xapi_uri = 'httpu:///var/run/xend/xen-api.sock' if not xapi_login: xapi_login = '' @@ -67,7 +74,7 @@ def _get_xapi_session(): except: raise CommandExecutionError('Failed to connect to XenAPI socket.') finally: - session.logout() + session.xenapi.session.logout() # Used rectypes (Record types): @@ -79,6 +86,16 @@ def _get_xapi_session(): # VBD +def _get_xtool(): + ''' + Internal, returns xl or xm command line path + ''' + for xtool in ['xl', 'xm']: + path = salt.utils.which(xtool) + if path is not None: + return path + + def _get_all(xapi, rectype): ''' Internal, returns all members of rectype @@ -416,6 +433,58 @@ def setvcpus(vm_, vcpus): return False +def vcpu_pin(vm_, vcpu, cpus): + ''' + Set which CPUs a VCPU can use. + + CLI Example:: + + salt 'foo' virt.vcpu_pin domU-id 2 1 + salt 'foo' virt.vcpu_pin domU-id 2 2-6 + ''' + with _get_xapi_session() as xapi: + + vm_uuid = _get_label_uuid(xapi, 'VM', vm_) + if vm_uuid is False: + return False + + # from xm's main + def cpu_make_map(cpulist): + cpus = [] + for c in cpulist.split(','): + if c == '': + continue + if c.find('-') != -1: + (x,y) = c.split('-') + for i in range(int(x),int(y)+1): + cpus.append(int(i)) + else: + # remove this element from the list + if c[0] == '^': + cpus = [x for x in cpus if x != int(c[1:])] + else: + cpus.append(int(c)) + cpus.sort() + return ",".join(map(str, cpus)) + + if cpus == 'all': + cpumap = cpu_make_map('0-63') + else: + cpumap = cpu_make_map('{0}'.format(cpus)) + + try: + xapi.VM.add_to_VCPUs_params_live(vm_uuid, + 'cpumap{0}'.format(vcpu), cpumap) + return True + # VM.add_to_VCPUs_params_live() implementation in xend 4.1+ has + # a bug which makes the client call fail. + # That code is accurate for all others XenAPI implementations, but + # for that particular one, fallback to xm / xl instead. + except: + return __salt__['cmd.run']('{0} vcpu-pin {1} {2} {3}'.format( + _get_xtool(), vm_, vcpu, cpus)) + + def freemem(): ''' Return an int representing the amount of memory that has not been given @@ -521,13 +590,7 @@ def create(config_): salt '*' virt.create ''' - def get_xtool(): - for xtool in ['xl', 'xm']: - path = salt.utils.which(xtool) - if path is not None: - return path - - return __salt__['cmd.run']('{0} create {1}'.format(get_xtool(), config_)) + return __salt__['cmd.run']('{0} create {1}'.format(_get_xtool(), config_)) def start(config_): ''' From 3c2e7635c0f3a20931c9e072d08c4d3db8f5526f Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Sun, 26 May 2013 22:32:43 -0500 Subject: [PATCH 09/19] npm function alias. --- salt/modules/npm.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/salt/modules/npm.py b/salt/modules/npm.py index 1dba14efe2..233dd0e605 100644 --- a/salt/modules/npm.py +++ b/salt/modules/npm.py @@ -14,6 +14,10 @@ from salt.exceptions import CommandExecutionError log = logging.getLogger(__name__) +# Function alias to make sure not to shadow built-in's +__func_alias__ = { + 'list_': 'list' +} def __virtual__(): ''' @@ -140,7 +144,7 @@ def uninstall(pkg, return True -def list(pkg=None, +def list_(pkg=None, dir=None): ''' List installed NPM packages. From f1798c842d11f7af3c5086756446a87e6912433a Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Sun, 26 May 2013 22:36:01 -0500 Subject: [PATCH 10/19] Nova built-in function alias --- salt/modules/nova.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/salt/modules/nova.py b/salt/modules/nova.py index 14cce8019f..4d17540fa7 100644 --- a/salt/modules/nova.py +++ b/salt/modules/nova.py @@ -23,6 +23,10 @@ except ImportError: # Import salt libs import salt.utils +# Function alias to not shadow built-in's +__func_alias__ = { + 'list_': 'list' +} def __virtual__(): ''' @@ -248,7 +252,7 @@ def image_meta_delete(id=None, # pylint: disable-msg=C0103 return {id: 'Deleted: {0}'.format(pairs)} -def list(): +def list_(): ''' To maintain the feel of the nova command line, this function simply calls the server_list function. From b94841ab6415b2bc668e7cbc70c08e68736d5ff2 Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Sun, 26 May 2013 22:37:03 -0500 Subject: [PATCH 11/19] Gem function alias --- salt/modules/gem.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/salt/modules/gem.py b/salt/modules/gem.py index 9328989cbf..eb15a71ae6 100644 --- a/salt/modules/gem.py +++ b/salt/modules/gem.py @@ -5,6 +5,9 @@ Manage ruby gems. # Import python libs import re +__func_alias__ = { + 'list_': 'list' +} def _gem(command, ruby=None, runas=None): cmdline = 'gem {command}'.format(command=command) @@ -117,7 +120,7 @@ def update_system(version='', ruby=None, runas=None): format(version=version), ruby, runas=runas) -def list(prefix='', ruby=None, runas=None): +def list_(prefix='', ruby=None, runas=None): ''' List locally installed gems. From 6d0e9bb058af43facd2531a0537a2012417ecc87 Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Sun, 26 May 2013 22:37:45 -0500 Subject: [PATCH 12/19] Match module function alias. --- salt/modules/match.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/salt/modules/match.py b/salt/modules/match.py index 7e4096b729..7afff7e4db 100644 --- a/salt/modules/match.py +++ b/salt/modules/match.py @@ -5,6 +5,9 @@ specs. import salt.minion +__func_alias__ = { + 'list_': 'list' +} def compound(tgt): ''' @@ -96,7 +99,7 @@ def grain(tgt): return False -def list(tgt): +def list_(tgt): ''' Return True if the minion matches the given list target From 50598514b55b35f286bf27ead23e4795513f9d13 Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Sun, 26 May 2013 22:38:22 -0500 Subject: [PATCH 13/19] nzbget function alias --- salt/modules/nzbget.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/salt/modules/nzbget.py b/salt/modules/nzbget.py index 443849bd60..1ab1ec8dca 100644 --- a/salt/modules/nzbget.py +++ b/salt/modules/nzbget.py @@ -5,6 +5,9 @@ Support for nzbget # Import salt libs import salt.utils +__func_alias__ = { + 'list_': 'list' +} def __virtual__(): ''' @@ -82,7 +85,7 @@ def stop(user=None): return out -def list(user=None): +def list_(user=None): ''' Return list of active downloads using nzbget -L. Default user is root. From a92c71939ee6c86b207d3b9c3f8d8ce9000bcb7f Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Sun, 26 May 2013 22:38:52 -0500 Subject: [PATCH 14/19] pecl function alias --- salt/modules/pecl.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/salt/modules/pecl.py b/salt/modules/pecl.py index ed9e60bbfb..8c5fc6094b 100644 --- a/salt/modules/pecl.py +++ b/salt/modules/pecl.py @@ -9,6 +9,9 @@ import re __opts__ = {} __pillar__ = {} +__func_alias__ = { + 'lits_': 'list' +} def _pecl(command): ''' @@ -66,7 +69,7 @@ def update(pecls): return _pecl('install -U {0}'.format(pecls)) -def list(): +def list_(): ''' List installed pecl extensions. From b539f9e36fb1e18550dbc7346ce5e8152913e946 Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Sun, 26 May 2013 22:39:43 -0500 Subject: [PATCH 15/19] pip function alias --- salt/modules/pip.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/salt/modules/pip.py b/salt/modules/pip.py index 0a6fdcd190..68e5014522 100644 --- a/salt/modules/pip.py +++ b/salt/modules/pip.py @@ -18,6 +18,10 @@ from salt.exceptions import CommandExecutionError, CommandNotFoundError logger = logging.getLogger(__name__) # pylint: disable-msg=C0103 +# Don't shadow built-in's. +__func_alias__ = { + 'list_': 'list' +} VALID_PROTOS = ['http', 'https', 'ftp'] @@ -526,7 +530,7 @@ def freeze(bin_env=None, return result['stdout'].splitlines() -def list(prefix='', +def list_(prefix='', bin_env=None, runas=None, cwd=None): From 6c2180628be1477456a52ca7f129f6873f148721 Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Sun, 26 May 2013 22:40:37 -0500 Subject: [PATCH 16/19] rvm function alias. --- salt/modules/rvm.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/salt/modules/rvm.py b/salt/modules/rvm.py index a8207da5a0..7844182b30 100644 --- a/salt/modules/rvm.py +++ b/salt/modules/rvm.py @@ -6,6 +6,11 @@ Manage ruby installations and gemsets with RVM, the Ruby Version Manager. import re import os +# Don't shadow built-in's. +__func_alias__ = { + 'list_': 'list' +} + __opts__ = { 'rvm.runas': None, } @@ -102,7 +107,7 @@ def reinstall_ruby(ruby, runas=None): return _rvm('reinstall', ruby, runas=runas) -def list(runas=None): +def list_(runas=None): ''' List all rvm installed rubies. From 7b831fd50059800392f8e8ea32497b854cef2a19 Mon Sep 17 00:00:00 2001 From: mguegan Date: Mon, 27 May 2013 22:37:40 +0200 Subject: [PATCH 17/19] modules/smartos_vmadm : add _gen_zone_json(**kwargs) function _gen_zone_json(**kwargs) will be needed as a template for Zone creation (aka. OS virtualization). For the moment, only the mandatory arguments are used. --- salt/modules/smartos_vmadm.py | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/salt/modules/smartos_vmadm.py b/salt/modules/smartos_vmadm.py index bdc23648af..3fb9de8aac 100644 --- a/salt/modules/smartos_vmadm.py +++ b/salt/modules/smartos_vmadm.py @@ -4,6 +4,7 @@ Module for managing VMs on SmartOS # Import Python libs import logging +import json # Import Salt libs from salt.exceptions import CommandExecutionError @@ -37,6 +38,43 @@ def _exit_status(retcode): return ret +def _gen_zone_json(**kwargs): + ''' + Generate the JSON for OS virtualization creation + + Example layout (all keys are mandatory) : + + {"brand": "joyent", + "dataset_uuid": "9eac5c0c-a941-11e2-a7dc-57a6b041988f", + "alias": "myname", + "hostname": "www.domain.com", + "max_physical_memory": 2048, + "quota": 10, + "nics": [ + { + "nic_tag": "admin", + "ip": "192.168.0.1", + "netmask": "255.255.255.0", + "gateway": "192.168.0.254" + } + ]} + ''' + ret = {} + check_args = ( + 'dataset_uuid','alias','hostname', + 'max_physical_memory','quota','nics') + # Lazy check of arguments + if not all (key in kwargs for key in check_args): + raise CommandExecutionError('Not all arguments are given') + # This one is mandatory for OS virt + ret.update(brand='joyent') + ret.update((key, kwargs[key]) + for key in verif + if key in kwargs) + + return json.dumps(ret) + + def list_vms(): ''' Return a list of virtual machine names on the minion From 7abfeb9e79d1ea83b508eaa3eec11acda42a1980 Mon Sep 17 00:00:00 2001 From: mguegan Date: Mon, 27 May 2013 22:42:32 +0200 Subject: [PATCH 18/19] modules/smartos_vmadm : Fix an incorrect variable --- salt/modules/smartos_vmadm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/modules/smartos_vmadm.py b/salt/modules/smartos_vmadm.py index 3fb9de8aac..ed0541d361 100644 --- a/salt/modules/smartos_vmadm.py +++ b/salt/modules/smartos_vmadm.py @@ -69,7 +69,7 @@ def _gen_zone_json(**kwargs): # This one is mandatory for OS virt ret.update(brand='joyent') ret.update((key, kwargs[key]) - for key in verif + for key in check_args if key in kwargs) return json.dumps(ret) From 9b36dbd72985ed4a6b25623921a80195bb785186 Mon Sep 17 00:00:00 2001 From: Robert Keizer Date: Mon, 27 May 2013 16:58:44 -0500 Subject: [PATCH 19/19] Typo. Thanks s0undt3ch. --- salt/modules/pecl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/modules/pecl.py b/salt/modules/pecl.py index 8c5fc6094b..d55465ee06 100644 --- a/salt/modules/pecl.py +++ b/salt/modules/pecl.py @@ -10,7 +10,7 @@ __opts__ = {} __pillar__ = {} __func_alias__ = { - 'lits_': 'list' + 'list_': 'list' } def _pecl(command):