mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 17:33:54 +00:00
Merge branch 'develop' of git://github.com/saltstack/salt into develop
This commit is contained in:
commit
c23c5f902a
@ -28,8 +28,8 @@ Options
|
|||||||
|
|
||||||
.. option:: -L, --list-all
|
.. option:: -L, --list-all
|
||||||
|
|
||||||
List all public keys on this salt master, both accepted and pending
|
List all public keys on this salt master: accepted, pending,
|
||||||
acceptance.
|
and rejected.
|
||||||
|
|
||||||
.. option:: -a ACCEPT, --accept=ACCEPT
|
.. option:: -a ACCEPT, --accept=ACCEPT
|
||||||
|
|
||||||
@ -39,6 +39,14 @@ Options
|
|||||||
|
|
||||||
Accepts all pending public keys.
|
Accepts all pending public keys.
|
||||||
|
|
||||||
|
.. option:: -r REJECT, --reject=REJECT
|
||||||
|
|
||||||
|
Reject the named minion public key.
|
||||||
|
|
||||||
|
.. option:: -R, --reject-all
|
||||||
|
|
||||||
|
Rejects all pending public keys.
|
||||||
|
|
||||||
.. option:: -c CONFIG, --config=CONFIG
|
.. option:: -c CONFIG, --config=CONFIG
|
||||||
|
|
||||||
The master configuration file needs to be read to determine where the salt
|
The master configuration file needs to be read to determine where the salt
|
||||||
|
@ -16,6 +16,7 @@ running and the Salt :term:`minions <minion>` point to the master.
|
|||||||
* `pyzmq`_ >= 2.1.9 — ZeroMQ Python bindings
|
* `pyzmq`_ >= 2.1.9 — ZeroMQ Python bindings
|
||||||
* `M2Crypto`_ — Python OpenSSL wrapper
|
* `M2Crypto`_ — Python OpenSSL wrapper
|
||||||
* `PyCrypto`_ — The Python cryptography toolkit
|
* `PyCrypto`_ — The Python cryptography toolkit
|
||||||
|
* `msgpack-python`_ — High-performance message interchange format
|
||||||
* `YAML`_ — Python YAML bindings
|
* `YAML`_ — Python YAML bindings
|
||||||
|
|
||||||
Optional Dependencies:
|
Optional Dependencies:
|
||||||
|
11
pkg/rpm/README.fedora
Normal file
11
pkg/rpm/README.fedora
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
These packages are *optional* dependencies for salt. By default, they are not included in the salt RPMs.
|
||||||
|
Install any of these packages to enable the functionality within salt.
|
||||||
|
|
||||||
|
MySQL-python
|
||||||
|
libvirt-python
|
||||||
|
python-mako
|
||||||
|
pymongo
|
||||||
|
python-redis / redis
|
||||||
|
|
||||||
|
A semi-canonical list of the optional salt modules can be found at
|
||||||
|
https://github.com/saltstack/salt/blob/develop/doc/conf.py#L30
|
@ -9,8 +9,8 @@
|
|||||||
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
|
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
|
||||||
|
|
||||||
Name: salt
|
Name: salt
|
||||||
Version: 0.9.4
|
Version: 0.9.6
|
||||||
Release: 6%{?dist}
|
Release: 2%{?dist}
|
||||||
Summary: A parallel remote execution system
|
Summary: A parallel remote execution system
|
||||||
|
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
@ -23,6 +23,7 @@ Source3: %{name}-minion
|
|||||||
Source4: %{name}-master.service
|
Source4: %{name}-master.service
|
||||||
Source5: %{name}-syndic.service
|
Source5: %{name}-syndic.service
|
||||||
Source6: %{name}-minion.service
|
Source6: %{name}-minion.service
|
||||||
|
Source7: README.fedora
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
|
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
@ -33,6 +34,7 @@ BuildRequires: python26-crypto
|
|||||||
BuildRequires: python26-devel
|
BuildRequires: python26-devel
|
||||||
BuildRequires: python26-PyYAML
|
BuildRequires: python26-PyYAML
|
||||||
BuildRequires: python26-m2crypto
|
BuildRequires: python26-m2crypto
|
||||||
|
BuildRequires: python26-msgpack
|
||||||
|
|
||||||
Requires: python26-crypto
|
Requires: python26-crypto
|
||||||
Requires: python26-zmq
|
Requires: python26-zmq
|
||||||
@ -40,6 +42,7 @@ Requires: python26-jinja2
|
|||||||
Requires: python26-PyYAML
|
Requires: python26-PyYAML
|
||||||
Requires: python26-m2crypto
|
Requires: python26-m2crypto
|
||||||
Requires: python26-PyXML
|
Requires: python26-PyXML
|
||||||
|
Requires: python26-msgpack
|
||||||
|
|
||||||
%else
|
%else
|
||||||
|
|
||||||
@ -48,6 +51,7 @@ BuildRequires: python-crypto
|
|||||||
BuildRequires: python-devel
|
BuildRequires: python-devel
|
||||||
BuildRequires: PyYAML
|
BuildRequires: PyYAML
|
||||||
BuildRequires: m2crypto
|
BuildRequires: m2crypto
|
||||||
|
BuildRequires: python-msgpack
|
||||||
|
|
||||||
Requires: python-crypto
|
Requires: python-crypto
|
||||||
Requires: python-zmq
|
Requires: python-zmq
|
||||||
@ -55,6 +59,7 @@ Requires: python-jinja2
|
|||||||
Requires: PyYAML
|
Requires: PyYAML
|
||||||
Requires: m2crypto
|
Requires: m2crypto
|
||||||
Requires: PyXML
|
Requires: PyXML
|
||||||
|
Requires: python-msgpack
|
||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
@ -71,7 +76,7 @@ BuildRequires: systemd-units
|
|||||||
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
Requires: MySQL-python libvirt-python yum
|
#Requires: MySQL-python libvirt-python yum
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Salt is a distributed remote execution system used to execute commands and
|
Salt is a distributed remote execution system used to execute commands and
|
||||||
@ -120,6 +125,11 @@ install -p -m 0644 %{SOURCE5} $RPM_BUILD_ROOT%{_unitdir}/
|
|||||||
install -p -m 0644 %{SOURCE6} $RPM_BUILD_ROOT%{_unitdir}/
|
install -p -m 0644 %{SOURCE6} $RPM_BUILD_ROOT%{_unitdir}/
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
install -p %{SOURCE7} .
|
||||||
|
|
||||||
|
install -p -m 0640 $RPM_BUILD_ROOT%{_sysconfdir}/salt/minion.template $RPM_BUILD_ROOT%{_sysconfdir}/salt/minion
|
||||||
|
install -p -m 0640 $RPM_BUILD_ROOT%{_sysconfdir}/salt/master.template $RPM_BUILD_ROOT%{_sysconfdir}/salt/master
|
||||||
|
|
||||||
%clean
|
%clean
|
||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
@ -129,6 +139,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%{python_sitelib}/%{name}/*
|
%{python_sitelib}/%{name}/*
|
||||||
%{python_sitelib}/%{name}-%{version}-py?.?.egg-info
|
%{python_sitelib}/%{name}-%{version}-py?.?.egg-info
|
||||||
%doc %{_mandir}/man7/salt.7.*
|
%doc %{_mandir}/man7/salt.7.*
|
||||||
|
%doc README.fedora
|
||||||
|
|
||||||
%files -n salt-minion
|
%files -n salt-minion
|
||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
@ -143,7 +154,8 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%{_unitdir}/salt-minion.service
|
%{_unitdir}/salt-minion.service
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%config(noreplace) /etc/salt/minion
|
%config(noreplace) %{_sysconfdir}/salt/minion
|
||||||
|
%config %{_sysconfdir}/salt/minion.template
|
||||||
|
|
||||||
%files -n salt-master
|
%files -n salt-master
|
||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
@ -166,7 +178,8 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%{_unitdir}/salt-master.service
|
%{_unitdir}/salt-master.service
|
||||||
%{_unitdir}/salt-syndic.service
|
%{_unitdir}/salt-syndic.service
|
||||||
%endif
|
%endif
|
||||||
%config(noreplace) /etc/salt/master
|
%config(noreplace) %{_sysconfdir}/salt/master
|
||||||
|
%config %{_sysconfdir}/salt/master.template
|
||||||
|
|
||||||
%if ! (0%{?rhel} >= 7 || 0%{?fedora} >= 15)
|
%if ! (0%{?rhel} >= 7 || 0%{?fedora} >= 15)
|
||||||
|
|
||||||
@ -242,6 +255,12 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jan 24 2012 Clint Savage <herlo1@gmail.com> - 0.9.6-2
|
||||||
|
- Added README.fedora and removed deps for optional modules
|
||||||
|
|
||||||
|
* Sat Jan 21 2012 Clint Savage <herlo1@gmail.com> - 0.9.6-1
|
||||||
|
- New upstream release
|
||||||
|
|
||||||
* Sun Jan 8 2012 Clint Savage <herlo1@gmail.com> - 0.9.4-6
|
* Sun Jan 8 2012 Clint Savage <herlo1@gmail.com> - 0.9.4-6
|
||||||
- Missed some critical elements for SysV and rpmlint cleanup
|
- Missed some critical elements for SysV and rpmlint cleanup
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
# pip requirements file for Salt
|
||||||
Jinja2
|
Jinja2
|
||||||
pyzmq
|
|
||||||
msgpack-python
|
|
||||||
M2Crypto
|
M2Crypto
|
||||||
pycrypto
|
msgpack-python
|
||||||
|
PyCrypto
|
||||||
PyYAML
|
PyYAML
|
||||||
|
pyzmq >= 2.1.9
|
||||||
|
@ -19,6 +19,22 @@ except ImportError as e:
|
|||||||
if e.message != 'No module named _msgpack':
|
if e.message != 'No module named _msgpack':
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def set_pidfile(pidfile):
|
||||||
|
'''
|
||||||
|
Save the pidfile
|
||||||
|
'''
|
||||||
|
pdir = os.path.dirname(pidfile)
|
||||||
|
if not os.path.isdir(pdir):
|
||||||
|
os.makedirs(pdir)
|
||||||
|
try:
|
||||||
|
open(pidfile, 'w+').write(str(os.getpid()))
|
||||||
|
except IOError:
|
||||||
|
err = ('Failed to commit the pid file to location {0}, please verify'
|
||||||
|
' that the location is available').format(pidfile)
|
||||||
|
log.error(err)
|
||||||
|
|
||||||
|
|
||||||
def verify_env(dirs):
|
def verify_env(dirs):
|
||||||
'''
|
'''
|
||||||
Verify that the named directories are in place and that the environment
|
Verify that the named directories are in place and that the environment
|
||||||
@ -103,6 +119,11 @@ class Master(object):
|
|||||||
'--user',
|
'--user',
|
||||||
dest='user',
|
dest='user',
|
||||||
help='Specify user to run minion')
|
help='Specify user to run minion')
|
||||||
|
parser.add_option('--pid-file',
|
||||||
|
dest='pidfile',
|
||||||
|
default='/var/run/salt-master.pid',
|
||||||
|
help=('Specify the location of the pidfile. Default'
|
||||||
|
' %default'))
|
||||||
parser.add_option('-l',
|
parser.add_option('-l',
|
||||||
'--log-level',
|
'--log-level',
|
||||||
dest='log_level',
|
dest='log_level',
|
||||||
@ -118,7 +139,8 @@ class Master(object):
|
|||||||
|
|
||||||
cli = {'daemon': options.daemon,
|
cli = {'daemon': options.daemon,
|
||||||
'config': options.config,
|
'config': options.config,
|
||||||
'user': options.user}
|
'user': options.user,
|
||||||
|
'pidfile': options.pidfile}
|
||||||
|
|
||||||
return cli
|
return cli
|
||||||
|
|
||||||
@ -128,6 +150,7 @@ class Master(object):
|
|||||||
'''
|
'''
|
||||||
verify_env([os.path.join(self.opts['pki_dir'], 'minions'),
|
verify_env([os.path.join(self.opts['pki_dir'], 'minions'),
|
||||||
os.path.join(self.opts['pki_dir'], 'minions_pre'),
|
os.path.join(self.opts['pki_dir'], 'minions_pre'),
|
||||||
|
os.path.join(self.opts['pki_dir'], 'minions_rejected'),
|
||||||
os.path.join(self.opts['cachedir'], 'jobs'),
|
os.path.join(self.opts['cachedir'], 'jobs'),
|
||||||
os.path.dirname(self.opts['log_file']),
|
os.path.dirname(self.opts['log_file']),
|
||||||
self.opts['sock_dir'],
|
self.opts['sock_dir'],
|
||||||
@ -143,6 +166,7 @@ class Master(object):
|
|||||||
# Late import so logging works correctly
|
# Late import so logging works correctly
|
||||||
if check_user(self.opts['user'], log):
|
if check_user(self.opts['user'], log):
|
||||||
import salt.master
|
import salt.master
|
||||||
|
set_pidfile(self.cli['pidfile'])
|
||||||
master = salt.master.Master(self.opts)
|
master = salt.master.Master(self.opts)
|
||||||
if self.cli['daemon']:
|
if self.cli['daemon']:
|
||||||
# Late import so logging works correctly
|
# Late import so logging works correctly
|
||||||
|
@ -447,6 +447,19 @@ class SaltKey(object):
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
help='Accept all pending keys')
|
help='Accept all pending keys')
|
||||||
|
|
||||||
|
parser.add_option('-r',
|
||||||
|
'--reject',
|
||||||
|
dest='reject',
|
||||||
|
default='',
|
||||||
|
help='Reject the specified public key')
|
||||||
|
|
||||||
|
parser.add_option('-R',
|
||||||
|
'--reject-all',
|
||||||
|
dest='reject_all',
|
||||||
|
default=False,
|
||||||
|
action='store_true',
|
||||||
|
help='Reject all pending keys')
|
||||||
|
|
||||||
parser.add_option('-p',
|
parser.add_option('-p',
|
||||||
'--print',
|
'--print',
|
||||||
dest='print_',
|
dest='print_',
|
||||||
@ -500,6 +513,8 @@ class SaltKey(object):
|
|||||||
opts['list_all'] = options.list_all
|
opts['list_all'] = options.list_all
|
||||||
opts['accept'] = options.accept
|
opts['accept'] = options.accept
|
||||||
opts['accept_all'] = options.accept_all
|
opts['accept_all'] = options.accept_all
|
||||||
|
opts['reject'] = options.reject
|
||||||
|
opts['reject_all'] = options.reject_all
|
||||||
opts['print'] = options.print_
|
opts['print'] = options.print_
|
||||||
opts['print_all'] = options.print_all
|
opts['print_all'] = options.print_all
|
||||||
opts['delete'] = options.delete
|
opts['delete'] = options.delete
|
||||||
|
@ -43,7 +43,7 @@ class Caller(object):
|
|||||||
)
|
)
|
||||||
except (TypeError, CommandExecutionError) as exc:
|
except (TypeError, CommandExecutionError) as exc:
|
||||||
msg = 'Error running \'{0}\': {1}\n'
|
msg = 'Error running \'{0}\': {1}\n'
|
||||||
sys.stderr.write(msg.format(yellow, end, fun, str(exc)))
|
sys.stderr.write(msg.format(fun, str(exc)))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
except CommandNotFoundError as exc:
|
except CommandNotFoundError as exc:
|
||||||
msg = 'Command not found in \'{0}\': {1}\n'
|
msg = 'Command not found in \'{0}\': {1}\n'
|
||||||
|
117
salt/cli/key.py
117
salt/cli/key.py
@ -28,6 +28,8 @@ class Key(object):
|
|||||||
subdir = ''
|
subdir = ''
|
||||||
if key_type == 'pre':
|
if key_type == 'pre':
|
||||||
subdir = 'minions_pre'
|
subdir = 'minions_pre'
|
||||||
|
elif key_type == 'rej':
|
||||||
|
subdir = 'minions_rejected'
|
||||||
elif key_type == 'acc':
|
elif key_type == 'acc':
|
||||||
subdir = 'minions'
|
subdir = 'minions'
|
||||||
dir_ = os.path.join(self.opts['pki_dir'], subdir)
|
dir_ = os.path.join(self.opts['pki_dir'], subdir)
|
||||||
@ -60,12 +62,21 @@ class Key(object):
|
|||||||
for key in sorted(self._keys('acc')):
|
for key in sorted(self._keys('acc')):
|
||||||
print utils.GREEN + key + utils.ENDC
|
print utils.GREEN + key + utils.ENDC
|
||||||
|
|
||||||
|
def _list_rejected(self):
|
||||||
|
'''
|
||||||
|
List the unaccepted keys
|
||||||
|
'''
|
||||||
|
print utils.LIGHT_BLUE + 'Rejected:' + utils.ENDC
|
||||||
|
for key in sorted(self._keys('rej')):
|
||||||
|
print utils.BLUE + key + utils.ENDC
|
||||||
|
|
||||||
def _list_all(self):
|
def _list_all(self):
|
||||||
'''
|
'''
|
||||||
List all keys
|
List all keys
|
||||||
'''
|
'''
|
||||||
self._list_pre()
|
self._list_pre()
|
||||||
self._list_accepted()
|
self._list_accepted()
|
||||||
|
self._list_rejected()
|
||||||
|
|
||||||
def _print_key(self, name):
|
def _print_key(self, name):
|
||||||
'''
|
'''
|
||||||
@ -88,74 +99,94 @@ class Key(object):
|
|||||||
for key in sorted(self._keys('acc', True)):
|
for key in sorted(self._keys('acc', True)):
|
||||||
print ' ' + utils.GREEN + os.path.basename(key) + utils.ENDC
|
print ' ' + utils.GREEN + os.path.basename(key) + utils.ENDC
|
||||||
print open(key, 'r').read()
|
print open(key, 'r').read()
|
||||||
|
print utils.LIGHT_BLUE + 'Rejected keys:' + utils.ENDC
|
||||||
|
for key in sorted(self._keys('pre', True)):
|
||||||
|
print ' ' + utils.BLUE + os.path.basename(key) + utils.ENDC
|
||||||
|
print open(key, 'r').read()
|
||||||
|
|
||||||
def _accept(self, key):
|
def _accept(self, key):
|
||||||
'''
|
'''
|
||||||
Accept a specified host's public key
|
Accept a specified host's public key
|
||||||
'''
|
'''
|
||||||
pre_dir = os.path.join(self.opts['pki_dir'], 'minions_pre')
|
(minions_accepted,
|
||||||
minions = os.path.join(self.opts['pki_dir'], 'minions')
|
minions_pre,
|
||||||
if not os.path.isdir(minions):
|
minions_rejected) = self._check_minions_directories()
|
||||||
err = ('The minions directory is not present, ensure that the '
|
pre = os.listdir(minions_pre)
|
||||||
'master server has been started')
|
|
||||||
sys.stderr.write(err + '\n')
|
|
||||||
sys.exit(42)
|
|
||||||
if not os.path.isdir(pre_dir):
|
|
||||||
err = ('The minions_pre directory is not present, ensure '
|
|
||||||
'that the master server has been started')
|
|
||||||
sys.stderr.write(err + '\n')
|
|
||||||
sys.exit(42)
|
|
||||||
pre = os.listdir(pre_dir)
|
|
||||||
if not pre.count(key):
|
if not pre.count(key):
|
||||||
err = ('The named host is unavailable, please accept an '
|
err = ('The named host is unavailable, please accept an '
|
||||||
'available key')
|
'available key')
|
||||||
sys.stderr.write(err + '\n')
|
sys.stderr.write(err + '\n')
|
||||||
sys.exit(43)
|
sys.exit(43)
|
||||||
shutil.move(os.path.join(pre_dir, key), os.path.join(minions, key))
|
shutil.move(os.path.join(minions_pre, key),
|
||||||
|
os.path.join(minions_accepted, key))
|
||||||
|
|
||||||
def _accept_all(self):
|
def _accept_all(self):
|
||||||
'''
|
'''
|
||||||
Accept all keys in pre
|
Accept all keys in pre
|
||||||
'''
|
'''
|
||||||
pre_dir = os.path.join(self.opts['pki_dir'], 'minions_pre')
|
(minions_accepted,
|
||||||
minions = os.path.join(self.opts['pki_dir'], 'minions')
|
minions_pre,
|
||||||
if not os.path.isdir(minions):
|
minions_rejected) = self._check_minions_directories()
|
||||||
err = ('The minions directory is not present, ensure that the '
|
for key in os.listdir(minions_pre):
|
||||||
'master server has been started')
|
|
||||||
sys.stderr.write(err + '\n')
|
|
||||||
sys.exit(42)
|
|
||||||
if not os.path.isdir(pre_dir):
|
|
||||||
err = ('The minions_pre directory is not present, ensure that the '
|
|
||||||
'master server has been started')
|
|
||||||
sys.stderr.write(err + '\n')
|
|
||||||
sys.exit(42)
|
|
||||||
for key in os.listdir(pre_dir):
|
|
||||||
self._accept(key)
|
self._accept(key)
|
||||||
|
|
||||||
def _delete_key(self):
|
def _delete_key(self):
|
||||||
'''
|
'''
|
||||||
Delete a key
|
Delete a key
|
||||||
'''
|
'''
|
||||||
pre_dir = os.path.join(self.opts['pki_dir'], 'minions_pre')
|
(minions_accepted,
|
||||||
minions = os.path.join(self.opts['pki_dir'], 'minions')
|
minions_pre,
|
||||||
if not os.path.isdir(minions):
|
minions_rejected) = self._check_minions_directories()
|
||||||
err = ('The minions directory is not present, ensure that the '
|
pre = os.path.join(minions_pre, self.opts['delete'])
|
||||||
'master server has been started')
|
acc = os.path.join(minions_accepted, self.opts['delete'])
|
||||||
sys.stderr.write(err + '\n')
|
rej= os.path.join(minions_rejected, self.opts['delete'])
|
||||||
sys.exit(42)
|
|
||||||
if not os.path.isdir(pre_dir):
|
|
||||||
err = ('The minions_pre directory is not present, ensure that the '
|
|
||||||
'master server has been started')
|
|
||||||
sys.stderr.write(err + '\n')
|
|
||||||
sys.exit(42)
|
|
||||||
pre = os.path.join(pre_dir, self.opts['delete'])
|
|
||||||
acc = os.path.join(minions, self.opts['delete'])
|
|
||||||
if os.path.exists(pre):
|
if os.path.exists(pre):
|
||||||
os.remove(pre)
|
os.remove(pre)
|
||||||
print 'Removed pending key %s' % self.opts['delete']
|
print 'Removed pending key %s' % self.opts['delete']
|
||||||
if os.path.exists(acc):
|
if os.path.exists(acc):
|
||||||
os.remove(acc)
|
os.remove(acc)
|
||||||
print 'Removed accepted key %s' % self.opts['delete']
|
print 'Removed accepted key %s' % self.opts['delete']
|
||||||
|
if os.path.exists(rej):
|
||||||
|
os.remove(rej)
|
||||||
|
print 'Removed rejected key %s' % self.opts['delete']
|
||||||
|
|
||||||
|
def _reject(self, key):
|
||||||
|
'''
|
||||||
|
Reject a specified host's public key
|
||||||
|
'''
|
||||||
|
(minions_accepted,
|
||||||
|
minions_pre,
|
||||||
|
minions_rejected) = self._check_minions_directories()
|
||||||
|
pre = os.listdir(minions_pre)
|
||||||
|
if not pre.count(key):
|
||||||
|
err = ('The named host is unavailable, please accept an '
|
||||||
|
'available key')
|
||||||
|
sys.stderr.write(err + '\n')
|
||||||
|
sys.exit(43)
|
||||||
|
shutil.move(os.path.join(minions_pre, key),
|
||||||
|
os.path.join(minions_rejected, key))
|
||||||
|
|
||||||
|
def _reject_all(self):
|
||||||
|
'''
|
||||||
|
Reject all keys in pre
|
||||||
|
'''
|
||||||
|
(minions_accepted,
|
||||||
|
minions_pre,
|
||||||
|
minions_rejected) = self._check_minions_directories()
|
||||||
|
for key in os.listdir(minions_pre):
|
||||||
|
self._reject(key)
|
||||||
|
|
||||||
|
def _check_minions_directories(self):
|
||||||
|
minions_accepted = os.path.join(self.opts['pki_dir'], 'minions')
|
||||||
|
minions_pre = os.path.join(self.opts['pki_dir'], 'minions_pre')
|
||||||
|
minions_rejected = os.path.join(self.opts['pki_dir'], 'minions_rejected')
|
||||||
|
for dir in [minions_accepted, minions_pre, minions_rejected]:
|
||||||
|
if not os.path.isdir(dir):
|
||||||
|
err = ('The minions directory {0} is not present, ensure '
|
||||||
|
'that the master server has been started'.format(dir))
|
||||||
|
sys.stderr.write(err + '\n')
|
||||||
|
sys.exit(42)
|
||||||
|
return minions_accepted, minions_pre, minions_rejected
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
'''
|
'''
|
||||||
@ -179,6 +210,10 @@ class Key(object):
|
|||||||
self._accept(self.opts['accept'])
|
self._accept(self.opts['accept'])
|
||||||
elif self.opts['accept_all']:
|
elif self.opts['accept_all']:
|
||||||
self._accept_all()
|
self._accept_all()
|
||||||
|
elif self.opts['reject']:
|
||||||
|
self._reject(self.opts['reject'])
|
||||||
|
elif self.opts['reject_all']:
|
||||||
|
self._reject_all()
|
||||||
elif self.opts['delete']:
|
elif self.opts['delete']:
|
||||||
self._delete_key()
|
self._delete_key()
|
||||||
else:
|
else:
|
||||||
|
@ -42,7 +42,7 @@ def prep_jid(opts, load):
|
|||||||
os.makedirs(jid_dir)
|
os.makedirs(jid_dir)
|
||||||
serial.dump(load, open(os.path.join(jid_dir, '.load.p'), 'w+'))
|
serial.dump(load, open(os.path.join(jid_dir, '.load.p'), 'w+'))
|
||||||
else:
|
else:
|
||||||
return prep_jid(cachedir, load)
|
return prep_jid(opts['cachedir'], load)
|
||||||
return jid
|
return jid
|
||||||
|
|
||||||
|
|
||||||
@ -646,6 +646,9 @@ class ClearFuncs(object):
|
|||||||
pubfn_pend = os.path.join(self.opts['pki_dir'],
|
pubfn_pend = os.path.join(self.opts['pki_dir'],
|
||||||
'minions_pre',
|
'minions_pre',
|
||||||
load['id'])
|
load['id'])
|
||||||
|
pubfn_rejected = os.path.join(self.opts['pki_dir'],
|
||||||
|
'minions_rejected',
|
||||||
|
load['id'])
|
||||||
if self.opts['open_mode']:
|
if self.opts['open_mode']:
|
||||||
# open mode is turned on, nuts to checks and overwrite whatever
|
# open mode is turned on, nuts to checks and overwrite whatever
|
||||||
# is there
|
# is there
|
||||||
@ -661,6 +664,12 @@ class ClearFuncs(object):
|
|||||||
ret = {'enc': 'clear',
|
ret = {'enc': 'clear',
|
||||||
'load': {'ret': False}}
|
'load': {'ret': False}}
|
||||||
return ret
|
return ret
|
||||||
|
elif os.path.isfile(pubfn_rejected):
|
||||||
|
# The key has been rejected, don't place it in pending
|
||||||
|
log.info('Public key rejected for %(id)s', load)
|
||||||
|
ret = {'enc': 'clear',
|
||||||
|
'load': {'ret': False}}
|
||||||
|
return ret
|
||||||
elif not os.path.isfile(pubfn_pend)\
|
elif not os.path.isfile(pubfn_pend)\
|
||||||
and not self.opts['auto_accept']:
|
and not self.opts['auto_accept']:
|
||||||
# This is a new key, stick it in pre
|
# This is a new key, stick it in pre
|
||||||
|
@ -208,8 +208,10 @@ class Minion(object):
|
|||||||
minion side execution.
|
minion side execution.
|
||||||
'''
|
'''
|
||||||
if self.opts['multiprocessing']:
|
if self.opts['multiprocessing']:
|
||||||
fn_ = os.path.join(self.proc_dir, str(os.getpid()))
|
fn_ = os.path.join(self.proc_dir, data['jid'])
|
||||||
open(fn_, 'w+').write(self.serial.dumps(data))
|
sdata = {'pid': os.getpid()}
|
||||||
|
sdata.update(data)
|
||||||
|
open(fn_, 'w+').write(self.serial.dumps(sdata))
|
||||||
ret = {}
|
ret = {}
|
||||||
for ind in range(0, len(data['arg'])):
|
for ind in range(0, len(data['arg'])):
|
||||||
try:
|
try:
|
||||||
@ -313,7 +315,7 @@ class Minion(object):
|
|||||||
Return the data from the executed command to the master server
|
Return the data from the executed command to the master server
|
||||||
'''
|
'''
|
||||||
if self.opts['multiprocessing']:
|
if self.opts['multiprocessing']:
|
||||||
fn_ = os.path.join(self.proc_dir, str(os.getpid()))
|
fn_ = os.path.join(self.proc_dir, ret['jid'])
|
||||||
if os.path.isfile(fn_):
|
if os.path.isfile(fn_):
|
||||||
os.remove(fn_)
|
os.remove(fn_)
|
||||||
log.info('Returning information for job: {0}'.format(ret['jid']))
|
log.info('Returning information for job: {0}'.format(ret['jid']))
|
||||||
@ -383,19 +385,10 @@ class Minion(object):
|
|||||||
Check to see if the salt refresh file has been laid down, if it has,
|
Check to see if the salt refresh file has been laid down, if it has,
|
||||||
refresh the functions and returners.
|
refresh the functions and returners.
|
||||||
'''
|
'''
|
||||||
if os.path.isfile(
|
fn_ = os.path.join(self.opts['cachedir'], 'module_refresh')
|
||||||
os.path.join(
|
if os.path.isfile(fn_):
|
||||||
self.opts['cachedir'],
|
os.remove(fn_)
|
||||||
'.module_refresh'
|
|
||||||
)
|
|
||||||
):
|
|
||||||
self.functions, self.returners = self.__load_modules()
|
self.functions, self.returners = self.__load_modules()
|
||||||
os.remove(
|
|
||||||
os.path.join(
|
|
||||||
self.opts['cachedir'],
|
|
||||||
'.module_refresh'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def tune_in(self):
|
def tune_in(self):
|
||||||
'''
|
'''
|
||||||
|
@ -10,6 +10,7 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
import salt.utils
|
import salt.utils
|
||||||
|
from salt.exceptions import CommandExecutionError
|
||||||
try:
|
try:
|
||||||
import pwd
|
import pwd
|
||||||
except:
|
except:
|
||||||
@ -19,16 +20,12 @@ except:
|
|||||||
# Set up logging
|
# Set up logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Set the default working directory to the home directory
|
|
||||||
# of the user salt-minion is running as. Default: /root
|
|
||||||
DEFAULT_CWD = os.path.expanduser('~')
|
|
||||||
|
|
||||||
# Set up the default outputters
|
# Set up the default outputters
|
||||||
__outputter__ = {
|
__outputter__ = {
|
||||||
'run': 'txt',
|
'run': 'txt',
|
||||||
}
|
}
|
||||||
def _run(cmd,
|
def _run(cmd,
|
||||||
cwd=DEFAULT_CWD,
|
cwd=None,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
quiet=False,
|
quiet=False,
|
||||||
@ -37,38 +34,49 @@ def _run(cmd,
|
|||||||
'''
|
'''
|
||||||
Do the DRY thing and only call subprocess.Popen() once
|
Do the DRY thing and only call subprocess.Popen() once
|
||||||
'''
|
'''
|
||||||
# Don't use runas in Windows
|
# Set the default working directory to the home directory
|
||||||
|
# of the user salt-minion is running as. Default: /root
|
||||||
|
if not cwd:
|
||||||
|
cwd = os.path.expanduser('~{0}'.format('' if not runas else runas))
|
||||||
|
|
||||||
|
# TODO: Figure out the proper way to do this in windows
|
||||||
disable_runas = [
|
disable_runas = [
|
||||||
'Windows',
|
'Windows',
|
||||||
]
|
]
|
||||||
|
|
||||||
ret = {}
|
ret = {}
|
||||||
|
|
||||||
if runas and __grains__['os'] not in disable_runas:
|
if runas and __grains__['os'] in disable_runas:
|
||||||
|
msg = 'Sorry, {0} does not support runas functionality'
|
||||||
|
raise CommandExecutionError(msg.format(__grains__['os']))
|
||||||
|
|
||||||
|
if runas:
|
||||||
|
# Save the original command before munging it
|
||||||
|
orig_cmd = cmd
|
||||||
try:
|
try:
|
||||||
p = pwd.getpwnam(runas)
|
p = pwd.getpwnam(runas)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
stderr_str = 'The user {0} is not available'.format(runas)
|
msg = 'User \'{0}\' is not available'.format(runas)
|
||||||
if stderr == subprocess.STDOUT:
|
raise CommandExecutionError(msg)
|
||||||
ret['stdout'] = stderr_str
|
|
||||||
else:
|
cmd_prefix = 'su'
|
||||||
ret['stdout'] = ''
|
|
||||||
ret['stderr'] = stderr_str
|
# Load the 'nix environment
|
||||||
ret['retcode'] = 1
|
|
||||||
return ret
|
|
||||||
cmd_prefix = 'su '
|
|
||||||
if with_env:
|
if with_env:
|
||||||
cmd_prefix += '- '
|
cmd_prefix += ' - '
|
||||||
|
|
||||||
cmd_prefix += runas + ' -c'
|
cmd_prefix += runas + ' -c'
|
||||||
cmd = '%s "%s"' % (cmd_prefix, cmd)
|
cmd = '{0} "{1}"'.format(cmd_prefix, cmd)
|
||||||
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
if runas and __grains__['os'] not in disable_runas:
|
# Put the most common case first
|
||||||
log.info('Executing command {0} as user {1} in directory {2}'.format(
|
if not runas:
|
||||||
cmd, runas, cwd))
|
|
||||||
else:
|
|
||||||
log.info('Executing command {0} in directory {1}'.format(cmd, cwd))
|
log.info('Executing command {0} in directory {1}'.format(cmd, cwd))
|
||||||
|
else:
|
||||||
|
log.info('Executing command {0} as user {1} in directory {2}'.format(
|
||||||
|
orig_cmd, runas, cwd))
|
||||||
|
|
||||||
|
# This is where the magic happens
|
||||||
proc = subprocess.Popen(cmd,
|
proc = subprocess.Popen(cmd,
|
||||||
cwd=cwd,
|
cwd=cwd,
|
||||||
shell=True,
|
shell=True,
|
||||||
@ -77,21 +85,21 @@ def _run(cmd,
|
|||||||
)
|
)
|
||||||
|
|
||||||
out = proc.communicate()
|
out = proc.communicate()
|
||||||
ret['stdout'] = out[0]
|
ret['stdout'] = out[0]
|
||||||
ret['stderr'] = out[1]
|
ret['stderr'] = out[1]
|
||||||
|
ret['pid'] = proc.pid
|
||||||
ret['retcode'] = proc.returncode
|
ret['retcode'] = proc.returncode
|
||||||
ret['pid'] = proc.pid
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def _run_quiet(cmd, cwd=DEFAULT_CWD, runas=None):
|
def _run_quiet(cmd, cwd=None, runas=None):
|
||||||
'''
|
'''
|
||||||
Helper for running commands quietly for minion startup
|
Helper for running commands quietly for minion startup
|
||||||
'''
|
'''
|
||||||
return _run(cmd, runas=runas, cwd=cwd, stderr=subprocess.STDOUT, quiet=True)['stdout']
|
return _run(cmd, runas=runas, cwd=cwd, stderr=subprocess.STDOUT, quiet=True)['stdout']
|
||||||
|
|
||||||
|
|
||||||
def run(cmd, cwd=DEFAULT_CWD, runas=None):
|
def run(cmd, cwd=None, runas=None):
|
||||||
'''
|
'''
|
||||||
Execute the passed command and return the output as a string
|
Execute the passed command and return the output as a string
|
||||||
|
|
||||||
@ -104,7 +112,7 @@ def run(cmd, cwd=DEFAULT_CWD, runas=None):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def run_stdout(cmd, cwd=DEFAULT_CWD, runas=None):
|
def run_stdout(cmd, cwd=None, runas=None):
|
||||||
'''
|
'''
|
||||||
Execute a command, and only return the standard out
|
Execute a command, and only return the standard out
|
||||||
|
|
||||||
@ -117,7 +125,7 @@ def run_stdout(cmd, cwd=DEFAULT_CWD, runas=None):
|
|||||||
return stdout
|
return stdout
|
||||||
|
|
||||||
|
|
||||||
def run_stderr(cmd, cwd=DEFAULT_CWD, runas=None):
|
def run_stderr(cmd, cwd=None, runas=None):
|
||||||
'''
|
'''
|
||||||
Execute a command and only return the standard error
|
Execute a command and only return the standard error
|
||||||
|
|
||||||
@ -130,7 +138,7 @@ def run_stderr(cmd, cwd=DEFAULT_CWD, runas=None):
|
|||||||
return stderr
|
return stderr
|
||||||
|
|
||||||
|
|
||||||
def run_all(cmd, cwd=DEFAULT_CWD, runas=None):
|
def run_all(cmd, cwd=None, runas=None):
|
||||||
'''
|
'''
|
||||||
Execute the passed command and return a dict of return data
|
Execute the passed command and return a dict of return data
|
||||||
|
|
||||||
@ -150,7 +158,7 @@ def run_all(cmd, cwd=DEFAULT_CWD, runas=None):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def retcode(cmd, cwd=DEFAULT_CWD, runas=None):
|
def retcode(cmd, cwd=None, runas=None):
|
||||||
'''
|
'''
|
||||||
Execute a shell command and return the command's return code.
|
Execute a shell command and return the command's return code.
|
||||||
|
|
||||||
@ -181,7 +189,7 @@ def which(cmd):
|
|||||||
'''
|
'''
|
||||||
return salt.utils.which(cmd)
|
return salt.utils.which(cmd)
|
||||||
|
|
||||||
def exec_code(lang, code, cwd=DEFAULT_CWD):
|
def exec_code(lang, code, cwd=None):
|
||||||
'''
|
'''
|
||||||
Pass in two strings, the first naming the executable language, aka -
|
Pass in two strings, the first naming the executable language, aka -
|
||||||
python2, python3, ruby, perl, lua, etc. the second string containing
|
python2, python3, ruby, perl, lua, etc. the second string containing
|
||||||
|
@ -19,30 +19,47 @@ def _check_puppet():
|
|||||||
return __salt__['cmd.has_exec']('puppetd')
|
return __salt__['cmd.has_exec']('puppetd')
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run(tags=None):
|
||||||
'''
|
'''
|
||||||
Execute a puppet run and return a dict with the stderr,stdout,return code
|
Execute a puppet run and return a dict with the stderr, stdout,
|
||||||
etc.
|
return code, etc. If an argument is specified, it is treated as
|
||||||
|
a comma separated list of tags passed to puppetd --test --tags:
|
||||||
|
http://projects.puppetlabs.com/projects/1/wiki/Using_Tags
|
||||||
|
|
||||||
CLI Example::
|
CLI Examples::
|
||||||
|
|
||||||
salt '*' puppet.run
|
salt '*' puppet.run
|
||||||
'''
|
|
||||||
if _check_puppet():
|
|
||||||
return __salt__['cmd.run_all']('puppetd --test')
|
|
||||||
else:
|
|
||||||
raise CommandNotFoundError("puppetd not available")
|
|
||||||
|
|
||||||
def noop():
|
salt '*' puppet.run basefiles::edit,apache::server
|
||||||
'''
|
'''
|
||||||
Execute a puppet noop run and return a dict with the stderr,stdout,return code
|
if not tags:
|
||||||
etc.
|
cmd = 'puppetd --test'
|
||||||
|
else:
|
||||||
|
cmd = 'puppetd --test --tags "{0}"'.format(tags)
|
||||||
|
|
||||||
|
if _check_puppet():
|
||||||
|
return __salt__['cmd.run_all'](cmd)
|
||||||
|
else:
|
||||||
|
raise CommandNotFoundError('puppetd not available')
|
||||||
|
|
||||||
|
def noop(tags=None):
|
||||||
|
'''
|
||||||
|
Execute a puppet noop run and return a dict with the stderr, stdout,
|
||||||
|
return code, etc. If an argument is specified, it is treated as a
|
||||||
|
comma separated list of tags passed to puppetd --test --noop --tags
|
||||||
|
|
||||||
CLI Example::
|
CLI Example::
|
||||||
|
|
||||||
salt '*' puppet.noop
|
salt '*' puppet.noop
|
||||||
|
|
||||||
|
salt '*' puppet.noop web::server,django::base
|
||||||
'''
|
'''
|
||||||
if _check_puppet():
|
if not tags:
|
||||||
return __salt__['cmd.run_all']('puppetd --test --noop')
|
cmd = 'puppetd --test --noop'
|
||||||
else:
|
else:
|
||||||
raise CommandNotFoundError("puppetd not available")
|
cmd = 'puppetd --test --tags "{0}" --noop'.format(tags)
|
||||||
|
|
||||||
|
if _check_puppet():
|
||||||
|
return __salt__['cmd.run_all'](cmd)
|
||||||
|
else:
|
||||||
|
raise CommandNotFoundError('puppetd not available')
|
||||||
|
@ -3,11 +3,16 @@ The Saltutil module is used to manage the state of the salt minion itself. It is
|
|||||||
used to manage minion modules as well as automate updates to the salt minion
|
used to manage minion modules as well as automate updates to the salt minion
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# Import Python libs
|
||||||
import os
|
import os
|
||||||
import hashlib
|
import hashlib
|
||||||
import shutil
|
import shutil
|
||||||
|
import signal
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
# Import Salt libs
|
||||||
|
import salt.payload
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def _sync(form, env):
|
def _sync(form, env):
|
||||||
@ -42,7 +47,7 @@ def _sync(form, env):
|
|||||||
shutil.copyfile(fn_, dest)
|
shutil.copyfile(fn_, dest)
|
||||||
ret.append('{0}.{1}'.format(form, os.path.basename(fn_)))
|
ret.append('{0}.{1}'.format(form, os.path.basename(fn_)))
|
||||||
if ret:
|
if ret:
|
||||||
open(os.path.join(__opts__['cachedir'], '.module_refresh'), 'w+').write('')
|
open(os.path.join(__opts__['cachedir'], 'module_refresh'), 'w+').write('')
|
||||||
if __opts__.get('clean_dynamic_modules', True):
|
if __opts__.get('clean_dynamic_modules', True):
|
||||||
current = set(os.listdir(mod_dir))
|
current = set(os.listdir(mod_dir))
|
||||||
for fn_ in current.difference(remote):
|
for fn_ in current.difference(remote):
|
||||||
@ -138,3 +143,94 @@ def sync_all(env='base'):
|
|||||||
ret.append(sync_renderers(env))
|
ret.append(sync_renderers(env))
|
||||||
ret.append(sync_returners(env))
|
ret.append(sync_returners(env))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def running():
|
||||||
|
'''
|
||||||
|
Return the data on all running processes salt on the minion
|
||||||
|
|
||||||
|
CLI Example::
|
||||||
|
|
||||||
|
salt '*' saltutil.running
|
||||||
|
'''
|
||||||
|
procs = __salt__['status.procs']()
|
||||||
|
ret = []
|
||||||
|
serial = salt.payload.Serial(__opts__)
|
||||||
|
pid = os.getpid()
|
||||||
|
proc_dir = os.path.join(__opts__['cachedir'], 'proc')
|
||||||
|
if not os.path.isdir(proc_dir):
|
||||||
|
return []
|
||||||
|
for fn_ in os.listdir(proc_dir):
|
||||||
|
path = os.path.join(proc_dir, fn_)
|
||||||
|
data = serial.loads(open(path, 'rb').read())
|
||||||
|
if not procs.get(str(data['pid'])):
|
||||||
|
# The process is no longer running, clear out the file and
|
||||||
|
# continue
|
||||||
|
os.remove(path)
|
||||||
|
continue
|
||||||
|
if data.get('pid') == pid:
|
||||||
|
continue
|
||||||
|
ret.append(data)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def find_job(jid):
|
||||||
|
'''
|
||||||
|
Return the data for a specific job id
|
||||||
|
|
||||||
|
CLI Example::
|
||||||
|
|
||||||
|
salt '*' saltutil.find_job <job id>
|
||||||
|
'''
|
||||||
|
for data in running():
|
||||||
|
if data['jid'] == jid:
|
||||||
|
return data
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
def signal_job(jid, sig):
|
||||||
|
'''
|
||||||
|
Sends a signal to the named salt job's process
|
||||||
|
|
||||||
|
CLI Example::
|
||||||
|
|
||||||
|
salt '*' saltutil.signal_job <job id> 15
|
||||||
|
'''
|
||||||
|
for data in running():
|
||||||
|
if data['jid'] == jid:
|
||||||
|
try:
|
||||||
|
os.kill(int(data['pid']), sig)
|
||||||
|
return 'Signal {0} sent to job {1} at pid {2}'.format(
|
||||||
|
int(sig),
|
||||||
|
jid,
|
||||||
|
data['pid']
|
||||||
|
)
|
||||||
|
except OSError:
|
||||||
|
path = os.path.join(__opts__['cachedir'], 'proc', str(jid))
|
||||||
|
if os.path.isfile(path):
|
||||||
|
os.remove(path)
|
||||||
|
return ('Job {0} was not running and job data has been '
|
||||||
|
' cleaned up').format(jid)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def term_job(jid):
|
||||||
|
'''
|
||||||
|
Sends a termination signal (SIGTERM 15) to the named salt job's process
|
||||||
|
|
||||||
|
CLI Example::
|
||||||
|
|
||||||
|
salt '*' saltutil.term_job <job id>
|
||||||
|
'''
|
||||||
|
return signal_job(jid, signal.SIGTERM)
|
||||||
|
|
||||||
|
|
||||||
|
def kill_job(jid):
|
||||||
|
'''
|
||||||
|
Sends a termination signal (SIGTERM 15) to the named salt job's process
|
||||||
|
|
||||||
|
CLI Example::
|
||||||
|
|
||||||
|
salt '*' saltutil.kill_job <job id>
|
||||||
|
'''
|
||||||
|
return signal_job(jid, signal.SIGKILL)
|
||||||
|
@ -26,6 +26,40 @@ def _number(text):
|
|||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def procs():
|
||||||
|
'''
|
||||||
|
Return the process data
|
||||||
|
|
||||||
|
CLI Example::
|
||||||
|
|
||||||
|
salt '*' status.procs
|
||||||
|
'''
|
||||||
|
# Get the user, pid and cmd
|
||||||
|
ret = {}
|
||||||
|
uind = 0
|
||||||
|
pind = 0
|
||||||
|
cind = 0
|
||||||
|
plines = __salt__['cmd.run'](__grains__['ps']).split('\n')
|
||||||
|
guide = plines.pop(0).split()
|
||||||
|
if 'USER' in guide:
|
||||||
|
uind = guide.index('USER')
|
||||||
|
elif 'UID' in guide:
|
||||||
|
uind = guide.index('UID')
|
||||||
|
if 'PID' in guide:
|
||||||
|
pind = guide.index('PID')
|
||||||
|
if 'COMMAND' in guide:
|
||||||
|
cind = guide.index('COMMAND')
|
||||||
|
elif 'CMD' in guide:
|
||||||
|
cind = guide.index('CMD')
|
||||||
|
for line in plines:
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
comps = line.split()
|
||||||
|
ret[comps[pind]] = {'user': comps[uind],
|
||||||
|
'cmd': ' '.join(comps[cind:])}
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def custom():
|
def custom():
|
||||||
'''
|
'''
|
||||||
Return a custom composite of status data and info for this minon,
|
Return a custom composite of status data and info for this minon,
|
||||||
|
@ -125,13 +125,13 @@ class State(object):
|
|||||||
self.load_modules()
|
self.load_modules()
|
||||||
open(os.path.join(
|
open(os.path.join(
|
||||||
self.opts['cachedir'],
|
self.opts['cachedir'],
|
||||||
'.module_refresh'),
|
'module_refresh'),
|
||||||
'w+').write('')
|
'w+').write('')
|
||||||
elif data['fun'] == 'recurse':
|
elif data['fun'] == 'recurse':
|
||||||
self.load_modules()
|
self.load_modules()
|
||||||
open(os.path.join(
|
open(os.path.join(
|
||||||
self.opts['cachedir'],
|
self.opts['cachedir'],
|
||||||
'.module_refresh'),
|
'module_refresh'),
|
||||||
'w+').write('')
|
'w+').write('')
|
||||||
|
|
||||||
def format_verbosity(self, returns):
|
def format_verbosity(self, returns):
|
||||||
|
Loading…
Reference in New Issue
Block a user