From b3f8b812ca74498a69d02752dd94760c7c3deb3b Mon Sep 17 00:00:00 2001
From: Pete Birley <pete@port.direct>
Date: Thu, 7 Sep 2017 02:22:41 -0500
Subject: [PATCH] Glance: Backend support and auth improvements

This PS enables the following backends for glance:
 * PVC
 * RBD
 * RadosGW (direct)
 * Swift

It also moves the creation of the RBD pool when required to a storage
init job. This job also creates credentials as required for glance to
use when accessing the required backend, rather than using the admin
keyring.

Change-Id: I90fead961ff73a9263826acc794128fa73ead2e1
---
 ceph/values.yaml                              |   1 -
 doc/source/install/developer/all-in-one.rst   |   2 +-
 doc/source/install/multinode.rst              |  14 ++
 glance/templates/bin/_ceph-keyring.sh.tpl     |   4 +-
 .../{_clean.sh.tpl => _clean-image.sh.tpl}    |   0
 glance/templates/bin/_clean-secrets.sh.tpl    |  21 +++
 glance/templates/bin/_storage-init.sh.tpl     |  76 ++++++++++
 glance/templates/configmap-bin.yaml           |   8 +-
 glance/templates/configmap-etc.yaml           |  28 +++-
 glance/templates/deployment-api.yaml          |  20 ++-
 glance/templates/etc/_swift-store.conf.tpl    |  30 ++++
 glance/templates/job-clean.yaml               |  28 +++-
 glance/templates/job-storage-init.yaml        | 133 ++++++++++++++++++
 glance/values.yaml                            |  49 ++++++-
 tools/gate/launch-osh/basic.sh                |  16 ++-
 tools/gate/vars.sh                            |   3 +
 tools/overrides/mvp/glance.yaml               |  33 -----
 17 files changed, 404 insertions(+), 62 deletions(-)
 rename glance/templates/bin/{_clean.sh.tpl => _clean-image.sh.tpl} (100%)
 create mode 100644 glance/templates/bin/_clean-secrets.sh.tpl
 create mode 100644 glance/templates/bin/_storage-init.sh.tpl
 create mode 100644 glance/templates/etc/_swift-store.conf.tpl
 create mode 100644 glance/templates/job-storage-init.yaml
 delete mode 100644 tools/overrides/mvp/glance.yaml

diff --git a/ceph/values.yaml b/ceph/values.yaml
index 784a03edf3..c25ed13c35 100644
--- a/ceph/values.yaml
+++ b/ceph/values.yaml
@@ -293,7 +293,6 @@ bootstrap:
       ceph osd pool stats $1 || ceph osd pool create $1 $2
     }
     ensure_pool volumes 8
-    ensure_pool images 8
 
 # if you change provision_storage_class to false
 # it is presumed you manage your own storage
diff --git a/doc/source/install/developer/all-in-one.rst b/doc/source/install/developer/all-in-one.rst
index 37e09dc4aa..5411ed1b6d 100644
--- a/doc/source/install/developer/all-in-one.rst
+++ b/doc/source/install/developer/all-in-one.rst
@@ -233,7 +233,7 @@ more sensible values for the All-in-One environment using the ``--values`` and
 
   helm install --name=keystone ./keystone --namespace=openstack
   helm install --name=glance ./glance --namespace=openstack \
-    --values=./tools/overrides/mvp/glance.yaml
+    --set storage=pvc
   helm install --name=nova ./nova --namespace=openstack \
     --values=./tools/overrides/mvp/nova.yaml \
     --set=conf.nova.libvirt.nova.conf.virt_type=qemu
diff --git a/doc/source/install/multinode.rst b/doc/source/install/multinode.rst
index 4b7a392dff..393bb5a54c 100644
--- a/doc/source/install/multinode.rst
+++ b/doc/source/install/multinode.rst
@@ -451,11 +451,25 @@ now create endpoints in the Keystone service catalog:
 
 **Install Glance:**
 
+Glance supports a number of backends:
+
+* ``pvc``: A simple file based backend using Kubernetes PVCs
+* ``rbd``: Uses Ceph RBD devices to store images.
+* ``radosgw``: Uses Ceph RadosGW object storage to store images.
+* ``swift``: Uses the ``object-storage`` service from the OpenStack service
+  catalog to store images.
+
+You can deploy Glance with any of these backends if you deployed both the
+RadosGW and created Keystone endpoints by changing the value for
+``GLANCE_BACKEND`` in the following:
+
 ::
 
+    : ${GLANCE_BACKEND:="radosgw"}
     helm install --namespace=openstack --name=glance ./glance \
       --set pod.replicas.api=2 \
       --set pod.replicas.registry=2
+      --set storage=${GLANCE_BACKEND}
 
 **Install Heat:**
 
diff --git a/glance/templates/bin/_ceph-keyring.sh.tpl b/glance/templates/bin/_ceph-keyring.sh.tpl
index 709191e48a..aa3a3e842d 100644
--- a/glance/templates/bin/_ceph-keyring.sh.tpl
+++ b/glance/templates/bin/_ceph-keyring.sh.tpl
@@ -19,8 +19,8 @@ limitations under the License.
 set -ex
 export HOME=/tmp
 
-cat <<EOF > /etc/ceph/ceph.client.{{ .Values.conf.glance.glance_store.glance.store.rbd_store_user }}.keyring
-[client.{{ .Values.conf.glance.glance_store.glance.store.rbd_store_user }}]
+cat <<EOF > /etc/ceph/ceph.client.${RBD_STORE_USER}.keyring
+[client.${RBD_STORE_USER}]
 {{- if .Values.conf.ceph.keyring }}
     key = {{ .Values.conf.ceph.keyring }}
 {{- else }}
diff --git a/glance/templates/bin/_clean.sh.tpl b/glance/templates/bin/_clean-image.sh.tpl
similarity index 100%
rename from glance/templates/bin/_clean.sh.tpl
rename to glance/templates/bin/_clean-image.sh.tpl
diff --git a/glance/templates/bin/_clean-secrets.sh.tpl b/glance/templates/bin/_clean-secrets.sh.tpl
new file mode 100644
index 0000000000..618458d1ee
--- /dev/null
+++ b/glance/templates/bin/_clean-secrets.sh.tpl
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+{{/*
+Copyright 2017 The Openstack-Helm Authors.
+
+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
+
+exec kubectl delete secret --namespace ${NAMESPACE} ${RBD_POOL_SECRET}
diff --git a/glance/templates/bin/_storage-init.sh.tpl b/glance/templates/bin/_storage-init.sh.tpl
new file mode 100644
index 0000000000..91522eaba2
--- /dev/null
+++ b/glance/templates/bin/_storage-init.sh.tpl
@@ -0,0 +1,76 @@
+#!/bin/bash
+
+{{/*
+Copyright 2017 The Openstack-Helm Authors.
+
+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 -x
+if [ "x$STORAGE_BACKEND" == "xrbd" ]; 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" == "xpvc" ] || [ "x$STORAGE_BACKEND" == "xswift" ]; then
+  echo "No action required."
+elif [ "x$STORAGE_BACKEND" == "xrbd" ]; then
+  ceph -s
+  function ensure_pool () {
+    ceph osd pool stats $1 || ceph osd pool create $1 $2
+  }
+  ensure_pool ${RBD_POOL_NAME} ${RBD_POOL_CHUNK_SIZE}
+
+  #NOTE(Portdirect): Determine proper privs to assign keyring
+  ceph auth get-or-create client.${RBD_POOL_USER} \
+    mon "allow *" \
+    osd "allow *" \
+    -o ${KEYRING}
+
+  ENCODED_KEYRING=$(sed -n 's/^[[:blank:]]*key[[:blank:]]\+=[[:blank:]]\(.*\)/\1/p' ${KEYRING} | base64 -w0)
+  cat > ${SECRET} <<EOF
+apiVersion: v1
+kind: Secret
+metadata:
+  name: "${RBD_POOL_SECRET}"
+type: kubernetes.io/rbd
+data:
+  key: |
+    $( echo ${ENCODED_KEYRING} )
+EOF
+  kubectl create --namespace ${NAMESPACE} -f ${SECRET}
+elif [ "x$STORAGE_BACKEND" == "xradosgw" ]; then
+  radosgw-admin user stats --uid="${RADOSGW_USERNAME}" || \
+    radosgw-admin user create \
+      --uid="${RADOSGW_USERNAME}" \
+      --display-name="${RADOSGW_USERNAME} user"
+
+  radosgw-admin subuser create \
+    --uid=${RADOSGW_USERNAME} \
+    --subuser=${RADOSGW_USERNAME}:swift \
+    --access=full
+
+  radosgw-admin key create \
+    --subuser=${RADOSGW_USERNAME}:swift \
+    --key-type=swift \
+    --secret=${RADOSGW_PASSWORD}
+
+  radosgw-admin user modify \
+    --uid=${RADOSGW_USERNAME} \
+    --temp-url-key=${RADOSGW_TMPURL_KEY}
+fi
diff --git a/glance/templates/configmap-bin.yaml b/glance/templates/configmap-bin.yaml
index 56917d3632..275a8d7afc 100644
--- a/glance/templates/configmap-bin.yaml
+++ b/glance/templates/configmap-bin.yaml
@@ -25,6 +25,8 @@ metadata:
 data:
   rally-test.sh: |
 {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }}
+  storage-init.sh: |+
+{{ tuple "bin/_storage-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
   db-init.py: |
 {{- include "helm-toolkit.scripts.db_init" . | indent 4 }}
   db-sync.sh: |
@@ -43,6 +45,8 @@ data:
 {{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
   ceph-keyring.sh: |+
 {{ tuple "bin/_ceph-keyring.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
-  clean.sh: |+
-{{ tuple "bin/_clean.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
+  clean-image.sh: |+
+{{ tuple "bin/_clean-image.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
+  clean-secrets.sh: |+
+{{ tuple "bin/_clean-secrets.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
 {{- end }}
diff --git a/glance/templates/configmap-etc.yaml b/glance/templates/configmap-etc.yaml
index b1fd2d0eb8..6a990d57cb 100644
--- a/glance/templates/configmap-etc.yaml
+++ b/glance/templates/configmap-etc.yaml
@@ -115,7 +115,31 @@ limitations under the License.
 {{- end -}}
 
 {{- if empty .Values.conf.glance.default.glance.api.public_endpoint -}}
-{{- tuple "image" "public" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set .Values.conf.glance.default.glance.api "public_endpoint" | quote | trunc 0 -}}
+{{- tuple "image" "public" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.glance.default.glance.api "public_endpoint" | quote | trunc 0 -}}
+{{- end -}}
+
+{{- if empty .Values.conf.glance.glance_store.glance.store.stores -}}
+{{- if eq .Values.storage "rbd" }}
+{{- "file, http, rbd" | set .Values.conf.glance.glance_store.glance.store "stores" | quote | trunc 0 -}}
+{{- end -}}
+{{- if eq .Values.storage "pvc" }}
+{{- "file, http" | set .Values.conf.glance.glance_store.glance.store "stores" | quote | trunc 0 -}}
+{{- end -}}
+{{ if or (eq .Values.storage "radosgw") (eq .Values.storage "swift") }}
+{{- "file, http, swift" | set .Values.conf.glance.glance_store.glance.store "stores" | quote | trunc 0 -}}
+{{- end -}}
+{{- end -}}
+
+{{- if empty .Values.conf.glance.glance_store.glance.store.default_store -}}
+{{- if eq .Values.storage "rbd" }}
+{{- "rbd" | set .Values.conf.glance.glance_store.glance.store "default_store" | quote | trunc 0 -}}
+{{- end -}}
+{{- if eq .Values.storage "pvc" }}
+{{- "file" | set .Values.conf.glance.glance_store.glance.store "default_store" | quote | trunc 0 -}}
+{{- end -}}
+{{ if or (eq .Values.storage "radosgw") (eq .Values.storage "swift") }}
+{{- "swift" | set .Values.conf.glance.glance_store.glance.store "default_store" | quote | trunc 0 -}}
+{{- end -}}
 {{- end -}}
 
 ---
@@ -136,4 +160,6 @@ data:
 {{- tuple .Values.conf.paste_registry "etc/_glance-registry-paste.ini.tpl" . | include "helm-toolkit.utils.configmap_templater" }}
   policy.json: |+
 {{  toJson .Values.conf.policy | indent 4 }}
+  swift-store.conf: |+
+{{- tuple .Values.conf.swift_store "etc/_swift-store.conf.tpl" . | include "helm-toolkit.utils.configmap_templater" }}
 {{- end }}
diff --git a/glance/templates/deployment-api.yaml b/glance/templates/deployment-api.yaml
index d7d3d4ad88..50cf810672 100644
--- a/glance/templates/deployment-api.yaml
+++ b/glance/templates/deployment-api.yaml
@@ -42,7 +42,6 @@ spec:
       terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "600" }}
       initContainers:
 {{ tuple $envAll $dependencies $mounts_glance_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
-        {{- if eq .Values.storage "pvc" }}
         - name: glance-perms
           image: {{ .Values.images.api }}
           imagePullPolicy: {{ .Values.images.pull_policy }}
@@ -57,13 +56,15 @@ spec:
           volumeMounts:
             - name: glance-images
               mountPath: {{ .Values.conf.glance.glance_store.glance.store.filesystem_store_datadir }}
-        {{- end }}
-        {{ if eq .Values.storage "ceph" }}
+        {{ if eq .Values.storage "rbd" }}
         - name: ceph-keyring-placement
           image: {{ .Values.images.api }}
           imagePullPolicy: {{ .Values.images.pull_policy }}
           securityContext:
             runAsUser: {{ .Values.pod.user.glance.uid }}
+          env:
+            - name: RBD_STORE_USER
+              value: {{ .Values.conf.glance.glance_store.glance.store.rbd_store_user | quote }}
           command:
             - /tmp/ceph-keyring.sh
           volumeMounts:
@@ -118,10 +119,13 @@ spec:
               mountPath: /etc/glance/policy.json
               subPath: policy.json
               readOnly: true
-{{- if eq .Values.storage "pvc" }}
+            - name: glance-etc
+              mountPath: {{ .Values.conf.glance.glance_store.glance.store.swift_store_config_file }}
+              subPath: swift-store.conf
+              readOnly: true
             - name: glance-images
               mountPath: {{ .Values.conf.glance.glance_store.glance.store.filesystem_store_datadir }}
-{{- else }}
+{{- if eq .Values.storage "rbd" }}
             - name: etcceph
               mountPath: /etc/ceph
             - name: ceph-etc
@@ -150,6 +154,10 @@ spec:
           persistentVolumeClaim:
             claimName: glance-images
 {{ else }}
+        - name: glance-images
+          emptyDir: {}
+{{- end }}
+{{- if eq .Values.storage "rbd" }}
         - name: etcceph
           emptyDir: {}
         - name: ceph-etc
@@ -158,7 +166,7 @@ spec:
             defaultMode: 0444
         - name: ceph-keyring
           secret:
-            secretName: pvc-ceph-client-key
+            secretName: {{ .Values.secrets.rbd | quote }}
 {{- end }}
 {{ if $mounts_glance_api.volumes }}{{ toYaml $mounts_glance_api.volumes | indent 8 }}{{ end }}
 {{- end }}
diff --git a/glance/templates/etc/_swift-store.conf.tpl b/glance/templates/etc/_swift-store.conf.tpl
new file mode 100644
index 0000000000..809e7dac8e
--- /dev/null
+++ b/glance/templates/etc/_swift-store.conf.tpl
@@ -0,0 +1,30 @@
+{{/*
+Copyright 2017 The Openstack-Helm Authors.
+
+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.
+*/}}
+
+[{{ .Values.conf.glance.glance_store.glance.store.default_swift_reference }}]
+{{- if eq .Values.storage "radosgw" }}
+auth_version = 1
+auth_address = {{ tuple "ceph_object_store" "public" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }}
+user = {{ .Values.endpoints.ceph_object_store.auth.user.username }}:swift
+key = {{ .Values.endpoints.ceph_object_store.auth.user.password }}
+{{- else }}
+user = {{ .Values.endpoints.identity.auth.user.project_name }}:{{ .Values.endpoints.identity.auth.user.username }}
+key = {{ .Values.endpoints.identity.auth.user.password }}
+auth_address = {{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" }}
+user_domain_name = {{ .Values.endpoints.identity.auth.user.user_domain_name }}
+project_domain_name = {{ .Values.endpoints.identity.auth.user.project_domain_name }}
+auth_version = 3
+{{- end -}}
diff --git a/glance/templates/job-clean.yaml b/glance/templates/job-clean.yaml
index a433bb4403..986ed1df47 100644
--- a/glance/templates/job-clean.yaml
+++ b/glance/templates/job-clean.yaml
@@ -32,7 +32,27 @@ spec:
     spec:
       restartPolicy: OnFailure
       containers:
-        - name: glance-clean
+        {{- if eq .Values.storage "rbd" }}
+        - name: glance-secret-clean
+          image: {{ .Values.images.storage_init }}
+          imagePullPolicy: {{ .Values.images.pull_policy }}
+{{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+          env:
+            - name: NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+            - name: RBD_POOL_SECRET
+              value: {{ .Values.secrets.rbd | quote }}
+          command:
+            - /tmp/clean-secrets.sh
+          volumeMounts:
+            - name: glance-bin
+              mountPath: /tmp/clean-secrets.sh
+              subPath: clean-secrets.sh
+              readOnly: true
+        {{ end }}
+        - name: glance-image-clean
           image: {{ .Values.images.bootstrap }}
           imagePullPolicy: {{ .Values.images.pull_policy }}
 {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
@@ -41,11 +61,11 @@ spec:
 {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }}
 {{- end }}
           command:
-            - /tmp/clean.sh
+            - /tmp/clean-image.sh
           volumeMounts:
             - name: glance-bin
-              mountPath: /tmp/clean.sh
-              subPath: clean.sh
+              mountPath: /tmp/clean-image.sh
+              subPath: clean-image.sh
               readOnly: true
       volumes:
         - name: glance-bin
diff --git a/glance/templates/job-storage-init.yaml b/glance/templates/job-storage-init.yaml
new file mode 100644
index 0000000000..0611a488dd
--- /dev/null
+++ b/glance/templates/job-storage-init.yaml
@@ -0,0 +1,133 @@
+{{/*
+Copyright 2017 The Openstack-Helm Authors.
+
+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.
+*/}}
+
+{{- if .Values.manifests.job_storage_init }}
+{{- $envAll := . }}
+{{- $dependencies := .Values.dependencies.storage_init }}
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: glance-storage-init
+spec:
+  template:
+    metadata:
+      labels:
+{{ tuple $envAll "glance" "storage-init" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
+    spec:
+      restartPolicy: OnFailure
+      nodeSelector:
+        {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }}
+      initContainers:
+{{ tuple $envAll $dependencies "[]" | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
+        {{ if or (eq .Values.storage "rbd") (eq .Values.storage "radosgw") }}
+        - name: ceph-keyring-placement
+          image: {{ .Values.images.api }}
+          imagePullPolicy: {{ .Values.images.pull_policy }}
+          securityContext:
+            runAsUser: {{ .Values.pod.user.glance.uid }}
+          env:
+            - name: RBD_STORE_USER
+              value: admin
+          command:
+            - /tmp/ceph-keyring.sh
+          volumeMounts:
+            - name: etcceph
+              mountPath: /etc/ceph
+            - name: glance-bin
+              mountPath: /tmp/ceph-keyring.sh
+              subPath: ceph-keyring.sh
+              readOnly: true
+            - name: ceph-keyring
+              mountPath: /tmp/client-keyring
+              subPath: key
+              readOnly: true
+        {{ end }}
+      containers:
+        - name: glance-storage-init
+          image: {{ .Values.images.storage_init }}
+          imagePullPolicy: {{ .Values.images.pull_policy }}
+{{ tuple $envAll $envAll.Values.pod.resources.jobs.storage_init | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+          env:
+            - name: NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+            - name: STORAGE_BACKEND
+              value: {{ .Values.storage | quote }}
+            {{- if eq .Values.storage "rbd" }}
+            - name: RBD_POOL_NAME
+              value: {{ .Values.conf.glance.glance_store.glance.store.rbd_store_pool | quote }}
+            - name: RBD_POOL_USER
+              value: {{ .Values.conf.glance.glance_store.glance.store.rbd_store_user | quote }}
+            - name: RBD_POOL_CHUNK_SIZE
+              value: {{ .Values.conf.glance.glance_store.glance.store.rbd_store_chunk_size | quote }}
+            - name: RBD_POOL_SECRET
+              value: {{ .Values.secrets.rbd | quote }}
+            {{ end }}
+            {{- if eq .Values.storage "radosgw" }}
+            - name: RADOSGW_USERNAME
+              value: {{ .Values.endpoints.ceph_object_store.auth.user.username | quote }}
+            - name: RADOSGW_PASSWORD
+              value: {{ .Values.endpoints.ceph_object_store.auth.user.password | quote }}
+            - name: RADOSGW_TMPURL_KEY
+              value: {{ .Values.endpoints.ceph_object_store.auth.user.tmpurlkey | quote }}
+            {{ end }}
+          command:
+            - /tmp/storage-init.sh
+          volumeMounts:
+            - name: glance-bin
+              mountPath: /tmp/storage-init.sh
+              subPath: storage-init.sh
+              readOnly: true
+            {{ if or (eq .Values.storage "rbd") (eq .Values.storage "radosgw") }}
+            - name: etcceph
+              mountPath: /etc/ceph
+            - name: ceph-etc
+              mountPath: /etc/ceph/ceph.conf
+              subPath: ceph.conf
+              readOnly: true
+            - name: ceph-keyring
+              mountPath: /tmp/client-keyring
+              subPath: key
+              readOnly: true
+            {{ end }}
+            {{- if eq .Values.storage "pvc" }}
+            - name: glance-images
+              mountPath: {{ .Values.conf.glance.glance_store.glance.store.filesystem_store_datadir }}
+            {{ end }}
+      volumes:
+        - name: glance-bin
+          configMap:
+            name: glance-bin
+            defaultMode: 0555
+        {{ if or (eq .Values.storage "rbd") (eq .Values.storage "radosgw") }}
+        - name: etcceph
+          emptyDir: {}
+        - name: ceph-etc
+          configMap:
+            name: ceph-etc
+            defaultMode: 0444
+        - name: ceph-keyring
+          secret:
+            secretName: pvc-ceph-client-key
+        {{ end }}
+        {{- if eq .Values.storage "pvc" }}
+        - name: glance-images
+          persistentVolumeClaim:
+            claimName: glance-images
+        {{ end }}
+{{- end }}
diff --git a/glance/values.yaml b/glance/values.yaml
index 616e05b531..7db3359b73 100644
--- a/glance/values.yaml
+++ b/glance/values.yaml
@@ -17,8 +17,8 @@
 # Declare name/value pairs to be passed into your templates.
 # name: value
 
-# ceph or pvc
-storage: ceph
+# radosgw, rbd, swift or pvc
+storage: radosgw
 
 labels:
   node_selector_key: openstack-control-plane
@@ -28,6 +28,7 @@ release_group: null
 
 images:
   test: docker.io/kolla/ubuntu-source-rally:4.0.0
+  storage_init: quay.io/attcomdev/ceph-daemon:tag-build-master-jewel-ubuntu-16.04
   db_init: docker.io/kolla/ubuntu-source-heat-engine:3.0.3
   db_sync: docker.io/kolla/ubuntu-source-glance-api:3.0.3
   ks_user: docker.io/kolla/ubuntu-source-heat-engine:3.0.3
@@ -139,13 +140,15 @@ conf:
     glance_store:
       glance:
         store:
-          stores: file, http, rbd
-          default_store: rbd
           rbd_store_chunk_size: 8
           rbd_store_pool: images
-          rbd_store_user: admin
+          rbd_store_user: images
           rbd_store_ceph_conf: /etc/ceph/ceph.conf
           filesystem_store_datadir: /var/lib/glance/images
+          default_swift_reference: ref1
+          swift_store_container: glance
+          swift_store_create_container_on_put: true
+          swift_store_config_file: /etc/glance/swift-store.conf
     paste_deploy:
       glance:
         api:
@@ -170,6 +173,9 @@ conf:
       glance:
         registry:
           flavor: keystone
+  swift_store:
+    override:
+    append:
 
 network:
   api:
@@ -191,6 +197,8 @@ volume:
   size: 2Gi
 
 dependencies:
+  storage_init:
+    services:
   db_init:
     services:
     - service: oslo_db
@@ -203,6 +211,7 @@ dependencies:
       endpoint: internal
   bootstrap:
     jobs:
+    - glance-storage-init
     - glance-db-sync
     - glance-ks-user
     - glance-ks-endpoints
@@ -227,6 +236,7 @@ dependencies:
       endpoint: internal
   api:
     jobs:
+    - glance-storage-init
     - glance-db-sync
     - glance-ks-user
     - glance-ks-endpoints
@@ -237,6 +247,7 @@ dependencies:
       endpoint: internal
   registry:
     jobs:
+    - glance-storage-init
     - glance-db-sync
     - glance-ks-user
     - glance-ks-endpoints
@@ -264,6 +275,7 @@ secrets:
   oslo_db:
     admin: glance-db-admin
     user: glance-db-user
+  rbd: images-rbd-keyring
 
 # typically overriden by environmental
 # values, but should include all endpoints
@@ -374,6 +386,25 @@ endpoints:
     port:
       amqp:
         default: 5672
+  ceph_object_store:
+    name: radosgw
+    namespace: ceph
+    auth:
+      user:
+        username: glance
+        password: password
+        tmpurlkey: supersecret
+    hosts:
+      default: ceph-rgw
+    host_fqdn_override:
+      default: null
+    path:
+      default: /auth/v1.0
+    scheme:
+      default: http
+    port:
+      api:
+        default: 8088
 
 pod:
   user:
@@ -433,6 +464,13 @@ pod:
         memory: "1024Mi"
         cpu: "2000m"
     jobs:
+      storage_init:
+        requests:
+          memory: "128Mi"
+          cpu: "100m"
+        limits:
+          memory: "1024Mi"
+          cpu: "2000m"
       db_sync:
         requests:
           memory: "128Mi"
@@ -497,6 +535,7 @@ manifests:
   job_ks_endpoints: true
   job_ks_service: true
   job_ks_user: true
+  job_storage_init: true
   pdb_api: true
   pdb_registry: true
   pod_rally_test: true
diff --git a/tools/gate/launch-osh/basic.sh b/tools/gate/launch-osh/basic.sh
index 6bd509e385..fe9733c8d9 100755
--- a/tools/gate/launch-osh/basic.sh
+++ b/tools/gate/launch-osh/basic.sh
@@ -117,17 +117,19 @@ fi
 
 helm install --namespace=openstack ${WORK_DIR}/etcd --name=etcd-rabbitmq
 helm install --namespace=openstack ${WORK_DIR}/rabbitmq --name=rabbitmq
+
+if [[ "x${PVC_BACKEND}" != "xceph"  ]] && [[ "x${GLANCE}" != "xpvc" ]] ; then
+    echo "Gate only supports glance with pvc backend when not using ceph"
+    exit 1
+fi
+helm install --namespace=openstack ${WORK_DIR}/glance --name=glance \
+  --set storage=${GLANCE}
+kube_wait_for_pods openstack ${SERVICE_LAUNCH_TIMEOUT}
+
 helm install --namespace=openstack ${WORK_DIR}/libvirt --name=libvirt
 helm install --namespace=openstack ${WORK_DIR}/openvswitch --name=openvswitch
 kube_wait_for_pods openstack ${SERVICE_LAUNCH_TIMEOUT}
 
-if [ "x$PVC_BACKEND" == "xceph" ]; then
-  helm install --namespace=openstack ${WORK_DIR}/glance --name=glance
-else
-  helm install --namespace=openstack ${WORK_DIR}/glance --name=glance \
-    --values=${WORK_DIR}/tools/overrides/mvp/glance.yaml
-fi
-kube_wait_for_pods openstack ${SERVICE_LAUNCH_TIMEOUT}
 if [ "x$PVC_BACKEND" == "xceph" ]; then
   helm install --namespace=openstack ${WORK_DIR}/nova --name=nova \
     --set=conf.nova.libvirt.nova.conf.virt_type=qemu
diff --git a/tools/gate/vars.sh b/tools/gate/vars.sh
index e680179e04..aeeffe26d3 100755
--- a/tools/gate/vars.sh
+++ b/tools/gate/vars.sh
@@ -41,6 +41,9 @@ export PVC_BACKEND=${PVC_BACKEND:-"ceph"}
 export CEPH_RGW_KEYSTONE_ENABLED=${CEPH_RGW_KEYSTONE_ENABLED:-"true"}
 export OPENSTACK_OBJECT_STORAGE=${OPENSTACK_OBJECT_STORAGE:-"radosgw"}
 
+# Set Glance Backend options
+export GLANCE=${GLANCE:-"radosgw"}
+
 # Set Upstream DNS
 export UPSTREAM_DNS=${UPSTREAM_DNS:-"8.8.8.8"}
 
diff --git a/tools/overrides/mvp/glance.yaml b/tools/overrides/mvp/glance.yaml
deleted file mode 100644
index 2ba89cc3ca..0000000000
--- a/tools/overrides/mvp/glance.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2017 The Openstack-Helm Authors.
-#
-# 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.
-
-# MVP values for glance.
-# This file contains overrides to launch a MVP deployment of glance for the
-# OpenStack-Helm Single node gates, and local development use. It should be
-# kept to the bare minimum required for this purpose.
-
-storage: pvc
-
-conf:
-  glance:
-    default:
-      oslo:
-        log:
-          debug: false
-    glance_store:
-      glance:
-        store:
-          stores: file, http
-          default_store: file
-          filesystem_store_datadir: /var/lib/glance/images