From 7ca90cded374685c8c68ea50381220b915eb0b63 Mon Sep 17 00:00:00 2001 From: Adam Gandelman Date: Wed, 4 Mar 2015 17:25:07 -0800 Subject: [PATCH] Allow devstack plugins to specify prereq packages We offer main devstack components the ability to install their own system package preqreqs via files/{debs, rpms}/$service. This adds similar functionality for plugins, who can now do the same in their own tree at ./devstack/files/{debs, rpms}/$plugin. Change-Id: I63af8dc54c75a6e80ca4b2a96c76233a0795aabb --- doc/source/plugins.rst | 21 +++++ functions-common | 183 +++++++++++++++++++++++---------------- tools/install_prereqs.sh | 2 + 3 files changed, 130 insertions(+), 76 deletions(-) diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst index 5d6d3f183d..a9153df0d1 100644 --- a/doc/source/plugins.rst +++ b/doc/source/plugins.rst @@ -154,3 +154,24 @@ functions: - ``start_nova_hypervisor`` - start any external services - ``stop_nova_hypervisor`` - stop any external services - ``cleanup_nova_hypervisor`` - remove transient data and cache + +System Packages +=============== + +Devstack provides a framework for getting packages installed at an early +phase of its execution. This packages may be defined in a plugin as files +that contain new-line separated lists of packages required by the plugin + +Supported packaging systems include apt and yum across multiple distributions. +To enable a plugin to hook into this and install package dependencies, packages +may be listed at the following locations in the top-level of the plugin +repository: + +- ``./devstack/files/debs/$plugin_name`` - Packages to install when running + on Ubuntu, Debian or Linux Mint. + +- ``./devstack/files/rpms/$plugin_name`` - Packages to install when running + on Red Hat, Fedora, CentOS or XenServer. + +- ``./devstack/files/rpms-suse/$plugin_name`` - Packages to install when + running on SUSE Linux or openSUSE. diff --git a/functions-common b/functions-common index df69cbad16..e791ad79c8 100644 --- a/functions-common +++ b/functions-common @@ -973,13 +973,18 @@ function get_or_create_endpoint { # _get_package_dir function _get_package_dir { + local base_dir=$1 local pkg_dir + + if [[ -z "$base_dir" ]]; then + base_dir=$FILES + fi if is_ubuntu; then - pkg_dir=$FILES/debs + pkg_dir=$base_dir/debs elif is_fedora; then - pkg_dir=$FILES/rpms + pkg_dir=$base_dir/rpms elif is_suse; then - pkg_dir=$FILES/rpms-suse + pkg_dir=$base_dir/rpms-suse else exit_distro_not_supported "list of packages" fi @@ -1005,84 +1010,14 @@ function apt_get { apt-get --option "Dpkg::Options::=--force-confold" --assume-yes "$@" } -# get_packages() collects a list of package names of any type from the -# prerequisite files in ``files/{debs|rpms}``. The list is intended -# to be passed to a package installer such as apt or yum. -# -# Only packages required for the services in 1st argument will be -# included. Two bits of metadata are recognized in the prerequisite files: -# -# - ``# NOPRIME`` defers installation to be performed later in `stack.sh` -# - ``# dist:DISTRO`` or ``dist:DISTRO1,DISTRO2`` limits the selection -# of the package to the distros listed. The distro names are case insensitive. -function get_packages { - local xtrace=$(set +o | grep xtrace) - set +o xtrace - local services=$@ - local package_dir=$(_get_package_dir) - local file_to_parse="" - local service="" +function _parse_package_files { + local files_to_parse=$@ - INSTALL_TESTONLY_PACKAGES=$(trueorfalse False INSTALL_TESTONLY_PACKAGES) - - if [[ -z "$package_dir" ]]; then - echo "No package directory supplied" - return 1 - fi if [[ -z "$DISTRO" ]]; then GetDistro fi - for service in ${services//,/ }; do - # Allow individual services to specify dependencies - if [[ -e ${package_dir}/${service} ]]; then - file_to_parse="${file_to_parse} $service" - fi - # NOTE(sdague) n-api needs glance for now because that's where - # glance client is - if [[ $service == n-api ]]; then - if [[ ! $file_to_parse =~ nova ]]; then - file_to_parse="${file_to_parse} nova" - fi - if [[ ! $file_to_parse =~ glance ]]; then - file_to_parse="${file_to_parse} glance" - fi - elif [[ $service == c-* ]]; then - if [[ ! $file_to_parse =~ cinder ]]; then - file_to_parse="${file_to_parse} cinder" - fi - elif [[ $service == ceilometer-* ]]; then - if [[ ! $file_to_parse =~ ceilometer ]]; then - file_to_parse="${file_to_parse} ceilometer" - fi - elif [[ $service == s-* ]]; then - if [[ ! $file_to_parse =~ swift ]]; then - file_to_parse="${file_to_parse} swift" - fi - elif [[ $service == n-* ]]; then - if [[ ! $file_to_parse =~ nova ]]; then - file_to_parse="${file_to_parse} nova" - fi - elif [[ $service == g-* ]]; then - if [[ ! $file_to_parse =~ glance ]]; then - file_to_parse="${file_to_parse} glance" - fi - elif [[ $service == key* ]]; then - if [[ ! $file_to_parse =~ keystone ]]; then - file_to_parse="${file_to_parse} keystone" - fi - elif [[ $service == q-* ]]; then - if [[ ! $file_to_parse =~ neutron ]]; then - file_to_parse="${file_to_parse} neutron" - fi - elif [[ $service == ir-* ]]; then - if [[ ! $file_to_parse =~ ironic ]]; then - file_to_parse="${file_to_parse} ironic" - fi - fi - done - for file in ${file_to_parse}; do - local fname=${package_dir}/${file} + for fname in ${files_to_parse}; do local OIFS line package distros distro [[ -e $fname ]] || continue @@ -1126,6 +1061,102 @@ function get_packages { done IFS=$OIFS done +} + +# get_packages() collects a list of package names of any type from the +# prerequisite files in ``files/{debs|rpms}``. The list is intended +# to be passed to a package installer such as apt or yum. +# +# Only packages required for the services in 1st argument will be +# included. Two bits of metadata are recognized in the prerequisite files: +# +# - ``# NOPRIME`` defers installation to be performed later in `stack.sh` +# - ``# dist:DISTRO`` or ``dist:DISTRO1,DISTRO2`` limits the selection +# of the package to the distros listed. The distro names are case insensitive. +function get_packages { + local xtrace=$(set +o | grep xtrace) + set +o xtrace + local services=$@ + local package_dir=$(_get_package_dir) + local file_to_parse="" + local service="" + + INSTALL_TESTONLY_PACKAGES=$(trueorfalse False INSTALL_TESTONLY_PACKAGES) + + if [[ -z "$package_dir" ]]; then + echo "No package directory supplied" + return 1 + fi + for service in ${services//,/ }; do + # Allow individual services to specify dependencies + if [[ -e ${package_dir}/${service} ]]; then + file_to_parse="${file_to_parse} ${package_dir}/${service}" + fi + # NOTE(sdague) n-api needs glance for now because that's where + # glance client is + if [[ $service == n-api ]]; then + if [[ ! $file_to_parse =~ nova ]]; then + file_to_parse="${file_to_parse} ${package_dir}/nova" + fi + if [[ ! $file_to_parse =~ glance ]]; then + file_to_parse="${file_to_parse} ${package_dir}/glance" + fi + elif [[ $service == c-* ]]; then + if [[ ! $file_to_parse =~ cinder ]]; then + file_to_parse="${file_to_parse} ${package_dir}/cinder" + fi + elif [[ $service == ceilometer-* ]]; then + if [[ ! $file_to_parse =~ ceilometer ]]; then + file_to_parse="${file_to_parse} ${package_dir}/ceilometer" + fi + elif [[ $service == s-* ]]; then + if [[ ! $file_to_parse =~ swift ]]; then + file_to_parse="${file_to_parse} ${package_dir}/swift" + fi + elif [[ $service == n-* ]]; then + if [[ ! $file_to_parse =~ nova ]]; then + file_to_parse="${file_to_parse} ${package_dir}/nova" + fi + elif [[ $service == g-* ]]; then + if [[ ! $file_to_parse =~ glance ]]; then + file_to_parse="${file_to_parse} ${package_dir}/glance" + fi + elif [[ $service == key* ]]; then + if [[ ! $file_to_parse =~ keystone ]]; then + file_to_parse="${file_to_parse} ${package_dir}/keystone" + fi + elif [[ $service == q-* ]]; then + if [[ ! $file_to_parse =~ neutron ]]; then + file_to_parse="${file_to_parse} ${package_dir}/neutron" + fi + elif [[ $service == ir-* ]]; then + if [[ ! $file_to_parse =~ ironic ]]; then + file_to_parse="${file_to_parse} ${package_dir}/ironic" + fi + fi + done + echo "$(_parse_package_files $file_to_parse)" + $xtrace +} + +# get_plugin_packages() collects a list of package names of any type from a +# plugin's prerequisite files in ``$PLUGIN/devstack/files/{debs|rpms}``. The +# list is intended to be passed to a package installer such as apt or yum. +# +# Only packages required for enabled and collected plugins will included. +# +# The same metadata used in the main devstack prerequisite files may be used +# in these prerequisite files, see get_packages() for more info. +function get_plugin_packages { + local xtrace=$(set +o | grep xtrace) + set +o xtrace + local files_to_parse="" + local package_dir="" + for plugin in ${DEVSTACK_PLUGINS//,/ }; do + local package_dir="$(_get_package_dir ${GITDIR[$plugin]}/devstack/files)" + files_to_parse+="$package_dir/$plugin" + done + echo "$(_parse_package_files $files_to_parse)" $xtrace } diff --git a/tools/install_prereqs.sh b/tools/install_prereqs.sh index 303cc63307..917980ccc5 100755 --- a/tools/install_prereqs.sh +++ b/tools/install_prereqs.sh @@ -62,6 +62,8 @@ export_proxy_variables # Install package requirements PACKAGES=$(get_packages general $ENABLED_SERVICES) +PACKAGES="$PACKAGES $(get_plugin_packages)" + if is_ubuntu && echo $PACKAGES | grep -q dkms ; then # ensure headers for the running kernel are installed for any DKMS builds PACKAGES="$PACKAGES linux-headers-$(uname -r)"