Skip to content

Commit

Permalink
Add remove boot dir to systemd-boot
Browse files Browse the repository at this point in the history
Move common code to library as well.
  • Loading branch information
johnramsden committed Jun 7, 2018
1 parent bf3783f commit 2453c38
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 55 deletions.
2 changes: 2 additions & 0 deletions tests/cli/test_destroy.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ def test_boot_environment_destroyed(root_dataset, created_boot_environment):
verbose = True
noconfirm = True
noop = True
bootloader = None

zedenv.cli.destroy.zedenv_destroy(created_boot_environment,
parent_dataset,
root_dataset,
bootloader,
verbose,
noconfirm,
noop)
Expand Down
52 changes: 2 additions & 50 deletions zedenv/cli/activate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys

import click
import platform

import pyzfscmds.cmd
import pyzfscmds.system.agnostic
import pyzfscmds.utility
Expand All @@ -17,54 +17,6 @@
from zedenv.lib.logger import ZELogger


def get_bootloader(boot_environment: str,
old_boot_environment: str,
bootloader: str,
verbose: bool,
noconfirm: bool,
noop: bool,
be_root: str):
bootloader_plugin = None
if bootloader:
plugins = zedenv.lib.configure.get_plugins()
if bootloader in plugins:
ZELogger.verbose_log({
"level": "INFO",
"message": ("Configuring boot environment "
f"bootloader with {bootloader}\n")
}, verbose)
if platform.system().lower() in plugins[bootloader].systems_allowed:
try:
bootloader_plugin = plugins[bootloader]({
'boot_environment': boot_environment,
'old_boot_environment': old_boot_environment,
'bootloader': bootloader,
'verbose': verbose,
'noconfirm': noconfirm,
'noop': noop,
'boot_environment_root': be_root
})
except ValueError as e:
ZELogger.log({
"level": "EXCEPTION",
"message": f"Failed to run plugin {bootloader}\n{e}\n"
}, exit_on_error=True)
else:
ZELogger.log({
"level": "EXCEPTION",
"message": (f"The plugin {bootloader} is "
f"not valid for {platform.system().lower()}\n")
}, exit_on_error=True)
else:
ZELogger.log({
"level": "EXCEPTION",
"message": f"bootloader type {bootloader} does not exist\n"
"Check available plugins with 'zedenv --plugins'\n"
}, exit_on_error=True)

return bootloader_plugin


def mount_and_modify_dataset(dataset: str,
verbose: bool = False,
noop: bool = False,
Expand Down Expand Up @@ -268,7 +220,7 @@ def zedenv_activate(boot_environment: str,

bootloader_plugin = None
if bootloader:
bootloader_plugin = get_bootloader(
bootloader_plugin = zedenv.lib.configure.get_bootloader(
boot_environment, current_be, bootloader, verbose, noconfirm, noop,
boot_environment_root
)
Expand Down
37 changes: 35 additions & 2 deletions zedenv/cli/destroy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from typing import Optional

import zedenv.lib.configure
import zedenv.lib.be
import zedenv.lib.check
from zedenv.lib.logger import ZELogger
Expand Down Expand Up @@ -174,6 +175,7 @@ def destroy_origin_snapshots(destroy_dataset, be_pool, origin_snaps, noop, verbo
def zedenv_destroy(target: str,
be_root: str,
root_dataset: str,
bootloader: Optional[str],
verbose: Optional[bool],
noconfirm: Optional[bool],
noop: Optional[bool]):
Expand All @@ -192,10 +194,21 @@ def zedenv_destroy(target: str,
"message": f"The destroy target {target} does not exist."
}, exit_on_error=True)

if zedenv.lib.be.is_current_boot_environment(target):
current_be = None
zpool = zedenv.lib.be.dataset_pool(destroy_dataset)
try:
current_be = pyzfscmds.utility.dataset_child_name(
zedenv.lib.be.bootfs_for_pool(zpool))
except RuntimeError:
ZELogger.log({
"level": "EXCEPTION",
"message": f"Cannot destroy the active boot environment '{target}'."
"message": f"Failed to get active boot environment'\n"
}, exit_on_error=True)

if current_be == target:
ZELogger.log({
"level": "EXCEPTION",
"message": f"Cannot destroy current active environment '{target}'."
}, exit_on_error=True)

if pyzfscmds.system.agnostic.dataset_mountpoint(destroy_dataset) == "/":
Expand All @@ -210,6 +223,19 @@ def zedenv_destroy(target: str,
f"Destroy '{destroy_dataset}'?", abort=True)
click.echo()

bootloader_set = zedenv.lib.be.get_property(destroy_dataset, "org.zedenv:bootloader")
if not bootloader and bootloader_set:
bootloader = bootloader_set if bootloader_set != '-' else None

bootloader_plugin = None
if bootloader:
bootloader_plugin = zedenv.lib.configure.get_bootloader(
target, current_be, bootloader, verbose, noconfirm, noop, be_root)
ZELogger.verbose_log({
"level": "INFO",
"message": f"Using plugin {bootloader}\n"
}, verbose)

if ds_is_snapshot:
if not noop:
try:
Expand Down Expand Up @@ -289,6 +315,9 @@ def zedenv_destroy(target: str,
if destroy_origin_snapshot:
destroy_origin_snapshots(destroy_dataset, be_pool, origin_snaps, noop, verbose)

if bootloader:
bootloader_plugin.post_destroy(target)

ZELogger.verbose_log({
"level": "INFO",
"message": f"Destroyed boot environment {target} successfully.\n"
Expand All @@ -306,9 +335,12 @@ def zedenv_destroy(target: str,
@click.option('--noop', '-n',
is_flag=True,
help="Print what would be destroyed but don't apply.")
@click.option('--bootloader', '-b',
help="Use bootloader type.")
@click.argument('boot_environment')
def cli(boot_environment: str,
verbose: Optional[bool],
bootloader: Optional[str],
# unmount: Optional[bool],
noconfirm: Optional[bool],
noop: Optional[bool]):
Expand All @@ -320,6 +352,7 @@ def cli(boot_environment: str,
zedenv_destroy(boot_environment,
zedenv.lib.be.root(),
pyzfscmds.system.agnostic.mountpoint_dataset("/"),
bootloader,
verbose,
noconfirm,
noop)
53 changes: 52 additions & 1 deletion zedenv/lib/configure.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,65 @@
import pkg_resources
import platform

from zedenv.lib.logger import ZELogger


# Import plugins
def get_plugins():
# https://packaging.python.org/guides/packaging-namespace-packages/
# https://packaging.python.org/guides/creating-and-discovering-plugins/

plugins = dict()
plugins = {}

for entry_point in pkg_resources.iter_entry_points('zedenv.plugins'):
plugins[entry_point.name] = entry_point.load()

return plugins


def get_bootloader(boot_environment: str,
old_boot_environment: str,
bootloader: str,
verbose: bool,
noconfirm: bool,
noop: bool,
be_root: str):
bootloader_plugin = None
if bootloader:
plugins = get_plugins()
if bootloader in plugins:
ZELogger.verbose_log({
"level": "INFO",
"message": ("Configuring boot environment "
f"bootloader with {bootloader}\n")
}, verbose)
if platform.system().lower() in plugins[bootloader].systems_allowed:
try:
bootloader_plugin = plugins[bootloader]({
'boot_environment': boot_environment,
'old_boot_environment': old_boot_environment,
'bootloader': bootloader,
'verbose': verbose,
'noconfirm': noconfirm,
'noop': noop,
'boot_environment_root': be_root
})
except ValueError as e:
ZELogger.log({
"level": "EXCEPTION",
"message": f"Failed to run plugin {bootloader}\n{e}\n"
}, exit_on_error=True)
else:
ZELogger.log({
"level": "EXCEPTION",
"message": (f"The plugin {bootloader} is "
f"not valid for {platform.system().lower()}\n")
}, exit_on_error=True)
else:
ZELogger.log({
"level": "EXCEPTION",
"message": f"bootloader type {bootloader} does not exist\n"
"Check available plugins with 'zedenv --plugins'\n"
}, exit_on_error=True)

return bootloader_plugin
16 changes: 14 additions & 2 deletions zedenv/plugins/systemdboot.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ def edit_bootloader_entry(self, temp_esp: str):

def modify_bootloader(self, temp_esp: str,):

real_kernel_dir = os.path.join(self.zedenv_properties["esp"], "env")
temp_kernel_dir = os.path.join(temp_esp, "env")
real_kernel_dir = os.path.join(self.zedenv_properties["esp"], self.env_dir)
temp_kernel_dir = os.path.join(temp_esp, self.env_dir)

real_old_dataset_kernel = os.path.join(real_kernel_dir, self.old_entry)
temp_new_dataset_kernel = os.path.join(temp_kernel_dir, self.new_entry)
Expand Down Expand Up @@ -295,3 +295,15 @@ def mid_activate(self, be_mountpoint: str):
esp=self.zedenv_properties["esp"], env=self.env_dir, boot=self.boot_mountpoint)

self.modify_fstab(be_mountpoint, replace_pattern, self.new_entry)

def post_destroy(self, target):
real_kernel_dir = os.path.join(self.zedenv_properties["esp"], self.env_dir)
dataset_kernels = os.path.join(real_kernel_dir, f"{self.entry_prefix}-{target}")

# if not self.noop:
if os.path.exists(dataset_kernels):
shutil.rmtree(dataset_kernels)
ZELogger.verbose_log({
"level": "INFO",
"message": f"Removed {dataset_kernels}.\n"
}, self.verbose)

0 comments on commit 2453c38

Please sign in to comment.