1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
| | ;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2022 pukkamustard <pukkamustard@posteo.net>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
(define-module (guix eris)
#:use-module (eris)
#:use-module (eris fs)
#:use-module (eris sqlite)
#:use-module (eris coap)
#:use-module (eris read-capability)
#:use-module (coap tcp)
#:use-module (web uri)
#:use-module (ice-9 match)
#:use-module (srfi srfi-171)
#:export (%eris-store-url
eris-encode-store-item))
(define %eris-store-url
(make-parameter
(getenv "ERIS_STORE_URL")
(lambda (val)
(cond
((uri? val) val)
((string? val) (string->uri val))
(else #f)))))
(define %guix-eris-convergence-secret
(make-parameter %null-convergence-secret))
(define (open-coap-unix-socket path)
(let ((sock (socket PF_UNIX SOCK_STREAM 0)))
;; Release FD on exec
(fcntl sock F_SETFD FD_CLOEXEC)
;; Set to non-blocking
(fcntl sock F_SETFL (logior O_NONBLOCK (fcntl sock F_GETFL)))
;; Connect
(connect sock AF_UNIX path)
;; Initialize the CoAP connection
(open-socket-for-uri #f
#:socket sock
;; Allow up to 64 in-flight requests
#:nstart 64)))
(define (guix-eris-block-reducer)
"Returns an ERIS block reducer."
(let ((store-url (%eris-store-url)))
(if (uri? store-url)
(match (uri-scheme store-url)
;; Store blocks in an SQLite database (see
;; https://eris.codeberg.page/eer/sqlite.xml)
('sqlite
(eris-sqlite-block-reducer (uri-path store-url)))
;; Connect to a CoAP ERIS store over a Unix socket
('coap+unix
;; Wrap the eris-coap-block-reducer to close the provided connection.
(let ((ecbr (eris-coap-block-reducer
(build-uri 'coap #:path ".well-known/eris")
#:nstart 64
#:connection (open-coap-unix-socket
(uri-path store-url)))))
(case-lambda
(() (ecbr))
((conn ref-block) (ecbr conn ref-block))
((conn)
(ecbr conn)
(close-port conn)))))
;; TODO
;; ('coap+tcp #f)
(_ (error "Don't know how to handle ERIS store URL "
(uri->string (%eris-store-url)))))
;; If no ERIS store URL is provided we just compute the ERIS URN without
;; storing the blocks anywhere. As dummy block-reducer we use `rcount` from
;; SRFI-171 that counts the number of blocks.
rcount)))
(define* (eris-encode-store-item item)
"Encodes the store item ITEM using ERIS and returns the read capability as
string."
(eris-read-capability->string
(eris-fs-encode item
#:convergence-secret (%guix-eris-convergence-secret)
#:block-reducer (guix-eris-block-reducer))))
|