为Snappy Ubuntu中的snap应用设置配置文件

对于细心的读者可能已经注意到在我的先前的文章中"如何在Snappy Ubuntu Core中设置autopilot"已经体会到使用Snappy Ubuntu中的config的便利.我们可以来重新温顾一下这个命令的语法:

$ snappy config -h
Usage:
  snappy [OPTIONS] config [package name] [config file]

Configures a package. The configuration is a YAML file, provided in the specified file which can be
"-" for stdin. Output of the command is the current configuration, so running this command with no
input file provides a snapshot of the app's current config.

Help Options:
  -h, --help              Show this help message

[config command arguments]
  package name:           Set configuration for a specific installed package
  config file:            The configuration for the given file

就像上面所述的那样,当我们直接使用config命令时,就显示当前的设置.如果后面还跟一个yaml的配置文件,这个文件的内容将被直接写入到最终的设置文件中.这个设置文件是一个yaml文件.我已经为此做了一个完整的例程.大家可以在如下的 地址进行下载:

$ git clone https://github.com/liu-xiao-guo/config-example

等下载完例程,我们可以参阅文章" 如何为我们的Snappy Ubuntu应用编译并打包Snap(1)"来编译并打包我们的应用,并部署到我们的target上.

在参阅本文章时,一定要注意一个bug.当我们使用ssh的方法进入到我们的target时,需要使用如下的方式.否则,我们的设置可能会发生错误.

$ LC_ALL=C.UTF-8 LANGUAGE=en ssh -p 8022 ubuntu@localhost

下面在我们展示在KVM中的运行情况:

(amd64)ubuntu@localhost:~$ snappy list -v
Name           Date       Version      Developer  
ubuntu-core    2015-11-13 10           ubuntu*    
ubuntu-core    2015-10-23 9            ubuntu     
config-example 2015-11-27 IGUIWdTOWeCa sideload*  
hello-xiaoguo  2015-11-05 IEeNEfBRVYGe sideload   
hello-xiaoguo  2015-11-27 IGTcTdAICYOL sideload*  
mqtt-piglow    2015-11-23 IGJVDbJOQafg sideload   
mqtt-piglow    2015-11-23 IGJVJYLbWCaC sideload*  
pastebinit     2015-11-02 1.4.0.0.2    mvo*       
webcam-webui   2015-11-27 IGTMIAMeQcbW sideload*  
webcam         2015-11-14 IFUaQLgTUKSU sideload*  
webdm          2015-10-23 0.9.2        canonical* 
generic-amd64  2015-10-23 1.4          canonical* 

从上面可以看出来,我们的config-example已经被成功安装到KVM里去了.我们可以通过如下的方法来运行我们的应用:

(amd64)ubuntu@localhost:~$ config-example.hello 
config:
  config-example:
    msg: good

它显示了当前的应用的配置文件.该文件存在于如下的地址:

(amd64)ubuntu@localhost:~$ cd /var/lib/apps/config-example.sideload/current
(amd64)ubuntu@localhost:/var/lib/apps/config-example.sideload/current$ cat message 
config:
  config-example:
    msg: good

我们的"hello"脚本(在bin目录下的脚本)应用是这么写的:

hello

#!/bin/sh

if [ -e ${SNAP_APP_DATA_PATH}/message ]; then
    cat ${SNAP_APP_DATA_PATH}//message
else
    cat <<EOF2
Hello from the config example!

You can configure this message by running:

$ cat > cfg.yaml <<'EOF'
config:
  config-example:
    msg: |
         Yay!
EOF
$ sudo snappy config config-example cfg.yaml


The message you set there is then displayed when running:
$ config-example.hello

EOF2
fi

在上面,如果设置文件存在,就直接显示出来.我们也可以通过如下的方式来显示我们的设置文件的内容:

(amd64)ubuntu@localhost:~$ snappy config config-example
config:
  config-example:
    msg: good

我们可以通过如下的方式来修改我们的配置文件:

(amd64)ubuntu@localhost:~$ snappy config config-example > my.yaml
(amd64)ubuntu@localhost:~$ vi my.yaml
我们通过修改my.yaml文件,并保存修改后的文件.然后使用如下的命令来重新设置我们的应用(在这里,我们把内容修改为" this is something very cool"):

(amd64)ubuntu@localhost:~$ sudo snappy config config-example  my.yaml
config:
  config-example:
    msg: this is something very cool

(amd64)ubuntu@localhost:~$ snappy config config-example
config:
  config-example:
    msg: this is something very cool

从上面我们可以看出来,我们以及重新设置了我们的设置文件:

(amd64)ubuntu@localhost:/var/lib/apps/config-example.sideload/current$ cat message 
config:
  config-example:
    msg: this is something very cool

那么我们应该通过怎样的软件方法来为我们的应用设计设置文件呢?答案就在config.py文件里:

config.py

#!/usr/bin/env python3

import os
import os.path
import sys
import yaml

_CONFIG = 'message'

_DEFAULT_MESSAGE = 'Hello, the world'


def main():
    config_file = os.path.join(os.environ['SNAP_APP_DATA_PATH'], _CONFIG)

    config_yaml = yaml.load(sys.stdin)
    if config_yaml:
        set_config(config_file, config_yaml)

    yaml.dump(get_config(config_file), stream=sys.stdout,
              default_flow_style=False)


def set_config(config_file, config_yaml={}):
    with open(config_file, 'w') as f:
        yaml.dump(_config(config_yaml), stream=f, default_flow_style=False)

    return config_yaml


def get_config(config_file):
    try:
        with open(config_file) as f:
            return yaml.load(f)
    except FileNotFoundError:
        return _config()


def _config(config_yaml={}):
    try:
        msg_value = config_yaml['config'][
            os.environ['SNAP_NAME']]['msg']
        if not isinstance( msg_value, str):
            config_yaml['config'][
                os.environ['SNAP_NAME']]['msg'] = _DEFAULT_MESSAGE
    except KeyError:
        msg = {
            'config': {
                os.environ['SNAP_NAME']: {
                    'msg': _DEFAULT_MESSAGE
                }
            }
        }
        config_yaml.update(msg)

    return config_yaml


if __name__ == '__main__':
    main()

注意上面的环境变量"SNAP_APP_DATA_PATH"及"SNAP_NAME".我们可以参阅文章" Snappy Ubuntu 入门"来得到更多的信息.
如果你想了解更多关于Snappy Ubuntu的信息,可以参阅文章" 到底Snappy Ubuntu是什么?".










你可能感兴趣的:(为Snappy Ubuntu中的snap应用设置配置文件)