Start Kitty in Fish and fix boot and module restoration after QEMU checks
This commit is contained in:
parent
52d4e90883
commit
ba98cf48a7
15 changed files with 159 additions and 42 deletions
|
|
@ -24,9 +24,9 @@ My personal Gentoo restoration kit, mainly for my own devices:
|
||||||
- Binaries preferred, with a small deliberate source-build list.
|
- Binaries preferred, with a small deliberate source-build list.
|
||||||
- A Bubble Tea chooser with a final preview, conflict prompts and backups.
|
- A Bubble Tea chooser with a final preview, conflict prompts and backups.
|
||||||
|
|
||||||
The Stock preset has been installed in a fresh Gentoo QEMU/KVM guest: packages,
|
Stock and Fiw's Ryzen have been installed and checked in Gentoo QEMU/KVM.
|
||||||
config restoration and Plasma Login Manager login passed. Custom kernels,
|
The full TUI restore, KDE presets, optional apps, GRUB/Limine and ext4/Btrfs
|
||||||
automatic bootloader deployment and optional setups still need full runtime checks.
|
booting passed. See [tested scope and hardware limits](docs/setup.md#current-scope).
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,10 @@
|
||||||
"label": "Kitty lavender profiles",
|
"label": "Kitty lavender profiles",
|
||||||
"group": "fiw-apps",
|
"group": "fiw-apps",
|
||||||
"packages": [
|
"packages": [
|
||||||
"x11-terms/kitty"
|
"x11-terms/kitty",
|
||||||
|
"app-shells/fish"
|
||||||
],
|
],
|
||||||
"note": "Select fonts separately for the bundled JetBrainsMono Nerd Font."
|
"note": "Both profiles start Fish. Select fonts separately for the bundled JetBrainsMono Nerd Font."
|
||||||
},
|
},
|
||||||
"neovim": {
|
"neovim": {
|
||||||
"label": "Neovim transparent purple style",
|
"label": "Neovim transparent purple style",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ italic_font auto
|
||||||
bold_italic_font auto
|
bold_italic_font auto
|
||||||
font_size 11.0
|
font_size 11.0
|
||||||
|
|
||||||
|
shell fish
|
||||||
linux_display_server auto
|
linux_display_server auto
|
||||||
background_blur 32
|
background_blur 32
|
||||||
dynamic_background_opacity yes
|
dynamic_background_opacity yes
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@ packages again, including requirements of apps whose installation was skipped.
|
||||||
|
|
||||||
Fish, Kitty, Neovim and Fastfetch have no Plasma or KWin requirements. Fonts
|
Fish, Kitty, Neovim and Fastfetch have no Plasma or KWin requirements. Fonts
|
||||||
have their own checkbox; Kitty can use its fallback font if those are omitted.
|
have their own checkbox; Kitty can use its fallback font if those are omitted.
|
||||||
|
Both Kitty profiles start Fish explicitly, so the Kitty preset requires Fish
|
||||||
|
even when the optional Fish preferences are unchecked.
|
||||||
|
For Fish in TTY and SSH logins too, run `chsh -s "$(command -v fish)"` as your
|
||||||
|
regular user after installing Fish, then log in again.
|
||||||
Neovim's config includes a pinned Catppuccin runtime in its native package
|
Neovim's config includes a pinned Catppuccin runtime in its native package
|
||||||
directory and loads it before the captured purple highlights. It needs no
|
directory and loads it before the captured purple highlights. It needs no
|
||||||
plugin manager or runtime download. A built-in fallback remains available if
|
plugin manager or runtime download. A built-in fallback remains available if
|
||||||
|
|
|
||||||
13
docs/boot.md
13
docs/boot.md
|
|
@ -55,6 +55,11 @@ is generated before replacing it. If the previous menu was edited locally,
|
||||||
the new menu becomes a `.new` proposal. Existing `/etc/default/grub` settings
|
the new menu becomes a `.new` proposal. Existing `/etc/default/grub` settings
|
||||||
are used by `grub-mkconfig`.
|
are used by `grub-mkconfig`.
|
||||||
|
|
||||||
|
Explicit deployment asks before replacing a conflicting GRUB menu or Limine
|
||||||
|
managed block, with a backup. Keeping it writes a proposal and leaves firmware
|
||||||
|
registration and order unchanged. Automatic kernel refreshes preserve edits
|
||||||
|
without prompting; review their proposals before using the new entries.
|
||||||
|
|
||||||
## Kernel updates and backups
|
## Kernel updates and backups
|
||||||
|
|
||||||
Deployment installs a standalone refresh helper at
|
Deployment installs a standalone refresh helper at
|
||||||
|
|
@ -72,9 +77,11 @@ live under `/var/lib/Fiw-Gentoo-Dots`. No existing disk partition is formatted.
|
||||||
Automatic deployment currently supports amd64 UEFI, GPT ESPs, plain ext4/Btrfs
|
Automatic deployment currently supports amd64 UEFI, GPT ESPs, plain ext4/Btrfs
|
||||||
roots and unsigned boot. Encrypted, UKI-only, BIOS and signing workflows can
|
roots and unsigned boot. Encrypted, UKI-only, BIOS and signing workflows can
|
||||||
keep their existing loader. Secure Boot being active stops unsigned deployment
|
keep their existing loader. Secure Boot being active stops unsigned deployment
|
||||||
before changes. A fresh ext4 QEMU/KVM guest booted the binary kernel with a
|
before changes. Automatic GRUB and Limine deployment and booting were checked
|
||||||
separately provisioned UEFI GRUB loader. The automatic deployment and kernel
|
in Gentoo QEMU/KVM with ext4 and a Btrfs `@` root. The custom Ryzen kernel and
|
||||||
update hooks described here still need end-to-end boot checks.
|
binary fallback booted, and addition/removal hooks and preservation of edited
|
||||||
|
menus were checked. Physical firmware and unsupported storage layouts still
|
||||||
|
need their own setup.
|
||||||
|
|
||||||
`optional/fiw-cachy-patch` refreshes the custom kernel patch; it does not select
|
`optional/fiw-cachy-patch` refreshes the custom kernel patch; it does not select
|
||||||
a bootloader. See the [helper list](scripts.md) before using it.
|
a bootloader. See the [helper list](scripts.md) before using it.
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ The report includes:
|
||||||
|
|
||||||
- Completed, partial, failed, cancelled and not attempted steps.
|
- Completed, partial, failed, cancelled and not attempted steps.
|
||||||
- Confirmed present Portage packages and skipped or missing packages.
|
- Confirmed present Portage packages and skipped or missing packages.
|
||||||
|
- NVIDIA module checks/builds for a selected custom kernel and binary fallback.
|
||||||
- Installed, existing, skipped or failed user Flatpaks.
|
- Installed, existing, skipped or failed user Flatpaks.
|
||||||
- Enabled, missing or skipped service units.
|
- Enabled, missing or skipped service units.
|
||||||
- Applied configs, preserved conflicts and pending `.new` proposals.
|
- Applied configs, preserved conflicts and pending `.new` proposals.
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,10 @@ Binary packages retain the binhost's USE settings; required dependency flags
|
||||||
are still checked. The preview includes dependency updates and replacements,
|
are still checked. The preview includes dependency updates and replacements,
|
||||||
such as adding Steam's 32-bit libraries to a fresh multilib installation.
|
such as adding Steam's 32-bit libraries to a fresh multilib installation.
|
||||||
|
|
||||||
|
Custom kernel installs with NVIDIA also check its modules against the selected
|
||||||
|
custom kernel and binary fallback. Missing or outdated modules are compiled
|
||||||
|
for each, and failures appear in the package report.
|
||||||
|
|
||||||
Read-only resolution and an export are available separately:
|
Read-only resolution and an export are available separately:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|
@ -144,14 +148,19 @@ or Btrfs roots, and unsigned boot. See [boot setup](boot.md) for previews,
|
||||||
firmware choices and kernel update integration. Other layouts can keep their
|
firmware choices and kernel update integration. Other layouts can keep their
|
||||||
existing loader.
|
existing loader.
|
||||||
|
|
||||||
The optional [TideWM recipe](tidewm.md) follows the audited upstream master
|
Gentoo QEMU/KVM checks covered a fresh Stock installation, Fiw's Ryzen custom
|
||||||
branch and uses the normal compile-or-skip prompt. The Stock package installation completed in a fresh ext4 Gentoo QEMU/KVM guest
|
kernel and binary fallback, all package sections, the complete TUI restore,
|
||||||
(539 package steps, no missing selected packages). Config restoration, conflict
|
all 16 config presets, capture filtering, preserved edits, proposals and backups.
|
||||||
handling, backups, the bundled chooser and Plasma Login Manager login were
|
Plasma Login Manager, KDE/GTK styling, shortcuts, optional autostart, service
|
||||||
checked there, along with portable terminal configs and optional service enabling.
|
enabling and both user Flatpaks were checked. GRUB and Limine booted ext4 and
|
||||||
The guest booted a binary kernel using a separately provisioned UEFI GRUB loader.
|
a Btrfs `@` root; kernel addition/removal hooks and menu conflicts were checked.
|
||||||
Automatic bootloader deployment, custom Ryzen kernel builds, Btrfs, TideWM,
|
The Btrfs guest used a converted copy of the installed ext4 guest.
|
||||||
optional Flatpak installation and physical GPU behaviour remain unverified.
|
|
||||||
|
App checks cover launches and local configuration, including MangoHud,
|
||||||
|
GameMode, FiwNode audio and Apdatifier. [TideWM](tidewm.md) compiled and ran
|
||||||
|
with virtual graphics. NVIDIA modules were built and checked for both selected
|
||||||
|
kernels. Physical NVIDIA rendering, Wi-Fi/Bluetooth devices, real audio hardware,
|
||||||
|
account sign-ins and gameplay still need checks on the target device.
|
||||||
|
|
||||||
Do not publish the private original fiw-gentoo archive. It has different
|
Do not publish the private original fiw-gentoo archive. It has different
|
||||||
history and host-specific files.
|
history and host-specific files.
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,11 @@ is enabled by default, including the session-specific portal files.
|
||||||
This is a source build. The main installer shows it as an additional
|
This is a source build. The main installer shows it as an additional
|
||||||
compile-or-skip choice; it is not part of the deliberately small source list.
|
compile-or-skip choice; it is not part of the deliberately small source list.
|
||||||
A live recipe follows future upstream changes, while the current audit SHA
|
A live recipe follows future upstream changes, while the current audit SHA
|
||||||
documents the version reviewed for this snapshot. Compilation of the
|
documents the version reviewed for this snapshot. That commit compiled and
|
||||||
refreshed tree on a fresh device remains unverified.
|
ran in the Gentoo QEMU/KVM guest, both nested inside Plasma and directly from
|
||||||
|
a TTY with virtual graphics. Kitty started Fish with the restored terminal
|
||||||
|
preferences in both sessions. Physical GPU and screencasting behaviour remain
|
||||||
|
device-specific checks.
|
||||||
|
|
||||||
After installation, choose **TideWM** at login. It creates its own default
|
After installation, choose **TideWM** at login. It creates its own default
|
||||||
configuration on first launch. No existing TideWM settings are captured or
|
configuration on first launch. No existing TideWM settings are captured or
|
||||||
|
|
|
||||||
56
lib/boot.py
56
lib/boot.py
|
|
@ -10,6 +10,7 @@ import shlex
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
@ -229,7 +230,35 @@ def write(path, content, backups, mode=0o644):
|
||||||
tmp.replace(path)
|
tmp.replace(path)
|
||||||
|
|
||||||
|
|
||||||
def refresh(saved, backups, exclude=None):
|
def grub_config(output, images, exclude=None):
|
||||||
|
env = dict(os.environ, GRUB_TOP_LEVEL=images[0]['kernel'])
|
||||||
|
command = ['grub-mkconfig', '-o', str(output)]
|
||||||
|
if not exclude:
|
||||||
|
subprocess.run(command, env=env, check=True)
|
||||||
|
return
|
||||||
|
# Removal hooks can run before the kernel file disappears. Filter discovery
|
||||||
|
# through GRUB's library override, without moving installed boot artifacts.
|
||||||
|
library = Path('/usr/share/grub')
|
||||||
|
source = (library / 'grub-mkconfig_lib').read_text()
|
||||||
|
source, count = re.subn(r'\bgrub_file_is_not_garbage\s*\(\s*\)',
|
||||||
|
'fiw_dots_file_is_not_garbage ()', source, count=1)
|
||||||
|
if count != 1:
|
||||||
|
raise RuntimeError('Cannot filter this GRUB library; preserving the boot menu.')
|
||||||
|
paths = ['/boot/kernel-' + exclude] + [prefix + exclude for prefix in
|
||||||
|
('/boot/vmlinuz-', '/vmlinuz-', '/boot/vmlinux-', '/vmlinux-')]
|
||||||
|
source += '\ngrub_file_is_not_garbage () {\n case "$1" in\n ' + '|'.join(
|
||||||
|
shlex.quote(path) for path in paths) + ') return 1 ;;\n esac\n fiw_dots_file_is_not_garbage "$@"\n}\n'
|
||||||
|
with tempfile.TemporaryDirectory(prefix='fiw-dots-grub-') as directory:
|
||||||
|
root = Path(directory)
|
||||||
|
for path in library.iterdir():
|
||||||
|
if path.name != 'grub-mkconfig_lib':
|
||||||
|
(root / path.name).symlink_to(path)
|
||||||
|
(root / 'grub-mkconfig_lib').write_text(source)
|
||||||
|
subprocess.run(command, env=dict(env, pkgdatadir=directory), check=True)
|
||||||
|
|
||||||
|
|
||||||
|
def refresh(saved, backups, exclude=None, ask=None):
|
||||||
|
saved.pop('pending_config', None)
|
||||||
# Recheck the mount every time; never write into an unmounted ESP directory.
|
# Recheck the mount every time; never write into an unmounted ESP directory.
|
||||||
target = discover_esp(Path(saved['esp']))
|
target = discover_esp(Path(saved['esp']))
|
||||||
images = kernel_images(exclude=exclude)
|
images = kernel_images(exclude=exclude)
|
||||||
|
|
@ -246,7 +275,10 @@ def refresh(saved, backups, exclude=None):
|
||||||
config = GRUB_DIRECTORY / 'grub/grub.cfg'
|
config = GRUB_DIRECTORY / 'grub/grub.cfg'
|
||||||
old_hash = file_hash(config)
|
old_hash = file_hash(config)
|
||||||
output = config
|
output = config
|
||||||
if old_hash and old_hash != saved.get('config_hash'):
|
edited = old_hash and old_hash != saved.get('config_hash')
|
||||||
|
replace = edited and ask and ask('Existing GRUB menu differs from the saved version. Replace it with the generated menu?',
|
||||||
|
['replace', 'keep'], 'keep') == 'replace'
|
||||||
|
if edited and not replace:
|
||||||
output = config.with_name(config.name + '.new.' + datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S.%fZ'))
|
output = config.with_name(config.name + '.new.' + datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S.%fZ'))
|
||||||
else:
|
else:
|
||||||
backup(config, backups)
|
backup(config, backups)
|
||||||
|
|
@ -264,12 +296,13 @@ def refresh(saved, backups, exclude=None):
|
||||||
shutil.copy2(source, dest)
|
shutil.copy2(source, dest)
|
||||||
scratch = output.with_name('.' + output.name + '.tmp')
|
scratch = output.with_name('.' + output.name + '.tmp')
|
||||||
try:
|
try:
|
||||||
subprocess.run(['grub-mkconfig', '-o', str(scratch)], check=True)
|
grub_config(scratch, images, exclude)
|
||||||
scratch.replace(output)
|
scratch.replace(output)
|
||||||
finally:
|
finally:
|
||||||
if scratch.exists():
|
if scratch.exists():
|
||||||
scratch.unlink()
|
scratch.unlink()
|
||||||
if output != config:
|
if output != config:
|
||||||
|
saved['pending_config'] = str(output)
|
||||||
print('Preserved edited GRUB config; review ' + str(output))
|
print('Preserved edited GRUB config; review ' + str(output))
|
||||||
else:
|
else:
|
||||||
saved['config_hash'] = file_hash(config)
|
saved['config_hash'] = file_hash(config)
|
||||||
|
|
@ -295,9 +328,13 @@ def refresh(saved, backups, exclude=None):
|
||||||
prior = managed_block(old)
|
prior = managed_block(old)
|
||||||
block = render_limine(images, saved['cmdline'])
|
block = render_limine(images, saved['cmdline'])
|
||||||
output = merge_limine(old, block)
|
output = merge_limine(old, block)
|
||||||
if prior and block_hash(prior) != saved.get('block_hash'):
|
edited = prior and block_hash(prior) != saved.get('block_hash')
|
||||||
|
replace = edited and ask and ask('Existing Limine entries differ from the saved version. Replace the managed entries?',
|
||||||
|
['replace', 'keep'], 'keep') == 'replace'
|
||||||
|
if edited and not replace:
|
||||||
proposal = config.with_name(config.name + '.new.' + datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S.%fZ'))
|
proposal = config.with_name(config.name + '.new.' + datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S.%fZ'))
|
||||||
write(proposal, output, backups)
|
write(proposal, output, backups)
|
||||||
|
saved['pending_config'] = str(proposal)
|
||||||
print('Preserved edited Limine entries; review ' + str(proposal))
|
print('Preserved edited Limine entries; review ' + str(proposal))
|
||||||
elif output != old:
|
elif output != old:
|
||||||
write(config, output, backups)
|
write(config, output, backups)
|
||||||
|
|
@ -381,7 +418,12 @@ def deploy(mode, esp=None, ask=confirm):
|
||||||
else:
|
else:
|
||||||
subprocess.run(proposed['commands'][0], check=True)
|
subprocess.run(proposed['commands'][0], check=True)
|
||||||
loader_path = '/EFI/Fiw-Gentoo/grubx64.efi'
|
loader_path = '/EFI/Fiw-Gentoo/grubx64.efi'
|
||||||
saved = refresh(saved, backups)
|
saved = refresh(saved, backups, ask=ask)
|
||||||
|
pending = saved.pop('pending_config', None)
|
||||||
|
if pending and firmware != 'keep':
|
||||||
|
commands = []
|
||||||
|
firmware = 'keep'
|
||||||
|
print('Kept the existing boot menu; firmware entries and order remain unchanged. Review ' + pending)
|
||||||
# Native installkernel provides versioned /boot kernel/initrd files; our
|
# Native installkernel provides versioned /boot kernel/initrd files; our
|
||||||
# final hook refreshes only the chosen loader's own configuration.
|
# final hook refreshes only the chosen loader's own configuration.
|
||||||
write(Path('/etc/kernel/install.conf'), proposed['installkernel_config'], backups)
|
write(Path('/etc/kernel/install.conf'), proposed['installkernel_config'], backups)
|
||||||
|
|
@ -403,7 +445,8 @@ def deploy(mode, esp=None, ask=confirm):
|
||||||
report.write_text(json.dumps({'plan': proposed, 'firmware_choice': firmware,
|
report.write_text(json.dumps({'plan': proposed, 'firmware_choice': firmware,
|
||||||
'backups': str(backups)}, indent=2) + '\n')
|
'backups': str(backups)}, indent=2) + '\n')
|
||||||
print('Boot deployment finished. Report: ' + str(report))
|
print('Boot deployment finished. Report: ' + str(report))
|
||||||
return {'status': 'completed', 'mode': mode, 'firmware_choice': firmware,
|
return {'status': 'partial' if pending else 'completed', 'mode': mode, 'firmware_choice': firmware,
|
||||||
|
'review': [pending] if pending else [],
|
||||||
'report': str(report), 'backups': str(backups)}
|
'report': str(report), 'backups': str(backups)}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -422,6 +465,7 @@ def main():
|
||||||
stamp = datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S.%fZ')
|
stamp = datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%S.%fZ')
|
||||||
backups = MANAGED / 'backups' / ('boot-refresh-' + stamp)
|
backups = MANAGED / 'backups' / ('boot-refresh-' + stamp)
|
||||||
updated = refresh(saved, backups, args.exclude_version)
|
updated = refresh(saved, backups, args.exclude_version)
|
||||||
|
updated.pop('pending_config', None)
|
||||||
write(STATE, json.dumps(updated, indent=2) + '\n', backups, 0o600)
|
write(STATE, json.dumps(updated, indent=2) + '\n', backups, 0o600)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
44
lib/rice.py
44
lib/rice.py
|
|
@ -447,6 +447,37 @@ def resolve(stage, selection, packages, execute=False):
|
||||||
stderr=None if execute else subprocess.STDOUT)
|
stderr=None if execute else subprocess.STDOUT)
|
||||||
|
|
||||||
|
|
||||||
|
def nvidia_modules():
|
||||||
|
"""Check both selected distribution kernels, not just /usr/src/linux."""
|
||||||
|
snapshot = json.loads((REPO / 'optional/kernel/snapshot.json').read_text())
|
||||||
|
driver = subprocess.check_output(['portageq', 'best_version', '/', 'x11-drivers/nvidia-drivers'], text=True).strip()
|
||||||
|
expected = re.sub(r'-r\d+$', '', driver.split('nvidia-drivers-', 1)[1])
|
||||||
|
result = {'checked': [], 'rebuilt': [], 'missing': []}
|
||||||
|
for atom in [snapshot['atom'], 'sys-kernel/gentoo-kernel-bin']:
|
||||||
|
cpv = subprocess.check_output(['portageq', 'best_version', '/', atom], text=True).strip()
|
||||||
|
contents = (Path('/var/db/pkg') / cpv / 'CONTENTS').read_text() if cpv else ''
|
||||||
|
versions = sorted(set(re.findall(r'/(?:usr/)?lib/modules/([^/ ]+)/', contents)))
|
||||||
|
if not versions:
|
||||||
|
result['missing'].append('NVIDIA kernel target: ' + atom)
|
||||||
|
for version in versions:
|
||||||
|
result['checked'].append(version)
|
||||||
|
def ready():
|
||||||
|
return all(subprocess.run(['modinfo', '-k', version, '-F', 'version', module],
|
||||||
|
text=True, capture_output=True).stdout.strip() == expected
|
||||||
|
for module in ['nvidia', 'nvidia_drm', 'nvidia_modeset', 'nvidia_uvm'])
|
||||||
|
if ready():
|
||||||
|
continue
|
||||||
|
build = Path('/lib/modules') / version / 'build'
|
||||||
|
print('Building NVIDIA modules for ' + version, flush=True)
|
||||||
|
command = ['emerge', '--oneshot', '--nodeps', '--usepkg=n', '--getbinpkg=n',
|
||||||
|
'--autounmask=n', '=' + driver]
|
||||||
|
if build.is_dir() and subprocess.run(command, env=dict(os.environ, KERNEL_DIR=str(build))).returncode == 0 and ready():
|
||||||
|
result['rebuilt'].append(version)
|
||||||
|
else:
|
||||||
|
result['missing'].append('NVIDIA modules for ' + version)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def install_packages(selection):
|
def install_packages(selection):
|
||||||
if os.geteuid() != 0:
|
if os.geteuid() != 0:
|
||||||
raise RuntimeError('Package installation requires root. Run sudo ./install --install-packages --selection <file>.')
|
raise RuntimeError('Package installation requires root. Run sudo ./install --install-packages --selection <file>.')
|
||||||
|
|
@ -504,6 +535,11 @@ def install_packages(selection):
|
||||||
if not accepted:
|
if not accepted:
|
||||||
print('All requested packages were skipped; no live configuration applied.')
|
print('All requested packages were skipped; no live configuration applied.')
|
||||||
return {'status': 'skipped', 'requested': requested, 'skipped': skipped, 'missing': requested}
|
return {'status': 'skipped', 'requested': requested, 'skipped': skipped, 'missing': requested}
|
||||||
|
build_modules = (selection['kernel'] == 'custom' and 'system' in selection['groups']
|
||||||
|
and 'x11-drivers/nvidia-drivers' in accepted
|
||||||
|
and any(atom.startswith('=sys-kernel/gentoo-kernel-') for atom in accepted))
|
||||||
|
if build_modules:
|
||||||
|
print('NVIDIA modules will be checked and compiled when needed for the selected custom kernel and binary fallback.')
|
||||||
if ask('Apply the previewed Portage files and install the accepted packages?', ['apply', 'cancel'], 'cancel') != 'apply':
|
if ask('Apply the previewed Portage files and install the accepted packages?', ['apply', 'cancel'], 'cancel') != 'apply':
|
||||||
return {'status': 'cancelled', 'requested': requested, 'skipped': skipped}
|
return {'status': 'cancelled', 'requested': requested, 'skipped': skipped}
|
||||||
publish_repositories(fetched)
|
publish_repositories(fetched)
|
||||||
|
|
@ -556,20 +592,24 @@ def install_packages(selection):
|
||||||
if final.returncode or ({cp_from_cpv(x) for x in source_builds(final.stdout)} - approved):
|
if final.returncode or ({cp_from_cpv(x) for x in source_builds(final.stdout)} - approved):
|
||||||
raise RuntimeError('The final package plan changed. Review it before retrying; backups are at ' + str(backup_root))
|
raise RuntimeError('The final package plan changed. Review it before retrying; backups are at ' + str(backup_root))
|
||||||
result = resolve(Path('/'), selection, ['@fiw-dots-selected'], execute=True)
|
result = resolve(Path('/'), selection, ['@fiw-dots-selected'], execute=True)
|
||||||
|
modules = nvidia_modules() if result.returncode == 0 and build_modules else {}
|
||||||
missing = [atom for atom in requested if subprocess.run(
|
missing = [atom for atom in requested if subprocess.run(
|
||||||
['portageq', 'has_version', '/', atom], stdout=subprocess.DEVNULL,
|
['portageq', 'has_version', '/', atom], stdout=subprocess.DEVNULL,
|
||||||
stderr=subprocess.DEVNULL).returncode != 0]
|
stderr=subprocess.DEVNULL).returncode != 0]
|
||||||
report = {'requested': requested, 'present': [atom for atom in accepted if atom not in missing],
|
report = {'requested': requested, 'present': [atom for atom in accepted if atom not in missing],
|
||||||
'skipped': skipped, 'emerge_exit_code': result.returncode,
|
'skipped': skipped, 'emerge_exit_code': result.returncode,
|
||||||
'missing': missing,
|
'missing': missing,
|
||||||
|
'modules': modules, 'failed': modules.get('missing', []),
|
||||||
'pending': []}
|
'pending': []}
|
||||||
state = Path('/var/lib/Fiw-Gentoo-Dots')
|
state = Path('/var/lib/Fiw-Gentoo-Dots')
|
||||||
state.mkdir(parents=True, exist_ok=True)
|
state.mkdir(parents=True, exist_ok=True)
|
||||||
(state / ('packages-' + stamp + '.json')).write_text(json.dumps(report, indent=2) + '\n')
|
(state / ('packages-' + stamp + '.json')).write_text(json.dumps(report, indent=2) + '\n')
|
||||||
print('Package report: ' + str(state / ('packages-' + stamp + '.json')))
|
print('Package report: ' + str(state / ('packages-' + stamp + '.json')))
|
||||||
print('Missing packages: ' + (', '.join(missing) or 'none'))
|
print('Missing packages: ' + (', '.join(missing) or 'none'))
|
||||||
if result.returncode:
|
if build_modules and result.returncode == 0:
|
||||||
error = RuntimeError('Some packages did not install; consult the package report and emerge output.')
|
print('Missing NVIDIA modules: ' + (', '.join(modules.get('missing', [])) or 'none'))
|
||||||
|
if result.returncode or modules.get('missing'):
|
||||||
|
error = RuntimeError('Some packages or kernel modules did not install; consult the package report and emerge output.')
|
||||||
error.report = report
|
error.report = report
|
||||||
raise error
|
raise error
|
||||||
if 'kde' in selection['groups'] and 'kde-plasma/plasma-login-manager' not in missing:
|
if 'kde' in selection['groups'] and 'kde-plasma/plasma-login-manager' not in missing:
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,10 @@ trap 'rm -rf "$work"' EXIT
|
||||||
cd "$work"
|
cd "$work"
|
||||||
|
|
||||||
# Newest CachyOS release for this kernel version (cachyos-7.2.8-1, -2, ...)
|
# Newest CachyOS release for this kernel version (cachyos-7.2.8-1, -2, ...)
|
||||||
tag=$(curl -fsSL "https://api.github.com/repos/CachyOS/linux/releases?per_page=50" |
|
releases=$(curl -fsSL "https://api.github.com/repos/CachyOS/linux/releases?per_page=50")
|
||||||
|
tag=$(printf '%s\n' "$releases" |
|
||||||
grep -oE "\"tag_name\": *\"cachyos-${ver//./\\.}-[0-9]+\"" |
|
grep -oE "\"tag_name\": *\"cachyos-${ver//./\\.}-[0-9]+\"" |
|
||||||
grep -oE "cachyos-[0-9.]+-[0-9]+" | sort -V | tail -1)
|
grep -oE "cachyos-[0-9.]+-[0-9]+" | sort -V | tail -1 || true)
|
||||||
[[ -n $tag ]] || { echo "CachyOS has no release for $ver yet" >&2; exit 1; }
|
[[ -n $tag ]] || { echo "CachyOS has no release for $ver yet" >&2; exit 1; }
|
||||||
echo "Using $tag"
|
echo "Using $tag"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# SpotX-Bash + spicetify (Marketplace) on Gentoo's media-sound/spotify.
|
# SpotX-Bash + spicetify (Marketplace) on Gentoo's media-sound/spotify.
|
||||||
# Run as your regular user after the first setup and after every Spotify update.
|
# Run as your regular user after the first setup and after every Spotify update.
|
||||||
# Write access comes from an ACL (/etc/portage/env/media-sound/spotify).
|
# Write access must be configured explicitly before opting in.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
client=/opt/spotify/spotify-client
|
client=/opt/spotify/spotify-client
|
||||||
|
|
@ -9,7 +9,7 @@ spotx_url=https://raw.githubusercontent.com/SpotX-Official/SpotX-Bash/main/spotx
|
||||||
spicetify=$HOME/.spicetify/spicetify
|
spicetify=$HOME/.spicetify/spicetify
|
||||||
|
|
||||||
[[ -w $client/Apps/xpui.spa && -w $client/spotify ]] || {
|
[[ -w $client/Apps/xpui.spa && -w $client/spotify ]] || {
|
||||||
echo "No write access to $client. Run once as root: the optional Spotify ACL setup described in docs/spotify.md" >&2
|
echo "No write access to $client. Review docs/spotify.md and configure client write access explicitly before opting in." >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
llvm-core/llvm heavy.conf notmpfs.conf
|
llvm-core/llvm fiw-dots-heavy.conf fiw-dots-notmpfs.conf
|
||||||
llvm-core/clang heavy.conf notmpfs.conf
|
llvm-core/clang fiw-dots-heavy.conf fiw-dots-notmpfs.conf
|
||||||
dev-qt/qtwebengine heavy.conf notmpfs.conf
|
dev-qt/qtwebengine fiw-dots-heavy.conf fiw-dots-notmpfs.conf
|
||||||
net-libs/nodejs heavy.conf
|
net-libs/nodejs fiw-dots-heavy.conf
|
||||||
dev-lang/spidermonkey heavy.conf
|
dev-lang/spidermonkey fiw-dots-heavy.conf
|
||||||
media-libs/embree heavy.conf notmpfs.conf
|
media-libs/embree fiw-dots-heavy.conf fiw-dots-notmpfs.conf
|
||||||
media-gfx/blender heavy.conf notmpfs.conf
|
media-gfx/blender fiw-dots-heavy.conf fiw-dots-notmpfs.conf
|
||||||
media-gfx/openvdb heavy.conf notmpfs.conf
|
media-gfx/openvdb fiw-dots-heavy.conf fiw-dots-notmpfs.conf
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
sys-kernel/gentoo-kernel notmpfs.conf
|
sys-kernel/gentoo-kernel fiw-dots-notmpfs.conf
|
||||||
sys-devel/gcc notmpfs.conf
|
sys-devel/gcc fiw-dots-notmpfs.conf
|
||||||
|
|
|
||||||
|
|
@ -183,10 +183,16 @@ def capture_fish():
|
||||||
|
|
||||||
|
|
||||||
def capture_kitty():
|
def capture_kitty():
|
||||||
|
def portable_profile(text, name):
|
||||||
|
text = re.sub(r'(?m)^linux_display_server\s+wayland\s*$',
|
||||||
|
'linux_display_server auto', text)
|
||||||
|
text = re.sub(r'(?m)^shell\s+.*\n?', '', text)
|
||||||
|
if name == 'kitty-common.conf':
|
||||||
|
text = text.rstrip() + '\n\nshell fish\n'
|
||||||
|
return text
|
||||||
for name in ['kitty.conf', 'kitty-main.conf', 'kitty-bright.conf', 'kitty-common.conf']:
|
for name in ['kitty.conf', 'kitty-main.conf', 'kitty-bright.conf', 'kitty-common.conf']:
|
||||||
copy('kitty', '.config/kitty/' + name,
|
copy('kitty', '.config/kitty/' + name,
|
||||||
lambda t: re.sub(r'(?m)^linux_display_server\s+wayland\s*$',
|
lambda t: portable_profile(t, name))
|
||||||
'linux_display_server auto', t))
|
|
||||||
|
|
||||||
|
|
||||||
def capture_neovim():
|
def capture_neovim():
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue