Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'develop' of github.com:saltstack/salt into hotfix/pylin…

…t/C0103
  • Loading branch information...
commit cc65301cc2a507d6004a791ddb8ac8724580f067 2 parents 32171d7 + 8f04fde
@s0undt3ch s0undt3ch authored
View
4 .pylintrc
@@ -41,7 +41,7 @@ load-plugins=
# can either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once).
-#disable=
+disable=W0142
[REPORTS]
@@ -170,7 +170,7 @@ dummy-variables-rgx=_|dummy
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
-additional-builtins=__opts__,__salt__,__pillar__,__grains__,__context__
+additional-builtins=__opts__,__salt__,__pillar__,__grains__,__context__,__ret__
[SIMILARITIES]
View
1  salt/config.py
@@ -396,6 +396,7 @@ def master_config(path):
'default_include': 'master.d/*.conf',
'win_repo': '/srv/salt/win/repo',
'win_repo_mastercachefile': '/srv/salt/win/repo/winrepo.p',
+ 'win_gitrepos': ['https://github.com/UtahDave/salt-winrepo.git'],
}
if len(opts['sock_dir']) > len(opts['cachedir']) + 10:
View
4 salt/modules/ebuild.py
@@ -117,12 +117,14 @@ def list_pkgs():
def refresh_db():
'''
- Updates the portage tree (emerge --sync)
+ Updates the portage tree (emerge --sync). Uses eix-sync if available.
CLI Example::
salt '*' pkg.refresh_db
'''
+ if 'eix.sync' in __salt__:
+ return __salt__['eix.sync']()
return __salt__['cmd.retcode']('emerge --sync --quiet') == 0
View
36 salt/modules/eix.py
@@ -0,0 +1,36 @@
+'''
+Support for Eix
+
+'''
+
+import salt.utils
+
+def __virtual__():
+ '''
+ Only work on Gentoo systems with eix installed
+ '''
+ if __grains__['os'] == 'Gentoo' and salt.utils.which('eix'):
+ return 'eix'
+ return False
+
+def sync():
+ '''
+ Sync portage/overlay trees and update the eix database
+
+ CLI Example::
+
+ salt '*' eix.sync
+ '''
+ cmd = 'eix-sync -q'
+ return __salt__['cmd.retcode'](cmd) == 0
+
+def update():
+ '''
+ Update the eix database
+
+ CLI Example::
+
+ salt '*' eix.update
+ '''
+ cmd = 'eix-update --quiet'
+ return __salt__['cmd.retcode'](cmd) == 0
View
45 salt/modules/gentoolkit.py
@@ -3,6 +3,8 @@
'''
+import salt.utils
+
def __virtual__():
'''
Only work on Gentoo systems with gentoolkit installed
@@ -28,3 +30,46 @@ def revdep_rebuild(lib=None):
if lib is not None:
cmd += ' --library={0}'.format(lib)
return __salt__['cmd.retcode'](cmd) == 0
+
+def eclean_dist(destructive=False, pkg_names=False, size=None,
+ time=None, restricted=False):
+ '''
+ Clean obsolete portage sources
+
+ destructive
+ Only keep minimum for reinstallation
+
+ pkg_names
+ Protect all versions of installed packages. Only meaningful if used
+ with destructive=True
+
+ size <size>
+ Don't delete distfiles bigger than <size>.
+ <size> is a size specification: "10M" is "ten megabytes",
+ "200K" is "two hundreds kilobytes", etc. Units are: G, M, K and B.
+
+ time <time>
+ Don't delete distfiles files modified since <time>
+ <time> is an amount of time: "1y" is "one year", "2w" is
+ "two weeks", etc. Units are: y (years), m (months), w (weeks),
+ d (days) and h (hours).
+
+ restricted
+ Protect fetch-restricted files. Only meaningful if used with
+ destructive=True
+
+ CLI Example::
+ salt '*' gentoolkit.eclean_dist destructive=True
+ '''
+ cmd = 'eclean-dist --quiet'
+ if destructive:
+ cmd += ' --destructive'
+ if pkg_names:
+ cmd += ' --package-names'
+ if size is not None:
+ cmd += ' --size-limit={0}'.format(size)
+ if time is not None:
+ cmd += ' --time-limit={0}'.format(time)
+ if restricted:
+ cmd += ' --fetch-restricted'
+ return __salt__['cmd.retcode'](cmd) == 0
View
86 salt/modules/layman.py
@@ -0,0 +1,86 @@
+'''
+Support for Layman
+
+'''
+
+import salt.utils
+
+def __virtual__():
+ '''
+ Only work on Gentoo systems with layman installed
+ '''
+ if __grains__['os'] == 'Gentoo' and salt.utils.which('layman'):
+ return 'layman'
+ return False
+
+def add(overlay):
+ '''
+ Add the given overlay from the caced remote list to your locally
+ installed overlays. Specify 'ALL' to add all overlays from the
+ remote list.
+
+ Return a list of the new overlay(s) added:
+
+ CLI Example::
+
+ salt '*' layman.add <overlay name>
+ '''
+ ret = list()
+ old_overlays = list_local()
+ cmd = 'layman --quietness=0 --add {0}'.format(overlay)
+ __salt__['cmd.retcode'](cmd)
+ new_overlays = list_local()
+
+ ret = [overlay for overlay in new_overlays if overlay not in old_overlays]
+ return ret
+
+
+def delete(overlay):
+ '''
+ Remove the given overlay from the your locally installed overlays.
+ Specify 'ALL' to remove all overlays.
+
+ Return a list of the overlays(s) that were removed:
+
+ CLI Example::
+
+ salt '*' layman.delete <overlay name>
+ '''
+ ret = list()
+ old_overlays = list_local()
+ cmd = 'layman --quietness=0 --delete {0}'.format(overlay)
+ __salt__['cmd.retcode'](cmd)
+ new_overlays = list_local()
+
+ ret = [overlay for overlay in old_overlays if overlay not in new_overlays]
+ return ret
+
+def sync(overlay='ALL'):
+ '''
+ Update the specified overlay. Use 'ALL' to synchronize all overlays.
+ This is the default if no overlay is specified.
+
+ overlay
+ Name of the overlay to sync. (Defaults to 'ALL')
+
+ CLI Example::
+
+ salt '*' layman.sync
+ '''
+ cmd = 'layman --quietness=0 --sync {0}'.format(overlay)
+ return __salt__['cmd.retcode'](cmd) == 0
+
+def list_local():
+ '''
+ List the locally installed overlays.
+
+ Return a list of installed overlays:
+
+ CLI Example::
+
+ salt '*' layman.list_local
+ '''
+ cmd = 'layman --quietness=1 --list-local --nocolor'
+ out = __salt__['cmd.run'](cmd).split('\n')
+ ret = [line.split()[1] for line in out]
+ return ret
View
36 salt/modules/virt.py
@@ -23,7 +23,7 @@
# Import salt libs
import salt.utils
-from salt._compat import StringIO
+from salt._compat import StringIO as _StringIO
from salt.exceptions import CommandExecutionError
@@ -177,6 +177,7 @@ def _info(vm_):
'cputime': int(raw[4]),
'disks': get_disks(vm_),
'graphics': get_graphics(vm_),
+ 'nics': get_nics(vm_),
'maxMem': int(raw[1]),
'mem': int(raw[2]),
'state': VIRT_STATE_NAME_MAP.get(raw[0], 'unknown')}
@@ -189,19 +190,30 @@ def _info(vm_):
return info
-def vm_state(vm_):
+def vm_state(vm_=None):
'''
- Return the status of the named VM.
+ Return list of all the vms and their state.
+
+ If you pass a VM name in as an argument then it will return info
+ for just the named VM, otherwise it will return all VMs.
CLI Example::
salt '*' virt.vm_state <vm name>
'''
- state = ''
- dom = _get_dom(vm_)
- raw = dom.info()
- state = VIRT_STATE_NAME_MAP.get(raw[0], 'unknown')
- return state
+ def _info(vm_):
+ state = ''
+ dom = _get_dom(vm_)
+ raw = dom.info()
+ state = VIRT_STATE_NAME_MAP.get(raw[0], 'unknown')
+ return state
+ info = {}
+ if vm_:
+ info[vm_] = _info(vm_)
+ else:
+ for vm_ in list_vms():
+ info[vm_] = _info(vm_)
+ return info
def node_info():
@@ -234,7 +246,7 @@ def get_nics(vm_):
salt '*' virt.get_nics <vm name>
'''
nics = {}
- doc = minidom.parse(StringIO(get_xml(vm_)))
+ doc = minidom.parse(_StringIO(get_xml(vm_)))
for node in doc.getElementsByTagName("devices"):
i_nodes = node.getElementsByTagName("interface")
for i_node in i_nodes:
@@ -274,7 +286,7 @@ def get_macs(vm_):
salt '*' virt.get_macs <vm name>
'''
macs = []
- doc = minidom.parse(StringIO(get_xml(vm_)))
+ doc = minidom.parse(_StringIO(get_xml(vm_)))
for node in doc.getElementsByTagName("devices"):
i_nodes = node.getElementsByTagName("interface")
for i_node in i_nodes:
@@ -297,7 +309,7 @@ def get_graphics(vm_):
'port': 'None',
'type': 'vnc'}
xml = get_xml(vm_)
- ssock = StringIO(xml)
+ ssock = _StringIO(xml)
doc = minidom.parse(ssock)
for node in doc.getElementsByTagName("domain"):
g_nodes = node.getElementsByTagName("graphics")
@@ -316,7 +328,7 @@ def get_disks(vm_):
salt '*' virt.get_disks <vm name>
'''
disks = {}
- doc = minidom.parse(StringIO(get_xml(vm_)))
+ doc = minidom.parse(_StringIO(get_xml(vm_)))
for elem in doc.getElementsByTagName('disk'):
sources = elem.getElementsByTagName('source')
targets = elem.getElementsByTagName('target')
View
75 salt/modules/win_pkg.py
@@ -21,6 +21,7 @@
import logging
import msgpack
import salt.utils
+from distutils.version import LooseVersion
log = logging.getLogger(__name__)
@@ -53,7 +54,13 @@ def available_version(name):
salt '*' pkg.available_version <package name>
'''
- return _get_package_info(name)
+ ret = {}
+ pkginfo = _get_package_info(name)
+ if not pkginfo:
+ return ret
+ for key in _get_package_info(name):
+ ret[key] = pkginfo[key]['full_name']
+ return ret
def upgrade_available(name):
@@ -307,12 +314,22 @@ def install(name=None, refresh=False, **kwargs):
refresh_db()
old = list_pkgs()
pkginfo = _get_package_info(name)
- cached_pkg = __salt__['cp.is_cached'](pkginfo['installer'])
- if not cached_pkg:
- # It's not cached. Cache it, mate.
- cached_pkg = __salt__['cp.cache_file'](pkginfo['installer'])
+ for pkg in pkginfo.keys():
+ if pkginfo[pkg]['full_name'] in old:
+ return '{0} already installed'.format(pkginfo[pkg]['full_name'])
+ if kwargs.get('version') is not None:
+ version = kwargs['version']
+ else:
+ version = _get_latest_pkg_version(pkginfo)
+ if pkginfo[version]['installer'].startswith('salt:') or pkginfo[version]['installer'].startswith('http:') or pkginfo[version]['installer'].startswith('https:') or pkginfo[version]['installer'].startswith('ftp:'):
+ cached_pkg = __salt__['cp.is_cached'](pkginfo[version]['installer'])
+ if not cached_pkg:
+ # It's not cached. Cache it, mate.
+ cached_pkg = __salt__['cp.cache_file'](pkginfo[version]['installer'])
+ else:
+ cached_pkg = pkginfo[version]['installer']
cached_pkg = cached_pkg.replace('/', '\\')
- cmd = '"' + str(cached_pkg) + '"' + str(pkginfo['install_flags'])
+ cmd = '"' + str(cached_pkg) + '"' + str(pkginfo[version]['install_flags'])
stderr = __salt__['cmd.run_all'](cmd).get('stderr', '')
if stderr:
log.error(stderr)
@@ -337,7 +354,7 @@ def upgrade():
return {}
-def remove(name):
+def remove(name, version=None):
'''
Remove a single package
@@ -347,8 +364,27 @@ def remove(name):
salt '*' pkg.remove <package name>
'''
- log.warning('pkg.remove not implemented on Windows yet')
- return []
+ old = list_pkgs()
+ pkginfo = _get_package_info(name)
+ if not version:
+ version = _get_latest_pkg_version(pkginfo)
+
+ if pkginfo[version]['uninstaller'].startswith('salt:'):
+ cached_pkg = __salt__['cp.is_cached'](pkginfo[version]['uninstaller'])
+ if not cached_pkg:
+ # It's not cached. Cache it, mate.
+ cached_pkg = __salt__['cp.cache_file'](pkginfo[version]['uninstaller'])
+ else:
+ cached_pkg = pkginfo[version]['uninstaller']
+ cached_pkg = cached_pkg.replace('/', '\\')
+ if not os.path.exists(os.path.expandvars(cached_pkg)) and '(x86)' in cached_pkg:
+ cached_pkg = cached_pkg.replace('(x86)', '')
+ cmd = '"' + str(os.path.expandvars(cached_pkg)) + '"' + str(pkginfo[version]['uninstall_flags'])
+ stderr = __salt__['cmd.run_all'](cmd).get('stderr', '')
+ if stderr:
+ log.error(stderr)
+ new = list_pkgs()
+ return __salt__['pkg_resource.find_changes'](old, new)
def purge(name):
@@ -362,8 +398,7 @@ def purge(name):
salt '*' pkg.purge <package name>
'''
- log.warning('pkg.purge not implemented on Windows yet')
- return []
+ return remove(name)
def _get_package_info(name):
'''
@@ -388,6 +423,20 @@ def _get_package_info(name):
if name in repodata:
return repodata[name]
else:
- return name, ' is not available.'
- return name, ' is not available.'
+ return False #name, ' is not available.'
+ return False #name, ' is not available.'
+
+def _reverse_cmp_pkg_versions(pkg1, pkg2):
+ '''
+ Compare software package versions
+ '''
+ if LooseVersion(pkg1) > LooseVersion(pkg2):
+ return 1
+ else:
+ return -1
+def _get_latest_pkg_version(pkginfo):
+ if len(pkginfo) == 1:
+ return pkginfo.keys().pop()
+ pkgkeys = pkginfo.keys()
+ return sorted(pkgkeys, cmp=_reverse_cmp_pkg_versions).pop()
View
2  salt/returners/redis_return.py
@@ -45,7 +45,7 @@ def returner(ret):
serv.set('{0}:{1}'.format(ret['id'], ret['jid']), json.dumps(ret))
serv.lpush('{0}:{1}'.format(ret['id'], ret['fun']), ret['jid'])
serv.sadd('minions', ret['id'])
- serv.sadd('jids', jid)
+ serv.sadd('jids', ret['jid'])
def save_load(jid, load):
View
21 salt/runners/winrepo.py
@@ -4,6 +4,7 @@
# Import python libs
import os
+import os.path
import yaml
from pprint import pprint
import msgpack
@@ -12,6 +13,7 @@
import salt.output
import salt.utils
import logging
+import salt.minion
log = logging.getLogger(__name__)
@@ -42,3 +44,22 @@ def genrepo():
repo.write(msgpack.dumps(ret))
salt.output.display_output(ret, 'pprint', __opts__)
return ret
+
+def update_git_repos():
+ '''
+ Checkout git repos containing Windows Software Package Definitions
+ '''
+ ret = {}
+ mminion = salt.minion.MasterMinion(__opts__)
+ repo = __opts__['win_repo']
+ gitrepos = __opts__['win_gitrepos']
+ for gitrepo in gitrepos:
+ if '/' in gitrepo:
+ targetname = gitrepo.split('/')[-1]
+ else:
+ targetname = gitrepo
+ gittarget = os.path.join(repo, targetname)
+ result = mminion.states['git.latest'](gitrepo, target=gittarget, force=True)
+ ret[result['name']] = result['result']
+ salt.output.display_output(ret, 'pprint', __opts__)
+ return ret
View
12 salt/states/git.py
@@ -130,12 +130,12 @@ def latest(name,
log.debug(
'target {0} is not found, "git clone" is required'.format(
target))
-
- if __opts__['test']:
- return _neutral_test(
- ret,
- 'Repository {0} is about to be cloned to {1}'.format(
- name, target))
+ if 'test' in __opts__:
+ if __opts__['test']:
+ return _neutral_test(
+ ret,
+ 'Repository {0} is about to be cloned to {1}'.format(
+ name, target))
try:
# make the clone
__salt__['git.clone'](target, name, user=runas)
View
8 salt/utils/process.py
@@ -23,10 +23,10 @@ def set_pidfile(pidfile, user):
ofile.write(str(os.getpid()))
except IOError:
pass
- log.debug('Created pidfile: {0}'.format(pidfile))
- if 'os' in os.environ:
- if os.environ['os'].startswith('Windows'):
- return True
+
+ log.debug(('Created pidfile: {0}').format(pidfile))
+ if salt.utils.is_windows():
+ return True
import pwd # after confirming not running Windows
#import grp
Please sign in to comment.
Something went wrong with that request. Please try again.