Skip to content

Commit d5878eb

Browse files
committed
update readme
1 parent 63d04fd commit d5878eb

File tree

1 file changed

+47
-235
lines changed

1 file changed

+47
-235
lines changed

daemon/README.md

Lines changed: 47 additions & 235 deletions
Original file line numberDiff line numberDiff line change
@@ -78,119 +78,80 @@ because is impossible to know the digest before to generate the image itself.
7878
Finally we model the repository as an append only structure, deleting
7979
layers could break some images actually running.
8080

81-
## Commands
82-
83-
Here follow the list of commands that the converter understand.
84-
85-
### add-wish
86-
87-
```
88-
add-wish --input-image $INPUT_IMAGE --output-image $OUTPUT_IMAGE --repository $CVMFS_REPO \
89-
--user-input $USER_INPUT --user-output $USER_OUTPUT
90-
```
91-
92-
Will add a new `wish` to the internal database, then it will try to
93-
convert the regular image into a thin image.
94-
95-
The users are the one that will try to log into the registry, you can add
96-
users (so usernames, password and registry) using the `add-user` command.
97-
98-
### add-image
99-
100-
```
101-
add-image $IMAGE
102-
```
103-
104-
Will add the image to the internal database
105-
106-
### check-image-syntax
107-
108-
```
109-
check-image-syntax $IMAGE
110-
```
111-
112-
Will parse your image and output what it is been able to parse.
113-
114-
### list-images
81+
## Recipes
11582

116-
```
117-
list-images
118-
```
83+
Recipes are a way to describe the wish we are interested in convert.
11984

120-
List all the images in the database
85+
### Recipe Syntax v1
12186

122-
### migrate-database
87+
An example of a complete recipe file is above, let's go over each key
12388

124-
```
125-
migrate-database
89+
``` yaml
90+
version: 1
91+
user: smosciat
92+
cvmfs_repo: unpacked.cern.ch
93+
output_format: '$(scheme)://registry.gitlab.cern.ch/thin/$(image)'
94+
input:
95+
- 'https://registry.hub.docker.com/econtal/numpy-mkl:latest'
96+
- 'https://registry.hub.docker.com/agladstein/simprily:version1'
97+
- 'https://registry.hub.docker.com/library/fedora:latest'
98+
- 'https://registry.hub.docker.com/library/debian:stable'
12699
```
127100
128-
Apply all the migration to the database up to the newest version of the
129-
software.
101+
**version**: indicate what version of recipe we are using, at the moment only
102+
`1` is supported.
103+
**user**: the user that will push the thin docker images into the registry,
104+
the password must be stored in the `DOCKER2CVMFS_DOCKER_REGISTRY_PASS`
105+
environment variable.
106+
**cvmfs_repo**: in which CVMFS repository store the layers and the singularity
107+
images.
108+
**output_format**: how to name the thin images. It accepts few "variables" that
109+
reference to the input image.
130110

131-
At the first run is necessary to run this function.
111+
* $(scheme), the very first part of the image url, most likely `http` or `https`
112+
* $(registry), in which registry the image is locate, in the case of the example it would be `registry.hub.docker.com`
113+
* $(repository), the repository of the input image, so something like `library/ubuntu` or `atlas/athena`
114+
* $(tag), the tag of the image examples could be `latest` or `stable` or `v0.1.4`
115+
* $(image), the $(repository) plus the $(tag)
132116

133-
### download-manifest
117+
**input**: list of docker images to convert
134118

135-
```
136-
download-manifest $IMAGE
137-
```
119+
This recipe format allow to specify only some wish, specifically all the images
120+
need to be stored in the same CVMFS repository and have the same format.
138121

139-
Will try to download the manifest of the image from the repository, if
140-
successful it will print the manifest itself, otherwise it will display the
141-
error. The same internal procedure is used in order to actually convert the
142-
images.
122+
## Commands
143123

144124
### convert
145125

146126
```
147-
convert
127+
convert recipe.yaml
148128
```
149129
150-
This command will try to convert all the wish in the wish list.
130+
This command will try to convert all the wish in the recipe.
151131
152132
### loop
153133
154134
```
155-
loop
135+
loop recipe.yaml
156136
```
157137
158138
This command is equivalent to call `convert` in an infinite loop, useful to
159139
make sure that all the images are up to date.
160140
161-
162-
## add-wish workflow
163-
164-
This section will go into the detail of what happens when we try to add a
165-
wish.
166-
167-
The very first step is the parse of both the input and output image, if any of
168-
those parse fails the whole command fails and we immediately return an error.
169-
170-
Then we check if the wish we are trying to add is already in the
171-
database, if it is we are not going to add it again and we simply return an
172-
error.
173-
174-
The next step is trying to download the input image manifest, if we are not
175-
able to access the input manifest we return an error.
176-
177-
Finally if every check completed successfully we add the wish to the
178-
internal database.
179-
180141
## convert workflow
181142
182143
The goal of convert is to actually create the thin images starting from the
183144
regular one.
184145
185-
In order to convert we iterate for every wish in the wish list.
146+
In order to convert we iterate for every wish in the recipe.
186147
187148
In general, some wish will be already converted while others will need to
188149
be converted ex-novo.
189150
190151
The first step is then to check if the wish is already been converted.
191152
In order to do this check, we download the input image manifest and check
192-
against the internal database if the input image digest is already been
193-
converted, if it is we can safely skip such conversion.
153+
in the repository if the specific image is been already converted, if it is we
154+
safely skip such conversion.
194155
195156
Then, every image is made of different layers, some of them could already be
196157
on the repository.
@@ -213,165 +174,16 @@ images are stored in the `singularity` subdirectory.
213174
214175
This section explains how this utility is intended to be used.
215176
216-
Internally this utility invokes `cvmfs_server` and `docker` commands, so it is
217-
necessary to use it in a stratum0 that also have docker installed.
218-
219-
The docker dependency can be dropped, but it would require some amount of work,
220-
so for this first release, as long as it is not a big hurdle, we are going to
221-
keep it.
222-
223-
The first time the utility is launched is necessary to create the SQLite
224-
database, to do so you can call the command `migrate-database` or its alias,
225-
`init`.
226-
227-
This command, create as SQLite database called `docker2cvmfs_archive.sqlite`,
228-
the utility will require this file to always be on `.`, the directory from
229-
where you are calling the utility itself, this requirements will be dropped in
230-
future releases.
231-
232-
Once the database is been created we can start adding users, images and
233-
wishes.
177+
Internally this utility invokes `cvmfs_server`, `docker` and `singularity`
178+
commands, so it is necessary to use it in a stratum0 that also have docker
179+
installed.
234180
235181
The conversion is quite straightforward, we first download the input image, we
236-
store each layer on the cvmfs repository, we create the output image and
237-
finally we upload the output image to the registry.
238-
239-
For downloading an image the credentials can be not necessary, while for
240-
uploading it they are mandatory.
241-
242-
Also, you may want to have different users upload different images to the same
243-
docker registry, maybe even one user for image.
244-
245-
The first step is so to call `add-user`.
246-
247-
```
248-
$ ./daemon init
249-
INFO[0000] Made migrations n=2
250-
$ ./daemon add-user --username foo --password secret --registry docker.foo.bar.com
251-
$ ./daemon list-users
252-
+------+--------------------+
253-
| USER | REGISTRY |
254-
+------+--------------------+
255-
| foo | docker.foo.bar.com |
256-
+------+--------------------+
257-
```
258-
259-
I wasn't able to figure out a reliable way to get authentication tokens so
260-
to avoid storing the password as clear text in the database, the suggestion at
261-
the moment is to use disposable users with very limited capabilities so that
262-
if the database get compromised (a third party has access to it) we are able to
263-
limit the treats.
264-
265-
The next step is to add a wish, to do so:
266-
267-
```
268-
$ ./daemon add-wish \
269-
--input-image https://registry.hub.docker.com/library/redis:4 \
270-
--output-image https://gitlab-registry.cern.ch/smosciat/containerd/thin/redis:4 \
271-
--repository cd.cern.ch \
272-
--user-output smosciat
273-
WARN[0000] Unable to retrieve the password, trying to get the manifest anonymously. error="sql: no rows in result set"
274-
Auth to: Bearer realm="https://auth.docker.io/token",service="registry.docker.io",scope="repository:library/redis:pull"
275-
https://auth.docker.io/token?scope=repository%3Alibrary%2Fredis%3Apull&service=registry.docker.io
276-
277-
$ ./daemon list-wish
278-
+----+----------------+-------------------------------------------------+------------+-----------------+------------------------------------------------------------------+
279-
| ID | INPUT IMAGE ID | INPUT IMAGE NAME | CVMFS REPO | OUTPUT IMAGE ID | OUTPUT IMAGE NAME |
280-
+----+----------------+-------------------------------------------------+------------+-----------------+------------------------------------------------------------------+
281-
| 1 | 1 | https://registry.hub.docker.com/library/redis:4 | cd.cern.ch | 2 | https://gitlab-registry.cern.ch/smosciat/containerd/thin/redis:4 |
282-
+----+----------------+-------------------------------------------------+------------+-----------------+------------------------------------------------------------------+
283-
```
284-
285-
Of course you can add as many wish as you need.
286-
287-
Now that all the wishes are in place you can simply start converting them:
288-
289-
```
290-
$ ./daemon convert
291-
```
292-
293-
The above command should provide enough logs to be able to infer what is
294-
happening and to debug any error.
295-
296-
Make sure that the user is able to start a cvmfs transaction and that is able
297-
to communicate with docker, anyway this errors should be pretty self evident
298-
in the logs.
299-
300-
The above command is quite cheap, it avoids to convert an images that is
301-
already been converted and it avoid to download layers that are already been
302-
downloaded, command line flags can change this behaviour if necessary.
303-
304-
You may want to keep the above command running in a loop, hence it will
305-
automatically pick up changes in the input images and start the conversion.
306-
307-
We are basically polling the registries for changing in the input image, again
308-
there was not a reliable and easy way to get updates from the registry, not
309-
even from the one inside CERN that we manage.
310-
311-
In order to run the conversion in a loop you can simply use:
312-
313-
```
314-
$./daemon loop
315-
```
316-
317-
While the daemon is running in a loop you should be able to iteract with the
318-
utility without any issue, so you should be able to add users, images and even
319-
new wishes, the next loop will pick the adding elements up.
320-
321-
Only be careful to don't leave the CVMFS repository in an inconsistet state
322-
(abort the program Ctrl-C while it is doing a transaction).
323-
324-
325-
## Recipes
326-
327-
Recipes are a way to describe the content of the wish list using a simple,
328-
static YAML file.
329-
330-
Recipes are read by the tool and set the wish list accordingly, adding and
331-
**removing** wishes.
332-
333-
The operation of setting a recipe is idempotence, this means that repeating the
334-
operation, with the same recipe, multiple times does not change the wish list.
335-
336-
Please make sure to be careful if you add a wish manually and then set a recipe,
337-
if the wish you add manually is not in the recipe the wish will be deleted.
338-
Similarly avoid to work with multiple recipe files, one will delete the wishes
339-
of the other.
340-
341-
Recipes are thought in such a way that you should have only a single recipe
342-
for CVMFS repository.
343-
344-
### Recipe Syntax v1
345-
346-
An example of a complete recipe file is above, let's go over each key
347-
348-
``` yaml
349-
version: 1
350-
user: smosciat
351-
cvmfs_repo: unpacked.cern.ch
352-
output_format: '$(scheme)://registry.gitlab.cern.ch/thin/$(image)'
353-
input:
354-
- 'https://registry.hub.docker.com/econtal/numpy-mkl:latest'
355-
- 'https://registry.hub.docker.com/agladstein/simprily:version1'
356-
- 'https://registry.hub.docker.com/library/fedora:latest'
357-
- 'https://registry.hub.docker.com/library/debian:stable'
358-
```
359-
360-
**version**: indicate what version of recipe we are using, at the moment only
361-
`1` is supported.
362-
**user**: the user that will push the thin docker images into the registry,
363-
this user need to be added separately into the database
364-
**cvmfs_repo**: in which CVMFS repository store the layers and the singularity
365-
images.
366-
**output_format**: how to name the thin images. It accepts few "variables" that
367-
reference to the input image.
368-
369-
* $(scheme), the very first part of the image url, most likely `http` or `https`
370-
* $(registry), in which registry the image is locate, in the case of the example it would be `registry.hub.docker.com`
371-
* $(repository), the repository of the input image, so something like `library/ubuntu` or `atlas/athena`
372-
* $(tag), the tag of the image examples could be `latest` or `stable` or `v0.1.4`
373-
* $(image), the $(repository) plus the $(tag)
374-
375-
**input**: list of docker images to convert
182+
store each layer on the cvmfs repository, we create the output image and unpack
183+
the singularity one, finally we upload the output image to the registry.
376184
185+
It does not support dowloading images that are not public.
377186
187+
In order to publish images to a repository is necessary to sign up in the
188+
docker hub. It will use the user from the recipe, while it will read the
189+
password from the `DOCKER2CVMFS_DOCKER_REGISTRY_PASS` environment variable.

0 commit comments

Comments
 (0)