helloworld Snap例程

我们在很多的语言开发中都少不了使用"Hello, the world!"来展示一个开发环境的成功与否,在今天的教程中,我们也毫不例外地利用这个例子来展示snap应用是如何构建的.虽然这个例子很简单,但是在我们进入例程的过程中,我们会慢慢地发现有关snap系统的一些特性,这样可以更好地帮助我们来了解这个系统.如果大家想了解16.04的桌面对snap的支持,请参阅文章"安装snap应用到Ubuntu 16.4桌面系统".


1)环境安装


我们仿照在文章" 安装snap应用到Ubuntu 16.4桌面系统"中的" 安装"一节进行安装.记得一定要选上" universe"才可以安装成功.



2)从Snap商店中安装hello-world应用


我们可以通过如下的命令在Snap商店中找到这个应用:

$ sudo snap install hello-world

在安装完这个应用后,我们可以在如下的目录中找到关于这个应用的snap.yaml文件.这个文件很类似于一个项目的snapcraft.yaml文件.只是它里面没有什么parts的部分.

liuxg@liuxg:/snap/hello-world/current/meta$ ls 
gui  snap.yaml

其中snap.yaml的内容如下:

snap.yaml

name: hello-world
version: 6.3
architectures: [ all ]
summary: The 'hello-world' of snaps
description: |
    This is a simple snap example that includes a few interesting binaries
    to demonstrate snaps and their confinement.
    * hello-world.env  - dump the env of commands run inside app sandbox
    * hello-world.evil - show how snappy sandboxes binaries
    * hello-world.sh   - enter interactive shell that runs in app sandbox
    * hello-world      - simply output text
apps:
 env:
   command: bin/env
 evil:
   command: bin/evil
 sh:
   command: bin/sh
 hello-world:
   command: bin/echo

可以看出来它的格式非常接近我们的snapcraft.yaml项目文件.这里文件中指出的 envevilshecho命令,我们可以在如下的目录中找到:

liuxg@liuxg:/snap/hello-world/current/bin$ ls
echo  env  evil  sh

当然,我们可以使用我们的vi编辑器来查看里面的具体的内容.整个的文件架构如下:

liuxg@liuxg:/snap/hello-world/current$ tree -L 3
.
├── bin
│   ├── echo
│   ├── env
│   ├── evil
│   └── sh
└── meta
    ├── gui
    │   └── icon.png
    └── snap.yaml


3)创建我们自己的hello-world项目


由于一些原因,我们在网上已经找不到这个项目的源码了.由于这个项目非常简单,我们可以通过我们自己的方法来重建这个项目:我们把上面的snap.yaml进行修改为我们所需要的snapcraft.yaml,并把我们所需要的文件考入到我们需哟啊的目录.这样我们就可以很容易地重构这个项目.这样做的目的是我们想通过修改这个项目来展示一些我们想看到的特性.

对于开发者来说,如果你没有一个现成的snapcraft.yaml文件供你参考的话,你可以直接使用如下的命令来生产一个模版来进行编辑:

$ snapcraft init

这样在我们的项目的根目录下就会生产一个snapcraft.yaml的样板件.我们可以利用这个文件来作为开始进行编辑:

snapcraft.yaml

name: my-snap  # the name of the snap
version: 0  # the version of the snap
summary: This is my-snap's summary  # 79 char long summary
description: This is my-snap's description  # a longer description for the snap
confinement: devmode  # use "strict" to enforce system access only via declared interfaces

parts:
    my-part:  # Replace with a part name of your liking
        # Get more information about plugins by running
        # snapcraft help plugins
        # and more information about the available plugins
        # by running
        # snapcraft list-plugins
        plugin: nil

经过我们的重构,我们终于完成了我们的第一个snap应用.目录架构如下:

liuxg@liuxg:~/snappy/desktop/helloworld$ tree -L 3
.
├── bin
│   ├── echo
│   ├── env
│   ├── evil
│   └── sh
├── setup
│   └── gui
│       └── icon.png
└── snapcraft.yaml

在这里snapcraft是我们的项目文件,它被用于来打包我们的应用.它的内容如下:

snapcraft.yaml


name: hello-xiaoguo
version: 1.0
architectures: [ all ]
summary: The 'hello-world' of snaps
description: |
    This is a simple snap example that includes a few interesting binaries
    to demonstrate snaps and their confinement.
    * hello-world.env  - dump the env of commands run inside app sandbox
    * hello-world.evil - show how snappy sandboxes binaries
    * hello-world.sh   - enter interactive shell that runs in app sandbox
    * hello-world      - simply output text
confinement: strict

apps:
 env:
   command: bin/env
 evil:
   command: bin/evil
 sh:
   command: bin/sh
 hello-world:
   command: bin/echo

parts:
 hello:
  plugin: copy
  files:
    ./bin: bin

从内容上看,它和我们之前看到的snap几乎是一样的.这里我们使用了copy plugin.如果大家想对snapcraft.yaml中的每一项搞清楚,建议大家阅读文章" Metadata YAML file".在其中,它也描述了哪些项是必须的.

我们可以通过如下的命令来查询目前已经支持的所有的plugins:

liuxg@liuxg:~/snappy/desktop/helloworld$ snapcraft list-plugins
ant        catkin  copy  gulp  kbuild  make   nil     python2  qmake  tar-content
autotools  cmake   go    jdk   kernel  maven  nodejs  python3  scons

事实上,在snapcraft下的plugin架构也是开放的,开发者可以开发自己所需要的plugin.
在我们打包我们的应用之前,我们必须确保在bin目录下的所有文件都是可以执行的:

liuxg@liuxg:~/snappy/desktop/helloworld/bin$ ls -al
total 24
drwxrwxr-x 2 liuxg liuxg 4096 7月  13 00:31 .
drwxrwxr-x 4 liuxg liuxg 4096 7月  18 10:31 ..
-rwxrwxr-x 1 liuxg liuxg   31 7月  12 05:20 echo
-rwxrwxr-x 1 liuxg liuxg   27 7月  12 05:20 env
-rwxrwxr-x 1 liuxg liuxg  274 7月  12 05:20 evil
-rwxrwxr-x 1 liuxg liuxg  209 7月  12 05:20 sh

否则的话,我们需要使用如下的命令来完成:

$ chmod a+x echo

至此,我们已经完成了一个最基本的hello-world项目.


4)编译并执行我们的应用


在我们的项目的根目录下,我们直接打入如下的命令:

$ snapcraft

如果一切顺利的话,我们可以在项目的根目录下看到如下的文件及目录:

liuxg@liuxg:~/snappy/desktop/helloworld$ tree -L 2
.
├── bin
│   ├── echo
│   ├── env
│   ├── evil
│   └── sh
├── hello-xiaoguo_1.0_all.snap
├── parts
│   └── hello
├── prime
│   ├── bin
│   ├── command-env.wrapper
│   ├── command-evil.wrapper
│   ├── command-hello-world.wrapper
│   ├── command-sh.wrapper
│   └── meta
├── setup
│   └── gui
├── snapcraft.yaml
└── stage
    └── bin

我们可以看见一个生产的snap文件.一个snap的文件名依赖于如下的规则:
__.snap
在我们这个例程中,我们指定architecture为all.

当然,我们也看到了一下其它的文件目录:parts, stage及prime.这些目录是在打包过程中自动生成的.有关更多关于snapcraft的帮助信息,我们可以通过如下的命令来获得:

liuxg@liuxg:~/snappy/desktop/helloworld$ snapcraft --help
...

The available lifecycle commands are:
  clean        Remove content - cleans downloads, builds or install artifacts.
  cleanbuild   Create a snap using a clean environment managed by lxd.
  pull         Download or retrieve artifacts defined for a part.
  build        Build artifacts defined for a part. Build systems capable of
               running parallel build jobs will do so unless
               "--no-parallel-build" is specified.
  stage        Stage the part's built artifacts into the common staging area.
  prime        Final copy and preparation for the snap.
  snap         Create a snap.

Parts ecosystem commands
  update       Updates the parts listing from the cloud.
  define       Shows the definition for the cloud part.
  search       Searches the remotes part cache for matching parts.

Calling snapcraft without a COMMAND will default to 'snap'

...

在上面我们可以看出,打包一个snap应用所必须的生命周期: pullbuildstageprimesnap.对于一个snap的项目来说,它的每个part的文件可以存在于一下网站上,比如git,bzr或tar.在打包的过程中,snapcraft可以将它们自动从网上下载下来,并存于parts目录下.通过build,把每个part的安装的文件至于每个part下的一个叫做install的子目录中.在stage过程中,它分别把每个part的文件(parts//install)集中起来,并存于一个统一的文件架构中.prime是最终把stage中可以用打包的文件放在一起,这样我们可以在最后的过程中来通过snap过程来打包为snap包.最终的.snap包文件其实就是把prime目录下的文件进行 squashfs处理.更多关于这些生命周期的描述,大家可以参阅文章" Snapcraft Overview".我们也可以参阅视频" Snapcraft操作演示--教你如何snap一个应用".

如果我们想在编译完我们的应用后,不需要留下任何的所安装的包,我们可以使用cleanbuild.它会创建一个lxd容器,在编译完后,后自动销毁:

$ snapcraft cleanbuild

在编译完后,我们可以发现所生产的.snap文件,但是我们可能找不到我们看见的中间文件目录: parts, stage及prime.

如果大家想清除这些在打包过程中的中间文件,我们可以在命令行中打入如下的命令:

$ snapcraft clean

我们可以通过如下的命令来安装我们的应用:

$ sudo snap install hello-xiaoguo_1.0_all.snap --force-dangerous

或如下的方式:

$ sudo snap install hello-xiaoguo_1.0_all.snap --dangerous

在编译一个snap应用时,我们也可以分别对以上的步骤进行操作.在每次操作过后,我们会发现我们的目录结构将会发送改变.
$ snapcraft clean
$ snapcraft pull
$ snapcraft build
$ snapcraft stage
$ snapcraft prime
$ snapcraft snap prime/
如果我们通过上面的方法进行安装的话,每次安装都会生产一个新的版本,并且占用系统的硬盘资源.我们也可以通过如下的方式来进行安装:

$ sudo snap try prime/

这种方法的好处是,它不必要每次都生产一个新的版本.在安装时,它直接使用一个软链接的方式,把我们编译的prime目录直接进行mount.

这样我们就可以把我们的应用安装到我们的16.04的桌面系统中了.我们可以通过如下的命令来查看:

liuxg@liuxg:~/snappy/desktop/helloworld$ snap list
Name           Version               Rev  Developer  Notes
hello-world    6.3                   27   canonical  -
hello-xiaoguo  1.0                   x2              -
ubuntu-core    16.04+20160531.11-56  122  canonical  -

如果你已经看到了hello-xiaoguo的应用在上面列表中.那么恭喜你,你已经创建了人生第一个snap.从上面的列表中我们可以看出,它即有一个Version也有一个Rev版本.显然我们的hello-xiaoguo应用已经被成功安装到系统中了.那么我们怎么来运行我们的应用呢?

从我们的snapcraft.yaml文件中,我们可以看出来,我们的包名叫做hello-xiaoguo.在我们的这个包中,我们定义了四个应用:env, evil,sh及hello-world.那么我们运行它们时,我们分别需要使用如下的命令来运行:

$ hello-xiaoguo.env
$ hello-xiaoguo.evil
$ hello-xiaoguo.sh
$ hello-xiaoguo.hello-world

也即,我们使用<<包名>>.<<应用名>>格式来运行我们的应用.比如:

liuxg@liuxg:~/snappy/desktop/helloworld$ hello-xiaoguo.hello-world 
Hello World!

整个项目的源码在: https://github.com/liu-xiao-guo/helloworld-snap.另外我们特别指出的是,如果你的包的名称和应用名称是一样的,那么你只需要运行包的名称即可.比如你的包的名称是hello,你的应用的名称是hello,那么你直接在命令行中运行hello就可以运行你的应用.

我们可以使用如下的命令来查看我们的snap文件包里的内容:

$ unsquashfs -l hello-xiaoguo_1.0_all.snap

一个snap文件包其实就是一个压缩的 squashfs文件.我们也可以通过如下的方式来得到包里所有的内容:
$ unsquashfs hello-xiaoguo_1.0_all.snap  
$ cd cd squashfs-root  
# Hack hack hack  
$ snapcraft snap  
这里我们就留给开发者们自己做练习.



5)Snap的运行环境


每个应用在被安装到系统的时候,系统将会为这个包里的每个应用生产一个相应的启动脚本.它们可以在如下的路径中找到:

liuxg@liuxg:/snap/bin$ ls -l
total 52
-rwxr-xr-x 1 root root 708 7月  20 15:37 hello-world
-rwxr-xr-x 1 root root 783 7月  21 15:13 hello-world-cli
-rwxr-xr-x 1 root root 683 7月  20 15:37 hello-world.env
-rwxr-xr-x 1 root root 687 7月  20 15:37 hello-world.evil
-rwxr-xr-x 1 root root 679 7月  20 15:37 hello-world.sh
-rwxr-xr-x 1 root root 743 7月  22 15:30 hello-xiaoguo.createfile
-rwxr-xr-x 1 root root 767 7月  22 15:30 hello-xiaoguo.createfiletohome
-rwxr-xr-x 1 root root 715 7月  22 15:30 hello-xiaoguo.env
-rwxr-xr-x 1 root root 719 7月  22 15:30 hello-xiaoguo.evil
-rwxr-xr-x 1 root root 747 7月  22 15:30 hello-xiaoguo.hello-world
-rwxr-xr-x 1 root root 711 7月  22 15:30 hello-xiaoguo.sh
-rwxr-xr-x 1 root root 726 7月  22 11:32 snappy-debug.security
-rwxr-xr-x 1 root root 798 7月  20 10:44 telegram-sergiusens.telegram

我们可以通过cat命令来查看这些脚本的具体的内容.
我们可以执行如下的命令:

$ hello-xiaoguo.env | grep SNAP

通过上面的指令,我们可以得到关于一个snap运行时的所有环境变量:

liuxg@liuxg:~$ hello-xiaoguo.env | grep SNAP
SNAP_USER_COMMON=/home/liuxg/snap/hello-xiaoguo/common
SNAP_LIBRARY_PATH=/var/lib/snapd/lib/gl:
SNAP_COMMON=/var/snap/hello-xiaoguo/common
SNAP_USER_DATA=/home/liuxg/snap/hello-xiaoguo/x2
SNAP_DATA=/var/snap/hello-xiaoguo/x2
SNAP_REVISION=x2
SNAP_NAME=hello-xiaoguo
SNAP_ARCH=amd64
SNAP_VERSION=1.0
SNAP=/snap/hello-xiaoguo/x2

这些和snap相关的环境变量可以在我们的应用中进行引用.这些变量的介绍如下:

helloworld Snap例程_第1张图片

在我们编程的过程中,我们不必要hard-code我们的变量.比如我们可以在我们的snapcraft中引用$SNAP,它表示我们当前的snap的安装的路径.同时,我们可以看到一个很重要的目录:

SNAP_DATA=/var/snap/hello-xiaoguo/x2

这个目录是我们的snap的私有的目录.我们的snap只能向这个目录或SNAP_USER_DATA进行读写的操作.否则,将会产生安全的错误信息.比如在我们的evil脚本中:

evil

#!/bin/sh

set -e
echo "Hello Evil World!"

echo "This example demonstrates the app confinement"
echo "You should see a permission denied error next"

echo "Haha" > /var/tmp/myevil.txt

echo "If you see this line the confinement is not working correctly, please file a bug"

我们通过这个脚本向/var/tmp/中的myevil.txt写入"Haha",它会造成安全的DENIED错误信息:

liuxg@liuxg:~$ hello-xiaoguo.evil
Hello Evil World!
This example demonstrates the app confinement
You should see a permission denied error next
/snap/hello-xiaoguo/x2/bin/evil: 9: /snap/hello-xiaoguo/x2/bin/evil: cannot create /var/tmp/myevil.txt: Permission denied

另外一种查找错误的方方法是打开我们的系统的log信息( /var/log/syslog

8307 comm="fswebcam" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Jul 19 13:27:18 liuxg kernel: [19665.330053] audit: type=1400 audit(1468906038.378:4309): apparmor="DENIED" operation="open" profile="snap.webcam-webui.webcam-webui" name="/etc/fonts/fonts.conf" pid=18307 comm="fswebcam" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Jul 19 13:27:25 liuxg gnome-session[2151]: (nm-applet:2584): nm-applet-WARNING **: ModemManager is not available for modem at /hfp/org/bluez/hci0/dev_F4_B7_E2_CC_F0_56
Jul 19 13:27:26 liuxg kernel: [19673.182647] audit: type=1400 audit(1468906046.230:4310): apparmor="DENIED" operation="mknod" profile="snap.hello-xiaoguo.evil" name="/var/tmp/myevil.txt" pid=18314 comm="evil" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000

或直接使用如下的命令:

liuxg@liuxg:~/snappy/desktop/helloworld$ cat /var/log/syslog | grep DENIED | grep hello-xiaoguo
Jul 19 13:25:25 liuxg kernel: [19552.926619] audit: type=1400 audit(1468905925.975:4276): apparmor="DENIED" operation="mknod" profile="snap.hello-xiaoguo.evil" name="/var/tmp/myevil.txt" pid=18273 comm="evil" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
Jul 19 13:27:26 liuxg kernel: [19673.182647] audit: type=1400 audit(1468906046.230:4310): apparmor="DENIED" operation="mknod" profile="snap.hello-xiaoguo.evil" name="/var/tmp/myevil.txt" pid=18314 comm="evil" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000

这其中最根本的原因是因为我们的snap应用不能访问不属于他自己的目录.这是snap应用最根本的安全机制.我们可以看到上面的operation项.他指出了我们具体的错误操作.
对于snap应用的另外一个安全方面的问题是seccomp violation.对于一个叫做audit的应用来说,我们可以通过如下的方式来得到它的错误信息:

$ sudo grep audit /var/log/syslog

一个seccomp violation的例子可能如下:

audit: type=1326 audit(1430766107.122:16): auid=1000 uid=1000 gid=1000 ses=15 pid=1491 comm="env" exe="/bin/bash" sig=31 arch=40000028 syscall=983045 compat=0 ip=0xb6fb0bd6 code=0x0

那么这个violation的具体的意思是什么呢?我们可以通过如下的命令来查看这个错我的信息:

$ scmp_sys_resolver 983045
set_tls

请注意上面的983045来自于我们的错误信息中的"syscall=983045".这样,我们就可以定位我们的哪些系统调用有问题.

为了说明问题,我们创建一个createfile的脚本:

createfile

#!/bin/sh

set -e
echo "Hello a nice World!"

echo "This example demonstrates the app confinement"
echo "This app tries to write to its own user directory"

echo "Haha" > $HOME/test.txt

echo "Succeeded! Please find a file created at $HOME/test.txt"
echo "If do not see this, please file a bug"

在我们的snapcraft.yaml中加入:

 createfile:
   command: bin/createfile

重新打包我们的应用:

liuxg@liuxg:~/snappy/desktop/helloworld$ hello-xiaoguo.createfile 
Hello a nice World!
This example demonstrates the app confinement
This app tries to write to its own user directory
Succeeded! Please find a file created at /home/liuxg/snap/hello-xiaoguo/x3/test.txt
If do not see this, please file a bug

在这里,我们可以看见我们已经成功地在位置/home/liuxg/snap/hello-xiaoguo/x3/生产一个文件.$HOME的定义可以通过如下的方式获得:

liuxg@liuxg:~/snappy/desktop/helloworld$ hello-xiaoguo.env | grep home
GPG_AGENT_INFO=/home/liuxg/.gnupg/S.gpg-agent:0:1
SNAP_USER_COMMON=/home/liuxg/snap/hello-xiaoguo/common
ANDROID_NDK_ROOT=/home/liuxg/android-ndk-r10e
SNAP_USER_DATA=/home/liuxg/snap/hello-xiaoguo/x3
PWD=/home/liuxg/snappy/desktop/helloworld
HOME=/home/liuxg/snap/hello-xiaoguo/x3
XAUTHORITY=/home/liuxg/.Xauthority

细心的开发者也许会发现它的定义其实和变量 SNAP_USER_DATA是一样的:

liuxg@liuxg:~/snappy/desktop/helloworld$ hello-xiaoguo.env | grep SNAP
SNAP_USER_COMMON=/home/liuxg/snap/hello-xiaoguo/common
SNAP_LIBRARY_PATH=/var/lib/snapd/lib/gl:
SNAP_COMMON=/var/snap/hello-xiaoguo/common
SNAP_USER_DATA=/home/liuxg/snap/hello-xiaoguo/x3
SNAP_DATA=/var/snap/hello-xiaoguo/x3
SNAP_REVISION=x3
SNAP_NAME=hello-xiaoguo
SNAP_ARCH=amd64
SNAP_VERSION=1.0
SNAP=/snap/hello-xiaoguo/x3

对于一个daemon应用来说,这个$HOME变量的值,是指向$SNAP_DATA而不是$SNAP_USER_DATA.这一点大家要记住.具体的描述可以参阅文章" Snap security policy and sandboxing".

关于security的调试是一件非常麻烦的是.庆幸的是,我们可以利用snappy-debug来帮我们调试.它可以帮我们解析我们到底是哪些地方有错误,并且帮我们解析系统调用的名称等.

$ sudo snap install snappy-debug
$ sudo /snap/bin/snappy-debug.security scanlog foo

具体的使用方法,我们可以参阅文章" Snap security policy and sandboxing".




6)创建一个可以向桌面home写入的app


在上一节的内容中,我们基本上已经看到了snap应用的安全性的一些方面.在我们的snap应用中,假如我们想向我们的桌面电脑中的home里写内容,那应该是怎么办呢?首先,我们创建一个如下的createfiletohome脚本:

createfiletohome:


#!/bin/sh

set -e
echo "Hello a nice World!"

echo "This example demonstrates the app confinement"
echo "This app tries to write to its own user directory"

echo "Haha" > /home/$USER/test.txt

echo "Succeeded! Please find a file created at $HOME/test.txt"
echo "If do not see this, please file a bug"

在上面我们向我们的用户的home目录写入我们需要的内容.如果我们重新编译并运行我们的应用,我们会发现:

liuxg@liuxg:~/snappy/desktop/helloworld$ hello-xiaoguo.createfiletohome 
Hello a nice World!
This example demonstrates the app confinement
This app tries to write to its own user directory
/snap/hello-xiaoguo/x1/bin/createfiletohome: 9: /snap/hello-xiaoguo/x1/bin/createfiletohome: cannot create /home/liuxg/test.txt: Permission denied

显然,它产生了一个错误的信息.我们不可以向我们的用户的home写入任何的内容.那么我们怎么才可以呢?

方法一: 我们使用如下的方法来安装我们的应用:

$ sudo snap install hello-xiaoguo_1.0_all.snap --devmode --force-dangerous

注意上面的 --devmode,它表明在开发的过程中,我们的snap应用忽略任何的安全问题,也就是我们的snap将和以前开发的任何应用一样,不接受snap系统所带来的任何的安全的限制.这种方式一般适合在早期开发一个snap应用时使用.等到我们把功能完善后,我们再来完善我们的安全的部分.

针对使用--devmode打包的snap来说(我们也可以在snapcraft.yaml中的confinement设为devmode),我们必须注意的是: 

Snaps can be uploaded to the edge and beta channels only


另外特别值得指出的是,如果我们的snapcraft.yaml中的confinement被定义为devmode,那个这个应用将能被"snap find"发现而进行安装.作为开发者本身,你可以通过命令" snap install --devmode"来进行安装测试,普通用户不能使用"snap find/install"来对该应用进行操作.

方法二:我们重新把我们的snapcraft.yaml改写如下:

snapcraft.yaml

name: hello-xiaoguo
version: 1.0
architectures: [ all ]
summary: The 'hello-world' of snaps
description: |
    This is a simple snap example that includes a few interesting binaries
    to demonstrate snaps and their confinement.
    * hello-world.env  - dump the env of commands run inside app sandbox
    * hello-world.evil - show how snappy sandboxes binaries
    * hello-world.sh   - enter interactive shell that runs in app sandbox
    * hello-world      - simply output text
confinement: strict

apps:
 env:
   command: bin/env
 evil:
   command: bin/evil
 sh:
   command: bin/sh
 hello-world:
   command: bin/echo
 createfile:
   command: bin/createfile
 createfiletohome:
   command: bin/createfiletohome
   plugs: [home]

parts:
 hello:
  plugin: copy
  files:
    ./bin: bin

在上面,我们在createfiletohome应用下加入了home plug.它表明我们的应用可以访问用户的home目录.在snap系统,如果一个应用想访问另外一个受限的资源或访问一个被其它应用所拥有的资源时,我们可以通过interface来实现.更多的关于snap的 interface方面的知识,大家可以参阅 Interfaces链接.我们可以通过如下的命令来查看所有的interface:

liuxg@liuxg:~$ snap interfaces
Slot                 Plug
:camera              -
:cups-control        -
:firewall-control    -
:gsettings           -
:home                -
:locale-control      -
:log-observe         -
:modem-manager       -
:mount-observe       -
:network             -
:network-bind        -
:network-control     -
:network-manager     -
:network-observe     -
:opengl              -
:optical-drive       -
:ppp                 -
:pulseaudio          -
:snapd-control       -
:system-observe      -
:timeserver-control  -
:timezone-control    -
:unity7              -
:x11                 -

重新打包我们的应用:

liuxg@liuxg:~/snappy/desktop/helloworld$ hello-xiaoguo.createfiletohome 
Hello a nice World!
This example demonstrates the app confinement
This app tries to write to its own user directory
Succeeded! Please find a file created at /home/liuxg/snap/hello-xiaoguo/x1/test.txt
If do not see this, please file a bug

现在,我们再也没有上面显示的那个错误信息了.
所有的源码在: https://github.com/liu-xiao-guo/helloworld-final


7)应用的shell


虽然我们的hello应用非常简单,但是它确实展示了我们很多希望看到的snap应用的一面.在我们的应用中,我们还有一个应用叫做sh.它事件上是一个shell.我们可以通过如下的方式来启动它:

$ hello-xiaoguo.sh

当这个应用被启动后:

liuxg@liuxg:~$ hello-xiaoguo.sh
Launching a shell inside the default app confinement. Navigate to your
app-specific directories with:

  $ cd $SNAP
  $ cd $SNAP_DATA
  $ cd $SNAP_USER_DATA

bash-4.3$ env | grep snap
SNAP_USER_COMMON=/home/liuxg/snap/hello-xiaoguo/common
SNAP_LIBRARY_PATH=/var/lib/snapd/lib/gl:
SNAP_COMMON=/var/snap/hello-xiaoguo/common
SNAP_USER_DATA=/home/liuxg/snap/hello-xiaoguo/x4
SNAP_DATA=/var/snap/hello-xiaoguo/x4
PATH=/snap/hello-xiaoguo/x4/bin:/snap/hello-xiaoguo/x4/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
HOME=/home/liuxg/snap/hello-xiaoguo/x4
XDG_DATA_DIRS=/usr/share/ubuntu:/usr/share/gnome:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop
SNAP=/snap/hello-xiaoguo/x4
bash-4.3$ 
我们可以通过这个shell来完成我们想要的任务.比如:

bash-4.3$ cd /home/liuxg
bash-4.3$ pwd
/home/liuxg
bash-4.3$ touch hello.text
touch: cannot touch 'hello.text': Permission denied

我们发现,由于snap安全的限制,我们不能向以前的系统那样,可以自由地在任何地方创建一个我们想要的文件了.还有更多的例子,我们留给你们自己来慢慢地体会.

如果大家对snapcraft想了解更多的话,你可以试一下如下的命令:

$ snapcraft tour
Snapcraft tour initialized in ./snapcraft-tour/
Instructions are in the README, or http://snapcraft.io/create/#tour

我们可以在我们的home里的snapcraft-tour目录中找到我们所需要学习的例程.









你可能感兴趣的:(移动开发,Ubuntu,Core)