从OpenNebula 3.8开始增加了镜像管理的功能,主要体现在增加了CLI - oneimage及其sunstone对应的UI。
1. 镜像类型
opennebula有三种类型的镜像,可以通过oneimage chtype改变镜像的类型。
- OS:此种镜像包含一个完整的os,每一个virtual template必须包含一个OS型的镜像作为root disk
- CDROM:此种镜像包含只读的数据
- DATABLOCK:此种镜像作为数据的存储,能够被不同的vm访问和修改
2. 镜像的生命周期
|
镜像生命周期的状态转换图

3. 镜像创建
首先,编写镜像创建的配置文件,如下所示:
$ cat ubuntu_img.one NAME = "Ubuntu" PATH = /home/cloud/images/ubuntu-desktop/disk.0 TYPE = OS DESCRIPTION = "Ubuntu 10.04 desktop for students." |
该文件的意思为:
a. 此镜像的名称为"Ubuntu"
b. 做好的镜像文件的路径为/home/cloud/images/ubuntu-desktop/disk.0,注意oneimage的功能是将做好的image文件导入opennebula的镜像管理模块中,并不是从一个iso文件来创建一个镜像文件,所以,需要事先通过virt-manager或virsh命令行来制作image文件
c. 指定镜像的类型为OS,即包含一个OS
d. 此镜像的简单描述
写好配置文件后,通过oneimage命令将此image添加到image repository中,具体命令如下:
- oneimage create ubuntu_image.one -d 100 // -d 选项指定此镜像属于哪个datastore
4. 镜像克隆
此功能为将已经存在的image克隆成一个新的,主要用于在修改一个镜像前的备份以及从公共镜像克隆一个私有的镜像,具体的命令为:
- oneimage clone oldimage_name newimage_name
5. 发布镜像
这里的发布,指的是将某个用户的镜像与其他用户或全部用户共享,通过oneimage chmod image_permission来实现, 类似于文件的权限控制。
上传镜像的操作是通过downloader.sh脚本来实现的,其功能是将镜像上传到指定的datastore的目录下,位置为: $INSTALL_PATH/var/datastores/100/
- #downloader.sh分析
-
- # Execute a command (first parameter) and use the first kb of stdout
- # to determine the file type
- # 获取上传image文件的类型,具体执行操作为:cat path/image | head -n 1024 | file -b --mime-type -
- function get_type
- {
- if [ "$NO_DECOMPRESS" = "yes" ]; then
- echo "application/octet-stream"
- else
- command=$1
-
- ( $command | head -n 1024 | file -b --mime-type - ) 2>/dev/null
- fi
- }
-
- # Gets the command needed to decompress an stream.
- function get_decompressor #get_type函数的返回值作为参数
- {
- type=$1
-
- case "$type" in
- "application/x-gzip")
- echo "gunzip -c -"
- ;;
- "application/x-bzip2")
- echo "bunzip2 -c -"
- ;;
- *)
- echo "cat"
- ;;
- esac
- }
-
- # Function called to decompress a stream. The first parameter is the command
- # used to decompress the stream. Second parameter is the output file or
- # - for stdout.
- function decompress
- {
- command="$1"
- to="$2"
-
- if [ "$to" = "-" ]; then
- $command
- else
- $command > "$to"
- fi
- }
-
- # Function called to hash a stream. First parameter is the algorithm name.
- function hasher
- {
- if [ -n "$1" ]; then
- openssl dgst -$1 | awk '{print $NF}' > $HASH_FILE
- else
- # Needs something consuming stdin or the pipe will break
- cat >/dev/null
- fi
- }
-
- # Unarchives a tar or a zip a file to a directpry with the same name.
- function unarchive ##对压缩的镜像进行解压
- {
- TO="$1"
-
- file_type=$(get_type "cat $TO")
-
- tmp="$TO"
-
- # Add full path if it is relative
- if [ ${tmp:0:1} != "/" ]; then
- tmp="$PWD/$tmp"
- fi
-
- IN="$tmp.tmp"
- OUT="$tmp"
-
- case "$file_type" in
- "application/x-tar")
- command="tar -xf $IN -C $OUT"
- ;;
- "application/zip")
- command="unzip -d $OUT $IN"
- ;;
- *)
- command=""
- ;;
- esac
-
- if [ -n "$command" ]; then
- mv "$OUT" "$IN"
- mkdir "$OUT"
-
- $command
-
- if [ "$?" != "0" ]; then
- echo "Error uncompressing archive" >&2
- exit -1
- fi
-
- rm "$IN"
- fi
- }
-
- TEMP=`getopt -o m:s:l:n -l md5:,sha1:,limit:,nodecomp -- "$@"`
-
- if [ $? != 0 ] ; then
- echo "Arguments error"
- exit -1
- fi
-
- eval set -- "$TEMP"
-
- while true; do ###处理downloader.sh脚本的输入参数
- case "$1" in
- -m|--md5)
- HASH_TYPE=md5
- HASH=$2
- shift 2
- ;;
- -s|--sha1)
- HASH_TYPE=sha1
- HASH=$2
- shift 2
- ;;
- -n|--nodecomp)
- export NO_DECOMPRESS="yes"
- shift
- ;;
- -l|--limit)
- export LIMIT_RATE="$2"
- shift 2
- ;;
- --)
- shift
- break
- ;;
- *)
- shift
- ;;
- esac
- done
-
- FROM="$1"
- TO="$2"
-
- # File used by the hasher function to store the resulting hash
- export HASH_FILE="/tmp/downloader.hash.$$"
-
- case "$FROM" in
- http://*|https://*)
- # -k so it does not check the certificate
- # -L to follow redirects
- # -sS to hide output except on failure
- # --limit_rate to limit the bw
- curl_args="-sS -k -L $FROM"
-
- if [ -n "$LIMIT_RATE" ]; then
- curl_args="--limit-rate $LIMIT_RATE $curl_args"
- fi
-
- command="curl $curl_args"
- ;;
- *)
- command="cat $FROM"
- ;;
- esac
-
-
-
- file_type=$(get_type "$command")
- decompressor=$(get_decompressor "$file_type")
-
- echo $file_type
- echo $decompressor
-
- $command | tee >( decompress "$decompressor" "$TO" ) \
- >( hasher $HASH_TYPE ) >/dev/null
-
- if [ "$?" != "0" ]; then
- echo "Error copying" >&2
- exit -1
- fi
-
- if [ -n "$HASH_TYPE" ]; then
- HASH_RESULT=$( cat $HASH_FILE)
- rm $HASH_FILE
- if [ "$HASH_RESULT" != "$HASH" ]; then
- echo "Hash does not match" >&2
- exit -1
- fi
- fi
-
- # Unarchive only if the destination is filesystem
- if [ "$TO" != "-" ]; then
- unarchive "$TO"
- fi