Support extras in Glance Store install

Recent change to devstack dropped installing test-requirements [1]
However, this caused gate failures due to lack of glance-store
deps for cinder and swift support.

This patch makes devstack install relevant extras depending on
enabled features.

Additionally, relevant functions are added/fixed to make this
possible.

glance-store = glance_store (for gerrit search match)

[1] https://review.opendev.org/715469

Change-Id: I0bf5792a6058b52936115b515ea8360f6264a7c9
diff --git a/inc/python b/inc/python
index 30b9a30..dd77296 100644
--- a/inc/python
+++ b/inc/python
@@ -21,6 +21,14 @@
 # project.  A null value installs to the system Python directories.
 declare -A -g PROJECT_VENV
 
+# Utility Functions
+# =================
+
+# Joins bash array of extras with commas as expected by other functions
+function join_extras {
+    local IFS=","
+    echo "$*"
+}
 
 # Python Functions
 # ================
@@ -80,9 +88,9 @@
 function pip_install_gr_extras {
     local name=$1
     local extras=$2
-    local clean_name
-    clean_name=$(get_from_global_requirements $name)
-    pip_install $clean_name[$extras]
+    local version_constraints
+    version_constraints=$(get_version_constraints_from_global_requirements $name)
+    pip_install $name[$extras]$version_constraints
 }
 
 # enable_python3_package() -- no-op for backwards compatibility
@@ -230,6 +238,19 @@
     echo $required_pkg
 }
 
+# get only version constraints of a package from global requirements file
+# get_version_constraints_from_global_requirements <package>
+function get_version_constraints_from_global_requirements {
+    local package=$1
+    local required_pkg_version_constraint
+    # drop the package name from output (\K)
+    required_pkg_version_constraint=$(grep -i -h -o -P "^${package}\K.*" $REQUIREMENTS_DIR/global-requirements.txt | cut -d\# -f1)
+    if [[ $required_pkg_version_constraint == ""  ]]; then
+        die $LINENO "Can't find package $package in requirements"
+    fi
+    echo $required_pkg_version_constraint
+}
+
 # should we use this library from their git repo, or should we let it
 # get pulled in via pip dependencies.
 function use_library_from_git {
@@ -278,7 +299,7 @@
 #
 # use this for non namespaced libraries
 #
-# setup_dev_lib [-bindep] <name>
+# setup_dev_lib [-bindep] <name> [<extras>]
 function setup_dev_lib {
     local bindep
     if [[ $1 == -bindep* ]]; then
@@ -287,7 +308,8 @@
     fi
     local name=$1
     local dir=${GITDIR[$name]}
-    setup_develop $bindep $dir
+    local extras=$2
+    setup_develop $bindep $dir $extras
 }
 
 # this should be used if you want to install globally, all libraries should
diff --git a/lib/glance b/lib/glance
index e8f846f..9398bd2 100644
--- a/lib/glance
+++ b/lib/glance
@@ -355,11 +355,24 @@
 
 # install_glance() - Collect source and prepare
 function install_glance {
+    local glance_store_extras=()
+
+    if is_service_enabled cinder; then
+        glance_store_extras=("cinder" "${glance_store_extras[@]}")
+    fi
+
+    if is_service_enabled swift; then
+        glance_store_extras=("swift" "${glance_store_extras[@]}")
+    fi
+
     # Install glance_store from git so we make sure we're testing
     # the latest code.
     if use_library_from_git "glance_store"; then
         git_clone_by_name "glance_store"
-        setup_dev_lib "glance_store"
+        setup_dev_lib "glance_store" $(join_extras "${glance_store_extras[@]}")
+    else
+        # we still need to pass extras
+        pip_install_gr_extras glance-store $(join_extras "${glance_store_extras[@]}")
     fi
 
     git_clone $GLANCE_REPO $GLANCE_DIR $GLANCE_BRANCH