-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
F#129: Parses cloudconfig data from USER_DATA (#130)
The following modules are supported: - write_files - runcmd Signed-off-by: Aleix Ramírez <[email protected]> Signed-off-by: Jaime <[email protected]>
- Loading branch information
Showing
5 changed files
with
558 additions
and
0 deletions.
There are no files selected for viewing
73 changes: 73 additions & 0 deletions
73
context-linux/src/etc/one-context.d/net-95-cloudinit-start
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#!/usr/bin/env bash | ||
|
||
# -------------------------------------------------------------------------- # | ||
# Copyright 2002-2024, OpenNebula Project, OpenNebula Systems # | ||
# # | ||
# 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. # | ||
#--------------------------------------------------------------------------- # | ||
|
||
set -eo pipefail | ||
|
||
export USER_DATA="${USER_DATA:-${USERDATA}}" | ||
if [ -z "$USER_DATA" ]; then | ||
echo "No USER_DATA env variable found. Skipping execution..." | ||
exit 0 | ||
fi | ||
|
||
CLOUDINIT_BASE_DIR="/var/lib/one-context/cloudinit" | ||
CLOUDINIT_ENV_FILE="${CLOUDINIT_BASE_DIR}/cloudinit_env.sh" | ||
CLOUDINIT_LOCK_FILE="${CLOUDINIT_BASE_DIR}/cloudinit-boot-finished" | ||
CLOUDINIT_RUNCMD_TMP_DIR="${CLOUDINIT_BASE_DIR}/tmp" | ||
CLOUDINIT_RUNCMD_TMP_SCRIPT="${CLOUDINIT_RUNCMD_TMP_DIR}/runcmd_script.sh" | ||
|
||
bootstrap_cloudinit_env() | ||
{ | ||
install -m "u=rwx,go=" -d "${CLOUDINIT_BASE_DIR}" | ||
{ | ||
echo "export CLOUDINIT_LOCK_FILE=${CLOUDINIT_LOCK_FILE}" | ||
echo "export CLOUDINIT_BASE_DIR=${CLOUDINIT_BASE_DIR}" | ||
echo "export CLOUDINIT_RUNCMD_TMP_DIR=${CLOUDINIT_RUNCMD_TMP_DIR}" | ||
echo "export CLOUDINIT_RUNCMD_TMP_SCRIPT=${CLOUDINIT_RUNCMD_TMP_SCRIPT}" | ||
} >> "${CLOUDINIT_ENV_FILE}" | ||
|
||
} | ||
|
||
if [ -e "${CLOUDINIT_LOCK_FILE}" ]; then | ||
echo "Lock file exists in ${CLOUDINIT_LOCK_FILE}. Skipping execution..." | ||
exit 0 | ||
fi | ||
bootstrap_cloudinit_env | ||
|
||
# creates tmp dir for cloudinit runcmd script | ||
install -m "u=rwx,go=" -d "${CLOUDINIT_RUNCMD_TMP_DIR}" | ||
|
||
USER_DATA_ENCODING="${USER_DATA_ENCODING:-${USERDATA_ENCODING}}" | ||
|
||
if [ "${USER_DATA_ENCODING}" = "base64" ]; then | ||
if ! USER_DATA="$(echo "${USER_DATA}" | base64 -d 2>/dev/null)"; then | ||
echo "Error: Failed base64 decoding of userdata" >&2 | ||
exit 1 | ||
fi | ||
fi | ||
|
||
# shellcheck source=/dev/null | ||
. "${CLOUDINIT_ENV_FILE}" | ||
|
||
one_cloudinit.rb | ||
EXIT_CODE=$? | ||
|
||
if [ "${EXIT_CODE}" -ne 0 ]; then | ||
echo "one_cloudinit execution failed. Exit code: ${EXIT_CODE}" | ||
exit 1 | ||
fi | ||
echo "one_cloudinit execution finished" |
68 changes: 68 additions & 0 deletions
68
context-linux/src/etc/one-context.d/net-96-cloudinit-finish
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#!/usr/bin/env bash | ||
|
||
# -------------------------------------------------------------------------- # | ||
# Copyright 2002-2024, OpenNebula Project, OpenNebula Systems # | ||
# # | ||
# 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. # | ||
#--------------------------------------------------------------------------- # | ||
|
||
set -eo pipefail | ||
|
||
# avoid executing this script when no $USER_DATA or $USERDATA is granted (avoids locking multi-stage builds) | ||
export USER_DATA="${USER_DATA:-${USERDATA}}" | ||
if [ -z "$USER_DATA" ]; then | ||
echo "No USER_DATA env variable found. Skipping execution..." | ||
exit 0 | ||
fi | ||
|
||
CLOUDINIT_BASE_DIR="/var/lib/one-context/cloudinit" | ||
CLOUDINIT_ENV_FILE="${CLOUDINIT_BASE_DIR}/cloudinit_env.sh" | ||
|
||
lock_and_cleanup() | ||
{ | ||
# write cloud-init boot finished file | ||
date +"%Y-%m-%d %H:%M:%S" > "${CLOUDINIT_LOCK_FILE}" | ||
rm -rf "${CLOUDINIT_RUNCMD_TMP_DIR}" | ||
} | ||
|
||
# Source cloudinit env vars | ||
# shellcheck source=/dev/null | ||
. "${CLOUDINIT_ENV_FILE}" | ||
|
||
if [ -e "${CLOUDINIT_LOCK_FILE}" ]; then | ||
echo "Lock file exists in ${CLOUDINIT_LOCK_FILE}. Skipping execution..." | ||
exit 0 | ||
fi | ||
|
||
trap lock_and_cleanup EXIT | ||
|
||
# Execute cloudinit scripts | ||
if [ -e "${CLOUDINIT_RUNCMD_TMP_SCRIPT}" ]; then | ||
|
||
chmod u+x "${CLOUDINIT_RUNCMD_TMP_SCRIPT}" | ||
|
||
echo "Executing ${CLOUDINIT_LOCK_FILE}..." | ||
set +e | ||
$SHELL -ex "${CLOUDINIT_RUNCMD_TMP_SCRIPT}" | ||
EXIT_CODE=$? | ||
set -e | ||
if [ "${EXIT_CODE}" -ne 0 ]; then | ||
echo "runcmd script execution failed. Exit code: ${EXIT_CODE}" | ||
exit 1 | ||
fi | ||
echo "runcmd script execution finished" | ||
|
||
else | ||
echo "No runcmd script found in: ${CLOUDINIT_RUNCMD_TMP_SCRIPT}. Skipping execution..." | ||
fi | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#!/usr/bin/env ruby | ||
|
||
# -------------------------------------------------------------------------- # | ||
# Copyright 2002-2024, OpenNebula Project, OpenNebula Systems # | ||
# # | ||
# 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. # | ||
#--------------------------------------------------------------------------- # | ||
|
||
require 'fileutils' | ||
|
||
module CloudInit | ||
|
||
## | ||
# RunCmd class implements the runcmd cloud-config directive. | ||
## | ||
class RunCmd | ||
|
||
attr_accessor :cmd_list | ||
|
||
def initialize(cmd_list) | ||
raise 'RunCmd must be instantiated with a command list as an argument' \ | ||
unless cmd_list.is_a?(Array) | ||
|
||
@cmd_list = cmd_list | ||
end | ||
|
||
def exec | ||
if @cmd_list.empty? | ||
CloudInit::Logger.debug('[runCmd] empty cmdlist, ignoring...') | ||
return | ||
end | ||
CloudInit::Logger.debug("[runCmd] processing commands'") | ||
|
||
runcmd_script_path = ENV['CLOUDINIT_RUNCMD_TMP_SCRIPT'] | ||
if !runcmd_script_path | ||
raise 'mandatory CLOUDINIT_RUNCMD_TMP_SCRIPT env var not found!' | ||
end | ||
|
||
begin | ||
file_content = create_shell_file_content | ||
rescue StandardError => e | ||
raise "could not generate runcmd script file content: #{e.message}" | ||
end | ||
|
||
File.open(runcmd_script_path, 'w', 0o700) do |file| | ||
file.write(file_content) | ||
end | ||
|
||
CloudInit::Logger.debug( | ||
"[runCmd] runcmd script successfully created in '#{runcmd_script_path}'" | ||
) | ||
end | ||
|
||
def create_shell_file_content | ||
content = "#!/bin/sh\n" | ||
@cmd_list.each do |cmd| | ||
if cmd.is_a?(Array) | ||
escaped = [] | ||
cmd.each do |token| | ||
# Ensure that each element of the command in the | ||
# array is properly shell-protected with single quotes | ||
modified_string = token.gsub("'") {|x| "'\\#{x}'" } | ||
escaped << "\'#{modified_string}\'" | ||
end | ||
content << "#{escaped.join(' ')}\n" | ||
elsif cmd.is_a?(String) | ||
content << "#{cmd}\n" | ||
else | ||
raise 'incompatible command specification, must be array or string' | ||
end | ||
end | ||
return content | ||
end | ||
|
||
end | ||
|
||
end |
Oops, something went wrong.