~jocave/snapcraft/plainbox-provider-plugin

105.3.3 by Michael Terry
fixups and expanded tutorial
1
# Snapcraft Tutorial
2
3
Let's make a snap from scratch using Snapcraft! We'll pick something a little
4
interesting: a webcam server.
5
6
## Preparation
7
8
You'll want a webcam and a Snappy device. We'll assume you have those,
9
but if you need help setting up a Snappy install, there is help
10
[online](https://developer.ubuntu.com/en/snappy/start/).
11
12
(Even if you don't have either of those, you can still follow along. You just
13
won't be able to use the final snap package you create. But you'll get to see
105.3.6 by Michael Terry
Some wording changes
14
how Snapcraft works, which is still super rewarding.)
105.3.3 by Michael Terry
fixups and expanded tutorial
15
105.3.6 by Michael Terry
Some wording changes
16
You should also install Snapcraft:
105.3.3 by Michael Terry
fixups and expanded tutorial
17
18
    $ sudo add-apt-repository ppa:snappy-dev/snapcraft-daily
19
    $ sudo apt-get update
20
    $ sudo apt-get install snapcraft
21
22
## Approach
23
24
This example is easy because we won't be doing much of the heavy lifting
25
ourselves. We're going to integrate a couple pieces of code together to make
26
an interesting app.
27
28
Namely, we'll combine a web server with a webcam program and combine
29
them to serve a new frame every ten seconds.
30
31
### The Web Server
32
33
Go has a simple web server in its standard libraries. So let's just use that.
34
35
It's trivial to write a complete (but basic) web server in a few lines:
36
37
    package main
38
    import "net/http"
39
    func main() {
40
        panic(http.ListenAndServe(":8080", http.FileServer(http.Dir("."))))
41
    }
42
120.2.5 by Daniel Holbach
indicate what's a file and directory name
43
This will serve the current directory on port `:8080`. If there is an 
44
`index.html` in the current directory, it will be served. Otherwise a 
45
directory listing will be shown.
105.3.3 by Michael Terry
fixups and expanded tutorial
46
47
I've provided the above code in a simple GitHub
48
[repository](https://github.com/mikix/golang-static-http).
49
50
### The Webcam Program
51
52
There is a webcam program provided in the Ubuntu archives called `fswebcam`.
53
It has a lot of neat features. But all we'll be needing for now is its ability
54
to take a webcam freeze frame and drop it to a file by calling it like so:
55
56
    $ fswebcam output.jpg
57
58
## Snapcraft Recipe
59
60
OK, let's create a Snapcraft recipe that combines the above programs into a
61
useful snap.
62
63
Snapcraft reads a single file, `snapcraft.yaml`, which tells it how to combine
64
code. It contains a list of `parts`, or pieces of code, and some metadata for
65
the final snap it will create. But let's not worry about the metadata yet.
66
67
### Web Server Part
68
69
Let's start with the web server.
70
71
    parts:
72
      golang-static-http:
73
        plugin: go1.4-project
74
        source: git://github.com/mikix/golang-static-http
75
76
You've got a `parts` list with one item, named `golang-static-http`, but we
77
could call it anything. That part has a few options. A `plugin` option that
78
tells Snapcraft how to interpret the part. In this case, it's a Go project
79
using Go 1.4. And finally, a `source` option telling Snapcraft where to
80
download the code.
81
82
Go ahead and create `snapcraft.yaml` with the above contents in an empty
83
directory.
84
85
Now we can build and "stage" this recipe. Staging just means putting the output
86
of the parts in a common folder that has the same layout as the snap we'll
87
eventually create. It lets you look at how the snap is constructed and make
88
sure everything is in place.
89
90
    $ snapcraft stage
91
92
You'll see a bunch of output, including Snapcraft downloading the Go compiler.
93
It will use this to compile the code found on GitHub. Eventually when it is
120.2.5 by Daniel Holbach
indicate what's a file and directory name
94
done, you'll be able to inspect the `./stage` folder and see the web server
95
executable sitting in `./stage/bin`:
105.3.3 by Michael Terry
fixups and expanded tutorial
96
97
    $ ls stage/bin
98
    golang-static-http
99
100
### Webcam Part
101
102
Now let's add the webcam program `fswebcam` to our snap. Edit `snapcraft.yaml`
103
to look like:
104
105
    parts:
106
      golang-static-http:
107
        plugin: go1.4-project
108
        source: git://github.com/mikix/golang-static-http
109
      fswebcam:
110
        plugin: ubuntu
111
112
We've added a new part called `fswebcam` handled by the `ubuntu` plugin. That
113
plugin will include an Ubuntu package and its dependencies into your snap. It
114
will use the name of the part as the package name to include.
115
116
Now let's stage our recipe again.
117
118
    $ snapcraft stage
119
120.2.5 by Daniel Holbach
indicate what's a file and directory name
120
You'll note that Snapcraft skipped downloading and building 
121
`golang-static-htpp` again because it knew it had already done so.
105.3.3 by Michael Terry
fixups and expanded tutorial
122
123
You'll also see Snapcraft downloading and unpacking all the Ubuntu packages
120.2.5 by Daniel Holbach
indicate what's a file and directory name
124
into your snap. If you look at `./stage`, you'll see a lot more files now:
105.3.3 by Michael Terry
fixups and expanded tutorial
125
126
    $ ls stage
127
    bin  etc  lib  usr  var
128
129
### Gluing the Parts Together
130
131
OK, so we have the two programs in our staging area. But how do we make them
132
work together?
133
134
We'll write a tiny little script that runs the server and `fswebcam` together:
135
136
    #!/bin/sh
137
    set -e
138
139
    cd "$SNAPP_APP_DATA_PATH"
140
141
    golang-static-http &
142
143
    while :; do
144
        fswebcam shot.jpeg
145
        sleep 10
146
    done
147
148
Save the above as `webcam-webui` and make it executable:
149
150
    $ chmod a+x webcam-webui
151
152
Alright, let's put this script in our snap too:
153
154
    parts:
155
      golang-static-http:
156
        plugin: go1.4-project
157
        source: git://github.com/mikix/golang-static-http
158
      fswebcam:
159
        plugin: ubuntu
160
      glue:
161
        plugin: copy
162
        files:
163
          webcam-webui: bin/webcam-webui
164
165
The `copy` plugin takes a list of files to just directly copy without building
166
or downloading anything. In this case, we just want to put our glue script in
120.2.5 by Daniel Holbach
indicate what's a file and directory name
167
the `bin/` directory.
105.3.3 by Michael Terry
fixups and expanded tutorial
168
169
If we run Snapcraft again, we won't be surprised:
170
171
    $ snapcraft stage
172
173
We should now see both the web server and our script in stage/bin (the webcam
174
program is in stage/usr/bin since it came from Ubuntu):
175
176
    $ ls stage/bin
177
    golang-static-http  webcam-webui
178
179
### Package Metadata
180
181
"But how do we actually make a snap?", you may be wondering. To do that, we
182
need some metadata files required by Snappy that describe how our code should
183
be installed and run.
184
185
You can read all about the [format of this metadata](https://developer.ubuntu.com/en/snappy/guides/packaging-format-apps/),
186
but we'll assume here that you're already familiar.
187
188
Let's make a new subdirectory called `meta` and put our Snappy package files
189
there. Here's the contents of `meta/package.yaml`:
190
191
    name: webcam-webui
192
    version: 1
193
    vendor: You <you@example.com>
194
    services:
195
    - name: webcam-webui
196
      start: bin/webcam-webui
197
198
And a very simple `meta/readme.md`:
199
200
    # Webcam web UI
201
202
    Exposes your webcam over a web UI
203
204
Now that we have that sorted, we can tell Snapcraft where to find our metadata:
205
206
    parts:
207
      golang-static-http:
208
        plugin: go1.4-project
209
        source: git://github.com/mikix/golang-static-http
210
      fswebcam:
211
        plugin: ubuntu
212
      glue:
213
        plugin: copy
214
        files:
215
          webcam-webui: bin/webcam-webui
216
    snappy-metadata: meta
217
218
And tell Snapcraft to actually make the snap package:
219
220
    $ snapcraft assemble
221
222
You should now have a `webcam-webui_1_amd64.snap` file sitting in your
223
directory (assuming you are running on amd64). Congratulations!
120.1.1 by Daniel Holbach
add some next steps
224
225
226
## Next steps
227
228
Well done, your first snap using snapcraft is ready. If you want to check out
229
a few examples for reference or to get inspired, have a look at the 
230
`examples` directory in the source directory of snapcraft:
231
232
    bzr branch lp:snapcraft
233
    cd snapcraft/examples
234
235
In `examples/` you can find a diverse set of examples which should help you 
236
get started on your own projects.
237
238
If you should have any more questions, ask us on
239
240
 * `#snappy` on `irc.freenode.net` or
241
 * the [snappy-app-devel](https://lists.ubuntu.com/mailman/listinfo/snappy-app-devel)
242
   mailing list
243