在我的上一篇文章中,我已经展示了如何在Desktop环境下编译我们的项目并成功部署到我们的KVM环境中.可能有兴趣的开发者们想更一步把我们的项目部署到一个设备中,比如树莓派中,那么我们该怎么做呢?在今天的这篇文章中,我们将介绍如何实现这个目标.我们将利用docker技术在我们的树莓派中建立一个可以编译的环境.
1)在树莓派中建立编译环境
我们知道我们目前的工具snapcraft还不支持cross-compile.那么唯一的办法就是在我们的树莓派中建立自己的armhf编译环境.如果大家还没有设置好自己的树莓派的话,请参阅为的文章"
如何安装Snappy Ubuntu到树莓派(RaspBerry PI)上".下面我们主要做的工作是在Snappy Ubuntu中建立一个可以编译的环境.
我们可以通过如下的方法连到我们的树莓派上:
$ ssh 192.168.1.112 -l ubuntu
或
$ ssh ubuntu@192.168.1.112
或更直接的办法
$ ssh ubuntu@webdm.local
我们可以首先查看一下docker是否已经被安装到我们的树莓派中:
(RaspberryPi2)ubuntu@localhost:~$ snappy list -v
Name Date Version Developer
ubuntu-core 2015-09-25 2 ubuntu*
ubuntu-core 2015-09-25 2 ubuntu
docker 2015-11-09 1.6.2.004 canonical*
go-webserver 2015-11-09 IFIUJRXOREgX sideload*
mqtt-piglow 2015-11-02 IEWUKJCENbWA sideload*
port-listener 2015-10-31 IERSNIVOKWSF sideload*
webdm 2015-10-27 0.9.3 sideload
webdm 2015-10-29 0.9.4 sideload*
pi2 2015-09-25 0.16 canonical*
在我们的系统中我们可以看到docker已经安装.如果你没有看到docker已经安装,我们可以打入如下的命令来安装自己的docker:
(RaspberryPi2)ubuntu@localhost:~$ sudo snappy install docker
等安装好自己的docker后,我们可以检查一下docker的版本:
(RaspberryPi2)ubuntu@localhost:~$ docker version
Client version: 1.6.2
Client API version: 1.18
Go version (client): go1.4.2
Git commit (client): a464a34
OS/Arch (client): linux/arm
Server version: 1.6.2
Server API version: 1.18
Go version (server): go1.4.2
Git commit (server): a464a34
OS/Arch (server): linux/arm
运行上面的命令后,docker将创建一个属于自己的私有目录,比如下面显示的路径.
(RaspberryPi2)ubuntu@localhost:~$ cd apps/docker/1.6.2.004/
(RaspberryPi2)ubuntu@localhost:~/apps/docker/1.6.2.004$ mkdir work
接下来,我们利用docker来安装一个armhf的image:
$ (RaspberryPi2)ubuntu@localhost:~/apps/docker/1.6.2.004$ docker pull kickinz1/snappy-dev-cli-armhf
(RaspberryPi2)ubuntu@localhost:/var/lib/apps/docker/1.6.2.004$ ls
aufs containers etc graph init linkgraph.db repositories-aufs tmp trust volumes
等下载完后,我们可以通过如下的命令来查看我们已经下载的镜像:
(RaspberryPi2)ubuntu@localhost:~/apps/docker/1.6.2.004$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
kickinz1/snappy-dev-cli-armhf latest 2531f9e3f23c 4 days ago 1.022 GB
从上面可以看到我们已经下载的镜像的信息.当然如果我们不想要这个镜像的话,我们可以使用如下的命令来删除:
(RaspberryPi2)ubuntu@localhost:~/apps/docker/1.6.2.004$ sudo docker rmi 2531f9e3f23c
注意这里使用的2531f9e3f23c是我们在上面显示的"IMAGE ID".我们需要根据自己的实际显示来替换这个ID.
我们有了一个armhf的image,接下来我们来创建一个时候我们自己使用的container:
sudo docker run -it -v /home/ubuntu/apps/docker/1.6.2.004/work:/home/ubuntu/work --name snappy-dev-cli kickinz1/snappy-dev-cli-armhf
我们可以使用如下的命令来查看我们已经安装的container及其所有信息:
(RaspberryPi2)ubuntu@localhost:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca5564878ccb kickinz1/snappy-dev-cli-armhf:latest "/bin/sh -c 'sudo ch 38 hours ago Exited (0) 38 hours ago snappy-dev-cli
有了上面的container,我们就可以有一个在armhf的ubuntu环境.我们不需要这个container时,我们可以使用如下的命令来删除它:
(RaspberryPi2)ubuntu@localhost:~$ sudo docker rm ca5564878ccb
$ sudo docker start -i snappy-dev-cli
注意这里的snappy-dev-cli是我们的新创建的container的名字.它在我们上面的命令行中已经被定义(--name snappy-dev-cli )
等我们进入到container后,我们运行如下的命令来更新最新的snapcraft:
$ sudo add-apt-repository ppa:snappy-dev/tools
$ sudo apt-get install snapcraft
$ snapcraft version
snapcraft (0.5).
Run "snapcraft help" to get started.
目前按理来说,所有的东西都已经安装好了,可以直接利用这个环境去编译我们的应用了.如果我们现在直接去编译一个我们自己的golang项目,我们会出现如下的错误:
ubuntu@34fc56495ebb:~/work$ snapcraft
Pulling webserver
env GOPATH=/home/ubuntu/work/parts/webserver/build go get -t -d github.com/liu-xiao-guo/golang-http
package github.com/liu-xiao-guo/golang-http
imports runtime: C source files not allowed when not using cgo or SWIG: defs.c float.c heapdump.c lfstack.c malloc.c mcache.c mcentral.c mem_linux.c mfixalloc.c mgc0.c mheap.c msize.c os_linux.c os_linux_arm.c panic.c parfor.c proc.c runtime.c signal.c signal_arm.c signal_unix.c softfloat_arm.c stack.c string.c sys_arm.c vlrt.c
Failed doing pull for webserver: Command '['/bin/sh', '/tmp/tmpr13qjaa9', 'env', 'GOPATH=/home/ubuntu/work/parts/webserver/build', 'go', 'get', '-t', '-d', 'github.com/liu-xiao-guo/golang-http']' returned non-zero exit status 1
我们可以做如下的步骤来矫正:
$ sudo apt-get update
$ sudo apt-get install curl
$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
$ source /home/ubuntu/.gvm/scripts/gvm
目前发现的问题是,如果再次进入还是发现如上面所述在编译golang项目时的错误情况,我们需要在terminal中重新输入如下的命令来纠正这个错误:
$ source /home/ubuntu/.gvm/scripts/gvm
2)编译并部署我们的应用
我们首先进入到我们的工作目录work中去,并键入如下的命令:
$ git clone https://github.com/liu-xiao-guo/go-webserver.git
我们已经下载好我们的应用到我们的go-webserver目录中.我们在我们项目的根目录中键入如下的命令:
ubuntu@ca5564878ccb:~/work/go-webserver$ snapcraft
从上面可以看出来,我们已经成功在armhf的ubuntu环境下编译出我们自己的snap文件.这个文件可以被用于arm板子上的安装.我们现在退出我们的docker环境:
ubuntu@ca5564878ccb:~/work/go-webserver$ exit
这样就重新回到我们的Snappy系统中.我们进入到docker的私有目录中:
从上面可以看出来,我们Snappy系统下文件目录中找到了已经编译并打包好的snap文件,我们可以通过如下的命令来进行安装:
(RaspberryPi2)ubuntu@localhost:~/apps/docker/1.6.2.004/work/go-webserver$ sudo snappy install --allow-unauthenticated go-webserver_1.0.7_armhf.snap
从上面我们可以看出,我们的go-webserver已经被成功安装.我们打开我们的firefox浏览器:
显然它在我们的树莓派上已经成功部署并运行.因为它是一个service,所有在安装完后,就自动运行起来了.
通过同样的方法,我们也可以来编译并打包我们的一个python项目"
mqtt-for-ubuntu-core".
如果你想了解如何为KVM编译并部署snap的方法,请参阅文章"
如何为我们的Snappy Ubuntu应用编译并打包Snap(1)"
3)编译本地源码
细心的开发者可以在自己的命令打入如下的命令来查看自己的snapcraft版本
$ snapcraft version
如果自己的版本是0.5以下,那么你的snapcraft版本将不能编译一个源码在本地的项目,比如,一个项目的snapcraft.yaml的内容如下:
name: piglow
version: 1.0
vendor: XiaoGuo, Liu <xiaoguo.liu@canonical.com>
summary: Piglow API
description: This is the webserver API to control the piglow
icon: icon.png
services:
piglow:
start: bin/piglow
caps:
- network-client
- network-service
parts:
piglow:
plugin: go
source: ./src/piglow
在上面,我们可以看到"./src/piglow",表明它的源码是在本地.0.5版本以前的snapcraft是不可以编译这样的项目的.它只能编译如下的snapcraft.yaml文件:
name: piglow
version: 1.0
vendor: XiaoGuo, Liu <xiaoguo.liu@canonical.com>
summary: Piglow API
description: This is the webserver API to control the piglow
icon: icon.png
services:
piglow:
start: bin/piglow
caps:
- network-client
- network-service
parts:
piglow:
plugin: go
source: git://github.com/mikix/golang-static-http
在这里,source的源码是指向一个git的repository.
如果你目前还不能得到0.4及以上的snapcraft的版本,我们可以使用如下的方法来得到最新的版本:
$ git clone https://github.com/ubuntu-core/snapcraft
$ ./setup.py build
$ sudo ./setup.py install
来得到最新的snapcraft的版本.