zoukankan      html  css  js  c++  java
  • openstack(liberty): devstack之screen

    在devstack的stack.sh文件中,可以看到所有配置的service启动方式有两种,根据是否USE_SCREEN进行是在screen window中启动,还是直接起。

    默认情况,USE_SCREEN是true的,这个可以在devstack/stackrc中找到,这个文件默认将USE_SCREEN设置为True。 即,所有的service将在screen window中启动。即每一个service对应一个screen window。下面,我就拿nova api这个service的启动代码进行分析这个是如何在SCREEN窗口中启动的。

    1. 下面的代码在devstack/lib/nova中。红色部分就是启动的第一级函数调用。

     1 # start_nova_api() - Start the API process ahead of other things
     2 function start_nova_api {
     3     # Get right service port for testing
     4     local service_port=$NOVA_SERVICE_PORT
     5     local service_protocol=$NOVA_SERVICE_PROTOCOL
     6     if is_service_enabled tls-proxy; then
     7         service_port=$NOVA_SERVICE_PORT_INT
     8         service_protocol="http"
     9     fi
    10 
    11     # Hack to set the path for rootwrap
    12     local old_path=$PATH
    13     export PATH=$NOVA_BIN_DIR:$PATH
    14 
    15     # If the site is not enabled then we are in a grenade scenario
    16     local enabled_site_file=$(apache_site_config_for nova-api)
    17     if [ -f ${enabled_site_file} ] && [ "$NOVA_USE_MOD_WSGI" == "True" ]; then
    18         enable_apache_site nova-api
    19         enable_apache_site nova-ec2-api
    20         restart_apache_server
    21         tail_log nova-api /var/log/$APACHE_NAME/nova-api.log
    22         tail_log nova-ec2-api /var/log/$APACHE_NAME/nova-ec2-api.log
    23     else
    24         run_process n-api "$NOVA_BIN_DIR/nova-api"
    25     fi
    26 
    27     echo "Waiting for nova-api to start..."
    28     if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$SERVICE_HOST:$service_port; then
    29         die $LINENO "nova-api did not start"
    30     fi
    31 
    32     # Start proxies if enabled
    33     if is_service_enabled tls-proxy; then
    34         start_tls_proxy '*' $NOVA_SERVICE_PORT $NOVA_SERVICE_HOST $NOVA_SERVICE_PORT_INT &
    35         start_tls_proxy '*' $EC2_SERVICE_PORT $NOVA_SERVICE_HOST $EC2_SERVICE_PORT_INT &
    36     fi
    37 
    38     export PATH=$old_path
    39 }

    2. run_process函数,devstack/functions-common.

     1 # Run a single service under screen or directly
     2 # If the command includes shell metachatacters (;<>*) it must be run using a shell
     3 # If an optional group is provided sg will be used to run the
     4 # command as that group.
     5 # run_process service "command-line" [group]
     6 function run_process {
     7     local service=$1            #此处的service就是n-api
     8     local command="$2"            #此处的command就是/usr/bin/nova-api,其他的nova相关的指令都在/usr/bin目录下。
     9     local group=$3
    10 
    11     if is_service_enabled $service; then
    12         if [[ "$USE_SCREEN" = "True" ]]; then    #由于前面分析了USE_SCREEN的值为True,所以,进入到screen_process处理
    13             screen_process "$service" "$command" "$group"
    14         else
    15             # Spawn directly without screen
    16             _run_process "$service" "$command" "$group" &
    17         fi
    18     fi
    19 }

    3. screen_process函数,在devstack/functions-common文件中

     1 # Helper to launch a process in a named screen
     2 # Uses globals ``CURRENT_LOG_TIME``, ```LOGDIR``, ``SCREEN_LOGDIR``, `SCREEN_NAME``,
     3 # ``SERVICE_DIR``, ``USE_SCREEN``
     4 # screen_process name "command-line" [group]
     5 # Run a command in a shell in a screen window, if an optional group
     6 # is provided, use sg to set the group of the command.
     7 function screen_process {
     8     local name=$1      #要启动的service的名字,此处为n-api
     9     local command="$2"   #要执行的命令,此处为nova-api
    10     local group=$3
    11 
    12     SCREEN_NAME=${SCREEN_NAME:-stack}
    13     SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
    14     USE_SCREEN=$(trueorfalse True USE_SCREEN)
    15 
    16     screen -S $SCREEN_NAME -X screen -t $name  #启动一个名为stack的session,在这个session中执行screen命令(给当前screen窗口起名为n-api)
    17 
    18     local real_logfile="${LOGDIR}/${name}.log.${CURRENT_LOG_TIME}"
    19     echo "LOGDIR: $LOGDIR"
    20     echo "SCREEN_LOGDIR: $SCREEN_LOGDIR"
    21     echo "log: $real_logfile"
    22     if [[ -n ${LOGDIR} ]]; then
    23         screen -S $SCREEN_NAME -p $name -X logfile "$real_logfile"
    24         screen -S $SCREEN_NAME -p $name -X log on
    25         ln -sf "$real_logfile" ${LOGDIR}/${name}.log
    26         if [[ -n ${SCREEN_LOGDIR} ]]; then
    27             # Drop the backward-compat symlink
    28             ln -sf "$real_logfile" ${SCREEN_LOGDIR}/screen-${1}.log
    29         fi
    30     fi
    31 
    32     # sleep to allow bash to be ready to be send the command - we are
    33     # creating a new window in screen and then sends characters, so if
    34     # bash isn't running by the time we send the command, nothing
    35     # happens.  This sleep was added originally to handle gate runs
    36     # where we needed this to be at least 3 seconds to pass
    37     # consistently on slow clouds. Now this is configurable so that we
    38     # can determine a reasonable value for the local case which should
    39     # be much smaller.
    40     sleep ${SCREEN_SLEEP:-3}
    41 
    42     NL=`echo -ne '15'`
    43     # This fun command does the following:
    44     # - the passed server command is backgrounded
    45     # - the pid of the background process is saved in the usual place
    46     # - the server process is brought back to the foreground
    47     # - if the server process exits prematurely the fg command errors
    48     # and a message is written to stdout and the process failure file
    49     #
    50     # The pid saved can be used in stop_process() as a process group
    51     # id to kill off all child processes
    52     if [[ -n "$group" ]]; then
    53         command="sg $group '$command'"
    54     fi
    55 
    56     # Append the process to the screen rc file
    57     screen_rc "$name" "$command"
    58 
    59     screen -S $SCREEN_NAME -p $name -X stuff "$command & echo $! >$SERVICE_DIR/$SCREEN_NAME/${name}.pid; fg || echo "$name failed to start" | tee "$SERVICE_DIR/$SCREEN_NAME/${name}.failure"$NL" #在指定name为nova-api的screen窗口里面执行启动nova-api的服务,并将pid写入对应文件。如果出错,将错误信息tee到指定格式的文件
    60 }

    其中,上面标识红色的部分,是关键指令。通过上面的3个函数的分析,是不是对于devstack的各个service的启动比较熟悉了?或者说有个比较直观感性的认识了?

    下面,介绍一下,screen相关的操作。首先看看screen都有些什么命令选项,或者说screen的帮助信息:

     1 [root@CloudGame shelltest]# screen -help
     2 Use: screen [-opts] [cmd [args]]
     3  or: screen -r [host.tty]
     4 
     5 Options:
     6 -4            Use IPv4.
     7 -6            Use IPv6.
     8 -a            Force all capabilities into each window's termcap.
     9 -A -[r|R]     Adapt all windows to the new display width & height.
    10 -c file       Read configuration file instead of '.screenrc'.
    11 -d (-r)       Detach the elsewhere running screen (and reattach here).
    12 -dmS name     Start as daemon: Screen session in detached mode.
    13 -D (-r)       Detach and logout remote (and reattach here).
    14 -D -RR        Do whatever is needed to get a screen session.
    15 -e xy         Change command characters.
    16 -f            Flow control on, -fn = off, -fa = auto.
    17 -h lines      Set the size of the scrollback history buffer.
    18 -i            Interrupt output sooner when flow control is on.
    19 -l            Login mode on (update /var/run/utmp), -ln = off.
    20 -list         or -ls. Do nothing, just list our SockDir.
    21 -L            Turn on output logging.
    22 -m            ignore $STY variable, do create a new screen session.
    23 -O            Choose optimal output rather than exact vt100 emulation.
    24 -p window     Preselect the named window if it exists.
    25 -q            Quiet startup. Exits with non-zero return code if unsuccessful.
    26 -r            Reattach to a detached screen process.
    27 -R            Reattach if possible, otherwise start a new session.
    28 -s shell      Shell to execute rather than $SHELL.
    29 -S sockname   Name this session <pid>.sockname instead of <pid>.<tty>.<host>.
    30 -t title      Set title. (window's name).
    31 -T term       Use term as $TERM for windows, rather than "screen".
    32 -U            Tell screen to use UTF-8 encoding.
    33 -v            Print "Screen version 4.00.03 (FAU) 23-Oct-06".
    34 -wipe         Do nothing, just clean up SockDir.
    35 -x            Attach to a not detached screen. (Multi display mode).
    36 -X            Execute <cmd> as a screen command in the specified session.

    在devstack环境下,相关的操作指令主要有:

    screen -ls:  列出当前sockdir。

    1 [stack@ip-10-121-4-176 devstack]$ screen -ls
    2 There is a screen on:
    3     6130.stack    (Detached)
    4 1 Socket in /var/run/screen/S-stack.

    attach screen:

    1 [stack@ip-10-121-4-176 devstack]$ screen -r 6130.stack

    进入了screen后,通过执行ctrl+a + n或者p键,可以实现screen窗口的滚动切换。当前的服务窗口对应于服务名字上有个*号:

    1 。。。。。。。。。。。。。。。
    2 4-12-03T00:00:00Z", "name": "CloudpipeUpdate", "links": [], "namespace": "http://docs.openstack.org/compute/ext/fake_xml", "alias": "os-cloudpipe-update", "description": ""}, {"updated": "2014-12-03T00:00:00Z", "name": "ConfigDrive", "links": [], "namespace": "http://docs.openstack.org/compute/ext/fake_xml", "alias": "os-config-drive", "description": "Config Drive Extension."}, {"updated": "2014-12-03T00:00:00Z", "name": "ConsoleAuthTokens", "links": [], "namespace": "http://docs.openstack.org/compute/ext/fake_xml", "alias": "os-console-auth-tokens", "description": "Console token authentication support."}, {"updated": "2014-12-03T00:00:00Z", "name": "ConsoleOutput", "links": [], "namespace": "http://docs.openstack.org/compute/ext/fake_xml", "alias": "os-console-output", "description": "Console log output support, with tailing ability."}, {"updated": "2014-12-03T00:00:00Z", "name": "Consoles", "links": [], "namespace": "http://docs.openstack.org/compute/ext/fake_xml", "alias": "os-consoles", "description": "Interactive Console support."}, {"updated": "2014-12-03T00:00:00Z", "name": "CreateBackup", "links": [], "namespace": "http://docs.openstack.org/compute/ext/fake_xml", "alias": "os-create-backup", "description": "Create a backup of a server."}, {"updated": "2014-12-03T00:00:00Z", "name": "Createserverext", "links": [], "namespace": "http://docs.openstack.org/compute/ext/fake_xml", "alias": "os-create-server-ext", "description": ""}, {"updated": "2014-12-03T00:00:00Z", "name": "DeferredDelete", "links": [], "namespace": "http://docs.openstack.org/compute/ext/fake_xml", "alias": "os-deferred-delete", "description": "Instance deferred delete."}, {"updated": "2014-12-03T00:00:0
    3 2016-01-25 04:41:05.346975
    4 :q!
    5 
    6  0-$ stack@ip-10-121-4-17  1$(L) dstat  2$(L) key  3$(L) key-access   4$(L) horizon*                         (ip-10-121-4-176/0.29 0.30 0.74)

    在当前窗口执行ctrl+c就是杀掉当前的process。

    deatch screen(ctrl+a + d):

    注意,是ctrl+a指令输入后等一会,再输入d键。

    进入服务列表模式(ctrl+a+双引号键,双引号键shift+,就是Enter键左边那个):

    在这种模式下,当前所在的process对应的服务名字高亮显示,例如上图中的horizon,此时,点击enter,会进入到常规模式。

    其他一些相关的指令,自己以后慢慢摸索吧!

  • 相关阅读:
    mysqldump 5.7
    MySQL 5.7主从复制
    MySQL 5.7安装与配置
    MySQL 5.7二进制日志
    Servlet3.x部署描述符
    Redis 4.0.2分布式锁的Java实现
    Redis 4.0.2安装与卸载
    Echarts主题颜色
    eclipse插件jd-eclipse的使用
    Crack IDEA
  • 原文地址:https://www.cnblogs.com/shihuc/p/5161267.html
Copyright © 2011-2022 走看看