Use 'formatted-message' instead of '&message' where appropriate.
* gnu.scm (%try-use-modules): Use 'formatted-message' instead of '&message'. * gnu/machine/digital-ocean.scm (maybe-raise-unsupported-configuration-error): Likewise. * gnu/machine/ssh.scm (machine-check-file-system-availability): Likewise. (machine-check-building-for-appropriate-system): Likewise. (deploy-managed-host): Likewise. (maybe-raise-unsupported-configuration-error): Likewise. * gnu/packages.scm (search-patch): Likewise. * gnu/services.scm (%service-with-default-value): Likewise. (files->etc-directory): Likewise. (fold-services): Likewise. * gnu/system.scm (locale-name->definition*): Likewise. * gnu/system/mapped-devices.scm (check-device-initrd-modules): Likewise. (check-luks-device): Likewise. * guix/channels.scm (latest-channel-instance): Likewise. * guix/cve.scm (json->cve-items): Likewise. * guix/git-authenticate.scm (commit-signing-key): Likewise. (commit-authorized-keys): Likewise. (authenticate-commit): Likewise. (verify-introductory-commit): Likewise. * guix/remote.scm (remote-pipe-for-gexp): Likewise. * guix/scripts/graph.scm (assert-package): Likewise. * guix/scripts/offload.scm (private-key-from-file*): Likewise. * guix/ssh.scm (authenticate-server*): Likewise. (open-ssh-session): Likewise. (remote-inferior): Likewise. * guix/ui.scm (matching-generations): Likewise. * guix/upstream.scm (package-update): Likewise. * tests/channels.scm ("latest-channel-instances, missing introduction for 'guix'"): Catch 'formatted-message?'. ("authenticate-channel, wrong first commit signer"): Likewise. * tests/lint.scm ("patches: not found"): Adjust message string. * tests/packages.scm ("patch not found yields a run-time error"): Catch 'formatted-message?'. * guix/lint.scm (check-patch-file-names): Handle 'formatted-message?'. (check-derivation): Ditto.master
parent
252a1926bc
commit
d51bfe242f
6
gnu.scm
6
gnu.scm
|
@ -78,10 +78,8 @@
|
||||||
(raise
|
(raise
|
||||||
(apply
|
(apply
|
||||||
make-compound-condition
|
make-compound-condition
|
||||||
(condition
|
(formatted-message (G_ "module ~a not found")
|
||||||
(&message
|
module)
|
||||||
(message (format #f (G_ "module ~a not found")
|
|
||||||
module))))
|
|
||||||
(condition
|
(condition
|
||||||
(&error-location (location location)))
|
(&error-location (location location)))
|
||||||
(or (and=> (make-hint module) list)
|
(or (and=> (make-hint module) list)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#:use-module (guix base32)
|
#:use-module (guix base32)
|
||||||
#:use-module (guix derivations)
|
#:use-module (guix derivations)
|
||||||
#:use-module (guix i18n)
|
#:use-module (guix i18n)
|
||||||
|
#:use-module ((guix diagnostics) #:select (formatted-message))
|
||||||
#:use-module (guix import json)
|
#:use-module (guix import json)
|
||||||
#:use-module (guix monads)
|
#:use-module (guix monads)
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
|
@ -414,9 +415,7 @@ one procured from https://cloud.digitalocean.com/account/api/tokens.")))))))
|
||||||
(let ((config (machine-configuration machine))
|
(let ((config (machine-configuration machine))
|
||||||
(environment (environment-type-name (machine-environment machine))))
|
(environment (environment-type-name (machine-environment machine))))
|
||||||
(unless (and config (digital-ocean-configuration? config))
|
(unless (and config (digital-ocean-configuration? config))
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "unsupported machine configuration '~a' \
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "unsupported machine configuration '~a'
|
|
||||||
for environment of type '~a'")
|
for environment of type '~a'")
|
||||||
config
|
config
|
||||||
environment))))))))
|
environment)))))
|
||||||
|
|
|
@ -179,11 +179,9 @@ exist on the machine."
|
||||||
(lambda args
|
(lambda args
|
||||||
(system-error-errno args)))))
|
(system-error-errno args)))))
|
||||||
(when (number? errno)
|
(when (number? errno)
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "device '~a' not found: ~a")
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "device '~a' not found: ~a")
|
|
||||||
(file-system-device fs)
|
(file-system-device fs)
|
||||||
(strerror errno)))))))))
|
(strerror errno))))))
|
||||||
|
|
||||||
(define (check-labeled-file-system fs)
|
(define (check-labeled-file-system fs)
|
||||||
(define remote-exp
|
(define remote-exp
|
||||||
|
@ -196,11 +194,9 @@ exist on the machine."
|
||||||
|
|
||||||
(remote-let ((result remote-exp))
|
(remote-let ((result remote-exp))
|
||||||
(unless result
|
(unless result
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "no file system with label '~a'")
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "no file system with label '~a'")
|
|
||||||
(file-system-label->string
|
(file-system-label->string
|
||||||
(file-system-device fs))))))))))
|
(file-system-device fs)))))))
|
||||||
|
|
||||||
(define (check-uuid-file-system fs)
|
(define (check-uuid-file-system fs)
|
||||||
(define remote-exp
|
(define remote-exp
|
||||||
|
@ -217,10 +213,8 @@ exist on the machine."
|
||||||
|
|
||||||
(remote-let ((result remote-exp))
|
(remote-let ((result remote-exp))
|
||||||
(unless result
|
(unless result
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "no file system with UUID '~a'")
|
||||||
(&message
|
(uuid->string (file-system-device fs)))))))
|
||||||
(message (format #f (G_ "no file system with UUID '~a'")
|
|
||||||
(uuid->string (file-system-device fs))))))))))
|
|
||||||
|
|
||||||
(append (map check-literal-file-system
|
(append (map check-literal-file-system
|
||||||
(filter (lambda (fs)
|
(filter (lambda (fs)
|
||||||
|
@ -285,12 +279,10 @@ by MACHINE."
|
||||||
(system (remote-system (machine-ssh-session machine))))
|
(system (remote-system (machine-ssh-session machine))))
|
||||||
(when (and (machine-ssh-configuration-build-locally? config)
|
(when (and (machine-ssh-configuration-build-locally? config)
|
||||||
(not (string= system (machine-ssh-configuration-system config))))
|
(not (string= system (machine-ssh-configuration-system config))))
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "incorrect target system\
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "incorrect target system\
|
|
||||||
('~a' was given, while the system reports that it is '~a')~%")
|
('~a' was given, while the system reports that it is '~a')~%")
|
||||||
(machine-ssh-configuration-system config)
|
(machine-ssh-configuration-system config)
|
||||||
system))))))))
|
system)))))
|
||||||
|
|
||||||
(define (check-deployment-sanity machine)
|
(define (check-deployment-sanity machine)
|
||||||
"Raise a '&message' error condition if it is clear that deploying MACHINE's
|
"Raise a '&message' error condition if it is clear that deploying MACHINE's
|
||||||
|
@ -402,11 +394,9 @@ environment type of 'managed-host."
|
||||||
(when (machine-ssh-configuration-authorize?
|
(when (machine-ssh-configuration-authorize?
|
||||||
(machine-configuration machine))
|
(machine-configuration machine))
|
||||||
(unless (file-exists? %public-key-file)
|
(unless (file-exists? %public-key-file)
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "no signing key '~a'. \
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "no signing key '~a'. \
|
|
||||||
have you run 'guix archive --generate-key?'")
|
have you run 'guix archive --generate-key?'")
|
||||||
%public-key-file))))))
|
%public-key-file)))
|
||||||
(remote-authorize-signing-key (call-with-input-file %public-key-file
|
(remote-authorize-signing-key (call-with-input-file %public-key-file
|
||||||
(lambda (port)
|
(lambda (port)
|
||||||
(string->canonical-sexp
|
(string->canonical-sexp
|
||||||
|
@ -497,9 +487,7 @@ connection to the host.")))
|
||||||
(let ((config (machine-configuration machine))
|
(let ((config (machine-configuration machine))
|
||||||
(environment (environment-type-name (machine-environment machine))))
|
(environment (environment-type-name (machine-environment machine))))
|
||||||
(unless (and config (machine-ssh-configuration? config))
|
(unless (and config (machine-ssh-configuration? config))
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "unsupported machine configuration '~a'
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "unsupported machine configuration '~a'
|
|
||||||
for environment of type '~a'")
|
for environment of type '~a'")
|
||||||
config
|
config
|
||||||
environment))))))))
|
environment)))))
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
#:use-module (guix ui)
|
#:use-module (guix ui)
|
||||||
#:use-module (guix utils)
|
#:use-module (guix utils)
|
||||||
|
#:use-module (guix diagnostics)
|
||||||
#:use-module (guix discovery)
|
#:use-module (guix discovery)
|
||||||
#:use-module (guix memoization)
|
#:use-module (guix memoization)
|
||||||
#:use-module ((guix build utils)
|
#:use-module ((guix build utils)
|
||||||
|
@ -92,9 +93,8 @@
|
||||||
(define (search-patch file-name)
|
(define (search-patch file-name)
|
||||||
"Search the patch FILE-NAME. Raise an error if not found."
|
"Search the patch FILE-NAME. Raise an error if not found."
|
||||||
(or (search-path (%patch-path) file-name)
|
(or (search-path (%patch-path) file-name)
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "~a: patch not found")
|
||||||
(&message (message (format #f (G_ "~a: patch not found")
|
file-name))))
|
||||||
file-name)))))))
|
|
||||||
|
|
||||||
(define-syntax-rule (search-patches file-name ...)
|
(define-syntax-rule (search-patches file-name ...)
|
||||||
"Return the list of absolute file names corresponding to each
|
"Return the list of absolute file names corresponding to each
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#:use-module (guix describe)
|
#:use-module (guix describe)
|
||||||
#:use-module (guix sets)
|
#:use-module (guix sets)
|
||||||
#:use-module (guix ui)
|
#:use-module (guix ui)
|
||||||
#:use-module ((guix utils) #:select (source-properties->location))
|
#:use-module (guix diagnostics)
|
||||||
#:autoload (guix openpgp) (openpgp-format-fingerprint)
|
#:autoload (guix openpgp) (openpgp-format-fingerprint)
|
||||||
#:use-module (guix modules)
|
#:use-module (guix modules)
|
||||||
#:use-module (gnu packages base)
|
#:use-module (gnu packages base)
|
||||||
|
@ -242,13 +242,13 @@ TYPE does not have a default value, an error is raised."
|
||||||
(if (eq? default &no-default-value)
|
(if (eq? default &no-default-value)
|
||||||
(let ((location (source-properties->location location)))
|
(let ((location (source-properties->location location)))
|
||||||
(raise
|
(raise
|
||||||
|
(make-compound-condition
|
||||||
(condition
|
(condition
|
||||||
(&missing-value-service-error (type type) (location location))
|
(&missing-value-service-error (type type) (location location)))
|
||||||
(&message
|
(formatted-message (G_ "~a: no value specified \
|
||||||
(message (format #f (G_ "~a: no value specified \
|
|
||||||
for service of type '~a'")
|
for service of type '~a'")
|
||||||
(location->string location)
|
(location->string location)
|
||||||
(service-type-name type)))))))
|
(service-type-name type)))))
|
||||||
(service type default))))
|
(service type default))))
|
||||||
|
|
||||||
(define-condition-type &service-error &error
|
(define-condition-type &service-error &error
|
||||||
|
@ -725,10 +725,8 @@ and FILE could be \"/usr/bin/env\"."
|
||||||
(() #t)
|
(() #t)
|
||||||
(((file _) rest ...)
|
(((file _) rest ...)
|
||||||
(when (set-contains? seen file)
|
(when (set-contains? seen file)
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "duplicate '~a' entry for /etc")
|
||||||
(&message
|
file)))
|
||||||
(message (format #f (G_ "duplicate '~a' entry for /etc")
|
|
||||||
file))))))
|
|
||||||
(loop rest (set-insert file seen))))))
|
(loop rest (set-insert file seen))))))
|
||||||
|
|
||||||
;; Detect duplicates early instead of letting them through, eventually
|
;; Detect duplicates early instead of letting them through, eventually
|
||||||
|
@ -1000,12 +998,12 @@ TARGET-TYPE; return the root service adjusted accordingly."
|
||||||
vlist-null))
|
vlist-null))
|
||||||
(()
|
(()
|
||||||
(raise
|
(raise
|
||||||
|
(make-compound-condition
|
||||||
(condition (&missing-target-service-error
|
(condition (&missing-target-service-error
|
||||||
(service #f)
|
(service #f)
|
||||||
(target-type target-type))
|
(target-type target-type)))
|
||||||
(&message
|
(formatted-message (G_ "service of type '~a' not found")
|
||||||
(message (format #f (G_ "service of type '~a' not found")
|
(service-type-name target-type)))))
|
||||||
(service-type-name target-type)))))))
|
|
||||||
(x
|
(x
|
||||||
(raise
|
(raise
|
||||||
(condition (&ambiguous-target-service-error
|
(condition (&ambiguous-target-service-error
|
||||||
|
|
|
@ -1113,9 +1113,7 @@ TYPE (one of 'iso9660 or 'dce). Return a UUID object."
|
||||||
"Variant of 'locale-name->definition' that raises an error upon failure."
|
"Variant of 'locale-name->definition' that raises an error upon failure."
|
||||||
(match (locale-name->definition name)
|
(match (locale-name->definition name)
|
||||||
(#f
|
(#f
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "~a: invalid locale name") name)))
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "~a: invalid locale name") name))))))
|
|
||||||
(def def)))
|
(def def)))
|
||||||
|
|
||||||
(define (operating-system-locale-directory os)
|
(define (operating-system-locale-directory os)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#:use-module (guix i18n)
|
#:use-module (guix i18n)
|
||||||
#:use-module ((guix diagnostics)
|
#:use-module ((guix diagnostics)
|
||||||
#:select (source-properties->location
|
#:select (source-properties->location
|
||||||
|
formatted-message
|
||||||
&fix-hint
|
&fix-hint
|
||||||
&error-location))
|
&error-location))
|
||||||
#:use-module (gnu services)
|
#:use-module (gnu services)
|
||||||
|
@ -132,11 +133,11 @@ DEVICE must be a \"/dev\" file name."
|
||||||
;; "usb_storage"), not file names (e.g., "usb-storage.ko"). This is
|
;; "usb_storage"), not file names (e.g., "usb-storage.ko"). This is
|
||||||
;; OK because we have machinery that accepts both the hyphen and the
|
;; OK because we have machinery that accepts both the hyphen and the
|
||||||
;; underscore version.
|
;; underscore version.
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
(&message
|
(formatted-message (G_ "you may need these modules \
|
||||||
(message (format #f (G_ "you may need these modules \
|
|
||||||
in the initrd for ~a:~{ ~a~}")
|
in the initrd for ~a:~{ ~a~}")
|
||||||
device missing)))
|
device missing)
|
||||||
|
(condition
|
||||||
(&fix-hint
|
(&fix-hint
|
||||||
(hint (format #f (G_ "Try adding them to the
|
(hint (format #f (G_ "Try adding them to the
|
||||||
@code{initrd-modules} field of your @code{operating-system} declaration, along
|
@code{initrd-modules} field of your @code{operating-system} declaration, along
|
||||||
|
@ -151,9 +152,10 @@ these lines:
|
||||||
|
|
||||||
If you think this diagnostic is inaccurate, use the @option{--skip-checks}
|
If you think this diagnostic is inaccurate, use the @option{--skip-checks}
|
||||||
option of @command{guix system}.\n")
|
option of @command{guix system}.\n")
|
||||||
missing)))
|
missing))))
|
||||||
|
(condition
|
||||||
(&error-location
|
(&error-location
|
||||||
(location (source-properties->location location)))))))
|
(location (source-properties->location location))))))))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
@ -215,13 +217,13 @@ option of @command{guix system}.\n")
|
||||||
(if (uuid? source)
|
(if (uuid? source)
|
||||||
(match (find-partition-by-luks-uuid (uuid-bytevector source))
|
(match (find-partition-by-luks-uuid (uuid-bytevector source))
|
||||||
(#f
|
(#f
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
(&message
|
(formatted-message (G_ "no LUKS partition with UUID '~a'")
|
||||||
(message (format #f (G_ "no LUKS partition with UUID '~a'")
|
(uuid->string source))
|
||||||
(uuid->string source))))
|
(condition
|
||||||
(&error-location
|
(&error-location
|
||||||
(location (source-properties->location
|
(location (source-properties->location
|
||||||
(mapped-device-location md)))))))
|
(mapped-device-location md))))))))
|
||||||
((? string? device)
|
((? string? device)
|
||||||
(check-device-initrd-modules device initrd-modules location)))
|
(check-device-initrd-modules device initrd-modules location)))
|
||||||
(check-device-initrd-modules source initrd-modules location)))))
|
(check-device-initrd-modules source initrd-modules location)))))
|
||||||
|
|
|
@ -378,16 +378,16 @@ their relation. When AUTHENTICATE? is false, CHANNEL is not authenticated."
|
||||||
;; TODO: Warn for all the channels once the authentication interface
|
;; TODO: Warn for all the channels once the authentication interface
|
||||||
;; is public.
|
;; is public.
|
||||||
(when (guix-channel? channel)
|
(when (guix-channel? channel)
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
(&message
|
(formatted-message (G_ "channel '~a' lacks an \
|
||||||
(message (format #f (G_ "channel '~a' lacks an \
|
|
||||||
introduction and cannot be authenticated~%")
|
introduction and cannot be authenticated~%")
|
||||||
(channel-name channel))))
|
(channel-name channel))
|
||||||
|
(condition
|
||||||
(&fix-hint
|
(&fix-hint
|
||||||
(hint (G_ "Add the missing introduction to your
|
(hint (G_ "Add the missing introduction to your
|
||||||
channels file to address the issue. Alternatively, you can pass
|
channels file to address the issue. Alternatively, you can pass
|
||||||
@option{--disable-authentication}, at the risk of running unauthenticated and
|
@option{--disable-authentication}, at the risk of running unauthenticated and
|
||||||
thus potentially malicious code.")))))))
|
thus potentially malicious code."))))))))
|
||||||
(warning (G_ "channel authentication disabled~%")))
|
(warning (G_ "channel authentication disabled~%")))
|
||||||
|
|
||||||
(when (guix-channel? channel)
|
(when (guix-channel? channel)
|
||||||
|
|
15
guix/cve.scm
15
guix/cve.scm
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
#:use-module (guix http-client)
|
#:use-module (guix http-client)
|
||||||
#:use-module (guix json)
|
#:use-module (guix json)
|
||||||
#:use-module (guix i18n)
|
#:use-module (guix i18n)
|
||||||
|
#:use-module ((guix diagnostics) #:select (formatted-message))
|
||||||
#:use-module (json)
|
#:use-module (json)
|
||||||
#:use-module (web uri)
|
#:use-module (web uri)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
|
@ -194,15 +195,11 @@ records."
|
||||||
(raise (condition (&message
|
(raise (condition (&message
|
||||||
(message "invalid CVE feed")))))
|
(message "invalid CVE feed")))))
|
||||||
(unless (equal? format "MITRE")
|
(unless (equal? format "MITRE")
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "unsupported CVE format: '~a'")
|
||||||
(&message
|
format)))
|
||||||
(message (format #f (G_ "unsupported CVE format: '~a'")
|
|
||||||
format))))))
|
|
||||||
(unless (equal? version "4.0")
|
(unless (equal? version "4.0")
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "unsupported CVE data version: '~a'")
|
||||||
(&message
|
version)))
|
||||||
(message (format #f (G_ "unsupported CVE data version: '~a'")
|
|
||||||
version))))))
|
|
||||||
|
|
||||||
(map json->cve-item
|
(map json->cve-item
|
||||||
(vector->list (assoc-ref alist "CVE_Items")))))
|
(vector->list (assoc-ref alist "CVE_Items")))))
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#:use-module ((guix git)
|
#:use-module ((guix git)
|
||||||
#:select (commit-difference false-if-git-not-found))
|
#:select (commit-difference false-if-git-not-found))
|
||||||
#:use-module (guix i18n)
|
#:use-module (guix i18n)
|
||||||
|
#:use-module ((guix diagnostics) #:select (formatted-message))
|
||||||
#:use-module (guix openpgp)
|
#:use-module (guix openpgp)
|
||||||
#:use-module ((guix utils)
|
#:use-module ((guix utils)
|
||||||
#:select (cache-directory with-atomic-file-output))
|
#:select (cache-directory with-atomic-file-output))
|
||||||
|
@ -105,23 +106,21 @@ not in KEYRING."
|
||||||
(lambda _
|
(lambda _
|
||||||
(values #f #f)))))
|
(values #f #f)))))
|
||||||
(unless signature
|
(unless signature
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
(&unsigned-commit-error (commit commit-id))
|
(condition (&unsigned-commit-error (commit commit-id)))
|
||||||
(&message
|
(formatted-message (G_ "commit ~a lacks a signature")
|
||||||
(message (format #f (G_ "commit ~a lacks a signature")
|
(oid->string commit-id)))))
|
||||||
(oid->string commit-id)))))))
|
|
||||||
|
|
||||||
(let ((signature (string->openpgp-packet signature)))
|
(let ((signature (string->openpgp-packet signature)))
|
||||||
(when (memq (openpgp-signature-hash-algorithm signature)
|
(when (memq (openpgp-signature-hash-algorithm signature)
|
||||||
`(,@disallowed-hash-algorithms md5))
|
`(,@disallowed-hash-algorithms md5))
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
(&unsigned-commit-error (commit commit-id))
|
(condition (&unsigned-commit-error (commit commit-id)))
|
||||||
(&message
|
(formatted-message (G_ "commit ~a has a ~a signature, \
|
||||||
(message (format #f (G_ "commit ~a has a ~a signature, \
|
|
||||||
which is not permitted")
|
which is not permitted")
|
||||||
(oid->string commit-id)
|
(oid->string commit-id)
|
||||||
(openpgp-signature-hash-algorithm
|
(openpgp-signature-hash-algorithm
|
||||||
signature)))))))
|
signature)))))
|
||||||
|
|
||||||
(with-fluids ((%default-port-encoding "UTF-8"))
|
(with-fluids ((%default-port-encoding "UTF-8"))
|
||||||
(let-values (((status data)
|
(let-values (((status data)
|
||||||
|
@ -130,23 +129,22 @@ which is not permitted")
|
||||||
(match status
|
(match status
|
||||||
('bad-signature
|
('bad-signature
|
||||||
;; There's a signature but it's invalid.
|
;; There's a signature but it's invalid.
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
|
(condition
|
||||||
(&signature-verification-error (commit commit-id)
|
(&signature-verification-error (commit commit-id)
|
||||||
(signature signature)
|
(signature signature)
|
||||||
(keyring keyring))
|
(keyring keyring)))
|
||||||
(&message
|
(formatted-message (G_ "signature verification failed \
|
||||||
(message (format #f (G_ "signature verification failed \
|
|
||||||
for commit ~a")
|
for commit ~a")
|
||||||
(oid->string commit-id)))))))
|
(oid->string commit-id)))))
|
||||||
('missing-key
|
('missing-key
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
(&missing-key-error (commit commit-id)
|
(condition (&missing-key-error (commit commit-id)
|
||||||
(signature signature))
|
(signature signature)))
|
||||||
(&message
|
(formatted-message (G_ "could not authenticate \
|
||||||
(message (format #f (G_ "could not authenticate \
|
|
||||||
commit ~a: key ~a is missing")
|
commit ~a: key ~a is missing")
|
||||||
(oid->string commit-id)
|
(oid->string commit-id)
|
||||||
(openpgp-format-fingerprint data)))))))
|
(openpgp-format-fingerprint data)))))
|
||||||
('good-signature data)))))))
|
('good-signature data)))))))
|
||||||
|
|
||||||
(define (read-authorizations port)
|
(define (read-authorizations port)
|
||||||
|
@ -179,13 +177,13 @@ does not specify anything, fall back to DEFAULT-AUTHORIZATIONS."
|
||||||
;; If COMMIT removes the '.guix-authorizations' file found in one of its
|
;; If COMMIT removes the '.guix-authorizations' file found in one of its
|
||||||
;; parents, raise an error.
|
;; parents, raise an error.
|
||||||
(when (parents-have-authorizations-file? commit)
|
(when (parents-have-authorizations-file? commit)
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
|
(condition
|
||||||
(&unauthorized-commit-error (commit (commit-id commit))
|
(&unauthorized-commit-error (commit (commit-id commit))
|
||||||
(signing-key #f))
|
(signing-key #f)))
|
||||||
(&message
|
(formatted-message (G_ "commit ~a attempts \
|
||||||
(message (format #f (G_ "commit ~a attempts \
|
|
||||||
to remove '.guix-authorizations' file")
|
to remove '.guix-authorizations' file")
|
||||||
(oid->string (commit-id commit)))))))))
|
(oid->string (commit-id commit)))))))
|
||||||
|
|
||||||
(define (commit-authorizations commit)
|
(define (commit-authorizations commit)
|
||||||
(catch 'git-error
|
(catch 'git-error
|
||||||
|
@ -234,16 +232,16 @@ not specify anything, fall back to DEFAULT-AUTHORIZATIONS."
|
||||||
(unless (member (openpgp-public-key-fingerprint signing-key)
|
(unless (member (openpgp-public-key-fingerprint signing-key)
|
||||||
(commit-authorized-keys repository commit
|
(commit-authorized-keys repository commit
|
||||||
default-authorizations))
|
default-authorizations))
|
||||||
(raise (condition
|
(raise (make-compound-condition
|
||||||
|
(condition
|
||||||
(&unauthorized-commit-error (commit id)
|
(&unauthorized-commit-error (commit id)
|
||||||
(signing-key signing-key))
|
(signing-key signing-key)))
|
||||||
(&message
|
(formatted-message (G_ "commit ~a not signed by an authorized \
|
||||||
(message (format #f (G_ "commit ~a not signed by an authorized \
|
|
||||||
key: ~a")
|
key: ~a")
|
||||||
(oid->string id)
|
(oid->string id)
|
||||||
(openpgp-format-fingerprint
|
(openpgp-format-fingerprint
|
||||||
(openpgp-public-key-fingerprint
|
(openpgp-public-key-fingerprint
|
||||||
signing-key))))))))
|
signing-key))))))
|
||||||
|
|
||||||
signing-key)
|
signing-key)
|
||||||
|
|
||||||
|
@ -366,13 +364,11 @@ EXPECTED-SIGNER."
|
||||||
(commit-signing-key repository (commit-id commit) keyring)))
|
(commit-signing-key repository (commit-id commit) keyring)))
|
||||||
|
|
||||||
(unless (bytevector=? expected-signer actual-signer)
|
(unless (bytevector=? expected-signer actual-signer)
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "initial commit ~a is signed by '~a' \
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "initial commit ~a is signed by '~a' \
|
|
||||||
instead of '~a'")
|
instead of '~a'")
|
||||||
(oid->string (commit-id commit))
|
(oid->string (commit-id commit))
|
||||||
(openpgp-format-fingerprint actual-signer)
|
(openpgp-format-fingerprint actual-signer)
|
||||||
(openpgp-format-fingerprint expected-signer))))))))
|
(openpgp-format-fingerprint expected-signer)))))
|
||||||
|
|
||||||
(define* (authenticate-repository repository start signer
|
(define* (authenticate-repository repository start signer
|
||||||
#:key
|
#:key
|
||||||
|
|
|
@ -668,7 +668,12 @@ patch could not be found."
|
||||||
;; Use %make-warning, as condition-mesasge is already
|
;; Use %make-warning, as condition-mesasge is already
|
||||||
;; translated.
|
;; translated.
|
||||||
(%make-warning package (condition-message c)
|
(%make-warning package (condition-message c)
|
||||||
#:field 'patch-file-names))))
|
#:field 'patch-file-names)))
|
||||||
|
((formatted-message? c)
|
||||||
|
(list (%make-warning package
|
||||||
|
(apply format #f
|
||||||
|
(G_ (formatted-message-string c))
|
||||||
|
(formatted-message-arguments c))))))
|
||||||
(define patches
|
(define patches
|
||||||
(match (package-source package)
|
(match (package-source package)
|
||||||
((? origin? origin) (origin-patches origin))
|
((? origin? origin) (origin-patches origin))
|
||||||
|
@ -955,7 +960,14 @@ descriptions maintained upstream."
|
||||||
(make-warning package
|
(make-warning package
|
||||||
(G_ "failed to create ~a derivation: ~a")
|
(G_ "failed to create ~a derivation: ~a")
|
||||||
(list system
|
(list system
|
||||||
(condition-message c)))))
|
(condition-message c))))
|
||||||
|
((formatted-message? c)
|
||||||
|
(let ((str (apply format #f
|
||||||
|
(formatted-message-string c)
|
||||||
|
(formatted-message-arguments c))))
|
||||||
|
(make-warning package
|
||||||
|
(G_ "failed to create ~a derivation: ~a")
|
||||||
|
(list system str)))))
|
||||||
(parameterize ((%graft? #f))
|
(parameterize ((%graft? #f))
|
||||||
(package-derivation store package system #:graft? #f)
|
(package-derivation store package system #:graft? #f)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2019 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
#:use-module (guix ssh)
|
#:use-module (guix ssh)
|
||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
#:use-module (guix i18n)
|
#:use-module (guix i18n)
|
||||||
|
#:use-module ((guix diagnostics) #:select (formatted-message))
|
||||||
#:use-module (guix inferior)
|
#:use-module (guix inferior)
|
||||||
#:use-module (guix store)
|
#:use-module (guix store)
|
||||||
#:use-module (guix monads)
|
#:use-module (guix monads)
|
||||||
|
@ -72,11 +73,9 @@ BECOME-COMMAND is given, use that to invoke the remote Guile REPL."
|
||||||
(when (eof-object? (peek-char pipe))
|
(when (eof-object? (peek-char pipe))
|
||||||
(let ((status (channel-get-exit-status pipe)))
|
(let ((status (channel-get-exit-status pipe)))
|
||||||
(close-port pipe)
|
(close-port pipe)
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "remote command '~{~a~^ ~}' failed \
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "remote command '~{~a~^ ~}' failed \
|
|
||||||
with status ~a")
|
with status ~a")
|
||||||
repl-command status)))))))
|
repl-command status))))
|
||||||
pipe))
|
pipe))
|
||||||
|
|
||||||
(define* (%remote-eval lowered session #:optional become-command)
|
(define* (%remote-eval lowered session #:optional become-command)
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
#:use-module ((guix build-system gnu) #:select (standard-packages))
|
#:use-module ((guix build-system gnu) #:select (standard-packages))
|
||||||
#:use-module (gnu packages)
|
#:use-module (gnu packages)
|
||||||
#:use-module (guix sets)
|
#:use-module (guix sets)
|
||||||
#:use-module ((guix utils) #:select (location-file))
|
#:use-module ((guix diagnostics)
|
||||||
|
#:select (location-file formatted-message))
|
||||||
#:use-module ((guix scripts build)
|
#:use-module ((guix scripts build)
|
||||||
#:select (show-transformation-options-help
|
#:select (show-transformation-options-help
|
||||||
options->transformation
|
options->transformation
|
||||||
|
@ -90,10 +91,8 @@ name."
|
||||||
package)
|
package)
|
||||||
(x
|
(x
|
||||||
(raise
|
(raise
|
||||||
(condition
|
(formatted-message (G_ "~a: invalid argument (package name expected)")
|
||||||
(&message
|
x)))))
|
||||||
(message (format #f (G_ "~a: invalid argument (package name expected)")
|
|
||||||
x))))))))
|
|
||||||
|
|
||||||
(define nodes-from-package
|
(define nodes-from-package
|
||||||
;; The default conversion method.
|
;; The default conversion method.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
|
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
|
@ -33,11 +33,12 @@
|
||||||
#:use-module ((guix serialization)
|
#:use-module ((guix serialization)
|
||||||
#:select (nar-error? nar-error-file))
|
#:select (nar-error? nar-error-file))
|
||||||
#:use-module (guix nar)
|
#:use-module (guix nar)
|
||||||
#:use-module (guix utils)
|
#:use-module ((guix utils) #:select (%current-system))
|
||||||
#:use-module ((guix build syscalls)
|
#:use-module ((guix build syscalls)
|
||||||
#:select (fcntl-flock set-thread-name))
|
#:select (fcntl-flock set-thread-name))
|
||||||
#:use-module ((guix build utils) #:select (which mkdir-p))
|
#:use-module ((guix build utils) #:select (which mkdir-p))
|
||||||
#:use-module (guix ui)
|
#:use-module (guix ui)
|
||||||
|
#:use-module (guix diagnostics)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (srfi srfi-11)
|
#:use-module (srfi srfi-11)
|
||||||
#:use-module (srfi srfi-26)
|
#:use-module (srfi srfi-26)
|
||||||
|
@ -156,10 +157,9 @@ can interpret meaningfully."
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(private-key-from-file file))
|
(private-key-from-file file))
|
||||||
(lambda (key proc str . rest)
|
(lambda (key proc str . rest)
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "failed to load SSH \
|
||||||
(&message (message (format #f (G_ "failed to load SSH \
|
|
||||||
private key from '~a': ~a")
|
private key from '~a': ~a")
|
||||||
file str))))))))
|
file str)))))
|
||||||
|
|
||||||
(define* (open-ssh-session machine #:optional (max-silent-time -1))
|
(define* (open-ssh-session machine #:optional (max-silent-time -1))
|
||||||
"Open an SSH session for MACHINE and return it. Throw an error on failure."
|
"Open an SSH session for MACHINE and return it. Throw an error on failure."
|
||||||
|
|
26
guix/ssh.scm
26
guix/ssh.scm
|
@ -20,7 +20,7 @@
|
||||||
#:use-module (guix store)
|
#:use-module (guix store)
|
||||||
#:use-module (guix inferior)
|
#:use-module (guix inferior)
|
||||||
#:use-module (guix i18n)
|
#:use-module (guix i18n)
|
||||||
#:use-module ((guix diagnostics) #:select (&fix-hint))
|
#:use-module ((guix diagnostics) #:select (&fix-hint formatted-message))
|
||||||
#:use-module (gcrypt pk-crypto)
|
#:use-module (gcrypt pk-crypto)
|
||||||
#:use-module (ssh session)
|
#:use-module (ssh session)
|
||||||
#:use-module (ssh auth)
|
#:use-module (ssh auth)
|
||||||
|
@ -88,14 +88,12 @@ actual key does not match."
|
||||||
;; provided its Ed25519 key when we where expecting its RSA key. XXX:
|
;; provided its Ed25519 key when we where expecting its RSA key. XXX:
|
||||||
;; Guile-SSH 0.10.1 doesn't know about ed25519 keys and 'get-key-type'
|
;; Guile-SSH 0.10.1 doesn't know about ed25519 keys and 'get-key-type'
|
||||||
;; returns #f in that case.
|
;; returns #f in that case.
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "server at '~a' returned host key \
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "server at '~a' returned host key \
|
|
||||||
'~a' of type '~a' instead of '~a' of type '~a'~%")
|
'~a' of type '~a' instead of '~a' of type '~a'~%")
|
||||||
(session-get session 'host)
|
(session-get session 'host)
|
||||||
(public-key->string server)
|
(public-key->string server)
|
||||||
(get-key-type server)
|
(get-key-type server)
|
||||||
key type))))))))
|
key type)))))
|
||||||
|
|
||||||
(define* (open-ssh-session host #:key user port identity
|
(define* (open-ssh-session host #:key user port identity
|
||||||
host-key
|
host-key
|
||||||
|
@ -148,12 +146,10 @@ Throw an error on failure."
|
||||||
(match (authenticate-server session)
|
(match (authenticate-server session)
|
||||||
('ok #f)
|
('ok #f)
|
||||||
(reason
|
(reason
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "failed to authenticate \
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "failed to authenticate \
|
|
||||||
server at '~a': ~a")
|
server at '~a': ~a")
|
||||||
(session-get session 'host)
|
(session-get session 'host)
|
||||||
reason))))))))
|
reason)))))
|
||||||
|
|
||||||
;; Use public key authentication, via the SSH agent if it's available.
|
;; Use public key authentication, via the SSH agent if it's available.
|
||||||
(match (userauth-public-key/auto! session)
|
(match (userauth-public-key/auto! session)
|
||||||
|
@ -173,10 +169,8 @@ server at '~a': ~a")
|
||||||
host (get-error session)))))))))))
|
host (get-error session)))))))))))
|
||||||
(x
|
(x
|
||||||
;; Connection failed or timeout expired.
|
;; Connection failed or timeout expired.
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "SSH connection to '~a' failed: ~a~%")
|
||||||
(&message
|
host (get-error session)))))))
|
||||||
(message (format #f (G_ "SSH connection to '~a' failed: ~a~%")
|
|
||||||
host (get-error session))))))))))
|
|
||||||
|
|
||||||
(define* (remote-inferior session #:optional become-command)
|
(define* (remote-inferior session #:optional become-command)
|
||||||
"Return a remote inferior for the given SESSION. If BECOME-COMMAND is
|
"Return a remote inferior for the given SESSION. If BECOME-COMMAND is
|
||||||
|
@ -187,11 +181,9 @@ given, use that to invoke the remote Guile REPL."
|
||||||
(when (eof-object? (peek-char pipe))
|
(when (eof-object? (peek-char pipe))
|
||||||
(let ((status (channel-get-exit-status pipe)))
|
(let ((status (channel-get-exit-status pipe)))
|
||||||
(close-port pipe)
|
(close-port pipe)
|
||||||
(raise (condition
|
(raise (formatted-message (G_ "remote command '~{~a~^ ~}' failed \
|
||||||
(&message
|
|
||||||
(message (format #f (G_ "remote command '~{~a~^ ~}' failed \
|
|
||||||
with status ~a")
|
with status ~a")
|
||||||
repl-command status)))))))
|
repl-command status))))
|
||||||
(port->inferior pipe)))
|
(port->inferior pipe)))
|
||||||
|
|
||||||
(define* (inferior-remote-eval exp session #:optional become-command)
|
(define* (inferior-remote-eval exp session #:optional become-command)
|
||||||
|
|
|
@ -1796,9 +1796,7 @@ DURATION-RELATION with the current time."
|
||||||
filter-by-duration)
|
filter-by-duration)
|
||||||
(else
|
(else
|
||||||
(raise
|
(raise
|
||||||
(condition (&message
|
(formatted-message (G_ "invalid syntax: ~a~%") str)))))
|
||||||
(message (format #f (G_ "invalid syntax: ~a~%")
|
|
||||||
str))))))))
|
|
||||||
|
|
||||||
(define (display-generation profile number)
|
(define (display-generation profile number)
|
||||||
"Display a one-line summary of generation NUMBER of PROFILE."
|
"Display a one-line summary of generation NUMBER of PROFILE."
|
||||||
|
|
|
@ -417,12 +417,13 @@ values: 'always', 'never', and 'interactive' (default)."
|
||||||
#f))))
|
#f))))
|
||||||
(match (assq method %method-updates)
|
(match (assq method %method-updates)
|
||||||
(#f
|
(#f
|
||||||
(raise (condition (&message
|
(raise (make-compound-condition
|
||||||
(message (format #f (G_ "cannot download for \
|
(formatted-message (G_ "cannot download for \
|
||||||
this method: ~s")
|
this method: ~s")
|
||||||
method)))
|
method)
|
||||||
|
(condition
|
||||||
(&error-location
|
(&error-location
|
||||||
(location (package-location package))))))
|
(location (package-location package)))))))
|
||||||
((_ . update)
|
((_ . update)
|
||||||
(update store package source
|
(update store package source
|
||||||
#:key-download key-download)))))
|
#:key-download key-download)))))
|
||||||
|
|
|
@ -27,7 +27,11 @@
|
||||||
#:use-module (guix sets)
|
#:use-module (guix sets)
|
||||||
#:use-module (guix gexp)
|
#:use-module (guix gexp)
|
||||||
#:use-module ((guix diagnostics)
|
#:use-module ((guix diagnostics)
|
||||||
#:select (error-location? error-location location-line))
|
#:select (error-location?
|
||||||
|
error-location location-line
|
||||||
|
formatted-message?
|
||||||
|
formatted-message-string
|
||||||
|
formatted-message-arguments))
|
||||||
#:use-module ((guix build utils) #:select (which))
|
#:use-module ((guix build utils) #:select (which))
|
||||||
#:use-module (git)
|
#:use-module (git)
|
||||||
#:use-module (guix git)
|
#:use-module (guix git)
|
||||||
|
@ -415,8 +419,8 @@
|
||||||
(channel (channel (url (string-append "file://" directory))
|
(channel (channel (url (string-append "file://" directory))
|
||||||
(name 'guix))))
|
(name 'guix))))
|
||||||
|
|
||||||
(guard (c ((message-condition? c)
|
(guard (c ((formatted-message? c)
|
||||||
(->bool (string-contains (condition-message c)
|
(->bool (string-contains (formatted-message-string c)
|
||||||
"introduction"))))
|
"introduction"))))
|
||||||
(with-store store
|
(with-store store
|
||||||
;; Attempt a downgrade from NEW to OLD.
|
;; Attempt a downgrade from NEW to OLD.
|
||||||
|
@ -459,9 +463,15 @@
|
||||||
(channel (channel (name 'example)
|
(channel (channel (name 'example)
|
||||||
(url (string-append "file://" directory))
|
(url (string-append "file://" directory))
|
||||||
(introduction intro))))
|
(introduction intro))))
|
||||||
(guard (c ((message-condition? c)
|
(guard (c ((formatted-message? c)
|
||||||
(->bool (string-contains (condition-message c)
|
(and (string-contains (formatted-message-string c)
|
||||||
"initial commit"))))
|
"initial commit")
|
||||||
|
(equal? (formatted-message-arguments c)
|
||||||
|
(list
|
||||||
|
(oid->string (commit-id commit1))
|
||||||
|
(key-fingerprint %ed25519-public-key-file)
|
||||||
|
(key-fingerprint
|
||||||
|
%ed25519bis-public-key-file))))))
|
||||||
(authenticate-channel channel directory
|
(authenticate-channel channel directory
|
||||||
(commit-id-string commit2)
|
(commit-id-string commit2)
|
||||||
#:keyring-reference-prefix "")
|
#:keyring-reference-prefix "")
|
||||||
|
|
|
@ -334,7 +334,7 @@
|
||||||
(check-patch-file-names pkg))))
|
(check-patch-file-names pkg))))
|
||||||
|
|
||||||
(test-equal "patches: not found"
|
(test-equal "patches: not found"
|
||||||
"this-patch-does-not-exist!: patch not found"
|
"this-patch-does-not-exist!: patch not found\n"
|
||||||
(single-lint-warning-message
|
(single-lint-warning-message
|
||||||
(let ((pkg (dummy-package
|
(let ((pkg (dummy-package
|
||||||
"x"
|
"x"
|
||||||
|
|
|
@ -618,12 +618,11 @@
|
||||||
(string=? (derivation->output-path drv)
|
(string=? (derivation->output-path drv)
|
||||||
(package-output %store package "out")))))
|
(package-output %store package "out")))))
|
||||||
|
|
||||||
(test-assert "patch not found yields a run-time error"
|
(test-equal "patch not found yields a run-time error"
|
||||||
(guard (c ((condition-has-type? c &message)
|
'("~a: patch not found\n" "does-not-exist.patch")
|
||||||
(and (string-contains (condition-message c)
|
(guard (c ((formatted-message? c)
|
||||||
"does-not-exist.patch")
|
(cons (formatted-message-string c)
|
||||||
(string-contains (condition-message c)
|
(formatted-message-arguments c))))
|
||||||
"not found"))))
|
|
||||||
(let ((p (package
|
(let ((p (package
|
||||||
(inherit (dummy-package "p"))
|
(inherit (dummy-package "p"))
|
||||||
(source (origin
|
(source (origin
|
||||||
|
|
Reference in New Issue