Merge "Add example of SoftwareDeployments with cirros"
This commit is contained in:
commit
b3f07503b9
|
@ -0,0 +1,22 @@
|
||||||
|
=====================
|
||||||
|
Simple Cirros example
|
||||||
|
=====================
|
||||||
|
|
||||||
|
This directory contains a very simple proof-of-concept hook script and
|
||||||
|
template which shows how you can use SoftwareDeployment resources with
|
||||||
|
a cirros image (which doesn't contain cloud-init or python), which may
|
||||||
|
be useful for testing.
|
||||||
|
|
||||||
|
Since cirros images don't currently support multi-part mime user-data,
|
||||||
|
it's necessary to inject the hook script to the image and upload the
|
||||||
|
modified image to glance:
|
||||||
|
|
||||||
|
1. wget http://download.cirros-cloud.net/0.3.2/cirros-0.3.2-x86_64-disk.img
|
||||||
|
2. virt-copy-in -a cirros-0.3.2-x86_64-disk.img init.d/heat-deploy-hook /etc/init.d
|
||||||
|
3. virt-copy-in -a cirros-0.3.2-x86_64-disk.img rc3.d/S99-heat-deploy-hook /etc/rc3.d
|
||||||
|
4. glance image-create --name cirros-0.3.2-sc --disk-format=qcow2 --container-format=bare < cirros-0.3.2-x86_64-disk.img
|
||||||
|
5. heat stack-create sc1 -f cirros-hello-world.yaml -P "image=cirros-0.3.2-sc"
|
||||||
|
|
||||||
|
*NOTE*: The hook script is very basic and has a number of TODO items related to
|
||||||
|
security and functionality - please don't use it for "real" deployments, it's
|
||||||
|
intended to enable easier testing and for developer experimentation only.
|
|
@ -0,0 +1,52 @@
|
||||||
|
heat_template_version: 2013-05-23
|
||||||
|
|
||||||
|
description: >
|
||||||
|
This template demonstrates a minimal SoftwareDeployment example
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
key_name:
|
||||||
|
type: string
|
||||||
|
default: stack_key
|
||||||
|
flavor:
|
||||||
|
type: string
|
||||||
|
default: m1.small
|
||||||
|
image:
|
||||||
|
type: string
|
||||||
|
|
||||||
|
resources:
|
||||||
|
sc:
|
||||||
|
type: OS::Heat::SoftwareConfig
|
||||||
|
properties:
|
||||||
|
inputs:
|
||||||
|
- name: message
|
||||||
|
default: 'NONE'
|
||||||
|
outputs:
|
||||||
|
- name: file_content
|
||||||
|
group: script
|
||||||
|
config: |
|
||||||
|
#!/bin/sh
|
||||||
|
echo "${message}" > /hello
|
||||||
|
cat /hello > ${heat_outputs_path}.file_content
|
||||||
|
|
||||||
|
sd:
|
||||||
|
type: OS::Heat::SoftwareDeployment
|
||||||
|
properties:
|
||||||
|
config: {get_resource: sc}
|
||||||
|
server: {get_resource: server}
|
||||||
|
signal_transport: HEAT_SIGNAL
|
||||||
|
input_values:
|
||||||
|
message: 'Hello, world!'
|
||||||
|
|
||||||
|
server:
|
||||||
|
type: OS::Nova::Server
|
||||||
|
properties:
|
||||||
|
image: {get_param: image}
|
||||||
|
flavor: {get_param: flavor}
|
||||||
|
key_name: {get_param: key_name}
|
||||||
|
user_data_format: SOFTWARE_CONFIG
|
||||||
|
software_config_transport: POLL_SERVER_HEAT
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
deploy_output:
|
||||||
|
value:
|
||||||
|
get_attr: [sd, file_content]
|
|
@ -0,0 +1,92 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Simple hook script to run Heat SoftwareDeployments in Cirros images
|
||||||
|
|
||||||
|
# FIXME: need to create a directory under var with appropriate permissions
|
||||||
|
TMPDIR="/tmp"
|
||||||
|
|
||||||
|
# Extract the os-collect-config json from the user-data
|
||||||
|
grep "^{" /var/run/cirros/datasource/data/user-data | grep os-collect-config > ${TMPDIR}/oscc_user_data.json
|
||||||
|
mkdir -p ${TMPDIR}/oscc_user_data_out
|
||||||
|
json2fstree ${TMPDIR}/oscc_user_data_out ${TMPDIR}/oscc_user_data.json
|
||||||
|
|
||||||
|
# Load credentials from the decoded data
|
||||||
|
OSC_DATA_PATH=${TMPDIR}/oscc_user_data_out/os-collect-config/heat
|
||||||
|
PASSWORD=$(cat $OSC_DATA_PATH/password)
|
||||||
|
USER_ID=$(cat $OSC_DATA_PATH/user_id)
|
||||||
|
AUTH_URL=$(cat $OSC_DATA_PATH/auth_url)
|
||||||
|
PROJECT_ID=$(cat $OSC_DATA_PATH/project_id)
|
||||||
|
|
||||||
|
# Get a token and de-jsonify the response
|
||||||
|
# FIXME currently this only works with v2 keystone
|
||||||
|
V2_JSON='{"auth": {"tenantId": "'$PROJECT_ID'", "passwordCredentials": {"userId": "'$USER_ID'", "password": "'$PASSWORD'"}}}'
|
||||||
|
curl -i -d "$V2_JSON" -H "Content-type: application/json" $AUTH_URL/tokens | grep "^{" > ${TMPDIR}/token_json.json
|
||||||
|
mkdir -p ${TMPDIR}/token_data_out
|
||||||
|
json2fstree ${TMPDIR}/token_data_out ${TMPDIR}/token_json.json
|
||||||
|
TOKEN=$(cat ${TMPDIR}/token_data_out/access/token/id)
|
||||||
|
|
||||||
|
# Locate the heat API endpoint from the token response
|
||||||
|
SC_DIR=$(grep -r orchestration ${TMPDIR}/token_data_out/access/serviceCatalog/ | sed "s/\/type:orchestration//")
|
||||||
|
SC_PUBURL=$(find $SC_DIR -name publicURL)
|
||||||
|
SC_ENDPOINT=$(cat $SC_PUBURL)
|
||||||
|
|
||||||
|
# Get resource metadata and decode it with json2fstree
|
||||||
|
STACK_ID=$(cat $OSC_DATA_PATH/stack_id)
|
||||||
|
RESOURCE_NAME=$(cat $OSC_DATA_PATH/resource_name)
|
||||||
|
curl -i -X GET -H "X-Auth-Token:$TOKEN" $SC_ENDPOINT/stacks/$STACK_ID/resources/$RESOURCE_NAME/metadata | grep "^{" > ${TMPDIR}/resource_metadata.json
|
||||||
|
mkdir -p ${TMPDIR}/resource_metadata_out
|
||||||
|
json2fstree ${TMPDIR}/resource_metadata_out ${TMPDIR}/resource_metadata.json
|
||||||
|
|
||||||
|
# Iterate over the configs and run them (ignores inputs and outputs atm)
|
||||||
|
CONFIGS=$(find ${TMPDIR}/resource_metadata_out/metadata/deployments -name config)
|
||||||
|
for config in $CONFIGS
|
||||||
|
do
|
||||||
|
echo "Processing config $config"
|
||||||
|
# Create output directory and set variable
|
||||||
|
DEPLOY_DIR=$(dirname $config)
|
||||||
|
DEPLOY_TYPE=$(cat $DEPLOY_DIR/group)
|
||||||
|
if [ $DEPLOY_TYPE != 'script' ];
|
||||||
|
then
|
||||||
|
echo "Skipping config $config, $DEPLOY_TYPE not script"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
OUTPUT_PREFIX=/tmp/heat_deploy/outputs/$(basename $DEPLOY_DIR)
|
||||||
|
mkdir -p /tmp/heat_deploy/outputs
|
||||||
|
export heat_outputs_path="$OUTPUT_PREFIX"
|
||||||
|
|
||||||
|
# Iterate over inputs and set them in the environment
|
||||||
|
DEPLOY_RESOURCE_INPUT=$(grep -r deploy_resource_name $DEPLOY_DIR/inputs | sed "s/name:deploy_resource_name//")
|
||||||
|
CONFIG_INPUTS=""
|
||||||
|
for input_dir in $DEPLOY_DIR/inputs/*
|
||||||
|
do
|
||||||
|
if [ -d $input_dir ]
|
||||||
|
then
|
||||||
|
name=$(cat $input_dir/name)
|
||||||
|
value=$(cat $input_dir/value)
|
||||||
|
echo "Exporting input $name=$value for deployment"
|
||||||
|
export $name="$value"
|
||||||
|
CONFIG_INPUTS="$CONFIG_INPUTS $name"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Run the config, capture stdout/stderr and the return code
|
||||||
|
sh $config 1> ${OUTPUT_PREFIX}.deploy_stdout 2> ${OUTPUT_PREFIX}.deploy_stderr
|
||||||
|
echo $? > ${OUTPUT_PREFIX}.deploy_status_code
|
||||||
|
|
||||||
|
# Signal completion
|
||||||
|
# FIXME: we're reusing the credentials associated with the server, in theory
|
||||||
|
# we should get another token using user associated with the deployment.
|
||||||
|
# Also we don't catch any errors
|
||||||
|
SIGNAL_DATA=""
|
||||||
|
for output_path in $OUTPUT_PREFIX.*
|
||||||
|
do
|
||||||
|
output=${output_path#$OUTPUT_PREFIX.}
|
||||||
|
echo "Got output $output"
|
||||||
|
SIGNAL_DATA="${SIGNAL_DATA}, \"$output\": \"$(cat $output_path)\""
|
||||||
|
done
|
||||||
|
echo "SIGNAL_DATA=$SIGNAL_DATA"
|
||||||
|
SIGNAL_DATA_JSON="{${SIGNAL_DATA#", "}}"
|
||||||
|
curl -i -X POST -d "${SIGNAL_DATA_JSON}" -H 'Content-Type: application/json' -H "X-Auth-Token:$TOKEN" $SC_ENDPOINT/stacks/$STACK_ID/resources/$deploy_resource_name/signal
|
||||||
|
|
||||||
|
# Clean the environment
|
||||||
|
unset $CONFIG_INPUTS
|
||||||
|
done
|
|
@ -0,0 +1 @@
|
||||||
|
../init.d/heat-deploy-hook
|
Loading…
Reference in New Issue