Adds in-instance hook for saltstack
An in-instance hook which allows salt to be used for provisioning software on instances using SoftwareConfig/StructuredConfig and SoftwareDeployment resources. Change-Id: Id5b2a63576d611cd33623db6a68813bc93882538 Closes-Bug: #1320727
This commit is contained in:
parent
c9b682f1ef
commit
75d7a881b3
@ -35,6 +35,7 @@ with the following:
|
||||
os-apply-config \
|
||||
heat-config-cfn-init \
|
||||
heat-config-puppet \
|
||||
heat-config-salt \
|
||||
heat-config-script \
|
||||
-o fedora-software-config.qcow2
|
||||
glance image-create --disk-format qcow2 --container-format bare --name fedora-software-config < \
|
||||
|
3
hot/software-config/elements/heat-config-salt/README.rst
Normal file
3
hot/software-config/elements/heat-config-salt/README.rst
Normal file
@ -0,0 +1,3 @@
|
||||
A hook which uses salt library to apply the provided configuration
|
||||
as a state. Config inputs are passed as opts and output values are
|
||||
read from the yaml returned.
|
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
SCRIPTDIR=$(dirname $0)
|
||||
|
||||
install-packages salt-minion
|
||||
|
||||
install -D -g root -o root -m 0755 ${SCRIPTDIR}/hook-salt.py /var/lib/heat-config/hooks/salt
|
99
hot/software-config/elements/heat-config-salt/install.d/hook-salt.py
Executable file
99
hot/software-config/elements/heat-config-salt/install.d/hook-salt.py
Executable file
@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import salt.cli
|
||||
import salt.config
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
from salt.exceptions import SaltInvocationError
|
||||
|
||||
|
||||
WORKING_DIR = os.environ.get('HEAT_SALT_WORKING',
|
||||
'/var/lib/heat-config/heat-config-salt')
|
||||
SALT_MINION_CONFIG = os.environ.get('SALT_MINION_CONFIG',
|
||||
'/etc/salt/minion')
|
||||
|
||||
|
||||
def prepare_dir(path):
|
||||
if not os.path.isdir(path):
|
||||
os.makedirs(path, 0o700)
|
||||
|
||||
|
||||
def main(argv=sys.argv):
|
||||
log = logging.getLogger('heat-config')
|
||||
handler = logging.StreamHandler(sys.stderr)
|
||||
handler.setFormatter(
|
||||
logging.Formatter(
|
||||
'[%(asctime)s] (%(name)s) [%(levelname)s] %(message)s'))
|
||||
log.addHandler(handler)
|
||||
log.setLevel('DEBUG')
|
||||
|
||||
prepare_dir(WORKING_DIR)
|
||||
os.chdir(WORKING_DIR)
|
||||
|
||||
c = json.load(sys.stdin)
|
||||
|
||||
opts = salt.config.minion_config(SALT_MINION_CONFIG)
|
||||
|
||||
opts['file_roots'] = {'base': [WORKING_DIR]}
|
||||
opts['file_client'] = 'local'
|
||||
opts['local'] = 'local'
|
||||
opts['fun'] = 'state.sls'
|
||||
opts['arg'] = [c['id']]
|
||||
|
||||
for input in c['inputs']:
|
||||
key = input['name']
|
||||
opts[key] = input.get('value', '')
|
||||
|
||||
state_file = '%s.sls' % c['id']
|
||||
config = c.get('config', '')
|
||||
|
||||
if isinstance(config, dict):
|
||||
yaml_config = yaml.safe_dump(config, default_flow_style=False)
|
||||
else:
|
||||
yaml_config = config
|
||||
|
||||
fn = os.path.join(WORKING_DIR, state_file)
|
||||
with os.fdopen(os.open(fn, os.O_CREAT | os.O_WRONLY, 0o700), 'w') as f:
|
||||
f.write(yaml_config)
|
||||
|
||||
caller = salt.cli.caller.Caller(opts)
|
||||
|
||||
log.debug('Applying Salt state %s' % state_file)
|
||||
|
||||
stdout, stderr = None, None
|
||||
|
||||
try:
|
||||
ret = caller.call()
|
||||
except SaltInvocationError as err:
|
||||
log.error(
|
||||
'Salt invocation error while applying Salt sate %s' % state_file)
|
||||
stderr = err
|
||||
log.info('Return code %s' % ret['retcode'])
|
||||
|
||||
# returncode of 0 means there were successfull changes
|
||||
if ret['retcode'] == 0:
|
||||
log.info('Completed applying salt state %s' % state_file)
|
||||
stdout = ret
|
||||
else:
|
||||
log.error('Error applying Salt state %s. [%s]\n'
|
||||
% (state_file, ret['retcode']))
|
||||
stderr = ret
|
||||
|
||||
response = {}
|
||||
|
||||
for output in c.get('outputs') or []:
|
||||
output_name = output['name']
|
||||
response[output_name] = ret[output_name]
|
||||
|
||||
response.update({
|
||||
'deploy_stdout': stdout,
|
||||
'deploy_stderr': stderr,
|
||||
'deploy_status_code': ret['retcode'],
|
||||
})
|
||||
json.dump(response, sys.stdout)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
@ -0,0 +1,7 @@
|
||||
testsls:
|
||||
pkg.installed:
|
||||
{% if grains['os_family'] == 'RedHat' %}
|
||||
- name: {{ pillar['master']['pkg-redhat'] }}
|
||||
{% elif grains['os_family'] == 'Debian' %}
|
||||
- name: {{ pillar['master']['pkg-apache'] }}
|
||||
{% endif %}
|
110
hot/software-config/example-templates/example-salt-template.yaml
Normal file
110
hot/software-config/example-templates/example-salt-template.yaml
Normal file
@ -0,0 +1,110 @@
|
||||
heat_template_version: 2013-05-23
|
||||
parameters:
|
||||
key_name:
|
||||
type: string
|
||||
flavor:
|
||||
type: string
|
||||
default: m1.small
|
||||
image:
|
||||
type: string
|
||||
default: fedora-software-config
|
||||
|
||||
resources:
|
||||
the_sg:
|
||||
type: OS::Neutron::SecurityGroup
|
||||
properties:
|
||||
name: the_sg
|
||||
description: Ping and SSH
|
||||
rules:
|
||||
- protocol: icmp
|
||||
- protocol: tcp
|
||||
port_range_min: 22
|
||||
port_range_max: 22
|
||||
|
||||
config:
|
||||
type: OS::Heat::SoftwareConfig
|
||||
properties:
|
||||
group: salt
|
||||
inputs:
|
||||
- name: pkg-redhat
|
||||
- name: pkg-debian
|
||||
outputs:
|
||||
- name: out
|
||||
config:
|
||||
get_file: config-scripts/example-salt-state.sls
|
||||
|
||||
structured_config:
|
||||
type: OS::Heat::StructuredConfig
|
||||
properties:
|
||||
group: salt
|
||||
inputs:
|
||||
- name: pkg-redhat
|
||||
- name: svc-redhat
|
||||
config:
|
||||
inline_sls:
|
||||
pkg.installed:
|
||||
- name: {get_input: pkg-redhat}
|
||||
service.running:
|
||||
- name: {get_input: svc-redhat}
|
||||
- require:
|
||||
- pkg: {get_input: pkg-redhat}
|
||||
|
||||
deployment:
|
||||
type: OS::Heat::SoftwareDeployment
|
||||
properties:
|
||||
config:
|
||||
get_resource: config
|
||||
server:
|
||||
get_resource: server
|
||||
input_values:
|
||||
pkg-redhat: httpd
|
||||
pkg-debian: apache2
|
||||
|
||||
other_deployment:
|
||||
type: OS::Heat::SoftwareDeployment
|
||||
properties:
|
||||
config:
|
||||
get_resource: config
|
||||
server:
|
||||
get_resource: server
|
||||
input_values:
|
||||
pkg-redhat: mariadb-server
|
||||
pkg-debian: mysql-server
|
||||
|
||||
structured_deployment:
|
||||
type: OS::Heat::StructuredDeployment
|
||||
properties:
|
||||
config:
|
||||
get_resource: structured_config
|
||||
server:
|
||||
get_resource: server
|
||||
input_values:
|
||||
pkg-redhat: mariadb-server
|
||||
svc-redhat: mysqld
|
||||
|
||||
server:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
image: {get_param: image}
|
||||
flavor: {get_param: flavor}
|
||||
key_name: {get_param: key_name}
|
||||
security_groups:
|
||||
- {get_resource: the_sg}
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
|
||||
outputs:
|
||||
status_code_deployment:
|
||||
value:
|
||||
get_attr: [deployment, deploy_status_code]
|
||||
status_code_other_deployment:
|
||||
value:
|
||||
get_attr: [other_deployment, deploy_status_code]
|
||||
status_code_structured_deployment:
|
||||
value:
|
||||
get_attr: [structured_deployment, deploy_status_code]
|
||||
stdout:
|
||||
value:
|
||||
get_attr: [deployment, deploy_stdout]
|
||||
stderr:
|
||||
value:
|
||||
get_attr: [deployment, deploy_stderr]
|
Loading…
Reference in New Issue
Block a user