From 94e8f759306fb64c7cdd21b67231e5154f7f7afe Mon Sep 17 00:00:00 2001 From: Hemanth Nakkina Date: Wed, 20 Mar 2019 16:35:07 +0530 Subject: [PATCH] Add seccomp profile on genesis node in multinode gate The bootactions which will be deployed via Drydock on nodes need to be performed on Genesis node as well. This should be done as part of pre-genesis setup before genesis.sh is executed. This commit deals with adding seccomp profile to genesis node as part of pre-genesis setup. Change-Id: I5ec6a66266181f0dc96161b9a7d9635db6df715a --- .../airship_gate/lib/bootaction-runner.sh | 134 ++++++++++++++++++ .../airship_gate/lib/config.sh | 1 + .../manifests/multinode_deploy.json | 8 ++ .../manifests/multinode_genesis.json | 8 ++ .../airship_gate/stages/genesis-setup.sh | 26 ++++ .../airship_gate/stages/pegleg-render.sh | 81 +++++++++++ 6 files changed, 258 insertions(+) create mode 100755 tools/multi_nodes_gate/airship_gate/lib/bootaction-runner.sh create mode 100755 tools/multi_nodes_gate/airship_gate/stages/genesis-setup.sh create mode 100755 tools/multi_nodes_gate/airship_gate/stages/pegleg-render.sh diff --git a/tools/multi_nodes_gate/airship_gate/lib/bootaction-runner.sh b/tools/multi_nodes_gate/airship_gate/lib/bootaction-runner.sh new file mode 100755 index 00000000..2a2e8fad --- /dev/null +++ b/tools/multi_nodes_gate/airship_gate/lib/bootaction-runner.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +# Copyright 2019 AT&T Intellectual Property. All other rights reserved. +# +# 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. + + +############################################################################### +# Helper functions +############################################################################### + +# Key/value lookups from manifests +manifests_lookup(){ + local file="$1" + local schema="$2" + local mdata_name="$3" + local key_path="$4" + local oper="$5" + local allow_fail="$6" + + FAIL=false + RESULT=`python3 -c " +import yaml,sys +y = yaml.load_all(open('$file')) +for x in y: + if x.get('schema') == '$schema': + if x['metadata']['name'] == '$mdata_name': + if isinstance(x$key_path,list): + if '$oper' == 'get_size': + print(len(x$key_path)) + break + else: + for i in x$key_path: + print(i) + break + else: + if '$oper' == 'dict_keys': + print(' '.join(x$key_path.keys())) + break + else: + print(x$key_path) + break +else: + sys.exit(1)" 2>&1` || FAIL=true + + if [[ $FAIL = true ]] && [[ $allow_fail != true ]]; then + echo "Lookup failed for schema '$schema', metadata.name '$mdata_name', key path '$key_path'" + exit 1 + fi +} + + +install_file(){ + local path="$1" + local content="$2" + local permissions="$3" + local dirname=$(dirname "$path") + + if [[ ! -d $dirname ]]; then + mkdir -p "$dirname" + fi + + if [[ ! -f $path ]] || [ "$(cat "$path")" != "$content" ]; then + echo "$content" > "$path" + chmod "$permissions" "$path" + FILE_UPDATED=true + else + FILE_UPDATED=false + fi +} + + +############################################################################### +# Script inputs and validations +############################################################################### + +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as sudo/root" + exit 1 +fi + +if ([[ -z $1 ]] && [[ -z $RENDERED ]]) || [[ $1 =~ .*[hH][eE][lL][pP].* ]]; then + echo "Missing required script argument" + echo "Usage: ./$(basename $BASH_SOURCE) /path/to/rendered/site/manifest.yaml" + exit 1 +fi + +if [[ -n $1 ]]; then + rendered_file="$1" +else + rendered_file="$RENDERED" +fi +if [[ ! -f $rendered_file ]]; then + echo "Specified rendered manifests file '$rendered_file' does not exist" + exit 1 +fi +echo "Using rendered manifests file '$rendered_file'" + +# env vars which can be set if you want to disable +: ${DISABLE_SECCOMP_PROFILE:=} + + +############################################################################### +# bootaction: seccomp-profiles +############################################################################### + +if [[ ! $DISABLE_SECCOMP_PROFILE ]]; then + + # Fetch seccomp profile data + manifests_lookup "$rendered_file" "drydock/BootAction/v1" \ + "seccomp-profiles" "['data']['assets'][0]['path']" + path="$RESULT" + echo "seccomp profiles asset[0] path located: '$path'" + manifests_lookup "$rendered_file" "drydock/BootAction/v1" \ + "seccomp-profiles" "['data']['assets'][0]['permissions']" + permissions="$RESULT" + echo "seccomp profiles asset[0] permissions located: '$permissions'" + manifests_lookup "$rendered_file" "drydock/BootAction/v1" \ + "seccomp-profiles" "['data']['assets'][0]['data']" + content="$RESULT" + echo "seccomp profiles assets[0] data located: '$content'" + + # seccomp_default + install_file "$path" "$content" "$permissions" +fi diff --git a/tools/multi_nodes_gate/airship_gate/lib/config.sh b/tools/multi_nodes_gate/airship_gate/lib/config.sh index d60b866d..c39d9608 100644 --- a/tools/multi_nodes_gate/airship_gate/lib/config.sh +++ b/tools/multi_nodes_gate/airship_gate/lib/config.sh @@ -1,5 +1,6 @@ export TEMP_DIR=${TEMP_DIR:-$(mktemp -d)} export DEFINITION_DEPOT="${TEMP_DIR}/site_yaml/" +export RENDERED_DEPOT="${TEMP_DIR}/rendered_yaml/" export CERT_DEPOT="${TEMP_DIR}/cert_yaml/" export GATE_DEPOT="${TEMP_DIR}/gate_yaml/" export SCRIPT_DEPOT="${TEMP_DIR}/scripts/" diff --git a/tools/multi_nodes_gate/airship_gate/manifests/multinode_deploy.json b/tools/multi_nodes_gate/airship_gate/manifests/multinode_deploy.json index 9bb6a855..5bf944df 100644 --- a/tools/multi_nodes_gate/airship_gate/manifests/multinode_deploy.json +++ b/tools/multi_nodes_gate/airship_gate/manifests/multinode_deploy.json @@ -19,6 +19,10 @@ "name": "Pegleg Collection", "script": "pegleg-collect.sh" }, + { + "name": "Pegleg Render", + "script": "pegleg-render.sh" + }, { "name": "Generate Certificates", "script": "generate-certificates.sh" @@ -41,6 +45,10 @@ "script": "bgp-router.sh", "arguments": ["build"] }, + { + "name": "Pre Genesis Setup", + "script": "genesis-setup.sh" + }, { "name": "Genesis", "script": "genesis.sh", diff --git a/tools/multi_nodes_gate/airship_gate/manifests/multinode_genesis.json b/tools/multi_nodes_gate/airship_gate/manifests/multinode_genesis.json index 028be0ef..96e11cc7 100644 --- a/tools/multi_nodes_gate/airship_gate/manifests/multinode_genesis.json +++ b/tools/multi_nodes_gate/airship_gate/manifests/multinode_genesis.json @@ -19,6 +19,10 @@ "name": "Pegleg Collection", "script": "pegleg-collect.sh" }, + { + "name": "Pegleg Render", + "script": "pegleg-render.sh" + }, { "name": "Generate Certificates", "script": "generate-certificates.sh" @@ -41,6 +45,10 @@ "script": "bgp-router.sh", "arguments": ["build"] }, + { + "name": "Pre Genesis Setup", + "script": "genesis-setup.sh" + }, { "name": "Genesis", "script": "genesis.sh", diff --git a/tools/multi_nodes_gate/airship_gate/stages/genesis-setup.sh b/tools/multi_nodes_gate/airship_gate/stages/genesis-setup.sh new file mode 100755 index 00000000..6ae064a7 --- /dev/null +++ b/tools/multi_nodes_gate/airship_gate/stages/genesis-setup.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright 2019 AT&T Intellectual Property. All other rights reserved. +# +# 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 -e + +source "${GATE_UTILS}" + +# Copies script and virtmgr private key to genesis VM +rsync_cmd "${REPO_ROOT}/tools/multi_nodes_gate/airship_gate/lib/bootaction-runner.sh" "${GENESIS_NAME}:/root/airship/" +rsync_cmd "${RENDERED_DEPOT}/rendered.yaml" "${GENESIS_NAME}:/root/airship/" + +set -o pipefail +ssh_cmd "${GENESIS_NAME}" /root/airship/bootaction-runner.sh /root/airship/rendered.yaml 2>&1 | tee -a "${LOG_FILE}" +set +o pipefail diff --git a/tools/multi_nodes_gate/airship_gate/stages/pegleg-render.sh b/tools/multi_nodes_gate/airship_gate/stages/pegleg-render.sh new file mode 100755 index 00000000..4c56e06b --- /dev/null +++ b/tools/multi_nodes_gate/airship_gate/stages/pegleg-render.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +# Copyright 2019 AT&T Intellectual Property. All other rights reserved. +# +# 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 -xe + +source "${GATE_UTILS}" + +mkdir -p "${RENDERED_DEPOT}" +chmod 777 "${RENDERED_DEPOT}" + +render_pegleg_cli() { + cli_string="pegleg -v site" + + if [[ "${GERRIT_SSH_USER}" ]] + then + cli_string+=" -u ${GERRIT_SSH_USER}" + fi + + if [[ "${GERRIT_SSH_KEY}" ]] + then + cli_string+=" -k /workspace/${GERRIT_SSH_KEY}" + fi + + primary_repo=$(config_pegleg_primary_repo) + + if [[ -d "${REPO_ROOT}/${primary_repo}" ]] + then + # NOTE: to get latest pegleg colllect to work + # airship-in-bottle repo has versions (v1.0demo, v1.0dev) within global + # and that is preventing pegleg to collect documents. + # It complains with duplicate data + $(find ${REPO_ROOT}/${primary_repo} -name "v1.0dev" -type d \ + -exec rm -r {} +) + cli_string="${cli_string} -r /workspace/${primary_repo}" + else + log "${primary_repo} not a valid primary repository" + return 1 + fi + + aux_repos=($(config_pegleg_aux_repos)) + + if [[ ${#aux_repos[@]} -gt 0 ]] + then + for r in ${aux_repos[*]} + do + cli_string="${cli_string} -e ${r}=/workspace/${r}" + done + fi + + cli_string="${cli_string} render -o /collect/rendered.yaml" + + cli_string="${cli_string} $(config_pegleg_sitename)" + + echo ${cli_string} +} + +collect_rendered_doc() { + docker run \ + --rm -t \ + --network host \ + -v "${HOME}/.ssh":/root/.ssh \ + -v "${REPO_ROOT}":/workspace \ + -v "${RENDERED_DEPOT}":/collect \ + "${IMAGE_PEGLEG_CLI}" \ + $(render_pegleg_cli) +} + +log "Collecting rendered document to ${RENDERED_DEPOT}" +collect_rendered_doc