services: <shepherd-service> no longer has an 'imported-modules' field.
[jackhill/guix/guix.git] / gnu / system / mapped-devices.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
3 ;;;
4 ;;; This file is part of GNU Guix.
5 ;;;
6 ;;; GNU Guix is free software; you can redistribute it and/or modify it
7 ;;; under the terms of the GNU General Public License as published by
8 ;;; the Free Software Foundation; either version 3 of the License, or (at
9 ;;; your option) any later version.
10 ;;;
11 ;;; GNU Guix is distributed in the hope that it will be useful, but
12 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;;; GNU General Public License for more details.
15 ;;;
16 ;;; You should have received a copy of the GNU General Public License
17 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19 (define-module (gnu system mapped-devices)
20 #:use-module (guix gexp)
21 #:use-module (guix records)
22 #:use-module (gnu services)
23 #:use-module (gnu services shepherd)
24 #:autoload (gnu packages cryptsetup) (cryptsetup)
25 #:use-module (srfi srfi-1)
26 #:use-module (ice-9 match)
27 #:export (mapped-device
28 mapped-device?
29 mapped-device-source
30 mapped-device-target
31 mapped-device-type
32
33 mapped-device-kind
34 mapped-device-kind?
35 mapped-device-kind-open
36 mapped-device-kind-close
37
38 device-mapping-service-type
39 device-mapping-service
40
41 luks-device-mapping))
42
43 ;;; Commentary:
44 ;;;
45 ;;; This module supports "device mapping", a concept implemented by Linux's
46 ;;; device-mapper.
47 ;;;
48 ;;; Code:
49
50 (define-record-type* <mapped-device> mapped-device
51 make-mapped-device
52 mapped-device?
53 (source mapped-device-source) ;string
54 (target mapped-device-target) ;string
55 (type mapped-device-type)) ;<mapped-device-kind>
56
57 (define-record-type* <mapped-device-type> mapped-device-kind
58 make-mapped-device-kind
59 mapped-device-kind?
60 (open mapped-device-kind-open) ;source target -> gexp
61 (close mapped-device-kind-close ;source target -> gexp
62 (default (const #~(const #f)))))
63
64 \f
65 ;;;
66 ;;; Device mapping as a Shepherd service.
67 ;;;
68
69 (define device-mapping-service-type
70 (shepherd-service-type
71 'device-mapping
72 (match-lambda
73 (($ <mapped-device> source target
74 ($ <mapped-device-type> open close))
75 (shepherd-service
76 (provision (list (symbol-append 'device-mapping- (string->symbol target))))
77 (requirement '(udev))
78 (documentation "Map a device node using Linux's device mapper.")
79 (start #~(lambda () #$(open source target)))
80 (stop #~(lambda _ (not #$(close source target))))
81 (respawn? #f)
82
83 ;; Add the modules needed by LUKS-DEVICE-MAPPING.
84 ;; FIXME: This info should be propagated via gexps.
85 (modules `((rnrs bytevectors) ;bytevector?
86 ((gnu build file-systems)
87 #:select (find-partition-by-luks-uuid))
88 ,@%default-modules)))))))
89
90 (define (device-mapping-service mapped-device)
91 "Return a service that sets up @var{mapped-device}."
92 (service device-mapping-service-type mapped-device))
93
94 \f
95 ;;;
96 ;;; Common device mappings.
97 ;;;
98
99 (define (open-luks-device source target)
100 "Return a gexp that maps SOURCE to TARGET as a LUKS device, using
101 'cryptsetup'."
102 (with-imported-modules '((gnu build file-systems)
103 (guix build bournish))
104 #~(let ((source #$source))
105 (zero? (system* (string-append #$cryptsetup "/sbin/cryptsetup")
106 "open" "--type" "luks"
107
108 ;; Note: We cannot use the "UUID=source" syntax here
109 ;; because 'cryptsetup' implements it by searching the
110 ;; udev-populated /dev/disk/by-id directory but udev may
111 ;; be unavailable at the time we run this.
112 (if (bytevector? source)
113 (or (find-partition-by-luks-uuid source)
114 (error "LUKS partition not found" source))
115 source)
116
117 #$target)))))
118
119 (define (close-luks-device source target)
120 "Return a gexp that closes TARGET, a LUKS device."
121 #~(zero? (system* (string-append #$cryptsetup "/sbin/cryptsetup")
122 "close" #$target)))
123
124 (define luks-device-mapping
125 ;; The type of LUKS mapped devices.
126 (mapped-device-kind
127 (open open-luks-device)
128 (close close-luks-device)))
129
130 ;;; mapped-devices.scm ends here