有一份英文版的源代码解读,不过如果对于Openstack没有过接触的人来说,可能看起来会有一些困难。
http://devstack.org/stack.sh.html
stack.sh 简介
stack.sh是一个openstack开发人员可以选择的一种安装脚本。
这个脚本的主要作用是安装并配置nova, glance, horizon, 以及keystone。
使用这个脚本,你可以设置一些配置选项,比如使用哪个git源,开启哪些服务,网络如何配置,以及各种密码的设置与管理。通过这个脚本,也可以灵活地在多台机器上运行,通过一个类似的资源进行一种共享式的配置。比如mysql, rabbitmq,从而可以组建一个多机环境下的云。
为了保证这个脚本足够简单,我们假设你是在一个Ubuntu 11.10 Oneiric的机器上执行。当然,这个脚本也可以在VM上运行,或是在物理机上运行。此外,我们把一些apt, pip安装包放到别的文件中去了,那么开始了解这个脚本,以及这些依赖的包。
如果你想进一步的学习或了解,可以去网站
Sanity Check
这个脚本首先来说是针对于Oneiric来写的,如果要在Ubuntu的其他版本上执行,当然也可以通过执行命令
- $FORCE=yes ./stack.sh
,从而达到要求。但是我个人而言,不建议采用这种方式进来安装部署。在其他版本上的安装部署,后面再补上。
版本检查
下面这段代码就是主要是在检查一下OS的版本。
# DISTRO变量就是拿到OS的版本。在Ubuntu上执行,会得到发行版的名字。oneiric。
# 接下来的几句只是在进行检查是否是oneiric版本的Ubuntu
- DISTRO=$(lsb_release -c -s)
- if [[ ! ${DISTRO} =~ (oneiric) ]]; then
- echo "WARNING: this script has only been tested on oneiric"
- if [[ "$FORCE" != "yes" ]]; then
- echo "If you wish to run this script anyway run with FORCE=yes"
- exit 1
- fi
- fi
目录设定
stack.sh把很多需要安装的包与其他一些依赖都放到别的文件里面的,你可以在/devstack/files中找到这些文件。但是在脚本中,我们是通过FILES变量来引用到这些配置文件的位置。
#首先是拿到顶级目录所在位置。比如/root/devstack,那么$TOP_DIR="/root/devstack"
#生成FILES变量的值。再去检查一下这个目录是否存在。
- TOP_DIR=$(cd $(dirname "$0") && pwd)
- FILES=$TOP_DIR/files
- if [ ! -d $FILES ]; then
- echo "ERROR: missing devstack/files - did you grab more than just stack.sh?"
- exit 1
- fi
设定
这个脚本的可定制性体现在,一些环境变量可以放到别的文件中,或者是通过设定环境变量来进行处理。比如
- $export MYSQL_PASSWORD=anothersecret
- $./stack.sh
可以达到效果。当然,你也可以把这些语句放在同一行,比如
- $MYSQL_PASSWORD=simple ./stack.sh
也可以把这些设定放到$TOP_DIR/localrc文件中。
比如:
- $ cat $TOP_DIR/localrc
- .........
- MYSQL_PASSWORD=anothersecret
- MYSQL_USER=hellaroot
一般来说,我们都使用的是一些很敏感的设定,所以为了省事,你也可以运行
- $./stack.sh
(一般而言,如果这样运行,脚本会在发现没有密码的时候,叫你输出密码,如果输入密码为空,那么会随机生成一个密码)。
环境变量
对于环境变量而言,一般我们都是放到stackrc文件中。这个文件是随着devstack一起发布的,并且主要是包含了需要使用的git源。如果你想要使用别的源,或者是别的分枝,那么你可以加入你自己的设定,并把这些设定写到localrc文件中。
一般而言localrc里面的设置会把stackrc文件中的变量给覆盖掉。这个是很有用的,特别是当你想使用别的源或者分枝的时候。你也可以更改掉一些已有设定,比如
- MYSQL_PASSWORD
- ADMIN_PASSWORD
否则devstack脚本会给你随机生成一个(这个随机生成的密码还有点长)。
#首先是从stackrc中引入环境变量
#$DEST变量是指的是安装目录,一般默认安装目录是/opt/stack
#下面是定义了一个函数,其实也就是使用apt-get命令。
- source ./stackrc
- DEST=${DEST:-/opt/stack}
- function apt_get() {
- [[ "$OFFLINE" = "True" ]] && return
- local sudo="sudo"
- [ "$(id -u)" = "0" ] && sudo="env"
- $sudo DEBIAN_FRONTEND=noninteractive apt-get \
- --option "Dpkg::Options::=--force-confold" --assume-yes "$@"
- }
这里检查是否已经有stack.sh程序在运行。
- if screen -ls | egrep -q "[0-9].stack"; then
- echo "You are already running a stack.sh session."
- echo "To rejoin this session type 'screen -x stack'."
- echo "To destroy this session, kill the running screen."
- exit 1
- fi
因为Openstack在设计的时候,是用的一般用户来运行的,主要原因是因为dashboard在运行的时候底层使用的是apache2的服务器,而apache2不可以在root权限下执行。
如果在运行脚本的时候是使用的是root权限,那么会自动新建一个stack用户来执行操作。并且这个用户会给足够的权限来进行很多操作
- if [[ $EUID -eq 0 ]]; then
- ROOTSLEEP=${ROOTSLEEP:-10}
- echo "You are running this script as root."
- echo "In $ROOTSLEEP seconds, we will create a user 'stack' and run as that user"
- sleep $ROOTSLEEP
- # 因为这个脚本接下来是按照一个普通用户来执行的,那么需要给这个普通用户以sudo的权限。
- #
- dpkg -l sudo || apt_get update && apt_get install sudo
- if ! getent passwd stack >/dev/null; then
- echo "Creating a user called stack"
- useradd -U -G sudo -s /bin/bash -d $DEST -m stack
- fi
- echo "Giving stack user passwordless sudo priviledges"
- # some uec images sudoers does not have a '#includedir'. add one.
- grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
- echo "#includedir /etc/sudoers.d" >> /etc/sudoers
- ( umask 226 && echo "stack ALL=(ALL) NOPASSWD:ALL" \
- > /etc/sudoers.d/50_stack_sh )
- echo "Copying files to stack user"
- STACK_DIR="$DEST/${PWD##*/}"
- cp -r -f -T "$PWD" "$STACK_DIR" #这里在拷文件,额外的拷文件的动作也可以加在这里。
- chown -R stack "$STACK_DIR"
- if [[ "$SHELL_AFTER_RUN" != "no" ]]; then
- exec su -c "set -e; cd $STACK_DIR; bash stack.sh; bash" stack
- else
- exec su -c "set -e; cd $STACK_DIR; bash stack.sh" stack
- fi
- exit 1
- else
- # Our user needs passwordless priviledges for certain commands which nova
- # uses internally.
- # Natty uec images sudoers does not have a '#includedir'. add one.