Permalink
Browse files

Merge pull request #44194 from vernondcole/saltify-create-with-wake-o…

…n-lan

add wake-on-LAN feature to saltify create
  • Loading branch information...
rallytime committed Oct 23, 2017
2 parents 2ccfaca + b7c0182 commit 4278a08e401785b0e8296ab57d2db7a6c56176d5
@@ -1,3 +1,5 @@
.. _misc-salt-cloud-options:
================================
Miscellaneous Salt Cloud Options
================================
@@ -4,7 +4,7 @@
Getting Started With Saltify
============================
The Saltify driver is a new, experimental driver for installing Salt on existing
The Saltify driver is a driver for installing Salt on existing
machines (virtual or bare metal).
@@ -37,16 +37,25 @@ the role usually performed by a vendor's cloud management system. The salt maste
must be running on the salt-cloud machine, and created nodes must be connected to the
master.
Additional information about which configuration options apply to which actions
can be studied in the
:ref:`Saltify Module documentation <saltify-module>`
and the
:ref:`Miscellaneous Salt Cloud Options <misc-salt-cloud-options>`
document.
Profiles
========
Saltify requires a profile to be configured for each machine that needs Salt
installed. The initial profile can be set up at ``/etc/salt/cloud.profiles``
Saltify requires a separate profile to be configured for each machine that
needs Salt installed [#]_. The initial profile can be set up at
``/etc/salt/cloud.profiles``
or in the ``/etc/salt/cloud.profiles.d/`` directory. Each profile requires
both an ``ssh_host`` and an ``ssh_username`` key parameter as well as either
an ``key_filename`` or a ``password``.
.. [#] Unless you are using a map file to provide the unique parameters.
Profile configuration example:
.. code-block:: yaml
@@ -68,40 +77,78 @@ The machine can now be "Salted" with the following command:
This will install salt on the machine specified by the cloud profile,
``salt-this-machine``, and will give the machine the minion id of
``my-machine``. If the command was executed on the salt-master, its Salt
key will automatically be signed on the master.
key will automatically be accepted by the master.
Once a salt-minion has been successfully installed on the instance, connectivity
to it can be verified with Salt:
.. code-block:: bash
salt my-machine test.ping
salt my-machine test.version
Destroy Options
---------------
.. versionadded:: Oxygen
For obvious reasons, the ``destroy`` action does not actually vaporize hardware.
If the salt master is connected using salt-api, it can tear down parts of
the client machines. It will remove the client's key from the salt master,
and will attempt the following options:
If the salt master is connected, it can tear down parts of the client machines.
It will remove the client's key from the salt master,
and can execute the following options:
.. code-block:: yaml
- remove_config_on_destroy: true
# default: true
# Deactivate salt-minion on reboot and
# delete the minion config and key files from its ``/etc/salt`` directory,
# NOTE: If deactivation is unsuccessful (older Ubuntu machines) then when
# delete the minion config and key files from its "/etc/salt" directory,
# NOTE: If deactivation was unsuccessful (older Ubuntu machines) then when
# salt-minion restarts it will automatically create a new, unwanted, set
# of key files. The ``force_minion_config`` option must be used in that case.
# of key files. Use the "force_minion_config" option to replace them.
- shutdown_on_destroy: false
# default: false
# send a ``shutdown`` command to the client.
# last of all, send a "shutdown" command to the client.
Wake On LAN
-----------
.. versionadded:: Oxygen
In addition to connecting a hardware machine to a Salt master,
you have the option of sending a wake-on-LAN
`magic packet`_
to start that machine running.
.. _magic packet: https://en.wikipedia.org/wiki/Wake-on-LAN
The "magic packet" must be sent by an existing salt minion which is on
the same network segment as the target machine. (Or your router
must be set up especially to route WoL packets.) Your target machine
must be set up to listen for WoL and to respond appropriatly.
You must provide the Salt node id of the machine which will send
the WoL packet \(parameter ``wol_sender_node``\), and
the hardware MAC address of the machine you intend to wake,
\(parameter ``wake_on_lan_mac``\). If both parameters are defined,
the WoL will be sent. The cloud master will then sleep a while
\(parameter ``wol_boot_wait``) to give the target machine time to
boot up before we start probing its SSH port to begin deploying
Salt to it. The default sleep time is 30 seconds.
.. code-block:: yaml
# /etc/salt/cloud.profiles.d/saltify.conf
salt-this-machine:
ssh_host: 12.34.56.78
ssh_username: root
key_filename: '/etc/salt/mysshkey.pem'
provider: my-saltify-config
wake_on_lan_mac: '00:e0:4c:70:2a:b2' # found with ifconfig
wol_sender_node: bevymaster # its on this network segment
wol_boot_wait: 45 # seconds to sleep
Using Map Files
---------------
The settings explained in the section above may also be set in a map file. An
@@ -1,12 +1,17 @@
# -*- coding: utf-8 -*-
'''
.. _`saltify-module`:
Saltify Module
==============
The Saltify module is designed to install Salt on a remote machine, virtual or
bare metal, using SSH. This module is useful for provisioning machines which
are already installed, but not Salted.
.. versionchanged:: Oxygen
The wake_on_lan capability, and actions destroy, reboot, and query functions were added.
Use of this module requires some configuration in cloud profile and provider
files as described in the
:ref:`Gettting Started with Saltify <getting-started-with-saltify>` documentation.
@@ -15,6 +20,7 @@
# Import python libs
from __future__ import absolute_import
import logging
import time
# Import salt libs
import salt.utils.cloud
@@ -210,12 +216,61 @@ def show_instance(name, call=None):
def create(vm_):
'''
Provision a single machine
if configuration parameter ``deploy`` is ``True``,
Provision a single machine, adding its keys to the salt master
else,
Test ssh connections to the machine
Configuration parameters:
- deploy: (see above)
- provider: name of entry in ``salt/cloud.providers.d/???`` file
- ssh_host: IP address or DNS name of the new machine
- ssh_username: name used to log in to the new machine
- ssh_password: password to log in (unless key_filename is used)
- key_filename: (optional) SSH private key for passwordless login
- ssh_port: (default=22) TCP port for SSH connection
- wake_on_lan_mac: (optional) hardware (MAC) address for wake on lan
- wol_sender_node: (optional) salt minion to send wake on lan command
- wol_boot_wait: (default=30) seconds to delay while client boots
- force_minion_config: (optional) replace the minion configuration files on the new machine
See also
:ref:`Miscellaneous Salt Cloud Options <misc-salt-cloud-options>`
and
:ref:`Getting Started with Saltify <getting-started-with-saltify>`
CLI Example:
.. code-block:: bash
salt-cloud -p mymachine my_new_id
'''
deploy_config = config.get_cloud_config_value(
'deploy', vm_, __opts__, default=False)
if deploy_config:
wol_mac = config.get_cloud_config_value(
'wake_on_lan_mac', vm_, __opts__, default='')
wol_host = config.get_cloud_config_value(
'wol_sender_node', vm_, __opts__, default='')
if wol_mac and wol_host:
log.info('sending wake-on-lan to %s using node %s',
wol_mac, wol_host)
local = salt.client.LocalClient()
if isinstance(wol_mac, six.string_types):
wol_mac = [wol_mac] # a smart user may have passed more params
ret = local.cmd(wol_host, 'network.wol', wol_mac)
log.info('network.wol returned value %s', ret)
if ret and ret[wol_host]:
sleep_time = config.get_cloud_config_value(
'wol_boot_wait', vm_, __opts__, default=30)
if sleep_time > 0.0:
log.info('delaying %d seconds for boot', sleep_time)
time.sleep(sleep_time)
log.info('Provisioning existing machine %s', vm_['name'])
ret = __utils__['cloud.bootstrap'](vm_, __opts__)
else:
@@ -8,7 +8,7 @@
Use of this module requires some configuration in cloud profile and provider
files as described in the
:ref:`Gettting Started with Vagrant <getting-started-with-vagrant>` documentation.
:ref:`Getting Started with Vagrant <getting-started-with-vagrant>` documentation.
.. versionadded:: Oxygen
@@ -22,9 +22,14 @@
'ssh_username': 'fred',
'remove_config_on_destroy': False, # expected for test
'shutdown_on_destroy': True # expected value for test
}
},
'testprofile3': { # this profile is used in test_create_wake_on_lan()
'wake_on_lan_mac': 'aa-bb-cc-dd-ee-ff',
'wol_sender_node': 'friend1',
'wol_boot_wait': 0.01 # we want the wait to be very short
}
}
TEST_PROFILE_NAMES = ['testprofile1', 'testprofile2']
TEST_PROFILE_NAMES = ['testprofile1', 'testprofile2', 'testprofile3']
@skipIf(NO_MOCK, NO_MOCK_REASON)
@@ -78,12 +83,38 @@ def test_create_and_deploy(self):
{'cloud.bootstrap': mock_cmd}):
vm_ = {'deploy': True,
'driver': 'saltify',
'name': 'testprofile2',
'name': 'new2',
'profile': 'testprofile2',
}
result = saltify.create(vm_)
mock_cmd.assert_called_once_with(vm_, ANY)
self.assertTrue(result)
def test_create_wake_on_lan(self):
'''
Test if wake on lan works
'''
mock_sleep = MagicMock()
mock_cmd = MagicMock(return_value=True)
mm_cmd = MagicMock(return_value={'friend1': True})
lcl = salt.client.LocalClient()
lcl.cmd = mm_cmd
with patch('time.sleep', mock_sleep):
with patch('salt.client.LocalClient', return_value=lcl):
with patch.dict(
'salt.cloud.clouds.saltify.__utils__',
{'cloud.bootstrap': mock_cmd}):
vm_ = {'deploy': True,
'driver': 'saltify',
'name': 'new1',
'profile': 'testprofile3',
}
result = saltify.create(vm_)
mock_cmd.assert_called_once_with(vm_, ANY)
mm_cmd.assert_called_with('friend1', 'network.wol', ['aa-bb-cc-dd-ee-ff'])
mock_sleep.assert_called_with(0.01)
self.assertTrue(result)
def test_avail_locations(self):
'''
Test the avail_locations will always return {}

0 comments on commit 4278a08

Please sign in to comment.