Browse Source

Remove docs, deprecated hooks, tests

Remove all deprecated hooks and tests.
Also since all test and hooks are removed,
we can remove the declare of python language in classifier.
Since we didn't actually provide any document,
we should remove docs too.

Hooks are maintained as Agents under heat-agents repo now.
Hooks in heat-templates are deprecated for a while. Hence, remove
hooks in heat-templates.

Depends-On: https://review.openstack.org/#/c/584774/
Change-Id: Ia886f71eaf99d75db0f9a6a7dfbe8664995c26e7
changes/77/584777/14
ricolin 3 years ago
committed by Zane Bitter
parent
commit
53800d1057
  1. 1
      .zuul.yaml
  2. 9
      README.rst
  3. 18
      doc/source/index.rst
  4. 5
      hot/software-config/boot-config/README.rst
  5. 6
      hot/software-config/boot-config/templates/install_config_agent_centos7_rdo.yaml
  6. 6
      hot/software-config/boot-config/templates/install_config_agent_fedora_pip.yaml
  7. 6
      hot/software-config/boot-config/templates/install_config_agent_fedora_yum.yaml
  8. 10
      hot/software-config/boot-config/templates/install_config_agent_test_image.yaml
  9. 6
      hot/software-config/boot-config/templates/install_config_agent_ubuntu_pip.yaml
  10. 51
      hot/software-config/elements/README.rst
  11. 4
      hot/software-config/elements/heat-config-ansible/README.rst
  12. 1
      hot/software-config/elements/heat-config-ansible/element-deps
  13. 7
      hot/software-config/elements/heat-config-ansible/install.d/50-heat-config-hook-ansible
  14. 133
      hot/software-config/elements/heat-config-ansible/install.d/hook-ansible.py
  15. 14
      hot/software-config/elements/heat-config-apply-config/README.rst
  16. 1
      hot/software-config/elements/heat-config-apply-config/element-deps
  17. 6
      hot/software-config/elements/heat-config-apply-config/install.d/50-heat-config-apply-config
  18. 60
      hot/software-config/elements/heat-config-apply-config/install.d/hook-apply-config.py
  19. 3
      hot/software-config/elements/heat-config-cfn-init/README.rst
  20. 1
      hot/software-config/elements/heat-config-cfn-init/element-deps
  21. 6
      hot/software-config/elements/heat-config-cfn-init/install.d/50-heat-config-hook-cfn-init
  22. 86
      hot/software-config/elements/heat-config-cfn-init/install.d/hook-cfn-init.py
  23. 36
      hot/software-config/elements/heat-config-chef/README.rst
  24. 1
      hot/software-config/elements/heat-config-chef/element-deps
  25. 7
      hot/software-config/elements/heat-config-chef/install.d/50-heat-config-hook-chef
  26. 165
      hot/software-config/elements/heat-config-chef/install.d/hook-chef.py
  27. 9
      hot/software-config/elements/heat-config-docker-cmd/README.rst
  28. 2
      hot/software-config/elements/heat-config-docker-cmd/element-deps
  29. 6
      hot/software-config/elements/heat-config-docker-cmd/install.d/50-heat-config-hook-docker-cmd
  30. 143
      hot/software-config/elements/heat-config-docker-cmd/install.d/hook-docker-cmd.py
  31. 145
      hot/software-config/elements/heat-config-docker-cmd/os-refresh-config/configure.d/50-heat-config-docker-cmd
  32. 18
      hot/software-config/elements/heat-config-docker-compose/README.rst
  33. 2
      hot/software-config/elements/heat-config-docker-compose/element-deps
  34. 17
      hot/software-config/elements/heat-config-docker-compose/install.d/50-heat-config-hook-docker-compose
  35. 131
      hot/software-config/elements/heat-config-docker-compose/install.d/hook-docker-compose.py
  36. 116
      hot/software-config/elements/heat-config-docker-compose/os-refresh-config/configure.d/50-heat-config-docker-compose
  37. 25
      hot/software-config/elements/heat-config-hiera/README.rst
  38. 1
      hot/software-config/elements/heat-config-hiera/element-deps
  39. 9
      hot/software-config/elements/heat-config-hiera/install.d/50-heat-config-hook-hiera
  40. 88
      hot/software-config/elements/heat-config-hiera/install.d/hook-hiera.py
  41. 19
      hot/software-config/elements/heat-config-json-file/README.rst
  42. 1
      hot/software-config/elements/heat-config-json-file/element-deps
  43. 6
      hot/software-config/elements/heat-config-json-file/install.d/50-heat-config-hook-json-file
  44. 55
      hot/software-config/elements/heat-config-json-file/install.d/hook-json-file.py
  45. 22
      hot/software-config/elements/heat-config-kubelet/README.rst
  46. 2
      hot/software-config/elements/heat-config-kubelet/element-deps
  47. 12
      hot/software-config/elements/heat-config-kubelet/extra-data.d/50-docker-images
  48. 82
      hot/software-config/elements/heat-config-kubelet/install.d/50-heat-config-kubelet
  49. 215
      hot/software-config/elements/heat-config-kubelet/install.d/hook-kubelet.py
  50. 72
      hot/software-config/elements/heat-config-kubelet/os-refresh-config/configure.d/50-heat-config-kubelet
  51. 16
      hot/software-config/elements/heat-config-puppet/README.rst
  52. 1
      hot/software-config/elements/heat-config-puppet/element-deps
  53. 7
      hot/software-config/elements/heat-config-puppet/install.d/50-heat-config-hook-puppet
  54. 186
      hot/software-config/elements/heat-config-puppet/install.d/hook-puppet.py
  55. 3
      hot/software-config/elements/heat-config-salt/README.rst
  56. 1
      hot/software-config/elements/heat-config-salt/element-deps
  57. 8
      hot/software-config/elements/heat-config-salt/install.d/50-heat-config-hook-salt
  58. 132
      hot/software-config/elements/heat-config-salt/install.d/hook-salt.py
  59. 3
      hot/software-config/elements/heat-config-script/README.rst
  60. 1
      hot/software-config/elements/heat-config-script/element-deps
  61. 6
      hot/software-config/elements/heat-config-script/install.d/50-heat-config-hook-script
  62. 99
      hot/software-config/elements/heat-config-script/install.d/hook-script.py
  63. 3
      hot/software-config/elements/heat-config/README.rst
  64. 163
      hot/software-config/elements/heat-config/bin/heat-config-notify
  65. 41
      hot/software-config/elements/heat-config/bin/heat-config-rebuild-deployed
  66. 2
      hot/software-config/elements/heat-config/element-deps
  67. 4
      hot/software-config/elements/heat-config/install.d/heat-config-package-install/50-heat-config-package
  68. 4
      hot/software-config/elements/heat-config/install.d/heat-config-source-install/50-heat-config-soure
  69. 1
      hot/software-config/elements/heat-config/os-apply-config/var/run/heat-config/heat-config
  70. 195
      hot/software-config/elements/heat-config/os-refresh-config/configure.d/55-heat-config
  71. 6
      hot/software-config/heat-container-agent/README.rst
  72. 2
      hot/software-config/heat-container-agent/scripts/50-heat-config-docker-compose
  73. 2
      hot/software-config/heat-container-agent/scripts/55-heat-config
  74. 2
      hot/software-config/heat-container-agent/scripts/heat-config-notify
  75. 2
      hot/software-config/heat-container-agent/scripts/hooks/docker-compose
  76. 2
      hot/software-config/heat-container-agent/scripts/hooks/script
  77. 1
      playbooks/devstack/run.yaml
  78. 0
      requirements.txt
  79. 16
      setup.cfg
  80. 18
      setup.py
  81. 21
      test-requirements.txt
  82. 0
      tests/__init__.py
  83. 0
      tests/software_config/__init__.py
  84. 38
      tests/software_config/common.py
  85. 58
      tests/software_config/config-tool-fake.py
  86. 1
      tests/software_config/heat_config_notify.py
  87. 60
      tests/software_config/hook-fake.py
  88. 1
      tests/software_config/hook_kubelet.py
  89. 272
      tests/software_config/test_heat_config.py
  90. 117
      tests/software_config/test_heat_config_docker_compose.py
  91. 147
      tests/software_config/test_heat_config_kubelet.py
  92. 209
      tests/software_config/test_heat_config_notify.py
  93. 225
      tests/software_config/test_hook_ansible.py
  94. 81
      tests/software_config/test_hook_apply_config.py
  95. 115
      tests/software_config/test_hook_atomic.py
  96. 112
      tests/software_config/test_hook_cfn_init.py
  97. 207
      tests/software_config/test_hook_chef.py
  98. 267
      tests/software_config/test_hook_docker_cmd.py
  99. 177
      tests/software_config/test_hook_docker_compose.py
  100. 85
      tests/software_config/test_hook_hiera.py

1
.zuul.yaml

@ -7,6 +7,7 @@
required-projects:
- openstack-infra/devstack-gate
- openstack/heat
- openstack/heat-agents
- openstack/heat-templates
- project:

9
README.rst

@ -19,3 +19,12 @@ This repository provides:
* Example templates which demonstrate core Heat functionality
* Related image-building templates
* Template-related scripts and conversion tools
============================
Software configuration hooks
============================
All hooks (heat agents) in heat-templates repository are removed,
please use hooks in `heat-agents https://git.openstack.org/cgit/openstack/heat-agents` instead.
Here is document entry for heat-agents: `https://docs.openstack.org/heat-agents/latest/`

18
doc/source/index.rst

@ -1,18 +0,0 @@
.. heat-templates documentation master file, created by
sphinx-quickstart on Thu Jul 20 09:19:39 2017.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Heat Templates!
==========================
.. toctree::
:maxdepth: 1
Indices and tables
==================
* :ref:`genindex`
* :ref:`search`

5
hot/software-config/boot-config/README.rst

@ -7,7 +7,10 @@ Heat::InstallConfigAgent.
This can be used by server user_data when booting a pristine image
to install the agent required to use software deployment resources in
templates.
templates. The templates assume that you have the heat-agents
repository checked out alongside the heat-templates repository; if the
agent code is in a different location you will need to adjust the paths
in the templates.
The environments only install the heat-config-script hook. If other hooks are
required then define your own environment file which defines a resource

6
hot/software-config/boot-config/templates/install_config_agent_centos7_rdo.yaml

@ -15,9 +15,9 @@ resources:
config:
str_replace:
params:
$heat_config_script: {get_file: ../../elements/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../elements/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../elements/heat-config/bin/heat-config-notify}
$heat_config_script: {get_file: ../../../../../heat-agents/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../../../../heat-agents/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../../../../heat-agents/heat-config/bin/heat-config-notify}
$occ_conf: {get_file: fragments/os-collect-config.conf}
$orc_oac: {get_file: fragments/20-os-apply-config}
template: {get_file: fragments/configure_config_agent.sh}

6
hot/software-config/boot-config/templates/install_config_agent_fedora_pip.yaml

@ -21,9 +21,9 @@ resources:
config:
str_replace:
params:
$heat_config_script: {get_file: ../../elements/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../elements/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../elements/heat-config/bin/heat-config-notify}
$heat_config_script: {get_file: ../../../../../heat-agents/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../../../../heat-agents/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../../../../heat-agents/heat-config/bin/heat-config-notify}
$occ_conf: {get_file: fragments/os-collect-config.conf}
$orc_oac: {get_file: fragments/20-os-apply-config}
template: {get_file: fragments/configure_config_agent.sh}

6
hot/software-config/boot-config/templates/install_config_agent_fedora_yum.yaml

@ -15,9 +15,9 @@ resources:
config:
str_replace:
params:
$heat_config_script: {get_file: ../../elements/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../elements/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../elements/heat-config/bin/heat-config-notify}
$heat_config_script: {get_file: ../../../../../heat-agents/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../../../../heat-agents/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../../../../heat-agents/heat-config/bin/heat-config-notify}
$occ_conf: {get_file: fragments/os-collect-config.conf}
$orc_oac: {get_file: fragments/20-os-apply-config}
template: {get_file: fragments/configure_config_agent.sh}

10
hot/software-config/boot-config/templates/install_config_agent_test_image.yaml

@ -32,9 +32,9 @@ resources:
config:
str_replace:
params:
$heat_config_script: {get_file: ../../elements/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../elements/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../elements/heat-config/bin/heat-config-notify}
$heat_config_script: {get_file: ../../../../../heat-agents/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../../../../heat-agents/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../../../../heat-agents/heat-config/bin/heat-config-notify}
$occ_conf: {get_file: fragments/os-collect-config.conf}
$orc_oac: {get_file: fragments/20-os-apply-config}
template: {get_file: fragments/configure_config_agent.sh}
@ -48,7 +48,7 @@ resources:
- path: /var/lib/heat-config/hooks/puppet
owner: "root:root"
permissions: "0755"
content: {get_file: ../../elements/heat-config-puppet/install.d/hook-puppet.py}
content: {get_file: ../../../../../heat-agents/heat-config-puppet/install.d/hook-puppet.py}
install_cfn_init_hook:
type: "OS::Heat::CloudConfig"
@ -59,7 +59,7 @@ resources:
- path: /var/lib/heat-config/hooks/cfn-init
owner: "root:root"
permissions: "0755"
content: {get_file: ../../elements/heat-config-cfn-init/install.d/hook-cfn-init.py}
content: {get_file: ../../../../../heat-agents/heat-config-cfn-init/install.d/hook-cfn-init.py}
start_config_agent:
type: "OS::Heat::SoftwareConfig"

6
hot/software-config/boot-config/templates/install_config_agent_ubuntu_pip.yaml

@ -21,9 +21,9 @@ resources:
config:
str_replace:
params:
$heat_config_script: {get_file: ../../elements/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../elements/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../elements/heat-config/bin/heat-config-notify}
$heat_config_script: {get_file: ../../../../../heat-agents/heat-config/os-refresh-config/configure.d/55-heat-config}
$hook_script: {get_file: ../../../../../heat-agents/heat-config-script/install.d/hook-script.py}
$heat_config_notify: {get_file: ../../../../../heat-agents/heat-config/bin/heat-config-notify}
$occ_conf: {get_file: fragments/os-collect-config.conf}
$orc_oac: {get_file: fragments/20-os-apply-config}
template: {get_file: fragments/configure_config_agent.sh}

51
hot/software-config/elements/README.rst

@ -1,51 +0,0 @@
============================
Software configuration hooks
============================
.. warning::
All hooks (heat agents) in heat-templates repository are deprecated,
please use hooks in `heat-agents https://git.openstack.org/cgit/openstack/heat-agents` instead.
Here is document entry for heat-agents: `https://docs.openstack.org/heat-agents/latest/`
This directory contains `diskimage-builder <https://github.com/openstack/diskimage-builder>`_
elements to build an image which contains the software configuration hook
required to use your preferred configuration method.
These elements depend on some elements found in the
`tripleo-image-elements <https://github.com/openstack/tripleo-image-elements>`_
repository. These elements will build an image which uses
`os-collect-config <https://github.com/openstack/os-collect-config>`_,
`os-refresh-config <https://github.com/openstack/os-refresh-config>`_, and
`os-apply-config <https://github.com/openstack/os-apply-config>`_ together to
invoke a hook with the supplied configuration data, and return any outputs back
to heat.
When building an image only the elements for the preferred configuration methods are required. The heat-config element is automatically included as a dependency.
An example fedora based image containing all hooks can be built and uploaded to glance
with the following:
::
git clone https://git.openstack.org/openstack/diskimage-builder.git
git clone https://git.openstack.org/openstack/tripleo-image-elements.git
git clone https://git.openstack.org/openstack/heat-templates.git
git clone https://git.openstack.org/openstack/dib-utils.git
export PATH="${PWD}/dib-utils/bin:$PATH"
export ELEMENTS_PATH=tripleo-image-elements/elements:heat-templates/hot/software-config/elements
diskimage-builder/bin/disk-image-create vm \
fedora selinux-permissive \
os-collect-config \
os-refresh-config \
os-apply-config \
heat-config \
heat-config-ansible \
heat-config-cfn-init \
heat-config-docker-compose \
heat-config-kubelet \
heat-config-puppet \
heat-config-salt \
heat-config-script \
-o fedora-software-config.qcow2
openstack image create --disk-format qcow2 --container-format bare fedora-software-config < \
fedora-software-config.qcow2

4
hot/software-config/elements/heat-config-ansible/README.rst

@ -1,4 +0,0 @@
A hook which invokes ``ansible-playbook -i "localhost,"`` on the provided
configuration. Config inputs are written to a 'variables.json' file and
then passed to ansible via the '--extra-vars @json_file' parameter.
Config output values are read from written-out files.

1
hot/software-config/elements/heat-config-ansible/element-deps

@ -1 +0,0 @@
heat-config

7
hot/software-config/elements/heat-config-ansible/install.d/50-heat-config-hook-ansible

@ -1,7 +0,0 @@
#!/bin/bash
set -x
SCRIPTDIR=$(dirname $0)
install-packages ansible
install -D -g root -o root -m 0755 ${SCRIPTDIR}/hook-ansible.py /var/lib/heat-config/hooks/ansible

133
hot/software-config/elements/heat-config-ansible/install.d/hook-ansible.py

@ -1,133 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import subprocess
import sys
import warnings
WORKING_DIR = os.environ.get('HEAT_ANSIBLE_WORKING',
'/var/lib/heat-config/heat-config-ansible')
OUTPUTS_DIR = os.environ.get('HEAT_ANSIBLE_OUTPUTS',
'/var/run/heat-config/heat-config-ansible')
ANSIBLE_CMD = os.environ.get('HEAT_ANSIBLE_CMD', 'ansible-playbook')
ANSIBLE_INVENTORY = os.environ.get('HEAT_ANSIBLE_INVENTORY', 'localhost,')
def prepare_dir(path):
if not os.path.isdir(path):
os.makedirs(path, 0o700)
def main(argv=sys.argv):
warnings.warn('This hook is deprecated, please use hooks from heat-agents '
'repository instead.', DeprecationWarning)
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(OUTPUTS_DIR)
prepare_dir(WORKING_DIR)
os.chdir(WORKING_DIR)
c = json.load(sys.stdin)
variables = {}
for input in c['inputs']:
variables[input['name']] = input.get('value', '')
tags = c['options'].get('tags')
modulepath = c['options'].get('modulepath')
fn = os.path.join(WORKING_DIR, '%s_playbook.yaml' % c['id'])
vars_filename = os.path.join(WORKING_DIR, '%s_variables.json' % c['id'])
heat_outputs_path = os.path.join(OUTPUTS_DIR, c['id'])
variables['heat_outputs_path'] = heat_outputs_path
config_text = c.get('config', '')
if not config_text:
log.warn("No 'config' input found, nothing to do.")
return
# Write 'variables' to file
with os.fdopen(os.open(
vars_filename, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as var_file:
json.dump(variables, var_file)
# Write the executable, 'config', to file
with os.fdopen(os.open(fn, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f:
f.write(c.get('config', '').encode('utf-8'))
cmd = [
ANSIBLE_CMD,
'-i',
ANSIBLE_INVENTORY,
fn,
'--extra-vars',
'@%s' % vars_filename
]
if tags:
cmd.insert(3, '--tags')
cmd.insert(4, tags)
if modulepath:
cmd.insert(3, '--module-path')
cmd.insert(4, modulepath)
log.debug('Running %s' % (' '.join(cmd),))
try:
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except OSError:
log.warn("ansible not installed yet")
return
stdout, stderr = subproc.communicate()
log.info('Return code %s' % subproc.returncode)
if stdout:
log.info(stdout)
if stderr:
log.info(stderr)
# TODO(stevebaker): Test if ansible returns any non-zero
# return codes in success.
if subproc.returncode:
log.error("Error running %s. [%s]\n" % (fn, subproc.returncode))
else:
log.info('Completed %s' % fn)
response = {}
for output in c.get('outputs') or []:
output_name = output['name']
try:
with open('%s.%s' % (heat_outputs_path, output_name)) as out:
response[output_name] = out.read()
except IOError:
pass
response.update({
'deploy_stdout': stdout,
'deploy_stderr': stderr,
'deploy_status_code': subproc.returncode,
})
json.dump(response, sys.stdout)
if __name__ == '__main__':
sys.exit(main(sys.argv))

14
hot/software-config/elements/heat-config-apply-config/README.rst

@ -1,14 +0,0 @@
A hook which invokes os-apply-config.
The intent is for this element (hook script) to be used in place of the one in
tripleo-image-elements which relies on an external signal handling
shell script at the end of the os-refresh-config run (99-refresh-completed).
This version will run os-apply-config and return a signal immediately. Because
it uses the heat-hook mechanisms it also supports a broader set of signal
handling capabilities... which 99-refresh-completed doesn't fully support.
It is worth noting that this hook runs os-apply-config against all the
accumulated metadata, not just data supplied to an individual hook.
To use this hook set group: to 'apply-config' instead of 'os-apply-config'
in your Heat software configuration resources.

1
hot/software-config/elements/heat-config-apply-config/element-deps

@ -1 +0,0 @@
heat-config

6
hot/software-config/elements/heat-config-apply-config/install.d/50-heat-config-apply-config

@ -1,6 +0,0 @@
#!/bin/bash
set -x
SCRIPTDIR=$(dirname $0)
install -D -g root -o root -m 0755 ${SCRIPTDIR}/hook-apply-config.py /var/lib/heat-config/hooks/apply-config

60
hot/software-config/elements/heat-config-apply-config/install.d/hook-apply-config.py

@ -1,60 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import subprocess
import sys
import warnings
APPLY_CONFIG_CMD = os.environ.get('HEAT_APPLY_CONFIG_CMD', 'os-apply-config')
def main(argv=sys.argv):
warnings.warn('This hook is deprecated, please use hooks from heat-agents '
'repository instead.', DeprecationWarning)
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')
env = os.environ.copy()
log.debug('Running %s' % APPLY_CONFIG_CMD)
subproc = subprocess.Popen([APPLY_CONFIG_CMD], stdout=subprocess.PIPE,
stderr=subprocess.PIPE, env=env)
stdout, stderr = subproc.communicate()
log.info(stdout)
log.debug(stderr)
if subproc.returncode:
log.error("Error running apply-config: [%s]\n" % subproc.returncode)
else:
log.info('Completed apply-config.')
response = {
'deploy_stdout': stdout,
'deploy_stderr': stderr,
'deploy_status_code': subproc.returncode,
}
json.dump(response, sys.stdout)
if __name__ == '__main__':
sys.exit(main(sys.argv))

3
hot/software-config/elements/heat-config-cfn-init/README.rst

@ -1,3 +0,0 @@
A hook which consumes configuration in the format of AWS::CloudFormation::Init
metadata. It is provided to enable migrating from CloudFormation metadata
configuration to configuration using config and deployment resources.

1
hot/software-config/elements/heat-config-cfn-init/element-deps

@ -1 +0,0 @@
heat-config

6
hot/software-config/elements/heat-config-cfn-init/install.d/50-heat-config-hook-cfn-init

@ -1,6 +0,0 @@
#!/bin/bash
set -x
SCRIPTDIR=$(dirname $0)
install -D -g root -o root -m 0755 ${SCRIPTDIR}/hook-cfn-init.py /var/lib/heat-config/hooks/cfn-init

86
hot/software-config/elements/heat-config-cfn-init/install.d/hook-cfn-init.py

@ -1,86 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import subprocess
import sys
import warnings
# Ideally this path would be /var/lib/heat-cfntools/cfn-init-data
# but this is where all boot metadata is stored
LAST_METADATA_DIR = os.environ.get('HEAT_CFN_INIT_LAST_METADATA_DIR',
'/var/cache/heat-cfntools')
CFN_INIT_CMD = os.environ.get('HEAT_CFN_INIT_CMD',
'cfn-init')
def main(argv=sys.argv, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr):
warnings.warn('This hook is deprecated, please use hooks from heat-agents '
'repository instead.', DeprecationWarning)
log = logging.getLogger('heat-config')
handler = logging.StreamHandler(stderr)
handler.setFormatter(
logging.Formatter(
'[%(asctime)s] (%(name)s) [%(levelname)s] %(message)s'))
log.addHandler(handler)
log.setLevel('DEBUG')
c = json.load(stdin)
config = c.get('config', {})
if not isinstance(config, dict):
config = json.loads(config)
meta = {'AWS::CloudFormation::Init': config}
if not os.path.isdir(LAST_METADATA_DIR):
os.makedirs(LAST_METADATA_DIR, 0o700)
fn = os.path.join(LAST_METADATA_DIR, 'last_metadata')
with os.fdopen(os.open(fn, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 0o700),
'w') as f:
json.dump(meta, f)
log.debug('Running %s' % CFN_INIT_CMD)
subproc = subprocess.Popen([CFN_INIT_CMD], stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
cstdout, cstderr = subproc.communicate()
if cstdout:
log.info(cstdout)
if cstderr:
log.info(cstderr)
if subproc.returncode:
log.error("Error running %s. [%s]\n" % (
CFN_INIT_CMD, subproc.returncode))
else:
log.info('Completed %s' % CFN_INIT_CMD)
response = {
'deploy_stdout': cstdout,
'deploy_stderr': cstderr,
'deploy_status_code': subproc.returncode,
}
json.dump(response, stdout)
if __name__ == '__main__':
sys.exit(main())

36
hot/software-config/elements/heat-config-chef/README.rst

@ -1,36 +0,0 @@
A hook which invokes ``chef-client`` in local mode (chef zero) on the
provided configuration.
Inputs:
-------
Inputs are attribute overrides. In order to format them correctly for
consumption, you need to explicitly declare each top-level section as an
input of type ``Json`` in your config resource.
Additionally, there is a special input named ``environment`` of type
``String`` that you can use to specify which environment to use when
applying the config. You do not have to explicitly declare this input in
the config resource.
Outputs:
--------
If you need to capture specific outputs from your chef run, you should
specify the output name(s) as normal in your config. Then, your recipes
should write files to the directory specified by the ``heat_outputs_path``
environment variable. The file name should match the name of the output
you are trying to capture.
Options:
-------------
kitchen : optional
A URL for a Git repository containing the desired recipes, roles,
environments and other configuration.
This will be cloned into ``kitchen_path`` for use by chef.
kitchen_path : default ``/var/lib/heat-config/heat-config-chef/kitchen``
Instance-local path for the recipes, roles, environments, etc.
If ``kitchen`` is not specified, this directory must be populated via
user-data, another software config, or other "manual" method.

1
hot/software-config/elements/heat-config-chef/element-deps

@ -1 +0,0 @@
heat-config

7
hot/software-config/elements/heat-config-chef/install.d/50-heat-config-hook-chef

@ -1,7 +0,0 @@
#!/bin/bash
set -x
SCRIPTDIR=$(dirname $0)
install-packages chef git
install -D -g root -o root -m 0755 ${SCRIPTDIR}/hook-chef.py /var/lib/heat-config/hooks/chef

165
hot/software-config/elements/heat-config-chef/install.d/hook-chef.py

@ -1,165 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import shutil
import six
import subprocess
import sys
import warnings
DEPLOY_KEYS = ("deploy_server_id",
"deploy_action",
"deploy_stack_id",
"deploy_resource_name",
"deploy_signal_transport",
"deploy_signal_id",
"deploy_signal_verb")
WORKING_DIR = os.environ.get('HEAT_CHEF_WORKING',
'/var/lib/heat-config/heat-config-chef')
OUTPUTS_DIR = os.environ.get('HEAT_CHEF_OUTPUTS',
'/var/run/heat-config/heat-config-chef')
def prepare_dir(path):
if not os.path.isdir(path):
os.makedirs(path, 0o700)
def run_subproc(fn, **kwargs):
env = os.environ.copy()
for k, v in kwargs.items():
env[six.text_type(k)] = v
try:
subproc = subprocess.Popen(fn, stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env)
stdout, stderr = subproc.communicate()
except OSError as exc:
ret = -1
stderr = six.text_type(exc)
stdout = ""
else:
ret = subproc.returncode
if not ret:
ret = 0
return ret, stdout, stderr
def main(argv=sys.argv):
warnings.warn('This hook is deprecated, please use hooks from heat-agents '
'repository instead.', DeprecationWarning)
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(OUTPUTS_DIR)
prepare_dir(WORKING_DIR)
os.chdir(WORKING_DIR)
c = json.load(sys.stdin)
client_config = ("log_level :debug\n"
"log_location STDOUT\n"
"local_mode true\n"
"chef_zero.enabled true")
# configure/set up the kitchen
kitchen = c['options'].get('kitchen')
kitchen_path = c['options'].get('kitchen_path', os.path.join(WORKING_DIR,
"kitchen"))
cookbook_path = os.path.join(kitchen_path, "cookbooks")
role_path = os.path.join(kitchen_path, "roles")
environment_path = os.path.join(kitchen_path, "environments")
client_config += "\ncookbook_path '%s'" % cookbook_path
client_config += "\nrole_path '%s'" % role_path
client_config += "\nenvironment_path '%s'" % environment_path
if kitchen:
log.debug("Cloning kitchen from %s", kitchen)
# remove the existing kitchen on update so we get a fresh clone
dep_action = next((input['value'] for input in c['inputs']
if input['name'] == "deploy_action"), None)
if dep_action == "UPDATE":
shutil.rmtree(kitchen_path, ignore_errors=True)
cmd = ["git", "clone", kitchen, kitchen_path]
ret, out, err = run_subproc(cmd)
if ret != 0:
log.error("Error cloning kitchen from %s into %s: %s", kitchen,
kitchen_path, err)
json.dump({'deploy_status_code': ret,
'deploy_stdout': out,
'deploy_stderr': err},
sys.stdout)
return 0
# write the json attributes
ret, out, err = run_subproc(['hostname', '-f'])
if ret == 0:
fqdn = out.strip()
else:
err = "Could not determine hostname with hostname -f"
json.dump({'deploy_status_code': ret,
'deploy_stdout': "",
'deploy_stderr': err}, sys.stdout)
return 0
node_config = {}
for input in c['inputs']:
if input['name'] == 'environment':
client_config += "\nenvironment '%s'" % input['value']
elif input['name'] not in DEPLOY_KEYS:
node_config.update({input['name']: input['value']})
node_config.update({"run_list": json.loads(c['config'])})
node_path = os.path.join(WORKING_DIR, "node")
prepare_dir(node_path)
node_file = os.path.join(node_path, "%s.json" % fqdn)
with os.fdopen(os.open(node_file, os.O_CREAT | os.O_WRONLY, 0o600),
'w') as f:
f.write(json.dumps(node_config, indent=4))
client_config += "\nnode_path '%s'" % node_path
# write out the completed client config
config_path = os.path.join(WORKING_DIR, "client.rb")
with os.fdopen(os.open(config_path, os.O_CREAT | os.O_WRONLY, 0o600),
'w') as f:
f.write(client_config)
# run chef
heat_outputs_path = os.path.join(OUTPUTS_DIR, c['id'])
cmd = ['chef-client', '-z', '--config', config_path, "-j", node_file]
ret, out, err = run_subproc(cmd, heat_outputs_path=heat_outputs_path)
resp = {'deploy_status_code': ret,
'deploy_stdout': out,
'deploy_stderr': err}
log.debug("Chef output: %s", out)
if err:
log.error("Chef return code %s:\n%s", ret, err)
for output in c.get('outputs', []):
output_name = output['name']
try:
with open('%s.%s' % (heat_outputs_path, output_name)) as out:
resp[output_name] = out.read()
except IOError:
pass
json.dump(resp, sys.stdout)
if __name__ == '__main__':
sys.exit(main(sys.argv))

9
hot/software-config/elements/heat-config-docker-cmd/README.rst

@ -1,9 +0,0 @@
A hook which uses the `docker` command to deploy containers.
The hook currently supports specifying containers in the `docker-compose v1
format <https://docs.docker.com/compose/compose-file/#/version-1>`_. The
intention is for this hook to also support the kubernetes pod format.
A dedicated os-refresh-config script will remove running containers if a
deployment is removed or changed, then the docker-cmd hook will run any
containers in new or updated deployments.

2
hot/software-config/elements/heat-config-docker-cmd/element-deps

@ -1,2 +0,0 @@
os-apply-config
os-refresh-config

6
hot/software-config/elements/heat-config-docker-cmd/install.d/50-heat-config-hook-docker-cmd

@ -1,6 +0,0 @@
#!/bin/bash
set -x
SCRIPTDIR=$(dirname $0)
install -D -g root -o root -m 0755 ${SCRIPTDIR}/hook-docker-cmd.py /var/lib/heat-config/hooks/docker-cmd

143
hot/software-config/elements/heat-config-docker-cmd/install.d/hook-docker-cmd.py

@ -1,143 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import six
import subprocess
import sys
import warnings
import yaml
DOCKER_CMD = os.environ.get('HEAT_DOCKER_CMD', 'docker')
log = None
def build_response(deploy_stdout, deploy_stderr, deploy_status_code):
return {
'deploy_stdout': deploy_stdout,
'deploy_stderr': deploy_stderr,
'deploy_status_code': deploy_status_code,
}
def docker_arg_map(key, value):
value = str(value).encode('ascii', 'ignore')
return {
'container_step_config': None,
'environment': "--env=%s" % value,
'image': value,
'net': "--net=%s" % value,
'pid': "--pid=%s" % value,
'privileged': "--privileged=%s" % 'true' if value else 'false',
'restart': "--restart=%s" % value,
'user': "--user=%s" % value,
'volumes': "--volume=%s" % value,
'volumes_from': "--volumes-from=%s" % value,
}.get(key, None)
def main(argv=sys.argv):
warnings.warn('This hook is deprecated, please use hooks from heat-agents '
'repository instead.', DeprecationWarning)
global log
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')
c = json.load(sys.stdin)
input_values = dict((i['name'], i['value']) for i in c.get('inputs', {}))
if input_values.get('deploy_action') == 'DELETE':
json.dump(build_response(
'', '', 0), sys.stdout)
return
config = c.get('config', '')
if not config:
log.debug("No 'config' input found, nothing to do.")
json.dump(build_response(
'', '', 0), sys.stdout)
return
stdout = []
stderr = []
deploy_status_code = 0
# convert config to dict
if not isinstance(config, dict):
config = yaml.safe_load(config)
for container in sorted(config):
container_name = '%s__%s' % (c['name'], container)
cmd = [
DOCKER_CMD,
'run',
'--detach=true',
'--name',
container_name.encode('ascii', 'ignore'),
]
image_name = ''
for key in sorted(config[container]):
# These ones contain a list of values
if key in ['environment', 'volumes', 'volumes_from']:
for value in config[container][key]:
# Somehow the lists get empty values sometimes
if type(value) is six.text_type and not value.strip():
continue
cmd.append(docker_arg_map(key, value))
elif key == 'image':
image_name = config[container][key].encode('ascii', 'ignore')
else:
arg = docker_arg_map(key, config[container][key])
if arg:
cmd.append(arg)
# Image name must come last.
cmd.append(image_name)
log.debug(' '.join(cmd))
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
cmd_stdout, cmd_stderr = subproc.communicate()
log.debug(cmd_stdout)
log.debug(cmd_stderr)
if cmd_stdout:
stdout.append(cmd_stdout)
if cmd_stderr:
stderr.append(cmd_stderr)
if subproc.returncode:
log.error("Error running %s. [%s]\n" % (cmd, subproc.returncode))
else:
log.debug('Completed %s' % cmd)
if subproc.returncode != 0:
deploy_status_code = subproc.returncode
json.dump(build_response(
'\n'.join(stdout), '\n'.join(stderr), deploy_status_code), sys.stdout)
if __name__ == '__main__':
sys.exit(main(sys.argv))

145
hot/software-config/elements/heat-config-docker-cmd/os-refresh-config/configure.d/50-heat-config-docker-cmd

@ -1,145 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import subprocess
import sys
import yaml
CONF_FILE = os.environ.get('HEAT_SHELL_CONFIG',
'/var/run/heat-config/heat-config')
WORKING_DIR = os.environ.get(
'HEAT_DOCKER_CMD_WORKING',
'/var/lib/heat-config/heat-config-docker-cmd')
DOCKER_CMD = os.environ.get('HEAT_DOCKER_CMD', 'docker')
log = None
def main(argv=sys.argv):
global log
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')
if not os.path.exists(CONF_FILE):
log.warning('No config file %s' % CONF_FILE)
return 1
if not os.path.isdir(WORKING_DIR):
os.makedirs(WORKING_DIR, 0o700)
try:
configs = json.load(open(CONF_FILE))
except ValueError as e:
log.warning('Could not load config json: %s' % e)
return 1
cmd_configs = list(build_configs(configs))
try:
delete_missing_projects(cmd_configs)
for c in cmd_configs:
delete_changed_project(c)
write_project(c)
except Exception as e:
log.exception(e)
def build_configs(configs):
for c in configs:
if c['group'] != 'docker-cmd':
continue
if not isinstance(c['config'], dict):
# convert config to dict
c['config'] = yaml.safe_load(c['config'])
yield c
def current_projects():
for proj_file in os.listdir(WORKING_DIR):
if proj_file.endswith('.json'):
proj = proj_file[:-5]
yield proj
def remove_project(proj):
proj_file = os.path.join(WORKING_DIR, '%s.json' % proj)
with open(proj_file, 'r') as f:
proj_data = json.load(f)
for name in extract_container_names(proj, proj_data):
remove_container(name)
os.remove(proj_file)
def remove_container(name):
cmd = [DOCKER_CMD, 'rm', '-f', name]
log.debug(' '.join(cmd))
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = subproc.communicate()
log.info(stdout)
log.debug(stderr)
def delete_missing_projects(configs):
config_names = [c['name'] for c in configs]
for proj in current_projects():
if proj not in config_names:
log.debug('%s no longer exists, deleting containers' % proj)
remove_project(proj)
def extract_container_names(proj, proj_data):
# For now, assume a docker-compose v1 format where the
# root keys are service names
for name in sorted(proj_data):
yield '%s__%s' % (proj, name)
def delete_changed_project(c):
proj = c['name']
proj_file = os.path.join(WORKING_DIR, '%s.json' % proj)
proj_data = c.get('config', {})
if os.path.isfile(proj_file):
with open(proj_file, 'r') as f:
prev_proj_data = json.load(f)
if proj_data != prev_proj_data:
log.debug('%s has changed, deleting containers' % proj)
remove_project(proj)
def write_project(c):
proj = c['name']
proj_file = os.path.join(WORKING_DIR, '%s.json' % proj)
proj_data = c.get('config', {})
with os.fdopen(os.open(
proj_file, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 0o600),
'w') as f:
json.dump(proj_data, f, indent=2)
if __name__ == '__main__':
sys.exit(main(sys.argv))

18
hot/software-config/elements/heat-config-docker-compose/README.rst

@ -1,18 +0,0 @@
A hook which uses `docker-compose` to deploy containers.
A special input 'env_files' can be used with SoftwareConfig and
StructuredConfig for docker-compose `env_file` key(s).
if env_file keys specified in the `docker-compose.yml`, do not
exist in input_values supplied, docker-compose will throw an
error, as it can't find these files.
Also, `--parameter-file` option can be used to pass env files from client.
Example:
$ openstack stack create test_stack -t example-docker-compose-template.yaml \
--parameter-file env_file_0=./common.env \
--parameter-file env_file_1=./apps/web.env \
--parameter-file env_file_2=./test.env \
--parameter-file env_file_3=./busybox.env

2
hot/software-config/elements/heat-config-docker-compose/element-deps

@ -1,2 +0,0 @@
os-apply-config
os-refresh-config

17
hot/software-config/elements/heat-config-docker-compose/install.d/50-heat-config-hook-docker-compose

@ -1,17 +0,0 @@
#!/bin/bash
set -x
SCRIPTDIR=$(dirname $0)
if [ -f /etc/debian_version ]; then
install-packages docker.io
update-rc.d docker.io defaults
elif [ -f /etc/redhat-release ]; then
yum -y install docker-io
systemctl enable docker.service
fi
pip install -U dpath docker-compose==1.4.0
install -D -g root -o root -m 0755 ${SCRIPTDIR}/hook-docker-compose.py /var/lib/heat-config/hooks/docker-compose

131
hot/software-config/elements/heat-config-docker-compose/install.d/hook-docker-compose.py

@ -1,131 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import ast
import dpath
import json
import logging
import os
import six
import subprocess
import sys
import warnings
import yaml
WORKING_DIR = os.environ.get('HEAT_DOCKER_COMPOSE_WORKING',
'/var/lib/heat-config/heat-config-docker-compose')
DOCKER_COMPOSE_CMD = os.environ.get('HEAT_DOCKER_COMPOSE_CMD',
'docker-compose')
def prepare_dir(path):
if not os.path.isdir(path):
os.makedirs(path, 0o700)
def write_input_file(file_path, content):
prepare_dir(os.path.dirname(file_path))
with os.fdopen(os.open(
file_path, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f:
f.write(content.encode('utf-8'))
def build_response(deploy_stdout, deploy_stderr, deploy_status_code):
return {
'deploy_stdout': deploy_stdout,
'deploy_stderr': deploy_stderr,
'deploy_status_code': deploy_status_code,
}
def main(argv=sys.argv):
warnings.warn('This hook is deprecated, please use hooks from heat-agents '
'repository instead.', DeprecationWarning)
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')
c = json.load(sys.stdin)
input_values = dict((i['name'], i['value']) for i in c['inputs'])
proj = os.path.join(WORKING_DIR, c.get('name'))
prepare_dir(proj)
stdout, stderr = {}, {}
if input_values.get('deploy_action') == 'DELETE':
json.dump(build_response(stdout, stderr, 0), sys.stdout)
return
config = c.get('config', '')
if not config:
log.debug("No 'config' input found, nothing to do.")
json.dump(build_response(stdout, stderr, 0), sys.stdout)
return
# convert config to dict
if not isinstance(config, dict):
config = ast.literal_eval(json.dumps(yaml.safe_load(config)))
os.chdir(proj)
compose_env_files = []
for value in dpath.util.values(config, '*/env_file'):
if isinstance(value, list):
compose_env_files.extend(value)
elif isinstance(value, six.string_types):
compose_env_files.extend([value])
input_env_files = {}
if input_values.get('env_files'):
input_env_files = dict(
(i['file_name'], i['content'])
for i in ast.literal_eval(input_values.get('env_files')))
for file in compose_env_files:
if file in input_env_files.keys():
write_input_file(file, input_env_files.get(file))
cmd = [
DOCKER_COMPOSE_CMD,
'up',
'-d',
'--no-build',
]
log.debug('Running %s' % cmd)
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = subproc.communicate()
log.debug(stdout)
log.debug(stderr)
if subproc.returncode:
log.error("Error running %s. [%s]\n" % (cmd, subproc.returncode))
else:
log.debug('Completed %s' % cmd)
json.dump(build_response(stdout, stderr, subproc.returncode), sys.stdout)
if __name__ == '__main__':
sys.exit(main(sys.argv))

116
hot/software-config/elements/heat-config-docker-compose/os-refresh-config/configure.d/50-heat-config-docker-compose

@ -1,116 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import subprocess
import sys
import yaml
CONF_FILE = os.environ.get('HEAT_SHELL_CONFIG',
'/var/run/heat-config/heat-config')
DOCKER_COMPOSE_DIR = os.environ.get(
'HEAT_DOCKER_COMPOSE_WORKING',
'/var/lib/heat-config/heat-config-docker-compose')
DOCKER_COMPOSE_CMD = os.environ.get('HEAT_DOCKER_COMPOSE_CMD',
'docker-compose')
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')
if not os.path.exists(CONF_FILE):
log.error('No config file %s' % CONF_FILE)
return 1
if not os.path.isdir(DOCKER_COMPOSE_DIR):
os.makedirs(DOCKER_COMPOSE_DIR, 0o700)
try:
configs = json.load(open(CONF_FILE))
except ValueError:
pass
try:
cleanup_stale_projects(configs)
for c in configs:
write_compose_config(c)
except Exception as e:
log.exception(e)
def cleanup_stale_projects(configs):
def deployments(configs):
for c in configs:
yield c['name']
def compose_projects(compose_dir):
for proj in os.listdir(compose_dir):
if os.path.isfile(
os.path.join(DOCKER_COMPOSE_DIR,
'%s/docker-compose.yml' % proj)):
yield proj
def cleanup_containers(project):
cmd = [
DOCKER_COMPOSE_CMD,
'kill'
]
subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = subproc.communicate()
for proj in compose_projects(DOCKER_COMPOSE_DIR):
if proj not in deployments(configs):
proj_dir = os.path.join(DOCKER_COMPOSE_DIR, proj)
os.chdir(proj_dir)
cleanup_containers(proj)
os.remove('%s/docker-compose.yml' % proj_dir)
def write_compose_config(c):
group = c.get('group')
if group != 'docker-compose':
return
def prepare_dir(path):
if not os.path.isdir(path):
os.makedirs(path, 0o700)
compose_conf = c.get('config', '')
if isinstance(compose_conf, dict):
yaml_config = yaml.safe_dump(compose_conf, default_flow_style=False)
else:
yaml_config = compose_conf
proj_dir = os.path.join(DOCKER_COMPOSE_DIR, c['name'])
prepare_dir(proj_dir)
fn = os.path.join(proj_dir, 'docker-compose.yml')
with os.fdopen(os.open(fn, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, 0o600),
'w') as f:
f.write(yaml_config.encode('utf-8'))
if __name__ == '__main__':
sys.exit(main(sys.argv))

25
hot/software-config/elements/heat-config-hiera/README.rst

@ -1,25 +0,0 @@
A hook which helps write hiera files to disk and creates
the hiera.yaml to order them. This is typically used alongside
of the puppet hook to generate Hiera in a more composable manner.
Example:
ComputeConfig:
type: OS::Heat::StructuredConfig
properties:
group: hiera
config:
hierarchy:
- compute
datafiles:
compute:
debug: true
db_connection: foo:/bar
# customized hiera goes here...
This would write out:
1) An /etc/hiera.yaml config file with compute in the hierarchy.
2) An /etc/puppet/hieradata/compute.json file loaded with the
custom hiera data.

1
hot/software-config/elements/heat-config-hiera/element-deps

@ -1 +0,0 @@
heat-config

9
hot/software-config/elements/heat-config-hiera/install.d/50-heat-config-hook-hiera

@ -1,9 +0,0 @@
#!/bin/bash
set -x
SCRIPTDIR=$(dirname $0)
install-packages hiera
install -D -g root -o root -m 0755 ${SCRIPTDIR}/hook-hiera.py /var/lib/heat-config/hooks/hiera
ln -f -s /etc/puppet/hiera.yaml /etc/hiera.yaml

88
hot/software-config/elements/heat-config-hiera/install.d/hook-hiera.py

@ -1,88 +0,0 @@
#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
import logging
import os
import sys
import warnings
HIERA_DATADIR = os.environ.get('HEAT_PUPPET_HIERA_DATADIR',
'/etc/puppet/hieradata')
HIERA_CONFIG = os.environ.get('HEAT_HIERA_CONFIG', '/etc/puppet/hiera.yaml')
HIERA_CONFIG_BASE = """
---
:backends:
- json
:json:
:datadir: %(datadir)s
:hierarchy:
""" % {'datadir': HIERA_DATADIR}
def prepare_dir(path):
if not os.path.isdir(path):
os.makedirs(path, 0o700)
def main(argv=sys.argv):
warnings.warn('This hook is deprecated, please use hooks from heat-agents '
'repository instead.', DeprecationWarning)
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')
c = json.load(sys.stdin)['config']
prepare_dir(HIERA_DATADIR)
hiera_config_file = os.path.join(HIERA_CONFIG)
# allow the end user to order the hiera config as they wish
if 'hierarchy' in c:
with os.fdopen(os.open(hiera_config_file,
os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o600),
'w') as config_file:
config_file.write(HIERA_CONFIG_BASE)
for item in c['hierarchy']:
config_file.write(' - %s\n' % item)
# write out the datafiles as YAML
if 'datafiles' in c:
for name, data in c['datafiles'].iteritems():
hiera_data = os.path.join(HIERA_DATADIR, '%s.json' % name)
with os.fdopen(os.open(hiera_data,
os.O_CREAT | os.O_TRUNC | os.O_WRONLY,
0o600),
'w') as hiera_data_file:
json.dump(data, hiera_data_file, indent=4, sort_keys=True)
response = {
'deploy_stdout': '',
'deploy_stderr': '',
'deploy_status_code': 0,
}
json.dump(response, sys.stdout)
if __name__ == '__main__':
sys.exit(main(sys.argv))

19
hot/software-config/elements/heat-config-json-file/README.rst

@ -1,19 +0,0 @@
A hook which helps write JSON files to disk for configuration or use
with ad-hoc scripts. The data files are written to the named file
location for each section listed under 'config'.