Based on daviwil’s dotfiles
- Why Guix
- Overview
- There is no SystemD
- Thus there is no journalctl
- Guix Can Generate Graphs of Package Dependencies
- Download all the Guix Savannah Source
- Run into problems on install or boot?
- Managing Guix Visually
- Where are configuration files?
- For User jobs, use mcron,
~/.bin
and libnotify - Setup Geiser to Run Guile Scheme Code
- Setup Geiser to run Guix Code
- Deploying
- Deploying to Not-Guix Systems
NOTE: this is just a brief overview of the methods available to you for customizing precisely how an environment is loaded for an application run under guix. You CANNOT replicate this functionality in debian, arch or flatpak … not without being an expert.
- Debian
- you will make fairly heavy use of their package mgmt toolchain.
- You will likely need a custom package repository.
- You will need tooling to auto-upgrade the builds of your custom packages.
- Arch
- you will need to … ditto.
- You will also need
aurutils
and, again, a custom package repo. - You will again need to automate upgraded packages
- Running multiple pacman databases is complicated and it is difficult to make packages install to the correct endpoints, while ensuring shared library objects are available (of the proper version, etc)
- It will break when you don’t upgrade things or when you reinstall.
- You will also need
- Guix
- you will also need to do similar things: you must run at least one
channel (i.e. package repo on your local file system) and you will heavily
interface with the package management tools.
- if I said Guix too much easier than the above, i’d be lying. nothing is
simpler than the domain. the difference with Guix is that, if you want a
build farm, it’s about as easy as it could possibly be.
- See Hydra/Cuirass
- Cuirass (Guix Manual)
- Growing Our Build Farm (Guix Blog 2016)
- with the alternative package managers above, good luck getting things like having consistent man pages or avoiding things like Gnome/GTK dependency issues.
- additionally, working with Scheme is a requirement. it’s hard. if you don’t want want to use Scheme (or learn 2+ lisps), then you can use Nix. That is completely reasonable.
- if I said Guix too much easier than the above, i’d be lying. nothing is
simpler than the domain. the difference with Guix is that, if you want a
build farm, it’s about as easy as it could possibly be.
If anything like the above sounds unfamiliar, you’re probably not using linux. Additionally, your system is probably not robust to failure. If the big bad wolf comes along and blows your shit over, GLHF. If you have a job where you use linux and your system goes down in such a way, you may get fired. You must automate.
In analogy to dialectical terms, Backups are like Marxist Dialectical and Declarative Config is like Hegelian Dialectical. You want both.
- Yes, you can have backups.
- This helps with problems you expect to have.
- Marxist dialectical because: this was the system state.
- But the technical debt you’ll incur when having a polluted environment is
something that backups cannot protect you from. If your environment is
polluted, you’re probably on stack overflow right now.
- These are the problems you don’t know you’re going to encounter.
- Hegelian dialectical because: ideally, this will be the system state, but is yet to be proven.
Precise control over a process’s environment with minimal effort: this is what makes guix shine. It might seem like more work at first, but you should know about all these interfaces anyways.
Another advantage of Guix System’s bloat-free Guix profiles, Shepherd service manager and declarative
/etc/strange
configs:Quite a bit of malware/metasploits will simply misfire. And persistence is just as amusing.
Just log the right shit, sit back and enjoy the unintended fireworks.
Guix and perhaps the Dotfiles project will confuse many people. This is a Linux
without SystemD, for example. Very confusing! I mean how do you even journalctl
-xb
?
Guix is fairly simple, but the language will be the main hangup for people.
- That’s really too bad. Guix, Shepherd and mcron all use Guile Scheme.
- There is a common interface for all of them. This means that they can all
extend each other without needing to shift through a language barrier.
- Ever wonder why so many tools integrate shell scripts?
- Among other reasons, the shell is how programs (processes) of various languages can speak a common language. Any language can be your shell. Here, scheme is not the shell, per se, but it is its own universal extension language.
- Still, the scheme programs confined to the domains of the processes/services
that run Scheme. So it’s not like you have the possiblity of non-hygenic
macros running everywhere … but you do still have to understand how the
environment for each scheme process is constructed.
- i.e. mcron may spawn a scheme program, but there should be a process boundary between them.
- viz. scheme processes should spawn with the parent env or with no env, but it should not share all the modules loaded into the parent process.
Instead, you have GNU Shepherd to manage services.
shepherd
is the daemonherd
is the service manager.- There are only two universal actions for herd: enable & disable.
- There should be at least two instances of shepherd running on your system:
- one for root and one for the user.
- For user services, you will find the logs in
- Service definitions are written in scheme.
See the <a href=”https://www.gnu.org/software/shepherd/manual/shepherd.html “>Shepherd manual for more information.
Instead find most logs in /var/log
.
To determine what logger your service uses, GENERATE A SERVICE GRAPH WITH GUIX.
See background behind commands like guix system shepherd-graph
for more
information.
Thus, Guix is like x-ray vision for GNU/Linux. Here are the packages for
bootstrapping GCC. Search the Guix Manual for guix graph
.
guix graph -t derivation \
-e '(@@ (gnu packages bootstrap) %bootsrap-gcc)' \
| dot -Tpng > bootstrap-gcc.png
The code for most core Guix packages – i.e. those available without adding a channel – is available in the source.
I would strongly recommend downloading the source and learning to search it with
find-grep
(in emacs) or with other features like +lookup/...
in doom emacs.
You can clone all the repositories for Guix with repo sync -u
https://github.com/ectorepo/guix.git
. This Repo project includes several
channels as well. You will need to install Google Repo with your package manager.
You can then update all the repositories with such commands:
repo help --all repo forall git stash # if you have updated any files in the project repo sync repo forall git stash pop # if you're feeling lucky
This will update each subproject to its most current version.
Repo is a tool that you’ll learn in your Google onboarding. Such a tool is essential for software development on a team..
Switch between vtty
’s and use emacs/tramp to view logs:
- Use
C-x d
and emacs will ask for a directory. - Then open
/sudo:root@localhost:/var/log
to view the logs directory- anywhere emacs asks for a file, this Tramp syntax is accepted.
- it is based on character gaps in the URL specification protocol and other features thereof. Tramp knows how to interpret these URL’s.
- You can use similar syntax to SSH or SCP to systems.
- Tramp will automatically timeout your sudo access (but buffers may remain open… they may not remain writable IDK)
You should run guix install emacs-guix
and run M-x guix
to manage/view Guix
information from inside emacs while you are still learning “unknown unknowns”.
- The Guix package in emacs gives you transient buffers.
- This makes it so much easier to begin to understand where profiles are installed, how Guix profiles are linked together
- You can even manage Shepherd services in this way.
- Bonus points: clone the guix.el source to learn how emacs interfaces with Guix. This is probably faster than reading the GNU Info manuals if you know emacs-lisp.
These live in the Guix packages. Navigate Guix from within emacs. You can find a package build directories there.
Or you can explore them:
- Bottom up: by browsing
/gnu/store
. Don’t ever touch anything inside this (it’s tough, but don’t) - Top Down: by browsing
~/.config/guix/current/
or with the paths in~/.guix-profile
There are several variables in the ~/.guix-profile/etc/profile
scripts.
Inspect these varibles in the shell to find your config files. (there’s probably
a better way to do this)
mcron has an GNU info manual.
If you get stuck on Scheme (outside of Guix source), open a Geiser repl and
evaluate the test cases to get a feel for the scheme cron syntax. To do this,
you’ll need scheme-mode
and geiser
installed/configured. Geiser should be
configured with the Guile variant of Scheme, which will require about 10 lines
of emacs-lisp.
You need to read the Geiser docs before attempting this. To open the REPL,
navigate to the ./tests/job-specifier.scm buffer for your file, and M-x
run-geiser
.
,help ;; view help ,m ;; show the module or switch to the module's namespace ;; in this case, evaluating code in the module namespace is not required
Now, from within the ./tests/job-specifier.scm
buffer, run M-x
geiser-eval-buffer
to run the tests. You may need to adjust the load path with
M-x geiser-add-to-load-path
. The mcron root folder must be in the Geiser load
path. Then from the source buffer, all lisp-mode
buffers will allow you to run
C-x C-e
to eval-last-sexp
.
- Placing the cursor behind the test defintion and running this will run the test and only that test!
- To mutate function definitions
- To inspect macros, set up
macrostep-expand
within emacs or doom-emacs.- It is a life-saver and will help you learn how top-level macros can be translated into “code you could write but could be written for you”
- it works for emacs-lisp, at least. Scheme has weird “define-syntax” macros… dot dot dot
Only rarely should you have to restart your REPL … if you’ve ever waited 15 minutes for your web-applications tests to run, then getting a lisp environment/project set up is well worth the wait.
No more sporking processes for your Rails environment.
It’s gonna be great to finally get around to Clojure development.
- When doing REPL-driven development in Scheme, mulitple Geiser repls will run.
- make sure you have the correct one selected.
- Also, the mcron code is included with other guile/scheme projects if you run
repo init -u https://github.com/ectorepo/scheme.git
. View the./default.xml
to see the full list of projects.
Using the scheme repl with mcron
should be a lot easier than evaluating Guix
package
and operating-system
specs from inside a Geiser Repl – i still
haven’t figured this out, except randomly getting it to work.
Emacs & Geiser don’t play nice with a guix repl
that’s started from the
commandline, whether it’s served via HTTP or via Unix socket. Emacs basically
locks up.
- it enables much faster development of
(operating-system...)
declarations and of(package ...)
declarations using lambda’s and macros, but it may not be super-useful
First and foremost, go look at daviwil’s dotfiles. It’s probably cleaner and
(last time i checked) there’s better documentation. <sarcasm mode=text/>
Most
of the SystemCrafters streams are also summarized in org files – and daviwil
also makes the squashed emacs-lisp files available.
This is for my own reference. My config is slightly different – it doesn’t use emacs windows manager, but still keeps the elisp snippets for templates. So the setup process is also different.
It is highly recommended that you install with the System Crafters USB image.
You’ll need to build this first. Why? You can skip one or two guix reconfigure
commands this way, which will slow you down. Further, you will want to know how
to use the following command in the command-line installer to get access to
nonguix substitutes (without needing to restart, then authorize guix channel
substitutes, then reconfigure, then restart)
sudo guix reconfigure --substitute-urls
…=
You will need to skim about 1,500 pages before you start. Learn how to use the
info
command. Expect to need to learn scheme. Trying out Guix commands on the
ISO is an easy, low-commitment way to try it out.
IMO, it’s just simpler to run the entire Guix system than it is to run another Linux with Guix. Doing so means that you’ll end up with:
- Package Manager
- Pacman + Guix
- You will need to more tightly manage the integration of Guix into your
.profile
so that it properly loads things like$PATH
without causing incompatibilities - In other words, you’ll probably just want to load Guix profiles manually
without making applications downloaded via guix (e.g. pGTK build of emacs)
available to users in the WM
- in this approach, if you download GUI apps via guix, then you will edit desktop files to ensure the proper profiles are loaded. This will require creating some init scripts to accompany those desktop files.
- You will need to more tightly manage the integration of Guix into your
- Service Manager
- Systemd + Shepherd
- It will be confusing to install things that depend on other services which
are not available to shepherd in its graph.
- you can still have these services load, but its much less confusing if you just have one service manager.
- System Services
- It will be confusing to install things that depend on other services which
are not available to shepherd in its graph.
- System Updates/Maintainence
- Arch + Guix System
- Don’t touch the
/gnu/store
or anything related to it. if you want it in it’s own partition, put it there before you install. If you break/gnu/store
you may not be able to reinstall guix … at least not without some serious headaches.
- Don’t touch the
- You can use Guix itself to produce these images.
- This can be done within a VM, as well.
- Guix can also produce OCI Docker images, so generating images from within and container is an option.
- You may want to interact with Guix work within a VM (at least initially)
- You’re going to have to think more about how your Guix packages and Shepherd Services interact with the system, not less .
- Clone the dcunited001/ellipsis repo to
~/.dotfiles
- Clone plexus/chemacs2 to
~/.emacs.d
- The
~/.emacs-profiles
will be linked in on your first stow
- The
DW avoids this by including chemacs as a submodule in the .files/emacs folder with
.emacs-profiles.el
in the parent folder. I’m not sure how this gets linked in. I either didn’t notice it or avoided the extra step, since I already had chemacs on my system.
From vanilla emacs, open Bash.org
, customize the environment variables in the
org table and tangle it with C-c C-v C-t
. These org vars will be inserted into
a script that is included with your .profile
.
Note that not all of these are used at the moment. Some will be removed, when I transition over to syncing things with syncthing.
From vanilla emacs, open Systems.org
. This has no environment vars. You can
tangle with C-c C-v t
. This will produce a few artifacts:
- ~/.emacs.d/lisp
You can keep emacs open, but if you started without plexus/chemacs2
in
~/.emacs.d
, then delete the ~/.emacs.d
that it automatically created. If you
have any bookmarks/cache, then it may complain that files are missing.
Alternatively, you could have started it with emacs -q
to avoid loading an
init file, but i have not tried this.
- tangle Desktop.org by running
update-dotfiles
- this contains the desktop profiles
- you will want to
stow .
before you run this- then the first
update-dotfiles
invocation will complain aboutper-system-settings.el
not existing it. runstow .
again to fix this. - then run
update-dotfiles
again to complete.
- then the first
- e.g.
.guix-extra-profiles
must be activated before they can be loadedupdate-channels
needs to be run for the user- if you haven’t authorized substitutes (read Guix manual) now is the time to do that
- then
activate-channels
, at least for profiles containing xorg/desktop dependencies- run
activate-profiles i3 desktop xdg devtools
or for the list of Guix profiles in either~/.xsession
or~/.config/sh/profile.d/guix.sh
- run
There are several scripts that depend on the hostname:
- ~/.bin/update-screens
- this is generated by
Desktop.org
- ~/.bin/update-system
- this provides the hostname to
guix reconfigure
- other
~/.bin/update-*
scripts will tend to
- other
- ~/.emacs.d/per-system-settings.el
- this describes settings like DPI
- you can’t tangle
Desktop.org
without understanding how this works! - it also requires scripts in
~/.emacs.d/lisp/dw-*.el
- this provides great examples of how to connect org/emacs/etc
- there are examples of how to use emacsclient for automation
You’ll need to ensure that these files are there before you tangle
Desktop.org
- you can’t tangle
The artifacts thus far need to be linked. The main ones of concern are:
- ~/.emacs-profiles.el
- the emacsclient scripts will check for the server
available. Emacs servers use unix sockets.
- If no server is available, I believe one will be started for you
- This will use the default chemacs config.
- This could be a problem (like if you haven’t set up
.doom.d
, but doom is default)
Simply run ~/.bin/update-dotfiles
and follow the white rabbit.
You’ll need to
guix install git emacs stow
, especially if you installed from the Guix system ISO.
In the Bash.org script, you will notice several *.eg.sh
files. These are all
intended to provide insertion points for the environment to be configured. If
you don’t configure them before you restart – then if some variables are not
set properly – this will prevent you from logging in.
- Copy all the
~/.dotfiles/.config/sh/**/*.eg.sh
to their counterparts.- the configuration is designed to load profile with
.profile
and interactive functionality (colors/etc) with.bashrc
. That is it..bash_profile
loads.profile
.profile
will load.bashrc
- the configuration is designed to load profile with
- There are four main insertion points:
- ~/.config/sh/_load_profiles.d.sh
- a whitelist of scripts to load
- ~/.config/sh/_load_rc.d.sh
- another whitelist of scripts to load
- ~/.xdg_shim.sh
- this provices a place to override xdg defaults
- if you don’t do this,
$XDG_CONFIG_HOME
values in some dependencies will be their defaults … but in my scripts will be nil. (and .xsession will fail, see notes in XDG Shim) - if this isn’t set up
- if you don’t do this,
- .xession
- this is the file that, for me, loads xorg.
- if the Guix system uses GDM to launch, it may not need an .xsession.
- if the Guix system uses Slim, it probably does
There are before/after hooks, but this is all explained in Bash.org
.
Restarting is necessary to refresh the window manager’s profile. You can also
reload the WM shell by logging in/out. You should just restart completely. By
ensuring a clean environment (after sorting anything out), this supports the
the upcoming updates to guix profiles and the last guix reconfigure
.
You can test that the above .profile
changes are working properly by
inspecting your environment in a vtty.
The profiles need to be activated (before they can be updates
Not everything for your system should be kept in git – thus, the ellipsis
in
dcunited001/ellipsis. So at this point, you’ll need to fill in those blanks,
however you do that for ~/.config/guix/systems/blank.scm
:
- decrypting system configurations with PGP
- patching system configs
- manually fetching things like disk UUID’s and filling in
(file-system ...)
directivesThis would usually mean fetching .....
Run ~/bin/update-system
and wait.
In the Bash.org
file is a subset of functionality that, with some tweaks, can
be deployed to most environments/systems.
The functionality therein should be independent of:
- File System
- Disk mount paths
- Window Manager
I’m not sure how long i’ll be using Manjaro, but I needed something quick to run in a VM with passthrough. I haven’t gotten around to tracing through the Guix OVMF packages to set up a system.
- I also diffed the directories in the standard installation’s
~/.config
and =~/.dotfiles/.config~- I also skimmed the tangled scripts in
- Bash.org
- Desktop.org
- Systems.org
- Conflicts include
- .config/dunstrc
- I also skimmed the tangled scripts in
- Collect the configs that may conflict & copy to
~/manjaro
To avoid boot issues or empty env-vars, install needed deps:
pacman -Syu stow direnv emacs-nativecomp
After grokking the differences,
Test in bash before logging in/out:
- Dunst
(this needs to be cleaned up lol)
I3 is started with lightdm, which uses an .xinitrc
instead of a
.xsession
.
Manjaro uses i3bar instead of polybar. It’s i3 config is loaded from ~/.i3/config
instead of $XDG_CONFIG_HOME
, so there shouldn’t be any dependency mismatches.
This is a bit of a pain, but some packages won’t finish compiling and deferred compilation is needed.
ln -s $HOME/.dotfiles/.emacs-profiles.el $HOME/.emacs-profiles.el
mv ~/.emacs.d ~/.emacs.vanilla
echo "vanilla" > ~/.emacs-profile
fdsa#+end_src
Clones & Directories
+ plexus/chemacs2 => ~/.emacs.d
+ dcunited001/dotfiles_doom => ~/.doom.d
+ doomemacs/doomemacs => ~/.emacs.doom
**** Install Doom
Tangle the Doom Config first. Otherwise, Doom install creates its ~/.doom.d first
Doom won't compile right unless a server is running and native comp is
deferred. This is why =.emacs-profile= points to =~/.emacs.d= This
needs to be set in the Chemacs =early-init.el=, so add:
(setq native-comp-deferred-compilation t
native-comp-async-report-warnings-errors t ;; nil
native-comp-warning-on-missing source t)
Then start a vanilla emacs server and run the doom installer.
After install is complete, stop/disable the vanilla server.
DOOMDIR
must be defined…- and
ORG_DIRECTORY
must exist…