Compare commits

..

149 Commits
v0.1.1 ... 2.1

Author SHA1 Message Date
Antynea
1b40cfee20 Update 41_snapshots-btrfs
Update 41_snapshots-btrfs
2018-02-03 22:59:03 +01:00
Antynea
358dedc392 Update 41_snapshots-btrfs
Update 41_snapshots-btrfs
2018-02-03 22:57:04 +01:00
Antynea
55dc182b34 Update README.md 2018-02-03 22:31:43 +01:00
Nathan Parsons
23ddb063cb Add systemd service configuration for grub updating (#38)
* Add systemd service configuration for grub updating

This configuration file causes `update-grub` to be run after
Snapper's cleanup and timeline services are run by systemd

* Make invoked command more universal

* Note the need to run systemctl daemon-reload
2018-02-03 21:50:40 +01:00
Antynea
ca51d74265 Update README.md 2018-01-26 11:00:55 +01:00
Antynea
f8937a3fc7 Update README.md 2018-01-26 10:58:04 +01:00
Antynea
9265eb96de Update README.md 2018-01-26 10:55:45 +01:00
Antynea
72edee3d1c Update README.md 2018-01-26 10:54:37 +01:00
Antynea
d24ba197a8 Update README.md 2018-01-26 10:53:42 +01:00
Antynea
0e826391f1 Update 41_snapshots-btrfs 2018-01-26 09:19:33 +01:00
Antynea
7166d939fa Update README.md 2018-01-26 09:18:13 +01:00
Antynea
5cfbf46c8c fix Snapper id too long #36
* fix Snapper id too long #36
2018-01-07 00:31:16 +01:00
Antynea
12cb591307 Update README.md 2018-01-04 10:06:41 +01:00
Maxim Baz
49c64425eb Use snapper's snapshot description if available, fixes #34 (#35)
* Use snapper's snapshot description if available, fixes #34

* List snapper's snapshot from all configs

* fix: Title format in grub-menu, that didn't work as expected
2018-01-03 21:15:26 +01:00
Antynea
cb4040cd24 fix issue #27
and add "Display name of microcode in menuentry when available"
2016-11-25 01:09:34 +01:00
Antynea
55d5a4c5c2 Merge pull request #26 from daftaupe/patch-1
Update the top-level subvolid from 0 to 5.
2016-11-18 14:40:19 +01:00
Pierre-Alain TORET
bfa42253e0 Fix typo 2016-11-18 14:23:23 +01:00
Pierre-Alain TORET
13f263ca0c Update the top-level subvolid from 0 to 5.
According to https://btrfs.wiki.kernel.org/index.php/SysadminGuide#Subvolumes, the toplevel subvolume is 5 not 0, so I guess that's what should be used here.
Also fixed a few typos.
2016-11-18 12:10:59 +01:00
Antynea
18e36190f4 Update README.md 2016-05-04 16:19:45 +02:00
Antynea
f4c02dac09 add "Create entries with matching version number instead of all possible combinations of kernel and initramfs"
* GRUB_BTRFS_CREATE_ONLY_HARMONIZED_ENTRIES="false" 
-----> (Create entries with matching version number instead of all possible combinations of kernel and initramfs)
2016-05-04 13:46:31 +02:00
Antynea
86c8d0a0e8 Merge pull request #22 from anyc/master
Create only entries with matching version numbers and one small improvement
2016-05-03 16:26:15 +02:00
anyc
9fcdab5277 create only entries where kernel and initramfs have the same version number 2016-05-03 16:15:20 +02:00
anyc
87932d900d use safe temporary directory 2016-05-03 11:19:33 +02:00
Antynea
f0c50d1d76 Fix : GRUB_BTRFS_LIMIT (Limit the number of snapshots populated in the GRUB menu.)
Fix : When a value =< 0, script stop correctly
fix : When a value => 1, script stop when the value is reached

e.g :
 - GRUB_BTRFS_LIMIT="0"
   script doesn't detect snapshot

 - GRUB_BTRFS_LIMIT"1" or "2" "etc..."
   script will stop the snapshot detection when value is reached
2016-04-22 15:29:38 +02:00
Antynea
87a94c19c2 Merge pull request #21 from Psykar/patch-1
Readme typos and grammar
2016-04-19 02:49:01 +02:00
Louis des Landes
c8a7214e22 Readme typos and grammar 2016-04-19 10:46:09 +10:00
Antynea
befb66e801 Update README.md 2016-04-19 02:30:07 +02:00
Antynea
7213d04a42 Update README.md 2016-04-19 02:29:09 +02:00
Antynea
5ea4c86400 Enhanced
add a option to : specific path to ignore during run grub-mkconfig
e.g :
# Found Snapshot: 2016-03-31 10:26:52 var/lib/docker/btrfs/subvolumes/74040aee4fa

docker is not a real snapshot available to boot
add : GRUB_BTRFS_IGNORE_SPECIFIC_PATH=("var/lib/docker") to your /etc/default/grub
and this path will be skip during run grub-mkconfig

Warning : copy exactly the right path (var/lib/docker , not /var/lib/docker/), do not put the full path
2016-04-19 02:28:19 +02:00
Antynea
f17ce68fb3 Merge pull request #19 from Antynea/v1.xx
Enhanced
2016-04-19 02:23:33 +02:00
Antynea
7720cec5f9 Enhanced
- clean code
- add a option to : specific path to ignore during run grub-mkconfig
e.g :
# Found Snapshot: 2016-03-31 10:26:52 var/lib/docker/btrfs/subvolumes/74040aee4fa

docker is not a real snapshot available to boot
add : GRUB_BTRFS_IGNORE_SPECIFIC_PATH=("var/lib/docker") to your /etc/default/grub
and this path will be skip during run grub-mkconfig

Warning : copy exactly the right path (var/lib/docker , not /var/lib/docker/), do not put the full path
2016-04-19 02:18:24 +02:00
Antynea
b4bd7b952c clean code 2016-04-18 17:58:57 +02:00
Antynea
56c11b8e2a - overhaul
- add two new custom variable to /etc/default/grub :
* GRUB_BTRFS_SHOW_TOTAL_SNAPSHOTS_FOUND="true"
(Show Total of snapshots found during run "grub-mkconfig")

* GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="true"
(Show snapshots found during run "grub-mkconfig")
2016-04-18 17:31:57 +02:00
Antynea
d469db0a2d - fix bug issue #18 :
if no snap found, menu generate correctly, and show a warning
- overhaul
- add two new custom variable to /etc/default/grub :
* GRUB_BTRFS_SHOW_TOTAL_SNAPSHOTS_FOUND="true"
(Show Total of snapshots found during run "grub-mkconfig")

* GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="true"
(Show snapshots found during run "grub-mkconfig")
2016-04-18 17:31:33 +02:00
Antynea
6ae56dbaf6 Merge pull request #16 from wesbarnett/master
Add GRUB_BTRFS_LIMIT 
add GRUB_BTRFS_SUBVOLUME_SORT
2016-03-19 16:35:54 +01:00
James Barnett
f820de4759 add sorting options 2016-03-19 08:19:10 -05:00
James Barnett
59164367e7 cleanup 2016-03-19 08:11:47 -05:00
James Barnett
f256338074 Add GRUB_BTRFS_LIMIT
Allow user to limit the number of snapshots listed in GRUB. This also reverses
the order of the snapshots such that the more recent ones come first. That is,
if a user specifies GRUB_BTRFS_LIMIT=10, then only the 10 most recent snapshots
will be shown. The default limit is 100, which seems very large. The more
snapshots in the GRUB menu, the longer the system takes to boot.
2016-03-18 16:46:11 -05:00
Antynea
52ab9dbe95 Merge pull request #14 from Antynea/v1.xx
fix: incorrect detection "$boot_dir_real_path" for initramfs
2016-02-15 03:44:10 +01:00
Antynea
28e9524ca5 fix: incorrect detection "$boot_dir_real_path" for initramfs 2016-02-08 00:01:42 +01:00
Antynea
8fffc13c2f Merge pull request #12 from Antynea/v1.xx
enhanced description
2016-01-15 18:31:18 +01:00
Antynea
a4db6a8870 enhanced description 2016-01-15 18:29:52 +01:00
Antynea
4388c334a3 Merge branch 'v1.xx' 2015-09-25 10:33:04 +02:00
Antynea
a2acaefa9c Merge branch 'master' into v1.xx 2015-09-25 10:32:33 +02:00
Antynea
3db73de479 fixme : choise of method 2015-09-25 10:24:20 +02:00
Antynea
39b2d09015 Add Show full path or only name of snapshots in grub-menu 2015-09-24 08:49:59 +02:00
Antynea
b511210646 Update README.md 2015-09-23 02:39:26 +02:00
Antynea
63d653746b Update README.md 2015-09-23 02:36:04 +02:00
Antynea
2df311179e Update README.md 2015-09-23 02:33:44 +02:00
Antynea
58b8f5d3ec Update README.md 2015-09-23 02:32:10 +02:00
Antynea
4081cbd27a update how to use it & to do:
add :

* GRUB_BTRFS_TITLE_FORMAT="p/d/n"
	(Custom title, shows/hides p"prefix" d"date" n"name" in grub-menu, separator "/", custom order available)

* Show full path or only name of snapshots in grub-menu
2015-09-23 02:29:01 +02:00
Antynea
9d3aa6d8a3 Update :
translation update

New option in /etc/default/grub

* GRUB_BTRFS_TITLE_FORMAT="p/d/n"
   (Custom title, shows/hides p"prefix" d"date" n"name" in grub-menu, separator "/", custom order available)
2015-09-23 02:14:46 +02:00
Antynea
25e2c16828 in progress
custom title menu
2015-09-19 04:48:45 +02:00
Antynea
14cbf60c5a in progress :
custom title menu
2015-09-19 04:31:17 +02:00
Antynea
2cf01a874f in progress
add custom title
2015-09-18 14:52:17 +02:00
Antynea
93b8ac07f5 new ideas 2015-09-11 22:46:26 +02:00
Antynea
252a6372dd Merge branch 'v1.xx' 2015-08-31 04:57:11 +02:00
Antynea
297f539f0a fixme: boot with microcode 2015-08-31 04:55:34 +02:00
Antynea
1c6c8c6051 Merge branch 'v1.xx'
Fix: redundancy parameter
2015-08-31 04:29:41 +02:00
Antynea
f0fb4b8e25 redundancy parameter 2015-08-31 04:20:33 +02:00
Antynea
650ac69552 Merge branch 'v1.xx' 2015-08-30 16:18:45 +02:00
Antynea
3ebc5b494a Update description
Add few comments
2015-08-30 16:14:59 +02:00
Antynea
615cbe9f3a Merge branch 'v1.xx' 2015-08-30 03:43:08 +02:00
Antynea
2e58a2b74d enhanced detect microcode 2015-08-30 03:39:15 +02:00
Antynea
4f725a8431 Merge branch 'master' into v1.xx 2015-08-30 02:38:23 +02:00
Antynea
d598529001 fixme : detect kernesl and initramfs with spaces
fixme : detect kernel and initramfs with spaces
2015-08-30 02:23:18 +02:00
Antynea
b925f639cd fixme : detect snapshot name with spaces
fixme : detect snapshot name with spaces
2015-08-30 01:19:25 +02:00
Antynea
31a0baa2b1 redundancy test
redundancy test
2015-08-30 00:15:15 +02:00
Antynea
3a7c6abece fixme : detect microcode
fixme : detect microcode
2015-08-29 23:45:32 +02:00
Antynea
5e0951d8cb Fixme : broken $boot_dir_real_path
Fixme : broken $boot_dir_real_path
2015-08-29 23:17:03 +02:00
Antynea
c9f5938e04 Merge branch 'v1.xx' 2015-08-29 18:22:16 +02:00
Antynea
128cbe28f3 Merge branch 'master' into v1.xx
Conflicts:
	41_snapshots-btrfs
2015-08-29 18:17:42 +02:00
Antynea
8102850627 Update README.md 2015-08-17 23:51:50 +02:00
Antynea
05fea226f9 don't create menu if snapshot is not bootable with /boot partition separate 2015-08-17 23:49:49 +02:00
Antynea
619686990e Update README.md 2015-08-12 06:02:45 +02:00
Antynea
1f3575efd1 Update README.md
To do : 
don't create menu if snapshot is not bootable with /boot partition separate
2015-08-12 06:01:49 +02:00
Antynea
2b33b88bea don't create menu if snapshot is not bootable with /boot partition separate 2015-08-11 02:57:09 +02:00
Antynea
aae6892218 Update README.md 2015-08-10 06:29:19 +02:00
Antynea
84ecc2a5a7 Update README.md 2015-08-10 06:27:31 +02:00
Antynea
7c1178b17c Update README.md 2015-08-10 06:26:49 +02:00
Antynea
2773382eb5 error if /grub is in /boot/EFI 2015-08-09 17:42:56 +02:00
Antynea
34c8fbd9cb error if /grub is in /boot/EFI 2015-08-09 16:43:56 +02:00
Antynea
9d04b96f3d Merge remote-tracking branch 'origin/v1.xx' into v1.xx 2015-08-09 16:41:11 +02:00
Antynea
c9d47b7854 error when /grub is not in /boot 2015-08-09 16:36:48 +02:00
Antynea
7d07503f07 Update README.md 2015-08-09 04:21:52 +02:00
Antynea
f646dfd900 Update README.md 2015-08-09 04:20:25 +02:00
Antynea
b4d4bc0aac Update README.md 2015-08-09 04:19:38 +02:00
Antynea
f379832df3 Update README.md 2015-08-08 03:50:00 +02:00
Antynea
00b8f4106d Update README.md
To do
Uefi compatibility
2015-08-08 03:45:08 +02:00
Antynea
26d8e83c8c structuring 2015-08-07 14:16:03 +02:00
Antynea
178cdb163c correct menuentry when /boot is separate partition 2015-08-07 13:01:00 +02:00
Antynea
f46c38d141 typo 2015-08-07 12:55:02 +02:00
Antynea
0ab7aa02bb Correct menuentry
add /boot separate partition
2015-08-07 12:54:03 +02:00
Antynea
be28f3657e * correct menuentry when /boot in separate partition 2015-08-07 01:45:11 +02:00
Antynea
81bb76fbc3 translation for grub-btrfs-git version 1.xx 2015-08-07 01:12:11 +02:00
Antynea
9d21a629d8 Update README.md 2015-08-07 00:40:56 +02:00
Antynea
bc650f2caf Update README.md
enhanced readme
2015-08-07 00:14:48 +02:00
Antynea
52dd376047 enhanced readme 2015-08-07 00:12:23 +02:00
Antynea
87bc0f6358 detect partition boot separate
check, ok
2015-08-06 23:57:29 +02:00
Antynea
94c9fedef3 detect partition boot separate
check, ok
2015-08-06 23:56:38 +02:00
Antynea
adc4fd6687 improve layout for entries in grub 2015-08-06 04:35:46 +02:00
Antynea
3a7ea84dda oops :) 2015-08-06 00:56:50 +02:00
Antynea
b199e29262 GRUB_BTRFS_NINIT=("initramfs-linux.img" "initramfs-linux-fallback.img")
(Use only if you have custom initramfs name or auto-detect failed.)

check , ok
2015-08-06 00:53:39 +02:00
Antynea
6afa8f03cd GRUB_BTRFS_NINIT=("initramfs-linux.img" "initramfs-linux-fallback.img")
(Use only if you have custom initramfs name or auto-detect failed.)

check, ok
2015-08-06 00:50:55 +02:00
Antynea
7cf432f359 auto-detect kernel and custom kernel
check , ok
2015-08-05 15:32:05 +02:00
Antynea
79f0ac6b0d GRUB_BTRFS_NKERNEL=("vmlinuz-linux")
(Use only if you have custom kernel name or auto-detect failed.)

check , ok
2015-08-05 15:30:42 +02:00
Antynea
63a96dfcfb GRUB_BTRFS_INTEL_UCODE=("intel-ucode.img")
(Use only if you have custom intel-ucode or auto-detect failed.)

check , ok
2015-08-02 17:29:35 +02:00
Antynea
6b3cf842b0 GRUB_BTRFS_INTEL_UCODE=("intel-ucode.img")
(Use only if you have custom intel-ucode or auto-detect failed.)

check , ok
2015-08-02 17:28:39 +02:00
Antynea
974b798f53 in progress 2015-07-26 18:13:24 +02:00
Antynea
cbe547de77 in progress 2015-07-26 18:11:33 +02:00
Antynea
422d46cc84 in progress 2015-07-26 18:06:37 +02:00
Antynea
6f7fb178fb Merge pull request #9 from Antynea/Development
enhanced
2015-07-22 02:05:05 +02:00
Antynea
fcdc5dea87 in progress
in progress
2015-07-22 02:00:22 +02:00
Antynea
d561206775 enhanced
enhanced
2015-07-22 01:59:28 +02:00
Antynea
563151507d enhanced
enhanced
2015-07-22 01:52:48 +02:00
Antynea
91f0a98a60 Update README.md 2015-07-22 01:30:37 +02:00
Antynea
205f7edf00 Update README.md 2015-07-22 01:28:59 +02:00
Antynea
fda6eb8c00 Merge pull request #8 from Antynea/Development
fix bug with underscore in subvolume name
2015-06-03 20:41:23 +02:00
Antynea
2385312345 fix bug with underscore in subvolume name 2015-06-03 11:05:05 +02:00
Antynea
5fe28d39be Merge remote-tracking branch 'origin/Development' 2015-06-02 15:59:34 +02:00
Antynea
5e8c722c6a v0.6 2015-06-02 15:58:46 +02:00
Antynea
91e72f60f8 Improve perfomance 2015-05-31 22:26:02 +02:00
Antynea
5bff1c80a7 Merge remote-tracking branch 'origin/Development' 2015-05-24 15:57:50 +02:00
Antynea
ed5e7ee6eb Improve snapshot detection 2015-05-23 16:06:05 +02:00
Antynea
1c4cac2397 Merge remote-tracking branch 'origin/Development' 2015-05-19 00:43:36 +02:00
Antynea
c4b9b3df95 Update README.md
Oops rollback last commit
2015-05-15 22:13:15 +02:00
Antynea
9fb9146e5b Update README.md
reflects change
2015-05-15 22:12:26 +02:00
Antynea
e61d0409ac Merge pull request #6 from penetal/patch-3
How to use /etc/default/grub config
2015-05-15 11:45:22 +02:00
Antynea
3f56de34ec Merge pull request #5 from penetal/patch-2
Pull config from /etc/default/grub
2015-05-15 11:44:14 +02:00
penetal
e0ef9c82e9 How to use /etc/default/grub config
How to change from default config via /etc/default/grub
2015-05-15 11:23:46 +02:00
penetal
788390cc93 Pull config from /etc/default/grub
Added parameter substitution so variables can be changed in /etc/default/grub.
This will let the script stay untouched, for easier updating.
2015-05-15 11:17:46 +02:00
Antynea
97dcaeae58 add warning 2015-05-14 00:38:10 +02:00
Antynea
8602220b98 Add warning 2015-05-13 23:59:07 +02:00
Antynea
7441e573f3 Ooops 2015-05-13 10:30:58 +02:00
Antynea
e06a8e1dd8 enhanced 2015-05-13 10:27:56 +02:00
Antynea
aeff81e861 enhanced 2015-05-13 10:22:36 +02:00
Antynea
876d1c5e98 enhanced 2015-05-13 10:20:00 +02:00
Antynea
4fb1f71b17 enhanced 2015-05-13 10:18:32 +02:00
Antynea
b80c04a751 enhanced 2015-05-13 10:15:13 +02:00
Antynea
11af1f69ba enhanced 2015-05-13 10:13:11 +02:00
Antynea
5ca00a1aa2 enhanced 2015-05-13 10:11:53 +02:00
Antynea
a1b876188c test 2015-05-13 10:10:59 +02:00
Antynea
50f63a9bec enhanced 2015-05-13 10:09:36 +02:00
Antynea
a10f775b8d enhanced 2015-05-13 10:06:57 +02:00
Antynea
7ebfbe05f9 enhanced 2015-05-13 10:03:24 +02:00
Antynea
eeae1d3084 Add intel microcode 2015-05-13 06:23:27 +02:00
Antynea
6a76ec8837 Internationalisation
by default, message en
add translate message fr
2015-05-12 07:40:18 +02:00
Antynea
7916ca2da9 Update 41_snapshots-btrfs
Ooops
2015-05-12 00:52:18 +02:00
Antynea
6b4e3f05e7 upgrade 41_snapshots-btrfs
Add date to menu entry + Output name of accepted snapshots
2015-05-11 22:45:46 +02:00
4 changed files with 594 additions and 101 deletions

2
10-update_grub.conf Normal file
View File

@@ -0,0 +1,2 @@
[Service]
ExecStartPost=/usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg

576
41_snapshots-btrfs Normal file → Executable file
View File

@@ -1,109 +1,489 @@
#! /bin/sh
#! /usr/bin/env bash
#
#
#########################################################################################################################################################################
# Written by: Antynea #
# BTC donation address: 1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt #
# #
# Purpose: Include btrfs snapshots at boot options (grub-menu). #
# #
# What this script does: #
# Simple rollback using snapshots you made previously. #
# - Automatically List snapshots existing on root partition (btrfs). #
# - Automatically Detect if "/boot" is in separate partition. #
# - Automatically Detect kernel, initramfs and intel microcode in "/boot" directory on snapshots. (For custon name, see below.) #
# - Automatically Create corresponding "menuentry" in grub.cfg , which ensures a very easy rollback. #
# - Automatically detect snapper and use snapper's snapshot description if available. #
# #
# How to use it: #
# - Add this lines to /etc/default/grub: #
# #
# * GRUB_BTRFS_SUBMENUNAME="Arch Linux snapshots" #
# (Name appearing in the Grub menu.) #
# * GRUB_BTRFS_PREFIXENTRY="Snapshot:" #
# (Add a name ahead your snapshots entries in the Grub menu.) #
# * GRUB_BTRFS_DISPLAY_PATH_SNAPSHOT="true" #
# (Show full path snapshot or only name in the Grub menu) #
# * GRUB_BTRFS_TITLE_FORMAT="p/d/n" #
# (Custom title, shows/hides p"prefix" d"date" n"name" in the Grub menu, separator "/", custom order available) #
# * GRUB_BTRFS_LIMIT="100" #
# (Limit the number of snapshots populated in the GRUB menu.) #
# * GRUB_BTRFS_SUBVOLUME_SORT="descending" #
# (Sort the found subvolumes by newest first ("descending") or oldest first ("ascending"). #
# If "ascending" is chosen then the $GRUB_BTRFS_LIMIT oldest subvolumes will populate the menu.) #
# * GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="true" #
# (Show snapshots found during run "grub-mkconfig") #
# * GRUB_BTRFS_SHOW_TOTAL_SNAPSHOTS_FOUND="true" #
# (Show Total of snapshots found during run "grub-mkconfig") #
# * GRUB_BTRFS_NKERNEL=("vmlinuz-linux") #
# (Use only if you have custom kernel name or auto-detect failed.) #
# * GRUB_BTRFS_NINIT=("initramfs-linux.img" "initramfs-linux-fallback.img") #
# (Use only if you have custom initramfs name or auto-detect failed.) #
# * GRUB_BTRFS_INTEL_UCODE=("intel-ucode.img") #
# (Use only if you have custom intel-ucode or auto-detect failed.) #
# * GRUB_BTRFS_IGNORE_SPECIFIC_PATH=("var/lib/docker" "nosnapshot") #
# (Ignore specific path during run "grub-mkconfig") #
# * GRUB_BTRFS_CREATE_ONLY_HARMONIZED_ENTRIES="false" #
# (Create entries with matching version number instead of all possible combinations of kernel and initramfs) #
# #
# - Generate grub.cfg (on Arch Linux use grub-mkconfig -o /boot/grub/grub.cfg) #
# #
# - grub-btrfs automatically generates snapshots entries. #
# - You will see it appear different entries (e.g : Snapshot: [2014-02-12 11:24:37] my snapshot name overkill) #
# #
# Automatically update grub #
# If you would like grub to automatically update when Snapper timeline snapshots and cleanups occur, simply install 10-update_grub.conf in the following locations: #
# - /etc/systemd/system/snapper-timeline.service.d/ #
# - /etc/systemd/system/snapper-cleanup.service.d/ #
# Once the configuration files are in place, systemctl daemon-reload should be run to reload the units and make the changes active. #
# #
#########################################################################################################################################################################
set -e
. /usr/share/grub/grub-mkconfig_lib
. /etc/default/grub
#prefix="/usr"
#exec_prefix="${prefix}"
datarootdir="/usr/share"
#datadir="${datarootdir}"
sysconfdir="/etc"
### variables modifiable ###
## fr: nom du sous-menu
## en: Name of the submenu
submenuname="ArchLinux Snapshots"
## fr: préfixe de l'entrée
## en: Prefix entry
prefixentry="Snapshot"
## fr: nom(s) du ou des kernel(s)
## en: Name(s) of the kernel(s)
nkernel=("vmlinuz-linux")
## fr: nom(s) de(s) l'init
## en: Name(s) of the init(s)
ninit=("initramfs-linux.img" "initramfs-linux-fallback.img")
. "${datarootdir}/grub/grub-mkconfig_lib"
. "${sysconfdir}/default/grub"
######################################
### Variables in /etc/default/grub ###
######################################
## Submenu name
submenuname=${GRUB_BTRFS_SUBMENUNAME:-"Arch Linux snapshots"}
## Prefix entry
prefixentry=${GRUB_BTRFS_PREFIXENTRY:-"Snapshot:"}
## Show full path snapshot or only name
path_snapshot=${GRUB_BTRFS_DISPLAY_PATH_SNAPSHOT:-"true"}
## Title format
title_format=${GRUB_BTRFS_TITLE_FORMAT:-"p/d/n"}
## Kernel(s) name(s)
nkernel=("${GRUB_BTRFS_NKERNEL[@]}")
## Initramfs name(s)
ninit=("${GRUB_BTRFS_NINIT[@]}")
## Microcode(s) name(s)
microcode=("${GRUB_BTRFS_INTEL_UCODE[@]}")
## Limit to show in the Grub menu
limit_snap_show="${GRUB_BTRFS_LIMIT:-100}"
## How to sort snapshots list
snap_list_sort=${GRUB_BTRFS_SUBVOLUME_SORT:-"descending"}
case "${snap_list_sort}" in
ascending) btrfssubvolsort=("--sort=+rootid");;
*) btrfssubvolsort=("--sort=-rootid")
esac
## Show snapshots found during run "grub-mkconfig"
show_snap_found=${GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND:-"true"}
## Show Total of snapshots found during run "grub-mkconfig"
show_total_snap_found=${GRUB_BTRFS_SHOW_TOTAL_SNAPSHOTS_FOUND:-"true"}
## Ignore specific path during run "grub-mkconfig"
ignore_specific_path=("${GRUB_BTRFS_IGNORE_SPECIFIC_PATH[@]}")
## create only entries with harmonized version numbers
harmonized_entries=${GRUB_BTRFS_CREATE_ONLY_HARMONIZED_ENTRIES:-"false"}
###########################
### fr: DÉBUT DU SCRIPT ###
### en: NAME OF SCRIPT ###
### fr: NE PAS TOUCHER ###
### en: DO NOT TOUCH ###
###########################
## fr: paramêtre des chaînes --hint
## en: Parameter of the chains --hint (Translation unclear)
pboot=$(${grub_probe} --target="hints_string" "/boot" 2>/dev/null)
## fr: uuid de la partition root
## en: UUID of the root partition
uuid=$(${grub_probe} "/" --target="fs_uuid" 2>/dev/null)
## fr: uuid de la partition boot
## en: UUID of the boot partition
buuid=$(${grub_probe} --target="fs_uuid" "/boot" 2>/dev/null)
## fr: paramêtre passé au kernel
## en: Parameters passed to the kernel
params="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
########################
### variables script ###
########################
## Internationalization (default : english)
export TEXTDOMAIN=grub-btrfs-git
export TEXTDOMAINDIR="/usr/share/locale"
## hints string
hs_boot=$(${grub_probe} --target="hints_string" "/boot" 2>/dev/null)
## UUID of the boot partition
boot_uuid=$(${grub_probe} --target="fs_uuid" "/boot" 2>/dev/null)
## Type filesystem of boot partition
boot_fs=$(${grub_probe} --target="fs" "/boot" 2>/dev/null)
## UUID of the root partition
root_uuid=$(${grub_probe} "/" --target="fs_uuid" 2>/dev/null)
## Parameters passed to the kernel
kernel_parameters="$GRUB_CMDLINE_LINUX $GRUB_CMDLINE_LINUX_DEFAULT"
## Mount point location
gbgmp=$(mktemp -d)
## Class for theme
CLASS="--class snapshots --class gnu-linux --class gnu --class os"
## save IFS
oldIFS=$IFS
## boot_dir (auto-detect if /boot is separate partition or not)
boot_dir()
{
boot_dir="$gbgmp/$snap_dir_name/boot"
[[ "$root_uuid" != "$boot_uuid" ]] && boot_dir="/boot"
echo "$boot_dir"
}
# fr: on affiche le menu
# en: Display the menu
echo "submenu '$submenuname' {"
##############
### Script ###
##############
# fr: on traite la variable kernel
# en: Treat the kernel variables (Translation unclear)
for kernel in ${nkernel[@]}; do
# fr: on test si le(s) nom(s) du(des) kernel existe(nt), autrement on affiche une erreur et on sort
# en: Check the specified kernel(s) exist, if it/they don't display an error and exit
if [ ! -f /boot/$kernel ]; then echo "/boot/$kernel: fr: Fichier inexistant en: File does not exist" >&2; exit 1; fi
# fr: on vérifie le nombre de kernel présent, si >1 on crée un menu
# en: If there are >1 kernels, create a menu
if [ ${#nkernel[*]} != 1 ]; then echo " submenu '$kernel' {
submenu '---> Kernel: $kernel <---' { echo }"; fi
# fr: On liste les snapshots présent sur le système de fichier
# en: List filesystem snapshots
for item in $($bindir/btrfs subvolume list -s / --sort=-ogen | $bindir/awk '{print $NF}'); do
# fr: On écarte les snapshots avec un statut de suppression
# en: Discard deleted snapshots
if [ $item = "DELETED" ]; then continue; fi
# fr: on crée un menu pour chaque snapshot présent
# en: Create a menu for remaining snapshots
echo " submenu '$prefixentry $item' {"
# fr: si plusieurs kernel on été trouvé, on affiche un titre indicatif
# en: Display message if more than one kernel is found
if [ ${#nkernel[*]} != 1 ]; then echo " submenu '---> Kernel: $kernel <---' { echo }"; fi
# fr: on traite la variable de l'initframs
# en: Treat the initramfs variables (Translation unclear)
for init in ${ninit[@]}; do
# fr: on test si le(s) nom(s) du(des) initframs existe(nt), autrement on affiche une erreur et on sort
# en: Check the specified initramfs(es) exist, if it/they don't display an error and exit
if [ ! -f /boot/$init ]; then echo "/boot/$init: Fichier inexistant" >&2; exit 1; fi
# fr: on traite chaque entrée des snapshots avec leurs kernel et initframs respectifs
# en: Specify a kernel and initramfs for every snapshot
echo "\
menuentry '$item $init' --class arch --class gnu-linux --class gnu --class os "\$menuentry_id_option" 'gnulinux-snapshots-$uuid'{
load_video
set gfxpayload=$GRUB_GFXPAYLOAD_LINUX
if [ x"\$feature_platform_search_hint" = xy ]; then
search --no-floppy --fs-uuid --set=root $pboot $buuid
else
search --no-floppy --fs-uuid --set=root $buuid
fi
echo 'Loading Linux snapshot ...'"
# fr: on vérifie l'emplacement de la partition /boot
# en: Check the location of the /boot partition
if [ $uuid = $buuid ]; then
echo "\
linux /$item/boot/$kernel root=UUID=$uuid rw rootflags=subvol=$item $params
echo 'Loading initial ramdisk ...'
initrd /$item/boot/$init"
else
echo "\
linux /$kernel root=UUID=$uuid rw rootflags=subvol=$item $params
echo 'Loading initial ramdisk ...'
initrd /$init"
fi
### BEGIN auto detect ###
## menu entries
snapshots_entry()
{
## \" required for snap,kernels,init,microcode with space in their name
echo " submenu '$title_menu' {
submenu '---> $title_menu <---' { echo }
"
for k in "${name_kernel[@]}"; do
for i in "${name_initramfs[@]}"; do
for u in "${name_microcode[@]}"; do
if [ -f "$(boot_dir)"/"${u}" ] ; then
echo "\
}"
done
menuentry '"${k}" & "${i}" & "${u}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid'{"
else
echo "\
menuentry '"${k}" & "${i}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid'{"
fi
echo "\
$(save_default_entry)
if [ x\$feature_all_video_module = xy ]; then
insmod all_video
fi
set gfxpayload=keep
insmod ${boot_fs}
if [ x\$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root ${hs_boot} ${boot_uuid}
else
search --no-floppy --fs-uuid --set=root ${boot_uuid}
fi
echo 'Loading Snapshot: "${snap_date_time}" "${snap_dir_name}"'
echo 'Loading Kernel: "${k}" ...'
linux \"${boot_dir_real_path}/"${k}"\" root=UUID=${root_uuid} rw rootflags=subvol=\""${snap_dir_name}"\" ${kernel_parameters}"
if [ -f "$(boot_dir)"/"${u}" ] ; then
echo "\
echo 'Loading Microcode & Initramfs: "${u}" "${i}" ...'
initrd \"${boot_dir_real_path}/"${u}"\" \"${boot_dir_real_path}/"${i}"\""
else
echo "\
echo 'Loading Initramfs: "${i}" ...'
initrd \"${boot_dir_real_path}/"${i}"\""
fi
echo " }"
done
done
done
# fr: on oubli pas de fermer le menu si plusieurs kernels ont été trouvé
# en: Don't forget to close menus if more than one kernel is found
if [ ${#nkernel[*]} != 1 ]; then echo " }"; fi
done
echo "}"
echo " }"
}
harmonized_snapshots_entry()
{
## \" required for snap,kernels,init,microcode with space in their name
echo " submenu '$title_menu' {
submenu '---> $title_menu <---' { echo }
"
for k in "${name_kernel[@]}"; do
version=${k#vmlinuz-}
i=""
if [ -f "$(boot_dir)"/initramfs-"${version}".img ]; then
i=initramfs-${version}.img
else
if [ -f "$(boot_dir)"/initrd.img-"${version}" ]; then
i=initrd.img-${version}
fi
fi
for u in "${name_microcode[@]}"; do
if [ -f "$(boot_dir)"/"${u}" ] ; then
echo "\
menuentry '"${k}" & "${i}" & "${u}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid'{"
else
echo "\
menuentry '"${k}" & "${i}"' ${CLASS} "\$menuentry_id_option" 'gnulinux-snapshots-$boot_uuid'{"
fi
echo "\
$(save_default_entry)
if [ x\$feature_all_video_module = xy ]; then
insmod all_video
fi
set gfxpayload=keep
insmod ${boot_fs}
if [ x\$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root ${hs_boot} ${boot_uuid}
else
search --no-floppy --fs-uuid --set=root ${boot_uuid}
fi
echo 'Loading Snapshot: "${snap_date_time}" "${snap_dir_name}"'
echo 'Loading Kernel: "${k}" ...'
linux \"${boot_dir_real_path}/"${k}"\" root=UUID=${root_uuid} rw rootflags=subvol=\""${snap_dir_name}"\" ${kernel_parameters}"
if [ -f "$(boot_dir)"/"${i}" ] ; then
if [ -f "$(boot_dir)"/"${u}" ] ; then
echo "\
echo 'Loading Microcode & Initramfs: "${u}" "${i}" ...'
initrd \"${boot_dir_real_path}/"${u}"\" \"${boot_dir_real_path}/"${i}"\""
else
echo "\
echo 'Loading Initramfs: "${i}" ...'
initrd \"${boot_dir_real_path}/"${i}"\""
fi
fi
echo " }"
done
done
echo " }"
}
## Trim a string from leading and trailing whitespaces
trim() {
local var="$*"
var="${var#"${var%%[![:space:]]*}"}"
var="${var%"${var##*[![:space:]]}"}"
echo -n "$var"
}
## List of snapshots on filesystem
snapshot_list()
{
# Query info from snapper if it is installed
type snapper >/dev/null 2>&1
if [[ $? -eq 0 ]]; then
local snapper_ids=($(snapper -t 0 list -a | tail -n +3 | cut -d'|' -f 2))
local snapper_types=($(snapper -t 0 list -a | tail -n +3 | cut -d'|' -f 1))
IFS=$'\n'
local snapper_descriptions=($(snapper -t 0 list -a | tail -n +3 | cut -d'|' -f 7))
fi
IFS=$'\n'
# Parse btrfs snapshots
local entries=()
local ids=()
local max_entry_length=0
for snap in $(btrfs subvolume list -sa "${btrfssubvolsort}" /); do
IFS=$oldIFS
snap=($snap)
local snap_path_name=${snap[@]:13:${#snap[@]}}
# Discard deleted snapshots
if [ "$snap_path_name" = "DELETED" ]; then continue; fi
[[ ${snap_path_name%%"/"*} == "<FS_TREE>" ]] && snap_path_name=${snap_path_name#*"/"}
local id="${snap_path_name//[!0-9]}" # brutal way to get id: remove everything non-numeric
ids+=("$id")
local entry="${snap[@]:10:2} | ${snap_path_name}"
entries+=("$entry")
# Find max length of a snapshot entry, needed for pretty formatting
local length="${#entry}"
[[ "$length" -gt "$max_entry_length" ]] && max_entry_length=$length
done
# Find max length of a snapshot type, needed for pretty formatting
local max_type_length=0
for id in "${ids[@]}"; do
for j in "${!snapper_ids[@]}"; do
local snapper_id="${snapper_ids[$j]//[[:space:]]/}"
if [[ "$snapper_id" == "$id" ]]; then
local snapper_type=$(trim "${snapper_types[$j]}")
local length="${#snapper_type}"
[[ "$length" -gt "$max_type_length" ]] && max_type_length=$length
fi
done
done
for i in "${!entries[@]}"; do
local id="${ids[$i]}"
local entry="${entries[$i]}"
for j in "${!snapper_ids[@]}"; do
local snapper_id="${snapper_ids[$j]//[[:space:]]/}"
if [[ "$snapper_id" == "$id" ]]; then
local snapper_type=$(trim "${snapper_types[$j]}")
local snapper_description=$(trim "${snapper_descriptions[$j]}")
printf -v entry "%-${max_entry_length}s | %-${max_type_length}s | %s" "$entry" "$snapper_type" "$snapper_description"
break
fi
done
echo "$entry"
done
IFS=$oldIFS
}
## Detect kernels in "/boot"
detect_kernel()
{
## Arch original kernel (auto-detect)
for akernel in "$(boot_dir)"/vmlinuz-* ; do
list_kernel+=("$akernel")
done
## Custom name kernel in GRUB_BTRFS_NKERNEL
if [ ! -z "${nkernel}" ] ; then
for ckernel in "${nkernel[@]}" ; do
[[ ! -f /"$(boot_dir)"/"${ckernel}" ]] && continue;
list_kernel+=("$ckernel")
done
fi
}
## Detect initramfs in "/boot"
detect_initramfs()
{
## Arch original initramfs (auto-detect)
for ainitramfs in "$(boot_dir)"/initramfs-* ; do
list_initramfs+=("$ainitramfs")
done
## Custom name initramfs in GRUB_BTRFS_NINIT
if [ ! -z "$ninit" ] ; then
for cinitramfs in "${ninit[@]}" ; do
[[ ! -f /"$(boot_dir)"/"${cinitramfs}" ]] && continue;
list_initramfs+=("$cinitramfs")
done
fi
}
## Detect microcode in "/boot"
detect_microcode()
{
## Arch original intel microcode
for aucode in "$(boot_dir)"/intel-ucode.img ; do
list_ucode+=("$aucode")
done
## Custom name microcode in GRUB_BTRFS_INTEL_UCODE
if [ ! -z "$microcode" ] ; then
for cucode in "${microcode[@]}" ; do
[[ ! -f /"$(boot_dir)"/"${cucode}" ]] && continue
list_ucode+=("$cucode")
done
fi
}
## Show full path snapshot or only name
path_snapshot()
{
case "${path_snapshot}" in
true) name_snapshot=("${snap_full_name}");;
*) name_snapshot=("${snap_full_name#*"/"}")
esac
}
## Title format in grub-menu
title_format()
{
case "${title_format}" in
p/d/n) title_menu="${prefixentry} ${snap_date_time} ${name_snapshot}";;
p/n/d) title_menu="${prefixentry} ${name_snapshot} ${snap_date_time}";;
p/d) title_menu="${prefixentry} ${snap_date_time}";;
p/n) title_menu="${prefixentry} ${name_snapshot}";;
d/n) title_menu="${snap_date_time} ${name_snapshot}";;
n/d) title_menu="${name_snapshot} ${snap_date_time}";;
p) title_menu="${prefixentry}";;
d) title_menu="${snap_date_time}";;
n) title_menu="${name_snapshot}";;
*) gettext_printf $"# Warning: GRUB_BTRFS_TITLE_FORMAT=${title_format}, syntax error \n" >&2
esac
}
## List of kernels, initramfs and microcode in snapshots
list_kernels_initramfs()
{
IFS=$'\n'
count_limit_snap=0
for item in $(snapshot_list); do
### fix: limit_snap_show=0
[[ ${limit_snap_show} -le 0 ]] && break;
IFS=$oldIFS
snap_full_name="$(echo "$item" | cut -d'|' -f2-)" # do not trim it to keep nice formatting
snap_dir_name="$(echo "$item" | cut -d'|' -f2)"
snap_dir_name="$(trim "$snap_dir_name")"
### ignore specific path during run "grub-mkconfig"
if [ ! -z "${ignore_specific_path}" ] ; then
for isp in ${ignore_specific_path[@]} ; do
[[ "${gbgmp}"/"${snap_dir_name}" == "${gbgmp}"/"${isp}"/* ]] && continue 2;
done
fi
### detect if /boot directory exists
[[ ! -d "$gbgmp/$snap_dir_name/boot" ]] && continue;
### show snapshot found during run "grub-mkconfig"
snap_date_time="$(echo "$item" | cut -d' ' -f1-2)"
snap_date_time="$(trim "$snap_date_time")"
if [[ "${show_snap_found}" = "true" ]]; then
gettext_printf $"# Found snapshot: %s\n" "$item" >&2 ;
fi
### Kernel (auto-detect + custom kernel)
unset list_kernel
detect_kernel
name_kernel=("${list_kernel[@]##*"/"}")
# echo "kernel = ${name_kernel[*]}"
if [[ "${harmonized_entries}" != "true" ]]; then
### Initramfs (autodetect + custom initramfs)
unset list_initramfs
detect_initramfs
name_initramfs=("${list_initramfs[@]##*"/"}")
# echo "initramfs = ${name_initramfs[*]}"
fi
### microcode (auto-detect + custom microcode)
unset list_ucode
detect_microcode
name_microcode=("${list_ucode[@]##*"/"}")
# echo "ucode = ${name_microcode[*]}"
### real path to boot
boot_dir_real_path="$(make_system_path_relative_to_its_root "$(boot_dir)")"
### Create menu entries
## name snapshot
path_snapshot
## title menu custom
title_format
# echo "${title_menu}"
if [[ "${harmonized_entries}" = "false" ]]; then
snapshots_entry
else
harmonized_snapshots_entry
fi
### Limit snapshots found during run "grub-mkconfig"
count_limit_snap=$((1+$count_limit_snap))
[[ $count_limit_snap -ge $limit_snap_show ]] && break;
done
IFS=$oldIFS
}
### END auto detect ###
### Start ###
gettext_printf "###### - Grub-btrfs: Auto-detect Start - ######\n" >&2 ;
### create mount point and mounts
[[ ! -d $gbgmp ]] && mkdir -p $gbgmp
mount -o subvolid=5 /dev/disk/by-uuid/$root_uuid $gbgmp/
### Create a menu in grub
echo "submenu '${submenuname}' {"
list_kernels_initramfs ;
## show total found snapshots
if [[ "${show_total_snap_found}" = "true" ]]; then
gettext_printf "# Found ${count_limit_snap} snapshot(s)\n" >&2 ;
fi
## if no snapshot found, show a warning
if [[ "${count_limit_snap}" = "0" ]]; then
echo " submenu '---> "No snapshot found : Press ESC to return previous menu" <---' { echo } ";
gettext_printf "# No snapshot found \n# make sure you have at least one snapshot \n# or please file a bug report at \"https://github.com/Antynea/grub-btrfs\"\n" >&2 ;
fi
echo "}"
## unmount mount point
umount $gbgmp
gettext_printf "###### - Grub-btrfs: Auto-detect End - ######\n" >&2 ;
### End ###

117
README.md
View File

@@ -1,4 +1,115 @@
grub-btrfs
==========
[![GitHub release](https://img.shields.io/github/release/Antynea/grub-btrfs.svg)](https://github.com/Antynea/grub-btrfs)
## grub-btrfs
grub-btrfs, add support for btrfs snapshots into grub menu
This is a version 2.xx of grub-btrfs
##### BTC donation address: 1Lbvz244WA8xbpHek9W2Y12cakM6rDe5Rt
##
### Description
grub-btrfs, Include btrfs snapshots at boot options. (grub menu)
##
### What does grub-btrfs v2.xx do :
Simple rollback using snapshots you made previously.
* Automatically List snapshots existing on root partition (btrfs).
* Automatically Detect if "/boot" is in separate partition.
* Automatically Detect kernel, initramfs and intel microcode in "/boot" directory on snapshots. (For custom name, see below.)
* Automatically Create corresponding "menuentry" in grub.cfg , which ensures a very easy rollback.
* Automatically detect snapper and use snapper's snapshot description if available.
##
### How to use it:
Add this lines to /etc/default/grub:
* GRUB_BTRFS_SUBMENUNAME="Arch Linux Snapshots"
(Name menu appearing in grub.)
* GRUB_BTRFS_PREFIXENTRY="Snapshot:"
(Add a name ahead your snapshots entries.)
* GRUB_BTRFS_DISPLAY_PATH_SNAPSHOT="true"
(Show full path snapshot or only name, weird reaction with snapper)
* GRUB_BTRFS_TITLE_FORMAT="p/d/n"
(Custom title, shows/hides p"prefix" d"date" n"name" in grub-menu, separator "/", custom order available)
* GRUB_BTRFS_NKERNEL=("vmlinuz-linux")
(Use only if you have a custom kernel name or auto-detect failed.)
* GRUB_BTRFS_NINIT=("initramfs-linux.img" "initramfs-linux-fallback.img")
(Use only if you have a custom initramfs name or auto-detect failed.)
* GRUB_BTRFS_INTEL_UCODE=("intel-ucode.img")
(Use only if you have custom intel-ucode or auto-detect failed.)
* GRUB_BTRFS_LIMIT="100"
(Limit the number of snapshots populated in the GRUB menu.)
* GRUB_BTRFS_SUBVOLUME_SORT="descending"
(Sort the found subvolumes by newest first ("descending") or oldest first ("ascending").
If "ascending" is chosen then the $GRUB_BTRFS_LIMIT oldest
subvolumes will populate the menu.)
* GRUB_BTRFS_SHOW_SNAPSHOTS_FOUND="true"
(Show snapshots found during run "grub-mkconfig")
* GRUB_BTRFS_SHOW_TOTAL_SNAPSHOTS_FOUND="true"
(Show Total number of snapshots found during run "grub-mkconfig")
* GRUB_BTRFS_IGNORE_SPECIFIC_PATH=("var/lib/docker" "nosnapshot")
(Ignore specific path during run "grub-mkconfig")
* GRUB_BTRFS_CREATE_ONLY_HARMONIZED_ENTRIES="false"
(Create entries with matching version number instead of all possible combinations of kernel and initramfs, very useful with debian-like distributions)
Generate grub.cfg (on Arch linux use grub-mkconfig -o /boot/grub/grub.cfg )
grub-btrfs automatically generates snapshots entries.
You will see it appear differents entries (e.g : Snapshot: 2018-01-03 15:08:41 @test1 )
##
### Automatically update grub
If you would like grub to automatically update when Snapper timeline snapshots and cleanups occur, simply install `10-update_grub.conf` in the following locations:
- `/etc/systemd/system/snapper-timeline.service.d/`
- `/etc/systemd/system/snapper-cleanup.service.d/`
Once the configuration files are in place, `systemctl daemon-reload` should be run to reload the units and make the changes active.
##
### Discussion
Pour les francophones : https://forums.archlinux.fr/viewtopic.php?f=18&t=17177
##
### Special thanks for assistance and contributions
* [maximbaz](https://github.com/maximbaz)
* [crossroads1112](https://github.com/crossroads1112)
* [penetal](https://github.com/penetal)
* [wesbarnett](https://github.com/wesbarnett)
* [Psykar](https://github.com/Psykar)
* [anyc](https://github.com/anyc)
* [daftaupe](https://github.com/daftaupe)
* [N-Parsons](https://github.com/N-Parsons)
##

Binary file not shown.