added seedng
diff --git a/_modules/seedng.py b/_modules/seedng.py
new file mode 100644
index 0000000..7d77a03
--- /dev/null
+++ b/_modules/seedng.py
@@ -0,0 +1,298 @@
+# -*- coding: utf-8 -*-
+'''
+Virtual machine image management tools
+'''
+
+from __future__ import absolute_import
+
+# Import python libs
+import os
+import shutil
+import logging
+import tempfile
+
+# Import salt libs
+import salt.crypt
+import salt.utils
+import salt.utils.cloud
+import salt.config
+import salt.syspaths
+import uuid
+
+
+# Set up logging
+log = logging.getLogger(__name__)
+
+# Don't shadow built-in's.
+__func_alias__ = {
+ 'apply_': 'apply'
+}
+
+
+def _file_or_content(file_):
+ if os.path.exists(file_):
+ with salt.utils.fopen(file_) as fic:
+ return fic.read()
+ return file_
+
+
+def prep_bootstrap(mpt):
+ '''
+ Update and get the random script to a random place
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt '*' seed.prep_bootstrap /tmp
+
+ '''
+ # Verify that the boostrap script is downloaded
+ bs_ = __salt__['config.gather_bootstrap_script']()
+ fpd_ = os.path.join(mpt, 'tmp', "{0}".format(
+ uuid.uuid4()))
+ if not os.path.exists(fpd_):
+ os.makedirs(fpd_)
+ os.chmod(fpd_, 0o700)
+ fp_ = os.path.join(fpd_, os.path.basename(bs_))
+ # Copy script into tmp
+ shutil.copy(bs_, fp_)
+ tmppath = fpd_.replace(mpt, '')
+ return fp_, tmppath
+
+
+def _mount(path, ftype, root=None):
+ mpt = None
+ if ftype == 'block':
+ mpt = tempfile.mkdtemp()
+ if not __salt__['mount.mount'](mpt, path):
+ os.rmdir(mpt)
+ return None
+ elif ftype == 'dir':
+ return path
+ elif ftype == 'file':
+ if 'guestfs.mount' in __salt__:
+ util = 'guestfs'
+ elif 'qemu_nbd.init' in __salt__:
+ util = 'qemu_nbd'
+ else:
+ return None
+ mpt = __salt__['mount.mount'](path, device=root, util=util)
+ if not mpt:
+ return None
+ return mpt
+
+
+def _umount(mpt, ftype):
+ if ftype == 'block':
+ __salt__['mount.umount'](mpt)
+ os.rmdir(mpt)
+ elif ftype == 'file':
+ __salt__['mount.umount'](mpt, util='qemu_nbd')
+
+
+def apply_(path, id_=None, config=None, approve_key=True, install=True,
+ prep_install=False, pub_key=None, priv_key=None, mount_point=None):
+ '''
+ Seed a location (disk image, directory, or block device) with the
+ minion config, approve the minion's key, and/or install salt-minion.
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt 'minion' seed.apply path id [config=config_data] \\
+ [gen_key=(true|false)] [approve_key=(true|false)] \\
+ [install=(true|false)]
+
+ path
+ Full path to the directory, device, or disk image on the target
+ minion's file system.
+
+ id
+ Minion id with which to seed the path.
+
+ config
+ Minion configuration options. By default, the 'master' option is set to
+ the target host's 'master'.
+
+ approve_key
+ Request a pre-approval of the generated minion key. Requires
+ that the salt-master be configured to either auto-accept all keys or
+ expect a signing request from the target host. Default: true.
+
+ install
+ Install salt-minion, if absent. Default: true.
+
+ prep_install
+ Prepare the bootstrap script, but don't run it. Default: false
+ '''
+ stats = __salt__['file.stats'](path, follow_symlinks=True)
+ if not stats:
+ return '{0} does not exist'.format(path)
+ ftype = stats['type']
+ path = stats['target']
+ log.debug('Mounting {0} at {1}'.format(ftype, path))
+ try:
+ os.makedirs(path)
+ except OSError:
+ # The directory already exists
+ pass
+
+ mpt = _mount(path, ftype, mount_point)
+
+ if not mpt:
+ return '{0} could not be mounted'.format(path)
+
+ tmp = os.path.join(mpt, 'tmp')
+ log.debug('Attempting to create directory {0}'.format(tmp))
+ try:
+ os.makedirs(tmp)
+ except OSError:
+ if not os.path.isdir(tmp):
+ raise
+ cfg_files = mkconfig(config, tmp=tmp, id_=id_, approve_key=approve_key,
+ pub_key=pub_key, priv_key=priv_key)
+
+ if _check_install(mpt):
+ # salt-minion is already installed, just move the config and keys
+ # into place
+ log.info('salt-minion pre-installed on image, '
+ 'configuring as {0}'.format(id_))
+ minion_config = salt.config.minion_config(cfg_files['config'])
+ pki_dir = minion_config['pki_dir']
+ if not os.path.isdir(os.path.join(mpt, pki_dir.lstrip('/'))):
+ __salt__['file.makedirs'](
+ os.path.join(mpt, pki_dir.lstrip('/'), '')
+ )
+ os.rename(cfg_files['privkey'], os.path.join(
+ mpt, pki_dir.lstrip('/'), 'minion.pem'))
+ os.rename(cfg_files['pubkey'], os.path.join(
+ mpt, pki_dir.lstrip('/'), 'minion.pub'))
+ os.rename(cfg_files['config'], os.path.join(mpt, 'etc/salt/minion'))
+ res = True
+ elif install:
+ log.info('Attempting to install salt-minion to {0}'.format(mpt))
+ res = _install(mpt)
+ elif prep_install:
+ log.error('The prep_install option is no longer supported. Please use '
+ 'the bootstrap script installed with Salt, located at {0}.'
+ .format(salt.syspaths.BOOTSTRAP))
+ res = False
+ else:
+ log.warning('No useful action performed on {0}'.format(mpt))
+ res = False
+
+ _umount(mpt, ftype)
+ return res
+
+
+def mkconfig(config=None,
+ tmp=None,
+ id_=None,
+ approve_key=True,
+ pub_key=None,
+ priv_key=None):
+ '''
+ Generate keys and config and put them in a tmp directory.
+
+ pub_key
+ absolute path or file content of an optional preseeded salt key
+
+ priv_key
+ absolute path or file content of an optional preseeded salt key
+
+ CLI Example:
+
+ .. code-block:: bash
+
+ salt 'minion' seed.mkconfig [config=config_data] [tmp=tmp_dir] \\
+ [id_=minion_id] [approve_key=(true|false)]
+ '''
+ if tmp is None:
+ tmp = tempfile.mkdtemp()
+ if config is None:
+ config = {}
+ if 'master' not in config and __opts__['master'] != 'salt':
+ config['master'] = __opts__['master']
+ if id_:
+ config['id'] = id_
+
+ # Write the new minion's config to a tmp file
+ tmp_config = os.path.join(tmp, 'minion')
+ with salt.utils.fopen(tmp_config, 'w+') as fp_:
+ fp_.write(salt.utils.cloud.salt_config_to_yaml(config))
+
+ # Generate keys for the minion
+ pubkeyfn = os.path.join(tmp, 'minion.pub')
+ privkeyfn = os.path.join(tmp, 'minion.pem')
+ preseeded = pub_key and priv_key
+ if preseeded:
+ log.debug('Writing minion.pub to {0}'.format(pubkeyfn))
+ log.debug('Writing minion.pem to {0}'.format(privkeyfn))
+ with salt.utils.fopen(pubkeyfn, 'w') as fic:
+ fic.write(_file_or_content(pub_key))
+ with salt.utils.fopen(privkeyfn, 'w') as fic:
+ fic.write(_file_or_content(priv_key))
+ os.chmod(pubkeyfn, 0o600)
+ os.chmod(privkeyfn, 0o600)
+ else:
+ salt.crypt.gen_keys(tmp, 'minion', 2048)
+ if approve_key and not preseeded:
+ with salt.utils.fopen(pubkeyfn) as fp_:
+ pubkey = fp_.read()
+ __salt__['pillar.ext']({'virtkey': [id_, pubkey]})
+
+ return {'config': tmp_config, 'pubkey': pubkeyfn, 'privkey': privkeyfn}
+
+
+def _install(mpt):
+ '''
+ Determine whether salt-minion is installed and, if not,
+ install it.
+ Return True if install is successful or already installed.
+ '''
+ _check_resolv(mpt)
+ boot_, tmppath = (prep_bootstrap(mpt)
+ or salt.syspaths.BOOTSTRAP)
+ # Exec the chroot command
+ cmd = 'if type salt-minion; then exit 0; '
+ cmd += 'else sh {0} -c /tmp; fi'.format(os.path.join(tmppath, 'bootstrap-salt.sh'))
+ return not __salt__['cmd.run_chroot'](mpt, cmd, python_shell=True)['retcode']
+
+
+def _check_resolv(mpt):
+ '''
+ Check that the resolv.conf is present and populated
+ '''
+ resolv = os.path.join(mpt, 'etc/resolv.conf')
+ replace = False
+ if os.path.islink(resolv):
+ resolv = os.path.realpath(resolv)
+ if not os.path.isdir(os.path.dirname(resolv)):
+ os.makedirs(os.path.dirname(resolv))
+ if not os.path.isfile(resolv):
+ replace = True
+ if not replace:
+ with salt.utils.fopen(resolv, 'rb') as fp_:
+ conts = fp_.read()
+ if 'nameserver' not in conts:
+ replace = True
+ if replace:
+ shutil.copy('/etc/resolv.conf', resolv)
+
+
+def _check_install(root):
+ sh_ = '/bin/sh'
+ if os.path.isfile(os.path.join(root, 'bin/bash')):
+ sh_ = '/bin/bash'
+
+ cmd = ('if ! type salt-minion; then exit 1; fi')
+ cmd = 'chroot \'{0}\' {1} -c \'{2}\''.format(
+ root,
+ sh_,
+ cmd)
+
+ return not __salt__['cmd.retcode'](cmd,
+ output_loglevel='quiet',
+ python_shell=True)
diff --git a/_modules/virtng.py b/_modules/virtng.py
index 02cf5f5..2bf3766 100644
--- a/_modules/virtng.py
+++ b/_modules/virtng.py
@@ -622,7 +622,7 @@
if kwargs.get('seed') and seedable:
install = kwargs.get('install', True)
- seed_cmd = kwargs.get('seed_cmd', 'seed.apply')
+ seed_cmd = kwargs.get('seed_cmd', 'seedng.apply')
__salt__[seed_cmd](img_dest,
id_=name,