Giter Site home page Giter Site logo

johnramsden / zedenv Goto Github PK

View Code? Open in Web Editor NEW
62.0 9.0 9.0 347 KB

ZFS Boot Environment manager (new development moved to zectl)

Home Page: https://zedenv.readthedocs.io

License: BSD 3-Clause "New" or "Revised" License

Python 97.94% Shell 1.72% Makefile 0.34%
zfs zfsonlinux freebsd linux python3 python

zedenv's Introduction

zedenv

Future development has been moved to zectl

image

ZFS boot environment manager

Documentation for the project can be found at readthedocs.

zedenv is still experimental and should not be used on production systems.

Install

zedenv requires python 3.6+, pyzfscmds, and ZFS running as the root filesystem.

The system should also be configured in the format:

${zpool}/${optional_datasets}/${boot_environment_root}/${root_dataset}

For example, zpool/ROOT/default or zpool/sys/hostname/ROOT/default.

zedenv can be installed a few ways:

First, clone the git repos.

git clone https://github.com/johnramsden/pyzfscmds
git clone https://github.com/johnramsden/zedenv

Makefile and setup.py

To install without poluting your system, you can also create a directory somewhere and install in a venv, otherwise install to the system.

Optionally, create a venv and activate.

python3.6 -m venv venv
. venv/bin/activate

setup.py

Enter the repos and install.

cd pyzfscmds
python setup.py install

cd ../zedenv
python setup.py install

Makefile

Enter the packaging directory in the repos run make, pyzfscmds must be installed first.

cd pyzfscmds/packaging
make

cd ../../zedenv/packaging
make

How To Use

zedenv can be used to manage boot environments using ZFS. If your system is set up in a way compatible with boot environments, you can start using them right away.

Create and activate a new Boot Environment.

$ zedenv create default-0
$ zedenv activate default-0

This will make it the Boot Environment used on reboot.

$ zedenv list
Name       Active   Mountpoint   Creation
default    N        -            Wed-May-23-23:48-2018
default-0  R        /            Thu-May-24-23:54-2018

This can be shown with a list, command. The boot environment currently being used will have a 'N' in the active column signifying the boot environment is being used now. An 'R' in the active column means this environment will be used on reboot.

Bootloader Plugins

Bootloader plugins are available for:

zedenv's People

Contributors

benyanke avatar johnramsden avatar mkessler001 avatar slicer69 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zedenv's Issues

The 'zedenv==0.3.7' distribution was not found and is required by the application

I opened a comment in the AUR on this issue. Let me know if you need more information.

$ zedenv list Traceback (most recent call last): File "/usr/bin/zedenv", line 6, in <module> from pkg_resources import load_entry_point File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3251, in <module> def _initialize_master_working_set(): File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3234, in _call_aside f(*args, **kwargs) File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3263, in _initialize_master_working_set working_set = WorkingSet._build_master() File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 583, in _build_master ws.require(__requires__) File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 900, in require needed = self.resolve(parse_requirements(requirements)) File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 786, in resolve raise DistributionNotFound(req, requirers) pkg_resources.DistributionNotFound: The 'zedenv==0.3.7' distribution was not found and is required by the application

"zedenv destroy" fails if LC_TIME is not C

zedenv fails destroying a BE if LC_TIME is not C (e.g. de_DE.UTF-8 (german)).
I think it's better if LC_TIME (or LC_ALL ?) is set to "C" in the script.

# zedenv create x

# env LC_ALL="" LC_TIME=de_DE.UTF-8 zedenv destroy x
Do you really want to destroy 'x'?
This action will be permanent.

Destroy 'zroot/ROOT/x'? [y/N]: y

Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/zedenv/cli/destroy.py", line 105, in get_clone_origin
    "%a %b %d %H:%M %Y")
  File "/usr/lib/python3.7/_strptime.py", line 577, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/usr/lib/python3.7/_strptime.py", line 359, in _strptime
    (data_string, format))
ValueError: time data 'Do Nov 29 18:11 2018' does not match format '%a %b %d %H:%M %Y'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/zedenv", line 11, in <module>
    load_entry_point('zedenv==0.3.3', 'console_scripts', 'zedenv')()
  File "/usr/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 717, in main
During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/zedenv", line 11, in <module>
    load_entry_point('zedenv==0.3.3', 'console_scripts', 'zedenv')()
  File "/usr/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.7/site-packages/zedenv/cli/destroy.py", line 364, in cli
    noop)
  File "/usr/lib/python3.7/site-packages/zedenv/cli/destroy.py", line 281, in zedenv_destroy
    clone_origin = get_clone_origin(destroy_dataset)
  File "/usr/lib/python3.7/site-packages/zedenv/cli/destroy.py", line 109, in get_clone_origin
    "message": f"Failed to parse time from origin {origin_property}\n{e}"
UnboundLocalError: local variable 'e' referenced before assignment

# env LC_ALL=C zedenv destroy x
(success)

(FYI: )

# env LC_ALL= LC_TIME=de_DE.UTF-8 date
Do 29. Nov 18:28:59 CET 2018
# env LC_ALL=C date
Thu Nov 29 18:29:05 CET 2018

update-grub doesn't work without /mnt/boot/zfsenv

legacy system using grub plugin. The only /etc/grub.d files executeable are 00_header and the zedenv file.

# update-grub
Generating grub configuration file ...
Traceback (most recent call last):
  File "/etc/grub.d/05_zfs_linux.py", line 718, in <module>
    grub = Generator()
  File "/etc/grub.d/05_zfs_linux.py", line 572, in __init__
    self.boot_list = self.get_boot_environments_boot_list()
  File "/etc/grub.d/05_zfs_linux.py", line 632, in get_boot_environments_boot_list
    for e in os.listdir(self.boot_env_kernels)]
FileNotFoundError: [Errno 2] No such file or directory: '/mnt/boot/zfsenv'
root@e6430:~# mkdir /mnt/boot/zfsenv

The debian system I am testing zedenv had /mnt/boot but not /mnt/boot/zfsenv.
I did mkdir /mnt/boot/zfsenv and update-grub worked as expected after that.

edit: It was completely disastrous because this bug causes "apt upgrade" to bail out of operations.
If the installation method is relevant, i cloned all the repos and used "python setup.py install"

Bootloader entries should be created on `create`, not `activate`

I'm talking about the systemd-boot plugin specifically, but this can/should be treated globally.

It feels more intuitive that when a boot env is created, it should be available in the bootloader as an entry. However, the bootloader entry/kernel directory/etc aren't created until activate is run.

I'm looking through the code, and this certainly seems possible. I'm very tempted to write up a PR to make this change, but before I do, I wanted to discuss the feasibility and impact of making such a change.

The "edit BE /fstab and create booloader entries" step seems pretty tied to the mid-activate step. It can easily be moved to post-create, but a LOT of other references will need to be updated and some of the CLI code possibly refactored.

I'm curious as to why the decision was made to modify the BE and create bootloader entries during activation instead of creation?

Thoughts?

get --defaults fails

I have installed zedenv-git and the grub-generators branch of zedenv-grub as per these instructions on an ALEZ 0.4 VM:

Building zedenv packages from git under Arch

mkdir ~/src && cd ~/src

# Build pyzfscmds arch package
git clone https://github.com/johnramsden/pyzfscmds.git
cd pyzfscmds/packaging/arch/
makepkg -s -p PKGBUILD-git
# Install pyzfscmds package
sudo pacman -U python-pyzfscmds-git-r38.8423bca-1-any.pkg.tar.xz

# Build zedenv Arch package
cd ~/src
git clone https://github.com/johnramsden/zedenv.git
cd zedenv/packaging/arch/
makepkg -s -p PKGBUILD-git
# Install zedenv package
sudo pacman -U zedenv-git-r142.8af5752-1-any.pkg.tar.xz

# Build grub-generators branch of zedenv-grub
cd ~/src
git clone https://github.com/johnramsden/zedenv-grub.git
cd zedenv-grub/
git checkout grub-generators
cd packaging/arch/
makepkg -s -p PKGBUILD-git
sudo pacman -U zedenv-grub-git-r124.7011da2-1-any.pkg.tar.xz

According to your instructions at https://github.com/johnramsden/zedenv-grub/blob/docs/README.rst I really need to configure the grub plugin before I use zedenv but I have just tried running zedenv get --defaults as both root and a normal user and I get this error:

[root@archlinux zedenv-grub]# zedenv get --defaults
Traceback (most recent call last):
  File "/usr/bin/zedenv", line 11, in <module>
    load_entry_point('zedenv==0.3.1', 'console_scripts', 'zedenv')()
  File "/usr/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.7/site-packages/zedenv/cli/get.py", line 172, in cli
    zedenv.lib.be.root())
  File "/usr/lib/python3.7/site-packages/zedenv/cli/get.py", line 115, in zedenv_get
    for bl in zedenv.lib.configure.get_bootloader_properties():
  File "/usr/lib/python3.7/site-packages/zedenv/lib/configure.py", line 28, in get_bootloader_properties
    "properties": plugins[p].allowed_properties
AttributeError: type object 'GRUB' has no attribute 'allowed_properties'

Fails to find `default` entry in `loader.conf` with preceding whitespaces (systemd-boot)

zedenv fails to find the default entry in the loader.conf file during activating a BE if the line has preceding white spaces.
See l.226 of plugins/systemdboot.py.

    line_num = next((l for l, val in enumerate(conf_list)
        if val.split(' ', 1)[0] == "default"), None)

val.split() returns '' (empty string) if the line contains preceding white spaces.
Note that ALEZ makes a /mnt/efi/loader/loader.conf with preceding white spaces.

I think the preceding white spaces should be omitted before split().


FYI: The manpage of loader.conf(5) says only

Each configuration file must consist of an option name, followed by whitespace, and the option value.

It seems that systemd removes the leading (and trailing) white spaces while reading loader.conf in
boot/efi/boot.c.

GrubBE - Booting on zedenv created BE fails with "failed to mount real root device"

I can boot fine to the default entry, but when booting to any of the zedenv created BE entries in GRUB I get that error.

The entry looks like:
linux /ROOT/31-03-19-Update@/boot/vmlinuz-linux root=ZFS=zroot/ROOT/31-03-19-Update rw radeon.si_support=0 amdgpu.si_support=1 quiet
echo 'Loading initial ramdisk ...'
initrd /ROOT/31-03-19-Update@/boot/initramfs-linux.img /ROOT/31-03-19-Update@/boot/intel-ucode.img

[ikidd@archlinux ~]$ zedenv list
Name Active Mountpoint Creation
default NR / Sun-Mar-24-1:51-2019
Base_Arch_KDE-Linux5.0.4 - Mon-Mar-25-0:23-2019
Backup_04-7-19 - Sun-Apr-7-11:32-2019

I mounted that zedenv via zedenv mount and looked at fstab, perhaps I don't understand how the process works but I'd have expected that would have altered the fstab to use the snapshot locations not zroot/ROOT/default still.

I haven't gone through the script well enough to understand what it does yet when it creates a BE and alters GRUB.

zedenv isn't able to destroy BE's that have dependant clones

reproduce:

assuming the current boot environment is "env" e.g. mounted rpool/root/env,

zedenv create new-env
zedenv activate new-env
reboot
zedenv create another-new-env
zedenv activate env
reboot
zedenv destroy new-env

result:
zedenv will be unable to destroy "new-env" because it has a dependant clone "another-new-env"

workaround:
zfs promote another-new-env && zedenv destroy new-env

If this is intended behavior, please close this bug report.

Prompt user to set default bootloader if undefined when using create or activate

Currently zedenv lets the user create a new BE and supposedly activate it before the default bootloader setting has been defined. In my case I had zedenv and the grub plugin installed, running GRUB bl. I created a new BE and tried to activate it but it failed because I forgot to set grub as the default bl with zedenv first.

If autodetecting the bootloader is tricky, then zedenv should prompt the user on how to set the default bootloader before letting them create or activate a BE.

zedenv description

zedenv's description on the AUR currently is:

"Utility to manage Boot Environments using ZFS"

I think that's slightly incorrectly worded, shouldn't it be

"Utility to manage ZFS Boot Environments"

It seems the GRUB plugin is still missing from the AUR - I presume you've just not had the time to upload it yet?

malformed conffile (systemd-boot)

The commands

# zedenv create a
# zedenv activate a
# zedenv create XXX
# zedenv activate XXX

generate a malformed conffile like this (/mnt/efi/loader/entries/zedenv-XXX.conf):

    title           [XXX] (Arch Linux)
    linux           /env/zedenv-XXX/vmlinuz-linux
    initrd          /env/zedenv-XXX/initrXXXmfs-linux.img
    options         zfs=zroot/ROOT/XXX rw

i.e. the entry for initrd is not correct.
Additional execution of the following commands

# zedenv create vm
# zedenv activate vm
# zedenv create YYY
# zedenv activate YYY

generate a conffile like this (/mnt/efi/loader/entries/zedenv-YYY.conf):

    title           [YYY] (Arch Linux)
    linux           /env/zedenv-YYY/YYYlinuz-linux
    initrd          /env/zedenv-YYY/initrYYYmfs-linux.img
    options         zfs=zroot/ROOT/YYY rw

If e then ZZZ, first 2 lines will be:

    titlZZZ           [ZZZ] (Arch Linux)
    linux           /ZZZnv/zZZZdZZZnv-ZZZ/ZZZlinuz-linux

I think this problem causes that replace() is used in plugins/systemdboot.py:

new_entry_list = [l.replace(self.old_boot_environment, self.boot_environment)
                  for l in old_conf_list]

Version: aur/zedenv 0.3.1-1 (1, 0.045712) on Arch Linux

zfs-auto-snapshot conflict

After installing and enabling zfs-auto-snapshot, typing update-grub fails.

root@e6430:/etc/default#

sudo !!
sudo update-grub
Generating grub configuration file ...
/mnt/boot/zfsenv/zedenv-testing
Failed mounting dataset to '/mnt/boot/zfsenv/zedenv-root@zfs-auto-snap_frequent-2018-11-08-0845'.
Failed to get mount data.
Command '['mount', '-t', 'zfs', '-o', 'zfsutil', 'rpool/root/root@zfs-auto-snap_frequent-2018-11-08-0845', '/mnt/boot/zfsenv/zedenv-root@zfs-auto-snap_frequent-2018-11-08-0845']' returned non-zero exit status 1.
.
1
root@e6430:/etc/default#

FYI what follows is a current listing via zfs list -t snap:

rpool@zfs-auto-snap_frequent-2018-11-08-0845 0B - 96K -
rpool@zfs-auto-snap_frequent-2018-11-08-0900 0B - 96K -
rpool@zfs-auto-snap_frequent-2018-11-08-0915 0B - 96K -
rpool@zfs-auto-snap_hourly-2018-11-08-0917 0B - 96K -
rpool@zfs-auto-snap_frequent-2018-11-08-0930 0B - 96K -
rpool/boot@zfs-auto-snap_frequent-2018-11-08-0845 0B - 96K -
rpool/boot@zfs-auto-snap_frequent-2018-11-08-0900 0B - 96K -
rpool/boot@zfs-auto-snap_frequent-2018-11-08-0915 0B - 96K -
rpool/boot@zfs-auto-snap_hourly-2018-11-08-0917 0B - 96K -
rpool/boot@zfs-auto-snap_frequent-2018-11-08-0930 0B - 96K -
rpool/boot/grub@zfs-auto-snap_frequent-2018-11-08-0845 0B - 7.48M -
rpool/boot/grub@zfs-auto-snap_frequent-2018-11-08-0900 0B - 7.48M -
rpool/boot/grub@zfs-auto-snap_frequent-2018-11-08-0915 0B - 7.48M -
rpool/boot/grub@zfs-auto-snap_hourly-2018-11-08-0917 0B - 7.48M -
rpool/boot/grub@zfs-auto-snap_frequent-2018-11-08-0930 8K - 7.48M -
rpool/ext4_backup@zfs-auto-snap_frequent-2018-11-08-0845 0B - 11.1G -
rpool/ext4_backup@zfs-auto-snap_frequent-2018-11-08-0900 0B - 11.1G -
rpool/ext4_backup@zfs-auto-snap_frequent-2018-11-08-0915 0B - 11.1G -
rpool/ext4_backup@zfs-auto-snap_hourly-2018-11-08-0917 0B - 11.1G -
rpool/ext4_backup@zfs-auto-snap_frequent-2018-11-08-0930 0B - 11.1G -
rpool/home@zfs-auto-snap_frequent-2018-11-08-0845 0B - 96K -
rpool/home@zfs-auto-snap_frequent-2018-11-08-0900 0B - 96K -
rpool/home@zfs-auto-snap_frequent-2018-11-08-0915 0B - 96K -
rpool/home@zfs-auto-snap_hourly-2018-11-08-0917 0B - 96K -
rpool/home@zfs-auto-snap_frequent-2018-11-08-0930 0B - 96K -
rpool/home/adam@zfs-auto-snap_frequent-2018-11-08-0845 9.57M - 1.35G -
rpool/home/adam@zfs-auto-snap_frequent-2018-11-08-0900 2.46M - 1.35G -
rpool/home/adam@zfs-auto-snap_frequent-2018-11-08-0915 1.79M - 1.35G -
rpool/home/adam@zfs-auto-snap_hourly-2018-11-08-0917 3.42M - 1.35G -
rpool/home/adam@zfs-auto-snap_frequent-2018-11-08-0930 4.32M - 1.35G -
rpool/root@zfs-auto-snap_frequent-2018-11-08-0845 0B - 96K -
rpool/root@zfs-auto-snap_frequent-2018-11-08-0900 0B - 96K -
rpool/root@zfs-auto-snap_frequent-2018-11-08-0915 0B - 96K -
rpool/root@zfs-auto-snap_hourly-2018-11-08-0917 0B - 96K -
rpool/root@zfs-auto-snap_frequent-2018-11-08-0930 0B - 96K -
rpool/root/stable@2018-11-07-01-920008 200M - 2.01G -
rpool/root/stable@zfs-auto-snap_frequent-2018-11-08-0845 420K - 1.87G -
rpool/root/stable@zfs-auto-snap_frequent-2018-11-08-0900 392K - 1.87G -
rpool/root/stable@zfs-auto-snap_frequent-2018-11-08-0915 352K - 1.87G -
rpool/root/stable@zfs-auto-snap_hourly-2018-11-08-0917 356K - 1.87G -
rpool/root/stable@zfs-auto-snap_frequent-2018-11-08-0930 20.9M - 1.87G -
rpool/root/testing@zfs-auto-snap_frequent-2018-11-08-0845 0B - 2.13G -
rpool/root/testing@zfs-auto-snap_frequent-2018-11-08-0900 0B - 2.13G -
rpool/root/testing@zfs-auto-snap_frequent-2018-11-08-0915 0B - 2.13G -
rpool/root/testing@zfs-auto-snap_hourly-2018-11-08-0917 0B - 2.13G -
rpool/root/testing@zfs-auto-snap_frequent-2018-11-08-0930 0B - 2.13G -

zedenv UI

It would be nice to have both an ncurses and a GUI eg Qt/pyQt or similar interface to easily manage zedenv BEs with.

I suspect we can borrow the Qt one from PCBSD / TrueOS / whatever they are calling it today with only minor modifications to the source.

Problem keeping DataSet structure

Hello.

I have mounted an arch Root ZFS with zfsbootmenu (which is super nice).

this is part of the structure of my zfs root

zroot/ROOT/lightdm                                  7.86G  93.0G     7.37G  /
zroot/ROOT/lightdm/srv                                 0B  93.0G      208K  /srv
zroot/ROOT/lightdm/usr                               192K  93.0G      192K  /usr
zroot/ROOT/lightdm/usr/local                         192K  93.0G      192K  /usr/local
zroot/ROOT/lightdm/var                              2.98M  93.0G      192K  /var
zroot/ROOT/lightdm/var/games                         192K  93.0G      192K  /var/games
zroot/ROOT/lightdm/var/lib                          2.42M  93.0G      960K  /var/lib
zroot/ROOT/lightdm/var/lib/AccountsService           244K  93.0G      244K  /var/lib/AccountsService
zroot/ROOT/lightdm/var/lib/docker                    696K  93.0G      696K  /var/lib/docker
zroot/ROOT/lightdm/var/lib/libvirt                   192K  93.0G      192K  /var/lib/libvirt
zroot/ROOT/lightdm/var/lib/lxc                       192K  93.0G      192K  /var/lib/lxc
zroot/ROOT/lightdm/var/lib/nfs                       192K  93.0G      192K  /var/lib/nfs
zroot/ROOT/lightdm/var/spool                         192K  93.0G      192K  /var/spool
zroot/ROOT/lightdm/var/www                           192K  93.0G      192K  /var/www

When I create a new environment, the dataset tree becomes flat

jorpilo@legion ~ [1]> sudo zedenv create test1
jorpilo@legion ~> zfs list -r zroot/ROOT/test1
NAME                               USED  AVAIL     REFER  MOUNTPOINT
zroot/ROOT/test1                    24K  93.0G     7.37G  /
zroot/ROOT/test1/AccountsService     0B  93.0G      244K  /AccountsService
zroot/ROOT/test1/docker              8K  93.0G      696K  /docker
zroot/ROOT/test1/games               0B  93.0G      192K  /games
zroot/ROOT/test1/lib                 8K  93.0G      992K  /lib
zroot/ROOT/test1/libvirt             0B  93.0G      192K  /libvirt
zroot/ROOT/test1/local               0B  93.0G      192K  /local
zroot/ROOT/test1/lxc                 0B  93.0G      192K  /lxc
zroot/ROOT/test1/nfs                 0B  93.0G      192K  /nfs
zroot/ROOT/test1/spool               0B  93.0G      192K  /spool
zroot/ROOT/test1/srv                 0B  93.0G      208K  /srv
zroot/ROOT/test1/usr                 0B  93.0G      192K  /usr
zroot/ROOT/test1/var                 0B  93.0G      192K  /var
zroot/ROOT/test1/www                 0B  93.0G      192K  /www
jorpilo@legion ~> zfs list -r zroot/ROOT/lightdm
NAME                                         USED  AVAIL     REFER  MOUNTPOINT
zroot/ROOT/lightdm                          7.86G  93.0G     7.37G  /
zroot/ROOT/lightdm/srv                         0B  93.0G      208K  /srv
zroot/ROOT/lightdm/usr                       192K  93.0G      192K  /usr
zroot/ROOT/lightdm/usr/local                 192K  93.0G      192K  /usr/local
zroot/ROOT/lightdm/var                      3.01M  93.0G      192K  /var
zroot/ROOT/lightdm/var/games                 192K  93.0G      192K  /var/games
zroot/ROOT/lightdm/var/lib                  2.45M  93.0G      992K  /var/lib
zroot/ROOT/lightdm/var/lib/AccountsService   244K  93.0G      244K  /var/lib/AccountsService
zroot/ROOT/lightdm/var/lib/docker            696K  93.0G      696K  /var/lib/docker
zroot/ROOT/lightdm/var/lib/libvirt           192K  93.0G      192K  /var/lib/libvirt
zroot/ROOT/lightdm/var/lib/lxc               192K  93.0G      192K  /var/lib/lxc
zroot/ROOT/lightdm/var/lib/nfs               192K  93.0G      192K  /var/lib/nfs
zroot/ROOT/lightdm/var/spool                 192K  93.0G      192K  /var/spool
zroot/ROOT/lightdm/var/www                   192K  93.0G      192K  /var/www

Why zedenv doesn't keep my folder structure and simply just flat all my file system on root? The datasets that were supposed to mount to /var/lib now get mount on /root

Possibly incorrect zfs/zpool parsing

I'm using this on a Void system, running ZFS 0.7.9 and kernel 4.16.12.

zpool get bootfs storage
NAME     PROPERTY  VALUE   SOURCE
storage  bootfs    -       default
zpool get bootfs boot
NAME  PROPERTY  VALUE             SOURCE
boot  bootfs    boot/ROOT/test-1  local
 zfs list
NAME                                       USED  AVAIL  REFER  MOUNTPOINT
boot                                      39.5G   422G    96K  none
boot/ROOT                                 4.98G   422G    96K  none
boot/ROOT/test-1                          4.98G   422G  4.21G  /
boot/ROOT/void                            1.27M   422G  4.21G  /
boot/home                                 34.3G   422G  29.0G  /home
storage                                    217G   705G   104K  /storage
storage/backups                            190G   705G   104K  /storage/backups
storage/backups/auri                      7.62G   705G  7.62G  /storage/backups/auri
storage/backups/fela                       144G   705G   104K  /storage/backups/fela
storage/backups/fela/storage               144G   705G   138G  /storage/backups/fela/storage
storage/backups/menegroth                 38.3G   705G   104K  /storage/backups/menegroth
storage/backups/menegroth/boot            4.93G   705G    96K  /storage/backups/menegroth/boot
storage/backups/menegroth/boot/ROOT       4.93G   705G   104K  /storage/backups/menegroth/boot/ROOT
storage/backups/menegroth/boot/ROOT/void  4.93G   705G  4.20G  /storage/backups/menegroth/boot/ROOT/void
storage/backups/menegroth/home            33.3G   705G  29.0G  /storage/backups/menegroth/home

I created and then activated boot/ROOT/test-1, and then booted from it via root=zfs:AUTO in GRUB. When I use zedenv to list boot environments, I get this:

./zfs-bootenv/bin/zedenv list
Name    Active   Mountpoint                                 Creation              
void             /storage/backups/menegroth/boot/ROOT/void  Wed-May-9-19:54-2018  
test-1  NR       /                                          Wed-May-30-17:25-2018 

I'm able to activate the 'void' environment successfully, which then changes the output of zedenv list.

# ./zfs-bootenv/bin/zedenv activate void
# ./zfs-bootenv/bin/zedenv list
Name    Active   Mountpoint   Creation              
void    R        -            Wed-May-9-19:54-2018  
test-1  N        /            Wed-May-30-17:25-2018

The various zfs filesystems under storage are created via znapzend. I'll be glad to provide additional debugging details if you need them.

I've done otherwise limited testing, but so far this fills a great niche in ZFS Linux land. Well done!

"zedenv activate" fails or makes a malformed conffile for a BE with a numerical name (systemd-boot)

"zedenv activate" fails for a BE whose name is 1:

# zedenv create 1
# zedenv activate 1
Replaced fstab entry:
/mnt/efi/env/zedenv-BE20181130  /boot           none            rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro,bind   0 0

With new entry:
/mnt/efi/env/zedenv-1   /boot           none            rw,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro,bind   0 0

In the boot environment's '/etc/fstab'.

Would you like to edit the generated 'fstab'? [Y/n]: y
Moved new '/etc/fstab' into place. A copy of the original '/etc/fstab' can be found at '/etc/fstab.bak'.

Using existing entry zedenv-x as template taking best guess at creating one at zedenv-1.conf

Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/zedenv/cli/activate.py", line 369, in cli
    noop)
  File "/usr/lib/python3.7/site-packages/zedenv/cli/activate.py", line 305, in zedenv_activate
    bootloader_plugin.post_activate()
  File "/usr/lib/python3.7/site-packages/zedenv/plugins/systemdboot.py", line 327, in post_activate
    self.edit_bootloader_entry(t_esp)
  File "/usr/lib/python3.7/site-packages/zedenv/plugins/systemdboot.py", line 134, in edit_bootloader_entry
    r"\1\2\3" + self.boot_environment + r"\5")
  File "/usr/lib/python3.7/site-packages/zedenv/plugins/systemdboot.py", line 63, in __config_replace
    new_conf_list[l[0]] = re.sub(regex, regex_replace, config[l[0]])
  File "/usr/lib/python3.7/re.py", line 192, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "/usr/lib/python3.7/re.py", line 309, in _subx
    template = _compile_repl(template, pattern)
  File "/usr/lib/python3.7/re.py", line 300, in _compile_repl
    return sre_parse.parse_template(repl, pattern)
  File "/usr/lib/python3.7/sre_parse.py", line 1018, in parse_template
    addgroup(int(this[1:]), len(this) - 1)
  File "/usr/lib/python3.7/sre_parse.py", line 962, in addgroup
    raise s.error("invalid group reference %d" % index, pos)
re.error: invalid group reference 34 at position 5

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/zedenv", line 11, in <module>
    load_entry_point('zedenv==0.3.3', 'console_scripts', 'zedenv')()
  File "/usr/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python3.7/site-packages/zedenv/cli/activate.py", line 369, in cli
    noop)
  File "/usr/lib/python3.7/site-packages/zedenv/lib/check.py", line 79, in __exit__
    if self.pidfd:
AttributeError: 'Pidfile' object has no attribute 'pidfd'

If I create a BE 2000 and try to active it, then zedenv makes a malformed conffile:

# zedenv create 2000
# zedenv activate 2000

Replaced fstab entry:
(snip)
Would you like to edit the generated 'fstab'? [Y/n]:
Moved new '/etc/fstab' into place. A copy of the original '/etc/fstab' can be found at '/etc/fstab.bak'.

Using existing entry zedenv-BE20181130 as template taking best guess at creating one at zedenv-2000.conf

Replacing old entry with:
        title           Ð00] (Arch Linux)
        linux           Ð00/vmlinuz-linux
        initrd          Ð00/initramfs-linux.img
        options         zfs=zroot/ROOT/2000 rw
.

Would you like to edit the generated bootloader config? [Y/n]:
(snip)

If I open the file with vi, I saw:

        title           \303\22000] (Arch Linux)
        linux           \303\22000/vmlinuz-linux
        initrd          \303\22000/initramfs-linux.img
        options         zfs=zroot/ROOT/2000 rw

Here \303 and \220 are a single character respectively (i.e. the first line is ... '\303' '\220' '0' '0' ']' ...).
I think the regular expression(s) (in plugins/systemdboot.py ?) does not work as you expected.

Add support for separate ZFS boot pool on second partition

At the moment, Grub supports only a subset of the ZFS features. This is reason why the ZoL-Guide suggests to use a separate ZFS pool to store grub and the kernel / ramdisk files.

The current version of zedenv offers only two modes:

  • storing the kernel files within a subfolder of the actual root dataset
  • using a second partition with a pre-defined folder structure.

To make this work with a second ZFS pool on a different partition, it requires some fixes in this repository and zedenv-grub. I've already looked in your code and got a working solution. Please see my solution only as suggestion how this problem could be solved. I'm currently in the cleanup phase and I'm going to create a pull request tomorrow for both repositories.

Current setup

This is the setup I'm using:

  • 1st partition EFI
  • 2nd partition ZFS - bpool
bpool/boot/env/zedenv-BE1
bpool/boot/env/zedenv-BE2
bpool/boot/env/zedenv-...
bpool/boot/grub
  • 3rd partition ZFS - rpool (optional, this partition can be encrypted with LUKS)
rpool/home
rpool/home/root
rpool/opt
rpool/root
rpool/root/BE1
rpool/root/BE2
rpool/root/...
rpool/var
...

Generating grub.cfg

I've set org.zedenv.grub:boot=/boot to mount the boot-env-tree temporary at /boot/zfsenv/zedenv-BE....

05_zfs_linux.py uses then the second partition for set root= ... and the kernel and ramdisk can be successfully loaded by grub at boot time.

To generate the grub entries, all boot datasets (including the current one mounted at /boot) are mounted at the temporary subfolder /boot/zfsenv.

Creating / Destroying / Renaming

The same operation is executed to the corresponding boot dataset if this mode has been recognized.

Mount

The boot dataset must be mounted after the root dataset at {mountpoint}/boot.

Unmount

The boot dataset must be unmounted before the root dataset.

Mounting /boot at startup

As I'm currently working under Ubuntu, I use systemd in combination with /etc/fstab to mount the datasets at the correct time. Based on the description from the ZoL-Guide:

  • Create zfs-import-bpool.service for importing bpool
  • Create a shell script with the following content:
# Note: I had to add `zedenv list -a` which displays only the active boot environment.
BE=`zedenv list -H -a | cut -f1`
/bin/mount -t zfs "bpool/boot/env/zedenv-$BE" /boot
  • Create zfs-import-zedenv-boot-env.service which calls the custom shell script from the previous step.
  • Define some datasets as legacy and add them in /etc/fstab.
  • For bpool/boot/grub, use x-systemd.requires=zfs-import-zedenv-boot-env.service to make sure /boot is mounted before /boot/grub.

Best regards
Markus

Unable to create snapshot

When running "zedenv create on a pool called "mydata" the command returns the error

"Failed to create snapshot mydata/mydata@2018-05-30"

This appears to be a problem with mydata not having a volume also called "mydata". Ideally, the zedenv command should be trying to create a snapshot called "mydata@2018-05-30".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.