Name: cinder-bin Namespace: openstack Labels: app.kubernetes.io/managed-by=Helm Annotations: meta.helm.sh/release-name: cinder meta.helm.sh/release-namespace: openstack Data ==== ceph-keyring.sh: ---- #!/bin/bash set -ex export HOME=/tmp cat < /etc/ceph/ceph.client.${RBD_USER}.keyring [client.${RBD_USER}] key = $(cat /tmp/client-keyring) EOF exit 0 cinder-scheduler.sh: ---- #!/bin/bash set -ex exec cinder-scheduler \ --config-file /etc/cinder/cinder.conf clean-secrets.sh: ---- #!/bin/bash set -ex exec kubectl delete secret \ --namespace ${NAMESPACE} \ --ignore-not-found=true \ ${RBD_POOL_SECRET} db-sync.sh: ---- #!/bin/bash set -ex exec cinder-manage db sync rally-test.sh: ---- #!/bin/bash set -ex : "${RALLY_ENV_NAME:="openstack-helm"}" : "${OS_INTERFACE:="public"}" : "${RALLY_CLEANUP:="true"}" if [ "x$RALLY_CLEANUP" == "xtrue" ]; then function rally_cleanup { openstack user delete \ --domain="${SERVICE_OS_USER_DOMAIN_NAME}" \ "${SERVICE_OS_USERNAME}" VOLUMES=$(openstack volume list -f value | grep -e "^s_rally_" | awk '{ print $1 }') if [ -n "$VOLUMES" ]; then echo $VOLUMES | xargs openstack volume delete fi } trap rally_cleanup EXIT fi function create_or_update_db () { revisionResults=$(rally db revision) if [ $revisionResults = "None" ] then rally db create else rally db upgrade fi } create_or_update_db cat > /tmp/rally-config.json << EOF { "openstack": { "auth_url": "${OS_AUTH_URL}", "region_name": "${OS_REGION_NAME}", "endpoint_type": "${OS_INTERFACE}", "admin": { "username": "${OS_USERNAME}", "password": "${OS_PASSWORD}", "user_domain_name": "${OS_USER_DOMAIN_NAME}", "project_name": "${OS_PROJECT_NAME}", "project_domain_name": "${OS_PROJECT_DOMAIN_NAME}" }, "users": [ { "username": "${SERVICE_OS_USERNAME}", "password": "${SERVICE_OS_PASSWORD}", "project_name": "${SERVICE_OS_PROJECT_NAME}", "user_domain_name": "${SERVICE_OS_USER_DOMAIN_NAME}", "project_domain_name": "${SERVICE_OS_PROJECT_DOMAIN_NAME}" } ], "https_insecure": false, "https_cacert": "${OS_CACERT}" } } EOF rally deployment create --file /tmp/rally-config.json --name "${RALLY_ENV_NAME}" rm -f /tmp/rally-config.json rally deployment use "${RALLY_ENV_NAME}" rally deployment check rally task validate /etc/rally/rally_tests.yaml rally task start /etc/rally/rally_tests.yaml rally task sla-check rally env cleanup rally deployment destroy --deployment "${RALLY_ENV_NAME}" bootstrap.sh: ---- #!/bin/bash set -ex export HOME=/tmp openstack volume type show rbd1 || \ openstack volume type create \ --public \ --property volume_backend_name=rbd1 \ rbd1 openstack volume type list --long openstack volume qos list exit 0 cinder-volume.sh: ---- #!/bin/bash set -ex exec cinder-volume \ --config-file /etc/cinder/cinder.conf \ --config-file /etc/cinder/conf/backends.conf \ --config-file /tmp/pod-shared/internal_tenant.conf create-internal-tenant.sh: ---- #!/bin/bash set -ex USER_PROJECT_ID=$(openstack project create --or-show --enable -f value -c id \ --domain="${PROJECT_DOMAIN_ID}" \ "${INTERNAL_PROJECT_NAME}"); USER_ID=$(openstack user create --or-show --enable -f value -c id \ --domain="${USER_DOMAIN_ID}" \ --project-domain="${PROJECT_DOMAIN_ID}" \ --project="${USER_PROJECT_ID}" \ "${INTERNAL_USER_NAME}"); ks-service.sh: ---- #!/bin/bash # Copyright 2017 Pete Birley # # 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 -ex # Service boilerplate description OS_SERVICE_DESC="${OS_REGION_NAME}: ${OS_SERVICE_NAME} (${OS_SERVICE_TYPE}) service" # Get Service ID if it exists unset OS_SERVICE_ID # FIXME - There seems to be an issue once in a while where the # openstack service list fails and encounters an error message such as: # Unable to establish connection to # https://keystone-api.openstack.svc.cluster.local:5000/v3/auth/tokens: # ('Connection aborted.', OSError("(104, 'ECONNRESET')",)) # During an upgrade scenario, this would cause the OS_SERVICE_ID to be blank # and it would attempt to create a new service when it was not needed. # This duplciate service would sometimes be used by other services such as # Horizon and would give an 'Invalid Service Catalog' error. # This loop allows for a 'retry' of the openstack service list in an # attempt to get the service list as expected if it does ecounter an error. # This loop and recheck can be reverted once the underlying issue is addressed. # If OS_SERVICE_ID is blank then wait a few seconds to give it # additional time and try again for i in $(seq 3) do OS_SERVICE_ID=$( openstack service list -f csv --quote none | \ grep ",${OS_SERVICE_NAME},${OS_SERVICE_TYPE}$" | \ sed -e "s/,${OS_SERVICE_NAME},${OS_SERVICE_TYPE}//g" ) # If the service was found, go ahead and exit successfully. if [[ -n "${OS_SERVICE_ID}" ]]; then exit 0 fi sleep 2 done # If we've reached this point and a Service ID was not found, # then create the service OS_SERVICE_ID=$(openstack service create -f value -c id \ --name="${OS_SERVICE_NAME}" \ --description "${OS_SERVICE_DESC}" \ --enable \ "${OS_SERVICE_TYPE}") rabbit-init.sh: ---- #!/bin/bash set -e # Extract connection details RABBIT_HOSTNAME=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $1}') RABBIT_PORT=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $2}') # Extract Admin User creadential RABBITMQ_ADMIN_USERNAME=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $4}') RABBITMQ_ADMIN_PASSWORD=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $5}' | \ sed 's/%/\\x/g' | \ xargs -0 printf "%b") # Extract User creadential RABBITMQ_USERNAME=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $4}') RABBITMQ_PASSWORD=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $1}' | \ awk -F'[//:]' '{print $5}' | \ sed 's/%/\\x/g' | \ xargs -0 printf "%b") # Extract User vHost RABBITMQ_VHOST=$(echo "${RABBITMQ_USER_CONNECTION}" | \ awk -F'[@]' '{print $2}' | \ awk -F'[:/]' '{print $3}') # Resolve vHost to / if no value is set RABBITMQ_VHOST="${RABBITMQ_VHOST:-/}" function rabbitmqadmin_cli () { if [ -n "$RABBITMQ_X509" ] then rabbitmqadmin \ --ssl \ --ssl-disable-hostname-verification \ --ssl-ca-cert-file="${USER_CERT_PATH}/ca.crt" \ --ssl-cert-file="${USER_CERT_PATH}/tls.crt" \ --ssl-key-file="${USER_CERT_PATH}/tls.key" \ --host="${RABBIT_HOSTNAME}" \ --port="${RABBIT_PORT}" \ --username="${RABBITMQ_ADMIN_USERNAME}" \ --password="${RABBITMQ_ADMIN_PASSWORD}" \ ${@} else rabbitmqadmin \ --host="${RABBIT_HOSTNAME}" \ --port="${RABBIT_PORT}" \ --username="${RABBITMQ_ADMIN_USERNAME}" \ --password="${RABBITMQ_ADMIN_PASSWORD}" \ ${@} fi } echo "Managing: User: ${RABBITMQ_USERNAME}" rabbitmqadmin_cli \ declare user \ name="${RABBITMQ_USERNAME}" \ password="${RABBITMQ_PASSWORD}" \ tags="user" echo "Deleting Guest User" rabbitmqadmin_cli \ delete user \ name="guest" || true if [ "${RABBITMQ_VHOST}" != "/" ] then echo "Managing: vHost: ${RABBITMQ_VHOST}" rabbitmqadmin_cli \ declare vhost \ name="${RABBITMQ_VHOST}" else echo "Skipping root vHost declaration: vHost: ${RABBITMQ_VHOST}" fi echo "Managing: Permissions: ${RABBITMQ_USERNAME} on ${RABBITMQ_VHOST}" rabbitmqadmin_cli \ declare permission \ vhost="${RABBITMQ_VHOST}" \ user="${RABBITMQ_USERNAME}" \ configure=".*" \ write=".*" \ read=".*" if [ ! -z "$RABBITMQ_AUXILIARY_CONFIGURATION" ] then echo "Applying additional configuration" echo "${RABBITMQ_AUXILIARY_CONFIGURATION}" > /tmp/rmq_definitions.json rabbitmqadmin_cli import /tmp/rmq_definitions.json fi storage-init.sh: ---- #!/bin/bash set -x if [ "x$STORAGE_BACKEND" == "xcinder.volume.drivers.rbd.RBDDriver" ]; then SECRET=$(mktemp --suffix .yaml) KEYRING=$(mktemp --suffix .keyring) function cleanup { rm -f ${SECRET} ${KEYRING} } trap cleanup EXIT fi set -ex if [ "x$STORAGE_BACKEND" == "xcinder.volume.drivers.rbd.RBDDriver" ]; then ceph -s # If RBD_DATA_POOL is set, pools are managed externally (e.g., by Rook) # Skip pool creation and only set up user with proper OSD caps if [ -n "${RBD_DATA_POOL:-}" ]; then echo "RBD_DATA_POOL is set, assuming pools are managed externally (Rook)" echo "Skipping pool creation, will only create user/keyring" OSD_CAPS="profile rbd pool=${RBD_POOL_NAME}, profile rbd pool=${RBD_DATA_POOL}" else function ensure_pool () { ceph osd pool stats $1 || ceph osd pool create $1 $2 if [[ $(ceph mgr versions | awk '/version/{print $3}' | cut -d. -f1) -ge 12 ]]; then ceph osd pool application enable $1 $3 fi size_protection=$(ceph osd pool get $1 nosizechange | cut -f2 -d: | tr -d '[:space:]') ceph osd pool set $1 nosizechange 0 ceph osd pool set $1 size ${RBD_POOL_REPLICATION} --yes-i-really-mean-it ceph osd pool set $1 nosizechange ${size_protection} ceph osd pool set $1 crush_rule "${RBD_POOL_CRUSH_RULE}" } ensure_pool ${RBD_POOL_NAME} ${RBD_POOL_CHUNK_SIZE} ${RBD_POOL_APP_NAME} OSD_CAPS="profile rbd" fi if USERINFO=$(ceph auth get client.${RBD_POOL_USER}); then echo "Cephx user client.${RBD_POOL_USER} already exist." echo "Update its cephx caps" ceph auth caps client.${RBD_POOL_USER} \ mon "profile rbd" \ osd "${OSD_CAPS}" ceph auth get client.${RBD_POOL_USER} -o ${KEYRING} else #NOTE(JCL): Restrict Cinder permissions to what is needed. MON Read only and RBD access to Cinder pool only. ceph auth get-or-create client.${RBD_POOL_USER} \ mon "profile rbd" \ osd "${OSD_CAPS}" \ -o ${KEYRING} fi ENCODED_KEYRING=$(sed -n 's/^[[:blank:]]*key[[:blank:]]\+=[[:blank:]]\(.*\)/\1/p' ${KEYRING} | base64 -w0) cat > ${SECRET} < /etc/ceph/ceph.client.admin.keyring [client.admin] key = $(cat /tmp/client-keyring) EOF exit 0 cinder-api.sh: ---- #!/bin/bash set -ex COMMAND="${@:-start}" function start () { exec uwsgi --ini /etc/cinder/cinder-api-uwsgi.ini } function stop () { kill -TERM 1 } $COMMAND cinder-backup.sh: ---- #!/bin/bash set -ex exec cinder-backup \ --config-file /etc/cinder/cinder.conf ks-user.sh: ---- #!/bin/bash # Copyright 2017 Pete Birley # # 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 -ex shopt -s nocasematch if [[ "${SERVICE_OS_PROJECT_DOMAIN_NAME}" == "Default" ]] then PROJECT_DOMAIN_ID="default" else # Manage project domain PROJECT_DOMAIN_ID=$(openstack domain create --or-show --enable -f value -c id \ --description="Domain for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_PROJECT_DOMAIN_NAME}" \ "${SERVICE_OS_PROJECT_DOMAIN_NAME}") fi if [[ "${SERVICE_OS_USER_DOMAIN_NAME}" == "Default" ]] then USER_DOMAIN_ID="default" else # Manage user domain USER_DOMAIN_ID=$(openstack domain create --or-show --enable -f value -c id \ --description="Domain for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_USER_DOMAIN_NAME}" \ "${SERVICE_OS_USER_DOMAIN_NAME}") fi shopt -u nocasematch # Manage user project USER_PROJECT_DESC="Service Project for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_PROJECT_DOMAIN_NAME}" USER_PROJECT_ID=$(openstack project create --or-show --enable -f value -c id \ --domain="${PROJECT_DOMAIN_ID}" \ --description="${USER_PROJECT_DESC}" \ "${SERVICE_OS_PROJECT_NAME}"); # Manage user USER_DESC="Service User for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_USER_DOMAIN_NAME}/${SERVICE_OS_SERVICE_NAME}" USER_ID=$(openstack user create --or-show --enable -f value -c id \ --domain="${USER_DOMAIN_ID}" \ --project-domain="${PROJECT_DOMAIN_ID}" \ --project="${USER_PROJECT_ID}" \ --description="${USER_DESC}" \ "${SERVICE_OS_USERNAME}"); # Manage user password (we do this in a seperate step to ensure the password is updated if required) set +x echo "Setting user password via: openstack user set --password=xxxxxxx ${USER_ID}" openstack user set --password="${SERVICE_OS_PASSWORD}" "${USER_ID}" set -x function ks_assign_user_role () { if [[ "$SERVICE_OS_ROLE" == "admin" ]] then USER_ROLE_ID="$SERVICE_OS_ROLE" else USER_ROLE_ID=$(openstack role create --or-show -f value -c id "${SERVICE_OS_ROLE}"); fi # Manage user role assignment openstack role add \ --user="${USER_ID}" \ --user-domain="${USER_DOMAIN_ID}" \ --project-domain="${PROJECT_DOMAIN_ID}" \ --project="${USER_PROJECT_ID}" \ "${USER_ROLE_ID}" } # Manage user service role IFS=',' for SERVICE_OS_ROLE in ${SERVICE_OS_ROLES}; do ks_assign_user_role done # Manage user member role : ${MEMBER_OS_ROLE:="member"} export USER_ROLE_ID=$(openstack role create --or-show -f value -c id \ "${MEMBER_OS_ROLE}"); ks_assign_user_role retrieve-internal-tenant.sh: ---- #!/bin/bash set -ex USER_PROJECT_ID=$(openstack project show -f value -c id \ "${INTERNAL_PROJECT_NAME}"); USER_ID=$(openstack user show -f value -c id \ "${INTERNAL_USER_NAME}"); tee /tmp/pod-shared/internal_tenant.conf < ${SECRET} <