2014-11-22 10:41:51 +00:00
|
|
|
#!/usr/bin/env python
|
2013-11-27 11:19:24 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-04-17 19:12:35 -06:00
|
|
|
The minionswarm script will start a group of salt minions with different ids
|
|
|
|
on a single system to test scale capabilities
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-04-04 13:11:54 +01:00
|
|
|
# pylint: disable=resource-leakage
|
2012-04-17 19:12:35 -06:00
|
|
|
# Import Python Libs
|
2014-11-21 19:05:13 +00:00
|
|
|
from __future__ import absolute_import, print_function
|
2020-04-02 20:10:20 -05:00
|
|
|
|
|
|
|
import hashlib
|
2012-04-17 19:12:35 -06:00
|
|
|
import optparse
|
2020-04-02 20:10:20 -05:00
|
|
|
import os
|
2015-09-23 15:59:55 -06:00
|
|
|
import random
|
2012-04-17 23:58:10 -06:00
|
|
|
import shutil
|
2020-04-02 20:10:20 -05:00
|
|
|
import signal
|
|
|
|
import subprocess
|
2014-07-14 16:59:44 -06:00
|
|
|
import sys
|
2020-04-02 20:10:20 -05:00
|
|
|
import tempfile
|
|
|
|
import time
|
2017-03-10 12:10:21 +01:00
|
|
|
import uuid
|
2012-04-17 19:12:35 -06:00
|
|
|
|
2012-06-05 11:44:01 -06:00
|
|
|
# Import salt libs
|
|
|
|
import salt
|
2017-11-08 12:36:23 -06:00
|
|
|
import salt.utils.files
|
2017-12-27 22:31:50 -06:00
|
|
|
import salt.utils.yaml
|
2020-04-02 20:10:20 -05:00
|
|
|
import tests.support.runtests
|
2012-06-05 11:44:01 -06:00
|
|
|
|
2012-04-17 19:12:35 -06:00
|
|
|
# Import third party libs
|
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
|
|
|
from salt.ext import six
|
2014-11-22 10:41:51 +00:00
|
|
|
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
|
2012-05-29 22:10:20 +05:30
|
|
|
|
2015-09-23 15:59:55 -06:00
|
|
|
OSES = [
|
2020-04-02 20:10:20 -05:00
|
|
|
"Arch",
|
|
|
|
"Ubuntu",
|
|
|
|
"Debian",
|
|
|
|
"CentOS",
|
|
|
|
"Fedora",
|
|
|
|
"Gentoo",
|
|
|
|
"AIX",
|
|
|
|
"Solaris",
|
|
|
|
]
|
2015-09-23 16:09:23 -06:00
|
|
|
VERS = [
|
2020-04-02 20:10:20 -05:00
|
|
|
"2014.1.6",
|
|
|
|
"2014.7.4",
|
|
|
|
"2015.5.5",
|
|
|
|
"2015.8.0",
|
|
|
|
]
|
2015-09-23 15:59:55 -06:00
|
|
|
|
|
|
|
|
2012-04-17 19:12:35 -06:00
|
|
|
def parse():
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-04-17 19:12:35 -06:00
|
|
|
Parse the cli options
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-04-17 19:12:35 -06:00
|
|
|
parser = optparse.OptionParser()
|
2014-01-23 12:22:26 +01:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"-m",
|
|
|
|
"--minions",
|
|
|
|
dest="minions",
|
2014-07-15 11:31:07 -06:00
|
|
|
default=5,
|
2020-04-02 20:10:20 -05:00
|
|
|
type="int",
|
|
|
|
help="The number of minions to make",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"-M",
|
|
|
|
action="store_true",
|
|
|
|
dest="master_too",
|
2014-07-15 11:31:07 -06:00
|
|
|
default=False,
|
2020-04-02 20:10:20 -05:00
|
|
|
help="Run a local master and tell the minions to connect to it",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--master",
|
|
|
|
dest="master",
|
|
|
|
default="salt",
|
|
|
|
help="The location of the salt master that this swarm will serve",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--name",
|
|
|
|
"-n",
|
|
|
|
dest="name",
|
|
|
|
default="ms",
|
|
|
|
help=(
|
|
|
|
"Give the minions an alternative id prefix, this is used "
|
|
|
|
"when minions from many systems are being aggregated onto "
|
|
|
|
"a single master"
|
|
|
|
),
|
|
|
|
)
|
2015-09-23 15:59:55 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--rand-os",
|
|
|
|
dest="rand_os",
|
2015-09-23 15:59:55 -06:00
|
|
|
default=False,
|
2020-04-02 20:10:20 -05:00
|
|
|
action="store_true",
|
|
|
|
help="Each Minion claims a different os grain",
|
|
|
|
)
|
2015-09-23 16:09:23 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--rand-ver",
|
|
|
|
dest="rand_ver",
|
2015-09-23 16:09:23 -06:00
|
|
|
default=False,
|
2020-04-02 20:10:20 -05:00
|
|
|
action="store_true",
|
|
|
|
help="Each Minion claims a different version grain",
|
|
|
|
)
|
2017-01-30 13:34:06 +01:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--rand-machine-id",
|
|
|
|
dest="rand_machine_id",
|
2017-01-30 13:34:06 +01:00
|
|
|
default=False,
|
2020-04-02 20:10:20 -05:00
|
|
|
action="store_true",
|
|
|
|
help="Each Minion claims a different machine id grain",
|
|
|
|
)
|
2017-03-10 12:10:21 +01:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--rand-uuid",
|
|
|
|
dest="rand_uuid",
|
2017-03-10 12:10:21 +01:00
|
|
|
default=False,
|
2020-04-02 20:10:20 -05:00
|
|
|
action="store_true",
|
|
|
|
help="Each Minion claims a different UUID grain",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"-k",
|
|
|
|
"--keep-modules",
|
|
|
|
dest="keep",
|
|
|
|
default="",
|
|
|
|
help="A comma delimited list of modules to enable",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"-f",
|
|
|
|
"--foreground",
|
|
|
|
dest="foreground",
|
2014-07-15 11:31:07 -06:00
|
|
|
default=False,
|
2020-04-02 20:10:20 -05:00
|
|
|
action="store_true",
|
|
|
|
help=(
|
|
|
|
"Run the minions with debug output of the swarm going to " "the terminal"
|
|
|
|
),
|
|
|
|
)
|
2017-01-30 11:36:28 +01:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--temp-dir",
|
|
|
|
dest="temp_dir",
|
2017-01-30 11:36:28 +01:00
|
|
|
default=None,
|
2020-04-02 20:10:20 -05:00
|
|
|
help="Place temporary files/directories here",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--no-clean",
|
|
|
|
action="store_true",
|
2014-07-15 11:31:07 -06:00
|
|
|
default=False,
|
2020-04-02 20:10:20 -05:00
|
|
|
help="Don't cleanup temporary files/directories",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--root-dir",
|
|
|
|
dest="root_dir",
|
2014-07-15 11:31:07 -06:00
|
|
|
default=None,
|
2020-04-02 20:10:20 -05:00
|
|
|
help="Override the minion root_dir config",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--transport",
|
|
|
|
dest="transport",
|
|
|
|
default="zeromq",
|
|
|
|
help="Declare which transport to use, default is zeromq",
|
|
|
|
)
|
2017-03-04 14:48:05 +01:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"--start-delay",
|
|
|
|
dest="start_delay",
|
2017-03-04 14:48:05 +01:00
|
|
|
default=0.0,
|
2020-04-02 20:10:20 -05:00
|
|
|
type="float",
|
|
|
|
help="Seconds to wait between minion starts",
|
|
|
|
)
|
2014-07-15 11:31:07 -06:00
|
|
|
parser.add_option(
|
2020-04-02 20:10:20 -05:00
|
|
|
"-c",
|
|
|
|
"--config-dir",
|
|
|
|
default="",
|
|
|
|
help=("Pass in a configuration directory containing base configuration."),
|
|
|
|
)
|
|
|
|
parser.add_option("-u", "--user", default=tests.support.runtests.this_user())
|
2012-04-17 19:12:35 -06:00
|
|
|
|
2014-07-15 11:31:07 -06:00
|
|
|
options, _args = parser.parse_args()
|
2012-05-13 19:48:05 +05:30
|
|
|
|
2012-04-17 19:12:35 -06:00
|
|
|
opts = {}
|
|
|
|
|
2014-11-22 10:41:51 +00:00
|
|
|
for key, val in six.iteritems(options.__dict__):
|
2012-04-17 19:12:35 -06:00
|
|
|
opts[key] = val
|
|
|
|
|
|
|
|
return opts
|
|
|
|
|
|
|
|
|
|
|
|
class Swarm(object):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-04-17 19:12:35 -06:00
|
|
|
Create a swarm of minions
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
|
2012-04-17 19:12:35 -06:00
|
|
|
def __init__(self, opts):
|
|
|
|
self.opts = opts
|
2012-10-08 14:13:05 -06:00
|
|
|
|
2017-01-30 11:36:28 +01:00
|
|
|
# If given a temp_dir, use it for temporary files
|
2020-04-02 20:10:20 -05:00
|
|
|
if opts["temp_dir"]:
|
|
|
|
self.swarm_root = opts["temp_dir"]
|
2012-10-09 12:19:50 -06:00
|
|
|
else:
|
2017-01-30 11:36:28 +01:00
|
|
|
# If given a root_dir, keep the tmp files there as well
|
2020-04-02 20:10:20 -05:00
|
|
|
if opts["root_dir"]:
|
|
|
|
tmpdir = os.path.join(opts["root_dir"], "tmp")
|
2017-01-30 11:36:28 +01:00
|
|
|
else:
|
2020-04-02 20:10:20 -05:00
|
|
|
tmpdir = opts["root_dir"]
|
2017-01-30 11:36:28 +01:00
|
|
|
self.swarm_root = tempfile.mkdtemp(
|
2020-04-02 20:10:20 -05:00
|
|
|
prefix="mswarm-root", suffix=".d", dir=tmpdir
|
|
|
|
)
|
2012-10-08 14:13:05 -06:00
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
if self.opts["transport"] == "zeromq":
|
2014-06-22 22:40:40 -06:00
|
|
|
self.pki = self._pki_dir()
|
2020-04-02 20:10:20 -05:00
|
|
|
self.zfill = len(str(self.opts["minions"]))
|
2012-09-08 20:31:25 +01:00
|
|
|
|
2012-04-17 19:12:35 -06:00
|
|
|
self.confs = set()
|
|
|
|
|
2017-01-30 13:37:29 +01:00
|
|
|
random.seed(0)
|
|
|
|
|
2012-06-13 13:37:28 -06:00
|
|
|
def _pki_dir(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-06-13 13:37:28 -06:00
|
|
|
Create the shared pki directory
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
path = os.path.join(self.swarm_root, "pki")
|
2017-01-30 11:55:33 +01:00
|
|
|
if not os.path.exists(path):
|
|
|
|
os.makedirs(path)
|
2012-09-08 20:31:25 +01:00
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
print("Creating shared pki keys for the swarm on: {0}".format(path))
|
2017-01-30 11:55:33 +01:00
|
|
|
subprocess.call(
|
2020-04-02 20:10:20 -05:00
|
|
|
"salt-key -c {0} --gen-keys minion --gen-keys-dir {0} "
|
|
|
|
"--log-file {1} --user {2}".format(
|
|
|
|
path, os.path.join(path, "keys.log"), self.opts["user"],
|
|
|
|
),
|
|
|
|
shell=True,
|
2017-01-30 11:55:33 +01:00
|
|
|
)
|
2020-04-02 20:10:20 -05:00
|
|
|
print("Keys generated")
|
2012-06-13 13:37:28 -06:00
|
|
|
return path
|
|
|
|
|
2014-07-15 11:31:07 -06:00
|
|
|
def start(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-15 11:31:07 -06:00
|
|
|
Start the magic!!
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
if self.opts["master_too"]:
|
2014-07-15 11:31:07 -06:00
|
|
|
master_swarm = MasterSwarm(self.opts)
|
|
|
|
master_swarm.start()
|
|
|
|
minions = MinionSwarm(self.opts)
|
|
|
|
minions.start_minions()
|
2020-04-02 20:10:20 -05:00
|
|
|
print("Starting minions...")
|
|
|
|
# self.start_minions()
|
|
|
|
print("All {0} minions have started.".format(self.opts["minions"]))
|
|
|
|
print("Waiting for CTRL-C to properly shutdown minions...")
|
2014-07-15 11:31:07 -06:00
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
time.sleep(5)
|
|
|
|
except KeyboardInterrupt:
|
2020-04-02 20:10:20 -05:00
|
|
|
print("\nShutting down minions")
|
2014-07-15 11:31:07 -06:00
|
|
|
self.clean_configs()
|
|
|
|
break
|
|
|
|
|
|
|
|
def shutdown(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-15 11:31:07 -06:00
|
|
|
Tear it all down
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
print("Killing any remaining running minions")
|
|
|
|
subprocess.call('pkill -KILL -f "python.*salt-minion"', shell=True)
|
|
|
|
if self.opts["master_too"]:
|
|
|
|
print("Killing any remaining masters")
|
|
|
|
subprocess.call('pkill -KILL -f "python.*salt-master"', shell=True)
|
|
|
|
if not self.opts["no_clean"]:
|
|
|
|
print("Remove ALL related temp files/directories")
|
2014-07-15 11:31:07 -06:00
|
|
|
shutil.rmtree(self.swarm_root)
|
2020-04-02 20:10:20 -05:00
|
|
|
print("Done")
|
2014-07-15 11:31:07 -06:00
|
|
|
|
|
|
|
def clean_configs(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-15 11:31:07 -06:00
|
|
|
Clean up the config files
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-15 11:31:07 -06:00
|
|
|
for path in self.confs:
|
2020-04-02 20:10:20 -05:00
|
|
|
pidfile = "{0}.pid".format(path)
|
2014-07-15 11:31:07 -06:00
|
|
|
try:
|
|
|
|
try:
|
2017-11-08 12:36:23 -06:00
|
|
|
with salt.utils.files.fopen(pidfile) as fp_:
|
|
|
|
pid = int(fp_.read().strip())
|
2014-07-15 11:31:07 -06:00
|
|
|
os.kill(pid, signal.SIGTERM)
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
if os.path.exists(pidfile):
|
|
|
|
os.remove(pidfile)
|
2020-04-02 20:10:20 -05:00
|
|
|
if not self.opts["no_clean"]:
|
2014-07-15 11:31:07 -06:00
|
|
|
shutil.rmtree(path)
|
|
|
|
except (OSError, IOError):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class MinionSwarm(Swarm):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-15 11:31:07 -06:00
|
|
|
Create minions
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
|
2014-07-15 11:31:07 -06:00
|
|
|
def start_minions(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-15 11:31:07 -06:00
|
|
|
Iterate over the config files and start up the minions
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-15 11:31:07 -06:00
|
|
|
self.prep_configs()
|
|
|
|
for path in self.confs:
|
2020-04-02 20:10:20 -05:00
|
|
|
cmd = "salt-minion -c {0} --pid-file {1}".format(
|
|
|
|
path, "{0}.pid".format(path)
|
|
|
|
)
|
|
|
|
if self.opts["foreground"]:
|
|
|
|
cmd += " -l debug &"
|
2014-07-15 11:31:07 -06:00
|
|
|
else:
|
2020-04-02 20:10:20 -05:00
|
|
|
cmd += " -d &"
|
2014-07-15 11:31:07 -06:00
|
|
|
subprocess.call(cmd, shell=True)
|
2020-04-02 20:10:20 -05:00
|
|
|
time.sleep(self.opts["start_delay"])
|
2014-07-15 11:31:07 -06:00
|
|
|
|
2012-09-08 20:31:25 +01:00
|
|
|
def mkconf(self, idx):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-04-17 19:12:35 -06:00
|
|
|
Create a config file for a single minion
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2016-03-21 16:04:15 +03:00
|
|
|
data = {}
|
2020-04-02 20:10:20 -05:00
|
|
|
if self.opts["config_dir"]:
|
|
|
|
spath = os.path.join(self.opts["config_dir"], "minion")
|
2017-11-08 12:36:23 -06:00
|
|
|
with salt.utils.files.fopen(spath) as conf:
|
2017-12-27 22:31:50 -06:00
|
|
|
data = salt.utils.yaml.safe_load(conf) or {}
|
2020-04-02 20:10:20 -05:00
|
|
|
minion_id = "{0}-{1}".format(self.opts["name"], str(idx).zfill(self.zfill))
|
2012-09-08 20:31:25 +01:00
|
|
|
|
|
|
|
dpath = os.path.join(self.swarm_root, minion_id)
|
2017-01-30 11:55:33 +01:00
|
|
|
if not os.path.exists(dpath):
|
|
|
|
os.makedirs(dpath)
|
2012-09-08 20:31:25 +01:00
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
data.update(
|
|
|
|
{
|
|
|
|
"id": minion_id,
|
|
|
|
"user": self.opts["user"],
|
|
|
|
"cachedir": os.path.join(dpath, "cache"),
|
|
|
|
"master": self.opts["master"],
|
|
|
|
"log_file": os.path.join(dpath, "minion.log"),
|
|
|
|
"grains": {},
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
if self.opts["transport"] == "zeromq":
|
|
|
|
minion_pkidir = os.path.join(dpath, "pki")
|
2017-01-30 11:55:33 +01:00
|
|
|
if not os.path.exists(minion_pkidir):
|
|
|
|
os.makedirs(minion_pkidir)
|
2020-04-02 20:10:20 -05:00
|
|
|
minion_pem = os.path.join(self.pki, "minion.pem")
|
|
|
|
minion_pub = os.path.join(self.pki, "minion.pub")
|
2017-01-30 11:55:33 +01:00
|
|
|
shutil.copy(minion_pem, minion_pkidir)
|
|
|
|
shutil.copy(minion_pub, minion_pkidir)
|
2020-04-02 20:10:20 -05:00
|
|
|
data["pki_dir"] = minion_pkidir
|
|
|
|
elif self.opts["transport"] == "tcp":
|
|
|
|
data["transport"] = "tcp"
|
2014-06-22 22:40:40 -06:00
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
if self.opts["root_dir"]:
|
|
|
|
data["root_dir"] = self.opts["root_dir"]
|
2012-10-09 12:19:50 -06:00
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
path = os.path.join(dpath, "minion")
|
2012-09-08 20:31:25 +01:00
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
if self.opts["keep"]:
|
|
|
|
keep = self.opts["keep"].split(",")
|
|
|
|
modpath = os.path.join(os.path.dirname(salt.__file__), "modules")
|
|
|
|
fn_prefixes = (fn_.partition(".")[0] for fn_ in os.listdir(modpath))
|
2013-05-02 14:49:43 -07:00
|
|
|
ignore = [fn_prefix for fn_prefix in fn_prefixes if fn_prefix not in keep]
|
2020-04-02 20:10:20 -05:00
|
|
|
data["disable_modules"] = ignore
|
|
|
|
|
|
|
|
if self.opts["rand_os"]:
|
|
|
|
data["grains"]["os"] = random.choice(OSES)
|
|
|
|
if self.opts["rand_ver"]:
|
|
|
|
data["grains"]["saltversion"] = random.choice(VERS)
|
|
|
|
if self.opts["rand_machine_id"]:
|
|
|
|
data["grains"]["machine_id"] = hashlib.md5(minion_id).hexdigest()
|
|
|
|
if self.opts["rand_uuid"]:
|
|
|
|
data["grains"]["uuid"] = str(uuid.uuid4())
|
|
|
|
|
|
|
|
with salt.utils.files.fopen(path, "w+") as fp_:
|
2017-12-27 22:31:50 -06:00
|
|
|
salt.utils.yaml.safe_dump(data, fp_)
|
2012-09-02 22:42:49 -06:00
|
|
|
self.confs.add(dpath)
|
2012-04-17 19:12:35 -06:00
|
|
|
|
|
|
|
def prep_configs(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-04-17 19:12:35 -06:00
|
|
|
Prepare the confs set
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
for idx in range(self.opts["minions"]):
|
2012-09-08 20:31:25 +01:00
|
|
|
self.mkconf(idx)
|
2012-04-17 19:12:35 -06:00
|
|
|
|
2014-07-14 16:59:44 -06:00
|
|
|
|
|
|
|
class MasterSwarm(Swarm):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-14 16:59:44 -06:00
|
|
|
Create one or more masters
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
|
2014-07-15 11:31:07 -06:00
|
|
|
def __init__(self, opts):
|
|
|
|
super(MasterSwarm, self).__init__(opts)
|
2020-04-02 20:10:20 -05:00
|
|
|
self.conf = os.path.join(self.swarm_root, "master")
|
2014-07-15 11:31:07 -06:00
|
|
|
|
2014-07-14 16:59:44 -06:00
|
|
|
def start(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-14 16:59:44 -06:00
|
|
|
Prep the master start and fire it off
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-14 16:59:44 -06:00
|
|
|
# sys.stdout for no newline
|
2020-04-02 20:10:20 -05:00
|
|
|
sys.stdout.write("Generating master config...")
|
2014-07-14 16:59:44 -06:00
|
|
|
self.mkconf()
|
2020-04-02 20:10:20 -05:00
|
|
|
print("done")
|
2014-07-14 16:59:44 -06:00
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
sys.stdout.write("Starting master...")
|
2014-07-14 16:59:44 -06:00
|
|
|
self.start_master()
|
2020-04-02 20:10:20 -05:00
|
|
|
print("done")
|
2014-07-14 16:59:44 -06:00
|
|
|
|
|
|
|
def start_master(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-14 16:59:44 -06:00
|
|
|
Do the master start
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
cmd = "salt-master -c {0} --pid-file {1}".format(
|
|
|
|
self.conf, "{0}.pid".format(self.conf)
|
|
|
|
)
|
|
|
|
if self.opts["foreground"]:
|
|
|
|
cmd += " -l debug &"
|
2014-07-14 16:59:44 -06:00
|
|
|
else:
|
2020-04-02 20:10:20 -05:00
|
|
|
cmd += " -d &"
|
2014-07-14 16:59:44 -06:00
|
|
|
subprocess.call(cmd, shell=True)
|
|
|
|
|
2014-07-15 01:42:40 +01:00
|
|
|
def mkconf(self): # pylint: disable=W0221
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-07-14 16:59:44 -06:00
|
|
|
Make a master config and write it'
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2016-03-21 16:04:15 +03:00
|
|
|
data = {}
|
2020-04-02 20:10:20 -05:00
|
|
|
if self.opts["config_dir"]:
|
|
|
|
spath = os.path.join(self.opts["config_dir"], "master")
|
2017-11-08 12:36:23 -06:00
|
|
|
with salt.utils.files.fopen(spath) as conf:
|
2017-12-27 22:31:50 -06:00
|
|
|
data = salt.utils.yaml.safe_load(conf)
|
2020-04-02 20:10:20 -05:00
|
|
|
data.update(
|
|
|
|
{
|
|
|
|
"log_file": os.path.join(self.conf, "master.log"),
|
|
|
|
"open_mode": True, # TODO Pre-seed keys
|
|
|
|
}
|
|
|
|
)
|
2014-07-14 16:59:44 -06:00
|
|
|
|
2014-07-15 11:31:07 -06:00
|
|
|
os.makedirs(self.conf)
|
2020-04-02 20:10:20 -05:00
|
|
|
path = os.path.join(self.conf, "master")
|
2014-07-14 16:59:44 -06:00
|
|
|
|
2020-04-02 20:10:20 -05:00
|
|
|
with salt.utils.files.fopen(path, "w+") as fp_:
|
2017-12-27 22:31:50 -06:00
|
|
|
salt.utils.yaml.safe_dump(data, fp_)
|
2014-07-14 16:59:44 -06:00
|
|
|
|
|
|
|
def shutdown(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
print("Killing master")
|
|
|
|
subprocess.call('pkill -KILL -f "python.*salt-master"', shell=True)
|
|
|
|
print("Master killed")
|
2014-07-14 16:59:44 -06:00
|
|
|
|
2018-12-20 16:19:01 -08:00
|
|
|
|
2014-07-15 11:31:07 -06:00
|
|
|
# pylint: disable=C0103
|
2020-04-02 20:10:20 -05:00
|
|
|
if __name__ == "__main__":
|
2012-04-17 19:12:35 -06:00
|
|
|
swarm = Swarm(parse())
|
2012-09-05 11:54:17 +01:00
|
|
|
try:
|
|
|
|
swarm.start()
|
|
|
|
finally:
|
|
|
|
swarm.shutdown()
|