root / docs / dev-guide.rst @ 8f9976c6
History | View | Annotate | Download (11.7 kB)
1 |
.. _dev-guide: |
---|---|
2 |
|
3 |
Synnefo Developer's Guide |
4 |
^^^^^^^^^^^^^^^^^^^^^^^^^ |
5 |
|
6 |
This is the complete Synnefo Developer's Guide |
7 |
|
8 |
Tying it all up with kamaki |
9 |
=========================== |
10 |
|
11 |
kamaki |
12 |
------ |
13 |
|
14 |
IM API (Astakos) |
15 |
================ |
16 |
|
17 |
This is the Identity Management API: |
18 |
|
19 |
.. toctree:: |
20 |
:maxdepth: 2 |
21 |
|
22 |
IM API <astakos-api-guide> |
23 |
|
24 |
Compute API (Cyclades) |
25 |
====================== |
26 |
|
27 |
This is the Cyclades Compute API: |
28 |
|
29 |
.. toctree:: |
30 |
:maxdepth: 2 |
31 |
|
32 |
Compute API <cyclades-api-guide> |
33 |
|
34 |
Network API (Cyclades) |
35 |
====================== |
36 |
|
37 |
Network API body |
38 |
|
39 |
Images API (Plankton) |
40 |
===================== |
41 |
|
42 |
Images API body |
43 |
|
44 |
Storage API (Pithos+) |
45 |
===================== |
46 |
|
47 |
This is the Pithos+ File Storage API: |
48 |
|
49 |
.. toctree:: |
50 |
:maxdepth: 2 |
51 |
|
52 |
File Storage API <pithos-api-guide> |
53 |
|
54 |
Implementing new clients |
55 |
======================== |
56 |
|
57 |
In this section we discuss implementation guidelines, that a developer should |
58 |
take into account before writing his own client for the above APIs. Before, |
59 |
starting your client implementation, make sure you have thoroughly read the |
60 |
corresponding Synnefo API. |
61 |
|
62 |
Pithos+ clients |
63 |
--------------- |
64 |
|
65 |
User Experience |
66 |
~~~~~~~~~~~~~~~ |
67 |
|
68 |
Hopefully this API will allow for a multitude of client implementations, each |
69 |
supporting a different device or operating system. All clients will be able to |
70 |
manipulate containers and objects - even software only designed for OOS API |
71 |
compatibility. But a Pithos interface should not be only about showing |
72 |
containers and folders. There are some extra user interface elements and |
73 |
functionalities that should be common to all implementations. |
74 |
|
75 |
Upon entrance to the service, a user is presented with the following elements - |
76 |
which can be represented as folders or with other related icons: |
77 |
|
78 |
* The ``home`` element, which is used as the default entry point to the user's |
79 |
"files". Objects under ``home`` are represented in the usual hierarchical |
80 |
organization of folders and files. |
81 |
* The ``trash`` element, which contains files that have been marked for |
82 |
deletion, but can still be recovered. |
83 |
* The ``shared`` element, which contains all objects shared by the user to |
84 |
other users of the system. |
85 |
* The ``others`` element, which contains all objects that other users share |
86 |
with the user. |
87 |
* The ``groups`` element, which contains the names of groups the user has |
88 |
defined. Each group consists of a user list. Group creation, deletion, and |
89 |
manipulation is carried out by actions originating here. |
90 |
* The ``history`` element, which allows browsing past instances of ``home`` |
91 |
and - optionally - ``trash``. |
92 |
|
93 |
Objects in Pithos+ can be: |
94 |
|
95 |
* Moved to trash and then deleted. |
96 |
* Shared with specific permissions. |
97 |
* Made public (shared with non-Pithos+ users). |
98 |
* Restored from previous versions. |
99 |
|
100 |
Some of these functions are performed by the client software and some by the |
101 |
Pithos+ server. |
102 |
|
103 |
In the first version of Pithos, objects could also be assigned custom tags. |
104 |
This is no longer supported. Existing deployments can migrate tags into a |
105 |
specific metadata value, i.e. ``X-Object-Meta-Tags``. |
106 |
|
107 |
Implementation Guidelines |
108 |
~~~~~~~~~~~~~~~~~~~~~~~~~ |
109 |
|
110 |
Pithos+ clients should use the ``pithos`` and ``trash`` containers for active |
111 |
and inactive objects respectively. If any of these containers is not found, the |
112 |
client software should create it, without interrupting the user's workflow. The |
113 |
``home`` element corresponds to ``pithos`` and the ``trash`` element to |
114 |
``trash``. Use ``PUT`` with the ``X-Move-From`` header, or ``MOVE`` to transfer |
115 |
objects from one container to the other. Use ``DELETE`` to remove from |
116 |
``pithos`` without trashing, or to remove from ``trash``. When moving objects, |
117 |
detect naming conflicts with the ``If-Match`` or ``If-None-Match`` headers. |
118 |
Such conflicts should be resolved by the user. |
119 |
|
120 |
Object names should use the ``/`` delimiter to impose a hierarchy of folders |
121 |
and files. |
122 |
|
123 |
The ``shared`` element should be implemented as a read-only view of the |
124 |
``pithos`` container, using the ``shared`` parameter when listing objects. The |
125 |
``others`` element, should start with a top-level ``GET`` to retrieve the list |
126 |
of accounts accessible to the user. It is suggested that the client software |
127 |
hides the next step of navigation - the container - if it only includes |
128 |
``pithos`` and forwards the user directly to the objects. |
129 |
|
130 |
Public objects are not included in ``shared`` and ``others`` listings. It is |
131 |
suggested that they are marked in a visually distinctive way in ``pithos`` |
132 |
listings (for example using an icon overlay). |
133 |
|
134 |
A special application menu, or a section in application preferences, should be |
135 |
devoted to managing groups (the ``groups`` element). All group-related actions |
136 |
are implemented at the account level. |
137 |
|
138 |
Browsing past versions of objects should be available both at the object and |
139 |
the container level. At the object level, a list of past versions can be |
140 |
included in the screen showing details or more information on the object |
141 |
(metadata, permissions, etc.). At the container level, it is suggested that |
142 |
clients use a ``history`` element, which presents to the user a read-only, |
143 |
time-variable view of ``pithos`` contents. This can be accomplished via the |
144 |
``until`` parameter in listings. Optionally, ``history`` may include ``trash``. |
145 |
|
146 |
Uploading and downloading data |
147 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
148 |
|
149 |
By using hashmaps to upload and download objects the corresponding operations |
150 |
can complete much faster. |
151 |
|
152 |
In the case of an upload, only the missing blocks will be submitted to the |
153 |
server: |
154 |
|
155 |
* Calculate the hash value for each block of the object to be uploaded. Use |
156 |
the hash algorithm and block size of the destination container. |
157 |
* Send a hashmap ``PUT`` request for the object. |
158 |
|
159 |
* Server responds with status ``201`` (Created): |
160 |
|
161 |
* Blocks are already on the server. The object has been created. Done. |
162 |
|
163 |
* Server responds with status ``409`` (Conflict): |
164 |
|
165 |
* Server's response body contains the hashes of the blocks that do not |
166 |
exist on the server. |
167 |
* For each hash value in the server's response (or all hashes together): |
168 |
|
169 |
* Send a ``POST`` request to the destination container with the |
170 |
corresponding data. |
171 |
|
172 |
* Repeat hashmap ``PUT``. Fail if the server's response is not ``201``. |
173 |
|
174 |
Consulting hashmaps when downloading allows for resuming partially transferred |
175 |
objects. The client should retrieve the hashmap from the server and compare it |
176 |
with the hashmap computed from the respective local file. Any missing parts can |
177 |
be downloaded with ``GET`` requests with the additional ``Range`` header. |
178 |
|
179 |
Syncing |
180 |
~~~~~~~ |
181 |
|
182 |
Consider the following algorithm for synchronizing a local folder with the |
183 |
server. The "state" is the complete object listing, with the corresponding |
184 |
attributes. |
185 |
|
186 |
:: |
187 |
|
188 |
L: local state (stored state from last sync with the server) |
189 |
C: current state (state computed right before sync) |
190 |
S: server state |
191 |
|
192 |
if C == L: |
193 |
# No local changes |
194 |
if S == L: |
195 |
# No remote changes, nothing to do |
196 |
else: |
197 |
# Update local state to match that of the server |
198 |
L = S |
199 |
else: |
200 |
# We have local changes |
201 |
if S == L: |
202 |
# No remote changes, update the server |
203 |
S = C |
204 |
L = S |
205 |
else: |
206 |
# Both we and server have changes |
207 |
if C == S: |
208 |
# We were lucky, we did the same change |
209 |
L = S |
210 |
else: |
211 |
# We have conflicting changes |
212 |
resolve conflict |
213 |
|
214 |
Notes: |
215 |
|
216 |
* States represent file hashes (it is suggested to use Merkle). Deleted or |
217 |
non-existing files are assumed to have a magic hash (e.g. empty string). |
218 |
* Updating a state (either local or remote) implies downloading, uploading or |
219 |
deleting the appropriate file. |
220 |
|
221 |
Recommended Practices and Examples |
222 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
223 |
|
224 |
Assuming an authentication token is obtained, the following high-level |
225 |
operations are available - shown with ``curl``: |
226 |
|
227 |
* Get account information :: |
228 |
|
229 |
curl -X HEAD -D - \ |
230 |
-H "X-Auth-Token: 0000" \ |
231 |
https://pithos.dev.grnet.gr/v1/user |
232 |
|
233 |
* List available containers :: |
234 |
|
235 |
curl -X GET -D - \ |
236 |
-H "X-Auth-Token: 0000" \ |
237 |
https://pithos.dev.grnet.gr/v1/user |
238 |
|
239 |
* Get container information :: |
240 |
|
241 |
curl -X HEAD -D - \ |
242 |
-H "X-Auth-Token: 0000" \ |
243 |
https://pithos.dev.grnet.gr/v1/user/pithos |
244 |
|
245 |
* Add a new container :: |
246 |
|
247 |
curl -X PUT -D - \ |
248 |
-H "X-Auth-Token: 0000" \ |
249 |
https://pithos.dev.grnet.gr/v1/user/test |
250 |
|
251 |
* Delete a container :: |
252 |
|
253 |
curl -X DELETE -D - \ |
254 |
-H "X-Auth-Token: 0000" \ |
255 |
https://pithos.dev.grnet.gr/v1/user/test |
256 |
|
257 |
* List objects in a container :: |
258 |
|
259 |
curl -X GET -D - \ |
260 |
-H "X-Auth-Token: 0000" \ |
261 |
https://pithos.dev.grnet.gr/v1/user/pithos |
262 |
|
263 |
* List objects in a container (extended reply) :: |
264 |
|
265 |
curl -X GET -D - \ |
266 |
-H "X-Auth-Token: 0000" \ |
267 |
https://pithos.dev.grnet.gr/v1/user/pithos?format=json |
268 |
|
269 |
It is recommended that extended replies are cached and subsequent requests |
270 |
utilize the ``If-Modified-Since`` header. |
271 |
|
272 |
* List metadata keys used by objects in a container |
273 |
|
274 |
Will be in the ``X-Container-Object-Meta`` reply header, included in |
275 |
container information or object list (``HEAD`` or ``GET``). (**TBD**) |
276 |
|
277 |
* List objects in a container having a specific meta defined :: |
278 |
|
279 |
curl -X GET -D - \ |
280 |
-H "X-Auth-Token: 0000" \ |
281 |
https://pithos.dev.grnet.gr/v1/user/pithos?meta=favorites |
282 |
|
283 |
* Retrieve an object :: |
284 |
|
285 |
curl -X GET -D - \ |
286 |
-H "X-Auth-Token: 0000" \ |
287 |
https://pithos.dev.grnet.gr/v1/user/pithos/README.txt |
288 |
|
289 |
* Retrieve an object (specific ranges of data) :: |
290 |
|
291 |
curl -X GET -D - \ |
292 |
-H "X-Auth-Token: 0000" \ |
293 |
-H "Range: bytes=0-9" \ |
294 |
https://pithos.dev.grnet.gr/v1/user/pithos/README.txt |
295 |
|
296 |
This will return the first 10 bytes. To get the first 10, bytes 30-39 and the |
297 |
last 100 use ``Range: bytes=0-9,30-39,-100``. |
298 |
|
299 |
* Add a new object (folder type) (**TBD**) :: |
300 |
|
301 |
curl -X PUT -D - \ |
302 |
-H "X-Auth-Token: 0000" \ |
303 |
-H "Content-Type: application/directory" \ |
304 |
https://pithos.dev.grnet.gr/v1/user/pithos/folder |
305 |
|
306 |
* Add a new object :: |
307 |
|
308 |
curl -X PUT -D - \ |
309 |
-H "X-Auth-Token: 0000" \ |
310 |
-H "Content-Type: text/plain" \ |
311 |
-T EXAMPLE.txt |
312 |
https://pithos.dev.grnet.gr/v1/user/pithos/folder/EXAMPLE.txt |
313 |
|
314 |
* Update an object :: |
315 |
|
316 |
curl -X POST -D - \ |
317 |
-H "X-Auth-Token: 0000" \ |
318 |
-H "Content-Length: 10" \ |
319 |
-H "Content-Type: application/octet-stream" \ |
320 |
-H "Content-Range: bytes 10-19/*" \ |
321 |
-d "0123456789" \ |
322 |
https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt |
323 |
|
324 |
This will update bytes 10-19 with the data specified. |
325 |
|
326 |
* Update an object (append) :: |
327 |
|
328 |
curl -X POST -D - \ |
329 |
-H "X-Auth-Token: 0000" \ |
330 |
-H "Content-Length: 10" \ |
331 |
-H "Content-Type: application/octet-stream" \ |
332 |
-H "Content-Range: bytes */*" \ |
333 |
-d "0123456789" \ |
334 |
https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt |
335 |
|
336 |
* Update an object (truncate) :: |
337 |
|
338 |
curl -X POST -D - \ |
339 |
-H "X-Auth-Token: 0000" \ |
340 |
-H "X-Source-Object: /folder/EXAMPLE.txt" \ |
341 |
-H "Content-Range: bytes 0-0/*" \ |
342 |
-H "X-Object-Bytes: 0" \ |
343 |
https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt |
344 |
|
345 |
This will truncate the object to 0 bytes. |
346 |
|
347 |
* Add object metadata :: |
348 |
|
349 |
curl -X POST -D - \ |
350 |
-H "X-Auth-Token: 0000" \ |
351 |
-H "X-Object-Meta-First: first_meta_value" \ |
352 |
-H "X-Object-Meta-Second: second_meta_value" \ |
353 |
https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt |
354 |
|
355 |
* Delete object metadata :: |
356 |
|
357 |
curl -X POST -D - \ |
358 |
-H "X-Auth-Token: 0000" \ |
359 |
-H "X-Object-Meta-First: first_meta_value" \ |
360 |
https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt |
361 |
|
362 |
Metadata can only be "set". To delete ``X-Object-Meta-Second``, reset all |
363 |
metadata. |
364 |
|
365 |
* Delete an object :: |
366 |
|
367 |
curl -X DELETE -D - \ |
368 |
-H "X-Auth-Token: 0000" \ |
369 |
https://pithos.dev.grnet.gr/v1/user/folder/EXAMPLE.txt |
370 |
|