services: MySQL: Upgrade database schemas automatically.
* gnu/services/databases.scm (<mysql-configuration>): Add AUTO-UPGRADE? field. (mysql-upgrade-wrapper, mysql-upgrade-shepherd-service, mysql-shepherd-services): New variables. (mysql-service-type): Use MYSQL-SHEPHERD-SERVICES instead of MYSQL-SHEPHERD-SERVICE. * doc/guix.texi (Database Services): Document the AUTO-UPGRADE? field of MYSQL-SERVICE-TYPE. * gnu/tests/databases.scm (run-mysql-test): Test that mysql_upgrade has run.
This commit is contained in:
		
							parent
							
								
									927bf98e0e
								
							
						
					
					
						commit
						e20388ad7f
					
				
					 3 changed files with 60 additions and 2 deletions
				
			
		|  | @ -19151,6 +19151,12 @@ Socket file to use for local (non-network) connections. | ||||||
| @item @code{extra-content} (default: @code{""}) | @item @code{extra-content} (default: @code{""}) | ||||||
| Additional settings for the @file{my.cnf} configuration file. | Additional settings for the @file{my.cnf} configuration file. | ||||||
| 
 | 
 | ||||||
|  | @item @code{auto-upgrade?} (default: @code{#t}) | ||||||
|  | Whether to automatically run @command{mysql_upgrade} after starting the | ||||||
|  | service.  This is necessary to upgrade the @dfn{system schema} after | ||||||
|  | ``major'' updates (such as switching from MariaDB 10.4 to 10.5), but can | ||||||
|  | be disabled if you would rather do that manually. | ||||||
|  | 
 | ||||||
| @end table | @end table | ||||||
| @end deftp | @end deftp | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| ;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org> | ;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org> | ||||||
| ;;; Copyright © 2018 Julien Lepiller <julien@lepiller.eu> | ;;; Copyright © 2018 Julien Lepiller <julien@lepiller.eu> | ||||||
| ;;; Copyright © 2019 Robert Vollmert <rob@vllmrt.net> | ;;; Copyright © 2019 Robert Vollmert <rob@vllmrt.net> | ||||||
|  | ;;; Copyright © 2020 Marius Bakke <marius@gnu.org> | ||||||
| ;;; | ;;; | ||||||
| ;;; This file is part of GNU Guix. | ;;; This file is part of GNU Guix. | ||||||
| ;;; | ;;; | ||||||
|  | @ -468,7 +469,8 @@ storage: | ||||||
|   (bind-address mysql-configuration-bind-address (default "127.0.0.1")) |   (bind-address mysql-configuration-bind-address (default "127.0.0.1")) | ||||||
|   (port mysql-configuration-port (default 3306)) |   (port mysql-configuration-port (default 3306)) | ||||||
|   (socket mysql-configuration-socket (default "/run/mysqld/mysqld.sock")) |   (socket mysql-configuration-socket (default "/run/mysqld/mysqld.sock")) | ||||||
|   (extra-content mysql-configuration-extra-content (default ""))) |   (extra-content mysql-configuration-extra-content (default "")) | ||||||
|  |   (auto-upgrade? mysql-configuration-auto-upgrade? (default #t))) | ||||||
| 
 | 
 | ||||||
| (define %mysql-accounts | (define %mysql-accounts | ||||||
|   (list (user-group |   (list (user-group | ||||||
|  | @ -559,6 +561,52 @@ FLUSH PRIVILEGES; | ||||||
|                      #:user "mysql" #:group "mysql"))) |                      #:user "mysql" #:group "mysql"))) | ||||||
|          (stop #~(make-kill-destructor))))) |          (stop #~(make-kill-destructor))))) | ||||||
| 
 | 
 | ||||||
|  | (define (mysql-upgrade-wrapper mysql socket-file) | ||||||
|  |   ;; The MySQL socket and PID file may appear before the server is ready to | ||||||
|  |   ;; accept connections.  Ensure the socket is responsive before attempting | ||||||
|  |   ;; to run the upgrade script. | ||||||
|  |   (program-file | ||||||
|  |    "mysql-upgrade-wrapper" | ||||||
|  |    #~(begin | ||||||
|  |        (let ((mysql-upgrade #$(file-append mysql "/bin/mysql_upgrade")) | ||||||
|  |              (timeout 10)) | ||||||
|  |          (begin | ||||||
|  |            (let loop ((i 0)) | ||||||
|  |              (catch 'system-error | ||||||
|  |                (lambda () | ||||||
|  |                  (let ((sock (socket PF_UNIX SOCK_STREAM 0))) | ||||||
|  |                    (connect sock AF_UNIX #$socket-file) | ||||||
|  |                    (close-port sock) | ||||||
|  |                    ;; The socket is ready! | ||||||
|  |                    (execl mysql-upgrade mysql-upgrade | ||||||
|  |                           (string-append "--socket=" #$socket-file)))) | ||||||
|  |                  (lambda args | ||||||
|  |                    (if (< i timeout) | ||||||
|  |                        (begin | ||||||
|  |                          (sleep 1) | ||||||
|  |                          (loop (+ 1 i))) | ||||||
|  |                        ;; No luck, give up. | ||||||
|  |                        (throw 'timeout-error | ||||||
|  |                               "MySQL server did not appear in time!")))))))))) | ||||||
|  | 
 | ||||||
|  | (define (mysql-upgrade-shepherd-service config) | ||||||
|  |   (list (shepherd-service | ||||||
|  |          (provision '(mysql-upgrade)) | ||||||
|  |          (requirement '(mysql)) | ||||||
|  |          (one-shot? #t) | ||||||
|  |          (documentation "Upgrade MySQL database schemas.") | ||||||
|  |          (start (let ((mysql (mysql-configuration-mysql config)) | ||||||
|  |                       (socket (mysql-configuration-socket config))) | ||||||
|  |                   #~(make-forkexec-constructor | ||||||
|  |                      (list #$(mysql-upgrade-wrapper mysql socket)) | ||||||
|  |                      #:user "mysql" #:group "mysql")))))) | ||||||
|  | 
 | ||||||
|  | (define (mysql-shepherd-services config) | ||||||
|  |   (if (mysql-configuration-auto-upgrade? config) | ||||||
|  |       (append (mysql-shepherd-service config) | ||||||
|  |               (mysql-upgrade-shepherd-service config)) | ||||||
|  |       (mysql-shepherd-service config))) | ||||||
|  | 
 | ||||||
| (define mysql-service-type | (define mysql-service-type | ||||||
|   (service-type |   (service-type | ||||||
|    (name 'mysql) |    (name 'mysql) | ||||||
|  | @ -568,7 +616,7 @@ FLUSH PRIVILEGES; | ||||||
|           (service-extension activation-service-type |           (service-extension activation-service-type | ||||||
|                              %mysql-activation) |                              %mysql-activation) | ||||||
|           (service-extension shepherd-root-service-type |           (service-extension shepherd-root-service-type | ||||||
|                              mysql-shepherd-service))) |                              mysql-shepherd-services))) | ||||||
|    (default-value (mysql-configuration)))) |    (default-value (mysql-configuration)))) | ||||||
| 
 | 
 | ||||||
| (define-deprecated (mysql-service #:key (config (mysql-configuration))) | (define-deprecated (mysql-service #:key (config (mysql-configuration))) | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| ;;; GNU Guix --- Functional package management for GNU | ;;; GNU Guix --- Functional package management for GNU | ||||||
| ;;; Copyright © 2017 Christopher Baines <mail@cbaines.net> | ;;; Copyright © 2017 Christopher Baines <mail@cbaines.net> | ||||||
|  | ;;; Copyright © 2020 Marius Bakke <marius@gnu.org> | ||||||
| ;;; | ;;; | ||||||
| ;;; This file is part of GNU Guix. | ;;; This file is part of GNU Guix. | ||||||
| ;;; | ;;; | ||||||
|  | @ -311,6 +312,9 @@ | ||||||
|                      ((pid) (number? pid)))))) |                      ((pid) (number? pid)))))) | ||||||
|              marionette)) |              marionette)) | ||||||
| 
 | 
 | ||||||
|  |           (test-assert "mysql_upgrade completed" | ||||||
|  |             (wait-for-file "/var/lib/mysql/mysql_upgrade_info" marionette)) | ||||||
|  | 
 | ||||||
|           (test-end) |           (test-end) | ||||||
|           (exit (= (test-runner-fail-count (test-runner-current)) 0))))) |           (exit (= (test-runner-fail-count (test-runner-current)) 0))))) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Reference in a new issue