Compare commits

...

77 Commits

Author SHA1 Message Date
Ryan Rix 6bf8cd19ac Merge branch 'exwm' 2023-07-27 15:38:51 -07:00
Ryan Rix 923978f09f update version pins 2023-07-27 15:37:40 -07:00
Ryan Rix 52b441dd19 fix vpype build 2023-07-27 15:27:38 -07:00
Ryan Rix ce7958ca5d streamline laptop configuration, ensure pihole DNS is working 2023-07-27 15:27:22 -07:00
Ryan Rix 5eb55a4add smol tweaks to audio configuration 2023-07-27 15:26:58 -07:00
Ryan Rix dd1ae80fdb re-build rss feedbot in-house 2023-07-27 15:26:01 -07:00
Ryan Rix d7c12716b8 enable gpc and disable sponsored stuff in [firefox] 2023-07-27 15:25:39 -07:00
Ryan Rix ada2502a76 tune nix configuration and remote builders 2023-07-27 15:25:26 -07:00
Ryan Rix 980cae01d2 [postgresql] tuning 2023-07-27 15:25:03 -07:00
Ryan Rix e303fd5ef9 fix umask in jellyfin metadata files 2023-07-27 15:24:48 -07:00
Ryan Rix 1b0895b157 default disable exwm 2023-07-27 15:24:36 -07:00
Ryan Rix 2d6b02c360 enable evil-arg [evil] 2023-07-27 15:23:26 -07:00
Ryan Rix 20bbe5583f disable eglot for lsp-mode 2023-07-27 15:23:20 -07:00
Ryan Rix ebacb87401 move mbsync to direct lcoal sync now that i don't use UA 2023-07-27 15:22:36 -07:00
Ryan Rix e882e04fac application changes 2023-07-27 15:19:41 -07:00
Ryan Rix c81b2e9339 swap to ef-bio and ef-cyprus 2023-07-27 15:19:23 -07:00
Ryan Rix f622fee2f9 enable Readability plugin in [ttrss] 2023-07-27 15:18:59 -07:00
Ryan Rix abda4ccf92 bunch of meta stuff 2023-07-27 15:18:52 -07:00
Ryan Rix 9751b0c587 ensure emoji fallback fonts are enabled 2023-07-27 15:17:01 -07:00
Ryan Rix d03e278ce1 fix some xterm-color load hooks 2023-07-27 15:16:43 -07:00
Ryan Rix 2fd4728ea8 i hack [org-fc] to have smaller card review stacks so that i can progress through deep stacks better 2023-07-27 15:16:15 -07:00
Ryan Rix 688288a8ad some [eshell] stuff like [eat] and [eshell/lcd] 2023-07-27 15:15:54 -07:00
Ryan Rix 2c1bfa43a7 disable CR email stuff 2023-07-27 15:11:43 -07:00
Ryan Rix 02eadd453e [nixos] support emacs lisp wasn't tangling to the right location 2023-07-27 15:08:16 -07:00
Ryan Rix e844549f8e fix and re-enable VFIO-pci shit on [tower] 2023-07-27 15:07:20 -07:00
Ryan Rix 2c12aa5a9a strengthen support for framework13, enable lvfs-testing... 2023-07-27 15:06:34 -07:00
Ryan Rix 036d94a879 rewrite atreus page with information about layout and "endgame" 2023-07-27 15:05:47 -07:00
Ryan Rix a1148f1bce stabilize [gpd pocket 3] support 2023-07-27 15:05:28 -07:00
Ryan Rix 090cd9ddd8 re-jigger [wobserver] gitea configuration to disable registration 2023-07-27 15:04:59 -07:00
Ryan Rix 2ab485a1c9 nerdicons and [org-roam] titles in modeline 2023-07-27 15:04:33 -07:00
Ryan Rix 08f9348f04 use [arroyo] to support direnv in literate programming environments 2023-07-27 15:04:04 -07:00
Ryan Rix d0f23201f2 swap to nixos 23.05 2023-07-27 15:03:38 -07:00
Ryan Rix d01396fef9 enable waydroid on endpoints 2023-07-27 15:02:54 -07:00
Ryan Rix 655d224cbb set up [morph] wrapper for easier deploys 2023-07-27 15:02:33 -07:00
Ryan Rix bc6dc6c20e add some lists to my mbsync 2023-04-03 11:39:21 -07:00
Ryan Rix 3166991510 fix shell-mode being aggressively-indented 2023-04-03 11:39:01 -07:00
Ryan Rix 6df05f075d splatter 2023-04-03 11:38:42 -07:00
Ryan Rix 40f4ff4874 strip pinentry-qt from the server build so that the closure is 2gb smaller 2023-04-03 11:35:42 -07:00
Ryan Rix 9f3054cfef clean up laptop support module -- need to do more work here. 2023-04-03 11:35:11 -07:00
Ryan Rix fb103376ae bootstrap for nix-on-droid 2023-04-03 11:34:43 -07:00
Ryan Rix 6348fec5c9 magit-fetch is async and this doesn't work unless you call it twice... use shell-command 2023-04-03 11:33:51 -07:00
Ryan Rix db51b72bcd update version pins 2023-04-03 11:32:28 -07:00
Ryan Rix cb0589349c don't force kernel 5.15 2023-04-03 11:29:42 -07:00
Ryan Rix 9c8fda225c fix the static site for akkoma instance 2023-04-03 11:29:25 -07:00
Ryan Rix 1d4cfad8c7 deployment network has desktop and gpd pocket 3 2023-04-03 11:28:54 -07:00
Ryan Rix 4c9839da24 gpd pocket 3 support module 2023-04-03 11:28:44 -07:00
Ryan Rix adf9f98e65 enable plantuml literate programming configuration 2023-04-03 11:20:49 -07:00
Ryan Rix f9f8691206 install bismuth tiling plugin to kwin 2023-04-03 11:20:40 -07:00
Ryan Rix 4cbdfab473 ws 2023-04-03 11:20:33 -07:00
Ryan Rix 214b142222 small tweaks to feediverse 2023-04-03 11:20:04 -07:00
Ryan Rix be42845fb3 start to swap to eglot maybe 2023-04-03 11:19:43 -07:00
Ryan Rix 2f83132b81 install neochat 2023-04-03 11:19:22 -07:00
Ryan Rix 52373413e0 make DPI/font scale overrides for some machines 2023-04-03 11:19:05 -07:00
Ryan Rix f168398dea more akkoma config 2023-04-03 11:18:53 -07:00
Ryan Rix 826a9c6ddb add configuration for window-smoke desktop with pcie forwarding to VM 2023-04-03 11:11:34 -07:00
Ryan Rix 2818dfb798 setup for my printer 2023-04-03 11:11:08 -07:00
Ryan Rix 96d1c671c9 new server modules jellyfin, feedbot, tt-rss 2023-04-03 11:10:51 -07:00
Ryan Rix cf5ce0dfa0 fixup vsketch builds 2023-04-03 11:10:29 -07:00
Ryan Rix 08187fc566 brush up nixos configuration w/ remote builders, etc 2023-04-03 11:09:53 -07:00
Ryan Rix b021c3b610 split syncthingtray out 2023-04-03 11:07:53 -07:00
Ryan Rix b9d513f179 use vertico/consult for completion-at-point/completion-in-region 2023-02-12 17:44:57 -08:00
Ryan Rix a395d35df7 pin pgsql to version 14, publish page 2023-02-12 17:44:39 -08:00
Ryan Rix 700d63a662 add build configuration, sort imports, publish nix-on-droid 2023-02-12 17:35:01 -08:00
Ryan Rix f8c00e1145 link to update feed in index page 2023-02-12 17:33:49 -08:00
Ryan Rix 08aa6cd6f9 sort HM imports so that it's consistent 2023-02-12 17:33:34 -08:00
Ryan Rix 87327e9df7 add shell and profile configuration 2023-02-12 17:31:47 -08:00
Ryan Rix 41d98f8faa make sure to specify UTF-8 language settings 2023-02-12 17:31:10 -08:00
Ryan Rix d70666efe1 deprecate feed2toot for my modified feediverse 2023-02-12 17:28:50 -08:00
Ryan Rix 8ed2fca04d trying my damndest to get consult-org-roam to behave how i want 2023-02-12 17:27:50 -08:00
Ryan Rix a4828ff0f1 stop using acousticbrainz 2023-02-12 17:26:44 -08:00
Ryan Rix 8c4cd2cfce cleanup beetcamp build 2023-02-12 17:26:36 -08:00
Ryan Rix c3c01512c6 fix face inheritance so that org-mode indent symbols work in ef-themes 2023-02-12 17:26:01 -08:00
Ryan Rix 7890d41c68 switch back to [exwm] :sickos.jpg: 2023-02-12 17:17:48 -08:00
Ryan Rix 50daa5588e publish drawingbot page 2023-02-12 17:14:43 -08:00
Ryan Rix 4fecc17fd4 disable delve 2023-02-12 17:14:31 -08:00
Ryan Rix b16909a384 enable modeline lighters and diminish many of them 2023-02-12 17:11:25 -08:00
Ryan Rix 3b886edbe6 bitwarden and vaultwarden setup on wobserver and endpoints 2023-02-12 16:59:00 -08:00
80 changed files with 3840 additions and 711 deletions

View File

@ -2,8 +2,8 @@
:ID: 20221202T122017.620403
:ROAM_REFS: https://akkoma.dev/AkkomaGang/akkoma https://akkoma.social/
:END:
#+TITLE: Self-Hosting on the Fediverse with (Pleroma for now, eventually) Akkoma
#+FILETAGS: :Akkoma Social:
#+TITLE: Self-Hosting on the Fediverse with Akkoma
#+FILETAGS: :Project:Akkoma Social:
#+ARCOLOGY_KEY: cce/akkoma
Akkoma is a [[id:62538db5-d94a-47c3-9998-086ded91fd88][Fediverse]]/[[id:activitypub][ActivityPub]] server forked from [[roam:Pleroma]] written in [[id:cce/elixir][Elixir]], supporting the [[id:339daa8c-cc01-4654-aa89-330a4e62aafa][Mastodon Server]] API. This is a light-weight thing and I intend to self-publish to the Fediverse with an instance running on [[id:20211120T220054.226284][The Wobserver]].
@ -15,43 +15,43 @@ Akkoma is a [[id:62538db5-d94a-47c3-9998-086ded91fd88][Fediverse]]/[[id:activity
:END:
[2022-12-02 Fri 12:22]
* +Akkoma+ Pleroma on [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][NixOS]]
* Akkoma on [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][NixOS]]
:PROPERTIES:
:ID: 20221202T122135.502628
:ROAM_ALIASES: "Akkoma Server"
:END:
:LOGBOOK:
CLOCK: [2022-12-02 Fri 12:22]--[2022-12-02 Fri 16:24] => 4:02
:END:
Akkoma is properly on its way to being integrated with NixOS through [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][nixpkgs]] in [[id:20221202T122230.525913][nixpkgs PR #192285]], but until then I will run pleroma after trying to get Akkoma to run in docker containers.
The [[https://docs.akkoma.dev/stable/installation/docker_en/][Docker installation]] instructions for Akkoma are built around [[roam:Docker Compose]] which is, fine, but I want to use my system [[id:cce/wobserver/postgres][PostgreSQL]] instead of one hidden in the Compose image so we'll have to do Some Work ourselves. I'll have to set up [[id:20221202T124113.404212][Docker on the Wobserver]] first...
This sucks though, i'll just wait for that nixos module and run Pleroma in the meantime. In theory it'll be easy enough to [[https://docs.akkoma.dev/stable/installation/migrating_to_akkoma/][migrate to akkoma]]...
The configuration interface in NixOS is nicer but also quite complicated. I have this broken up a bit and it consists of *most* of the configuration but not things like emoji and some other static assets like my favicon and whatnot.
It's not super complicated but we'll break it up in to multiple imports so that I can explain what is going on a bit:
#+ARROYO_NIXOS_ROLE: server
#+ARROYO_NIXOS_MODULE: nixos/akkoma.nix
#+AUTO_TANGLE: t
Right now my Pleroma includes an un-released patch to [[https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3661][enable TLSv1.3 support]] so that I can follow users on https://defcon.social:
=myAkkoma= carries an [[https://akkoma.dev/AkkomaGang/akkoma/commit/af7c3fab98f4f5d1fa541035fd8b2821e0abb77b][unreleased patch]] to skip over the Pleroma observability rules -- i need to fix the [[id:20220101T190353.843667][Wobservability]] section below to use this anyways, but I couldn't turn off the observability rules because they were in the DB configuration. Oughtta make sure I move that stuff out in to =config.exs= fairly often.
#+begin_src nix :tangle ~/arroyo-nix/nixos/akkoma.nix :noweb yes
{ config, pkgs, ... }:
{ config, pkgs, lib, ... }:
let
# remove in 2.4.6
myPleroma = pkgs.pleroma.overrideAttrs (old: old // {
patches = (old.patches or []) ++ [ <arroyo/files/pleroma-tls13.patch> ];
myAkkoma = pkgs.akkoma.overrideAttrs (old: old // {
# patches = [
# (<arroyo/files/akkoma-fix-pleroma-migration.patch>)
# ];
});
in
{
in{
imports = [
./akkoma-users.nix
./akkoma-statics.nix
./akkoma-frontends.nix
./akkoma-virtualhost.nix
./akkoma-wobservability.nix
./akkoma-pwa.nix
./akkoma-config.nix
./akkoma-mrf.nix
];
services.postgresql.ensureDatabases = ["akkoma"];
@ -66,60 +66,95 @@ in
}
];
systemd.services.pleroma.path = with pkgs; [exiftool ffmpeg imagemagick];
services.pleroma = {
services.akkoma = {
enable = true;
package = myPleroma;
package = myAkkoma;
# don't feel like needing to chown later on...
group = "akkoma";
user = "akkoma";
configs = [
''
<<initial-configuration>>
''
];
# manually populated
secretConfigFile = "/srv/akkoma/secrets.exs";
};
}
#+end_src
** Initial =config.exs=
** Akkoma Service Configuration
This configuration tells Pleroma that it's fine to be configured in the =admin-fe= interface and provides some defaults from the configuration generator:
ref [[https://docs.akkoma.dev/stable/configuration/cheatsheet/][Configuration Cheat Sheet]], none of this is particularly exciting.
#+begin_src elixir :noweb-ref initial-configuration
import Config
#+begin_src nix :tangle ~/arroyo-nix/nixos/akkoma-config.nix
{ config, pkgs, ... }:
{
services.akkoma.extraPackages = with pkgs; [exiftool ffmpeg-headless imagemagick];
# don't feel like setting password._secret here...
services.akkoma.initDb.enable = false;
services.akkoma.config = {
":pleroma".":instance" = {
name = "Computers :(";
description = "rrix's fediverse home";
email = "fedi@whatthefuck.computer";
registrations_open = false;
limit = 5000;
local_bubble = [
"botsin.space"
"hackers.town"
"tenforward.social"
"regenerate.social"
];
export_prometheus_metrics = true;
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "notes.whatthefuck.computer", scheme: "https", port: 443],
http: [ip: {127, 0, 0, 1}, port: 4000]
static_dir = "/srv/akkoma/static";
upload_dir = "/srv/akkoma/uploads";
};
config :pleroma, :instance,
name: "Computers :(",
email: "fedi@whatthefuck.computer",
notify_email: "fedi@whatthefuck.computer",
limit: 5000,
registrations_open: false
":pleroma".":static_fe".enabled = true;
config :pleroma, :media_proxy,
enabled: false,
redirect_on_failure: true
":pleroma"."Pleroma.Repo" = {
adapter = (pkgs.formats.elixirConf { }).lib.mkRaw "Ecto.Adapters.Postgres";
username = config.services.akkoma.user;
database = "akkoma";
hostname = "localhost";
};
config :pleroma, :database, rum_enabled: false
config :pleroma, :instance, static_dir: "/srv/akkoma/static"
config :pleroma, Pleroma.Uploaders.Local, uploads: "/srv/akkoma/uploads"
":pleroma".":configurable_from_database" = true;
# Enable Strict-Transport-Security once SSL is working:
# config :pleroma, :http_security,
# sts: true
":pleroma".":media_proxy" = {
enabled = true;
proxy_opts.redirect_on_failure = true;
};
config :pleroma, configurable_from_database: true
":pleroma"."Pleroma.Upload".filters =
map (pkgs.formats.elixirConf { }).lib.mkRaw [
"Pleroma.Upload.Filter.Exiftool"
"Pleroma.Upload.Filter.Dedupe"
"Pleroma.Upload.Filter.AnonymizeFilename"
];
config :pleroma, Pleroma.Upload, filters: [Pleroma.Upload.Filter.Exiftool, Pleroma.Upload.Filter.Dedupe]
":pleroma"."Pleroma.Web.Endpoint" = {
http = {
ip = "127.0.0.1";
port = 4000;
};
url = {
host = "notes.whatthefuck.computer";
scheme = "https";
port = 443;
};
};
# secrets
":pleroma"."Pleroma.Repo".password._secret = "/srv/akkoma/dbpass";
":joken".":default_signer"._secret = "/srv/akkoma/jwt-signer";
":pleroma"."Pleroma.Web.Endpoint" = {
live_view.signing_salt._secret = "/srv/akkoma/liveview-salt";
secret_key_base._secret = "/srv/akkoma/secret-key-base";
signing_salt._secret = "/srv/akkoma/signing-salt";
};
":web_push_encryption".":vapid_details" = {
private_key._secret = "/srv/akkoma/vapid-private";
public_key._secret = "/srv/akkoma/vapid-public";
subject = "mailto:fedi@whatthefuck.computer";
};
};
}
#+end_src
** System Users
@ -149,6 +184,99 @@ I really would like to manage my uids and gids better, but alas.
}
#+end_src
** Frontend Management
so if you set a =static_dir= to a mutable directory on the server, the NixOS module won't install the frontends you ask for. This is good and fine, and not a surprise, certainly not undocumented. So what if you just:
=pleroma_ctl frontend install admin-fe --ref stable=
=pleroma_ctl frontend install fedibird-fe --ref akkoma=
=pleroma_ctl frontend install pleroma-fe --ref stable=
That fails because =BindReadOnlyPaths= is set in the NixOS module as part of the hardening of the service. I shouldn't mind, but =** (File.Error) could not make directory (with -p) "/srv/akkoma/static/frontends/tmp": read-only file system=
so, okay, make sure =BindReadOnlyPaths= is not set, and set =ReadWritePaths= just to be sure.
In theory it'd be possible to use a =system.activationScripts= entry to take =frontends.$foo.package= and slam a symlink in like I do for the terms of service above, but i'm tired.
#+begin_src nix :tangle ~/arroyo-nix/nixos/akkoma-frontends.nix
{ config, pkgs, lib, ... }:
{
systemd.services.akkoma.serviceConfig.ReadWritePaths = [ config.services.akkoma.config.":pleroma".":instance".static_dir ];
systemd.services.akkoma.serviceConfig.BindReadOnlyPaths = lib.mkForce [ ];
services.akkoma.frontends = {
primary = {
name = "pleroma-fe";
ref = "stable";
};
mastodon= {
name = "fedibird-fe";
ref = "akkoma";
};
admin = {
name = "admin-fe";
ref = "stable";
};
};
# shove this thing in a system.activationScript to symlink to static_dir/frontends
# frontends.primary.package = pkgs.runCommand "akkoma-fe" {
# config = builtins.toJSON {
# expertLevel = 1;
# collapseMessageWithSubject = false;
# replyVisibility = "following";
# hideScopeNotice = true;
# renderMisskeyMarkdown = false;
# hideSiteFavicon = true;
# postContentType = "text/markdown";
# showNavShortcuts = false;
# };
# nativeBuildInputs = with pkgs; [ jq xorg.lndir ];
# passAsFile = [ "config" ];
# } ''
# mkdir $out
# lndir ${pkgs.akkoma-frontends.akkoma-fe} $out
#
# rm $out/static/config.json
# jq -s add ${pkgs.akkoma-frontends.akkoma-fe}/static/config.json ${config} \
# >$out/static/config.json
# '';
}
#+end_src
** Nginx Frontend for Akkoma
Nothing special here -- I have it split in to two blocks here because one of my old iterations of [[id:1d917282-ecf4-4d4c-ba49-628cbb4bb8cc][The Arcology Project]] used this domain to host short-form [[id:fa6cee69-dca0-45f5-ae9e-b71cad3702a6][IndieWeb]]/microformat notes. The old files still exist and can be resolved in the =try_files= block, and any failures will proxy through to the app backend. I also adjust the max body size for image uploads, etc. I might replace that with S3 in the future but for now the images can just go on to the file system.
#+begin_src nix :tangle ~/arroyo-nix/nixos/akkoma-virtualhost.nix
{ ... }:
{
services.nginx.virtualHosts."notes.whatthefuck.computer" = {
root = "/srv/static-sites/notes.whatthefuck.computer/_site";
extraConfig = ''
client_max_body_size 100M;
'';
locations."/".extraConfig = ''
try_files $uri @proxy;
'';
locations."@proxy" = {
proxyPass = "http://127.0.0.1:4000";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
'';
};
locations."/phoenix/live_dashboard".extraConfig = ''
auth_basic "closed site";
auth_basic_user_file /etc/nginx-htpasswd;
'';
};
}
#+end_src
** Static Files
I could just splat this on to the filesystem but no harm in having it in the Nix store:
@ -161,11 +289,6 @@ I could just splat this on to the filesystem but no harm in having it in the Nix
what is going on here.
</p>
<p>
This is a Pleroma instance. Not because I want it to be but because
Akkoma isn't natively packaged in NixOS yet.
</p>
<p>
<ul>
<li>I'm not a fascist.</li>
@ -192,7 +315,7 @@ I could just splat this on to the filesystem but no harm in having it in the Nix
<p>
At the same time, I'm likely not going to be able to go
up against government requests for data stored on this instace. As
of [2022-12-04] this instance has not been compelled to give data to
of [2023-02-16] this instance has not been compelled to give data to
any government or law enforcement agency and has not done so
voluntarily. I'm just one homie hanging out making posts with my
friends and trying to make new ones, and you're here reading
@ -203,52 +326,24 @@ I could just splat this on to the filesystem but no harm in having it in the Nix
#+begin_src nix :tangle ~/arroyo-nix/nixos/akkoma-statics.nix :noweb yes
{ config, pkgs, ... }:
{
system.activationScripts = let
tos = pkgs.writeTextFile {
name="pleroma-terms-of-service";
text = ''
<<tos>>
let
tos = pkgs.writeTextFile {
name="pleroma-terms-of-service";
text = ''
<<tos>
'';
};
in {
install-pleroma-tos.text = ''
};
in
{
# services.akkoma.extraStatic."static/terms-of-service.html" = tos;
system.activationScripts.install-pleroma-tos.text = ''
echo "Installing Pleroma Terms of Service to static directory"
export DEST_DIR=/srv/akkoma/static/
mkdir -p $DEST_DIR
ln -sf ${tos} $DEST_DIR/static/terms-of-service.html
'';
};
}
#+end_src
** Nginx Frontend for Akkoma
Nothing special here -- I have it split in to two blocks here because one of my old iterations of [[id:1d917282-ecf4-4d4c-ba49-628cbb4bb8cc][The Arcology Project]] used this domain to host short-form [[id:fa6cee69-dca0-45f5-ae9e-b71cad3702a6][IndieWeb]]/microformat notes. The old files still exist and can be resolved in the =try_files= block, and any failures will proxy through to the app backend. I also adjust the max body size for image uploads, etc. I might replace that with S3 in the future but for now the images can just go on to the file system.
#+begin_src nix :tangle ~/arroyo-nix/nixos/akkoma-frontends.nix
{ ... }:
{
services.nginx.virtualHosts."notes.whatthefuck.computer" = {
extraConfig = ''
client_max_body_size 100M;
'';
locations."/".extraConfig = ''
try_files $uri @proxy;
'';
locations."@proxy" = {
proxyPass = "http://127.0.0.1:4000";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
'';
};
};
}
#+end_src
** [[id:20220101T190353.843667][Wobservability]]
@ -270,3 +365,114 @@ Enable =Pleroma.Web.Endpoint.MetricsExporter= in settings.
];
}
#+end_src
** PWA manifest for Pleroma-FE
Pleroma's mute filters, etc aren't 1-1 compatible with Mastodon API so they don't work in Mastodon-FE or Subway Tooter... This is ...unfortunate. Let's see how using Pleroma-FE as a [[https://developer.mozilla.org/en-US/docs/Web/Manifest][Progressive Web App]] goes..
#+begin_src json :tangle ~/arroyo-nix/files/notes-pwa.json
{
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
"name": "Fedi Notes",
"short_name": "Fedi Notes",
"start_url": "https://notes.whatthefuck.computer/",
"display": "standalone",
"background_color": "#004daa",
"theme_color": "#31363b",
"description": "Pleroma-FE on notes.whatthefuck.computer",
"icons": [{
"src": "https://notes.whatthefuck.computer/media/e8ecd309a5e3d99736beff056fb461ba157dc4ff9317f3cc6063c4ce280bd604.blob",
"sizes": "312x312",
"type": "image/png"
}]
}
#+end_src
This needs to be shoved in to =<head>= and there's no way to do that directly in Pleroma-FE so I make a silly little HTML page and shove it on to a virtualhost:
#+begin_src web :tangle ~/arroyo-nix/files/notes-pwa.html
<html>
<head>
<link rel="manifest" href="notes-pwa.json" />
</head>
<body>
<h1>Pleroma-FE as PWA</h1>
<p>
On browsers which support "add to home screen" or similar
things, you can create a Progressive Web App which will
load the <code>Computer :(</code> site in a dedicated frame.
</p>
</body>
</html>
#+end_src
And this is installed, like so:
#+begin_src nix :tangle ~/arroyo-nix/nixos/akkoma-pwa.nix
{ config, pkgs, ... }:
{
system.activationScripts = let
json = <arroyo/files/notes-pwa.json>;
html = <arroyo/files/notes-pwa.html>;
in {
install-pleroma-tos.text = ''
echo "Installing Pleroma PWA manifest and static page"
export DEST_DIR=/srv/static-sites/default
mkdir -p $DEST_DIR
ln -sf ${html} $DEST_DIR/pwa.html
ln -sf ${json} $DEST_DIR/notes-pwa.json
'';
};
services.nginx.virtualHosts."fontkeming.fail".extraConfig = ''
disable_symlinks off;
'';
}
#+end_src
## why 404?
** NEXT Akkoma Moderation Rules
the new [[https://docs.akkoma.dev/stable-docs/configuration/mrf/][Message Rewrite Facility]] x [[https://fediblock.neocities.org/][fediblock]] dropped. I don't see a lot of this stuff and part of me thinks that having it boosted in to my TWKN or even home timeline is a great signal that I should be unfollowing whoever is bringing the filth in to my instance, but also I want to respect my own sanity.
#+begin_src nix :tangle ~/arroyo-nix/nixos/akkoma-mrf.nix :noweb yes
{ pkgs, ... }:
let ecf = pkgs.formats.elixirConf {};
in
{
services.akkoma.config = {
":pleroma".":instance" = {
quarantined_instances = [
<<quarantined_instances()>>
];
};
":pleroma".":mrf".policies = ecf.lib.mkRaw "Pleroma.Web.ActivityPub.MRF.SimplePolicy";
":pleroma".":mrf_simple".reject = [
<<reject_instances()>>
];
};
}
#+end_src
These two functions generate those from a table I don't export.
#+NAME: quarantined_instances
#+begin_src emacs-lisp :noweb-ref quarantined_instances :var tbl=blocked-domains
(->> tbl
(-map #'first)
(--map (format "\"%s\"" it))
(s-join "\n"))
#+end_src
This elixirConf stuff, and the declarative config model, is pretty slick. [[file:~/Code/nixpkgs/pkgs/pkgs-lib/formats.nix::{ lib, pkgs }:][<nixpkgs/pkgs/pkgs-lib/formats.nix>]]
#+NAME: reject_instances
#+begin_src emacs-lisp :noweb-ref reject_instances :var tbl=blocked-domains
(->> tbl
(--map (format "(ecf.lib.mkTuple [\"%s\" \"%s\"])" (first it) (second it)))
(s-join "\n"))
#+end_src

View File

@ -4,17 +4,20 @@
:END:
#+TITLE: Themeing my Emacs and Desktop
#+PROPERTY: header-args :mkdirp yes
#+ARCOLOGY_ALLOW_CRAWL: t
#+PROPERTY: header-args:emacs-lisp :tangle appearance.el
#+ARCOLOGY_KEY: cce/appearance
#+ARCOLOGY_ALLOW_CRAWL: t
* Themeing my Emacs
#+ARROYO_EMACS_MODULE: appearance
#+ARCOLOGY_KEY: cce/appearance
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARROYO_MODULE_WANTS: cce/external_display_test_functions.org
#+ARROYO_MODULE_WANTS: cce/emacs_session.org
#+ARROYO_MODULE_WANTS: cce/shared_cce_helpers.org
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARROYO_MODULE_WANTS: cce/external_display_test_functions.org
#+ARROYO_MODULE_WANTS: cce/emacs_session.org
#+ARROYO_MODULE_WANTS: cce/shared_cce_helpers.org
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+ARROYO_MODULE_WANTED: cce/run_hooks_after_init.org
#+begin_src emacs-lisp
@ -25,23 +28,17 @@ I generally prefer dark and muted colors for the computers that I use. Barring e
Right now, I am experimenting with using some themes from the [[https://github.com/hlissner/emacs-doom-themes/][Doom Themes]] or [[https://github.com/protesilaos/ef-themes][ef-themes]] repositories, trying to find an earthy natural theme which I can use also on my web sites.
I load a dark theme and a light theme, +=manegarm= and =acario-light=+ =ef-autumn= and =ef-spring= respectively.
I load a dark theme and a light theme, +=manegarm= and =acario-light=+ +=ef-autumn= and =ef-spring=+ =ef-bio= and =ef-cyprus= respectively.
#+begin_src emacs-lisp
(load custom-file)
;; (use-package doom-themes
;; :ensure t
;; :demand
;; :config
;; (load-theme 'doom-manegarm t)
;; (load-theme 'doom-opera-light t t))
(use-package ef-themes
:ensure t
:demand
:config
(load-theme 'ef-autumn t)
(load-theme 'ef-spring t t))
(load-theme 'ef-bio t)
(load-theme 'ef-cyprus t t))
#+end_src
I don't use my mouse very often so things like icon-bars and scroll-bars aren't useful to me. The modeline contains the buffer's progress, and I don't actually use the scrollbar to navigate. This leaves a tiny bit more room for the fringe and the buffers, which I consider a win.
@ -53,6 +50,10 @@ I don't use my mouse very often so things like icon-bars and scroll-bars aren't
(column-number-mode -1)
(line-number-mode -1)
(setq x-stretch-cursor t)
(setq visible-bell t)
(with-eval-after-load "diminish"
(diminish 'buffer-face-mode)
(diminish 'evil-collection-unimpaired-mode))
#+END_SRC
** Set cursor for each =evil-state= based on Doom Theme colors
@ -95,7 +96,7 @@ Here is a set of functions for [[id:cce/cce][CCE]] which set up my font preferen
(with-eval-after-load 'org (set-face-attribute 'org-block nil :inherit 'fixed-pitch))
(with-eval-after-load 'linum (set-face-attribute 'linum nil :inherit 'default :height size)))
(set-face-attribute 'default nil :height size)
(set-face-attribute 'fixed-pitch nil)
;; (set-face-attribute 'fixed-pitch nil)
(set-face-attribute 'variable-pitch nil :slant 'oblique :height size)
(cce/enable-ipaex-font (/ size 3)))
#+end_src
@ -114,6 +115,8 @@ This calculates the DPI of external displays, assuming they report their physica
(defun cce/refresh-display-scale ()
(interactive)
(cond ((not (cce/has-display-frames)) nil)
((equal (system-name) "window-smoke") (cce/set-font-scale 110))
((equal (system-name) "rose-quine") (cce/set-font-scale 125))
((cce/external-display-connected) (-> (cce/external-display-dpis)
(first)
(cdr)

View File

@ -44,7 +44,10 @@ in
home.file.".config/autostart/cantata.desktop".source = "${cantata}/share/applications/cantata.desktop";
home.file.".config/autostart/signal-desktop.desktop".source = "${signal-desktop}/share/applications/signal-desktop.desktop";
home.file.".config/autostart/discord.desktop".source = "${discord}/share/applications/discord.desktop";
home.file.".config/autostart/discord.desktop" = {
enable= false;
source = "${discord}/share/applications/discord.desktop";
};
home.file.".config/autostart/element-desktop.desktop".source = "${element-desktop}/share/applications/element-desktop.desktop";
home.packages = [
@ -63,8 +66,10 @@ in
(mkNixGLWrapper { name="xournalpp"; })
(mkNixGLWrapper { name="element-desktop"; })
(mkNixGLWrapper { name="neochat"; })
(mkNixGLWrapper { name="discord"; })
(mkNixGLWrapper { name="signal-desktop"; })
(mkNixGLWrapper { name="tokodon"; })
# (mkNixGLWrapper { name="tdesktop"; }) # telegram-desktop
pavucontrol
@ -74,6 +79,8 @@ in
cataclysm-dda
(mkNixGLWrapper { name="runelite"; })
(mkNixGLWrapper { name="ryujinx"; })
(mkNixGLWrapper { name="yuzu-mainline"; })
virt-manager
libvirt

View File

@ -8,11 +8,13 @@
#+PROPERTY: header-args:emacs-lisp :tangle code-base.el
#+PROPERTY: header-args:yaml :tangle roles/endpoint/tasks/code-base.yml
#+ARROYO_EMACS_MODULE: code-base
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARCOLOGY_KEY: cce/code-base
#+ARROYO_EMACS_MODULE: code-base
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+begin_src emacs-lisp
(provide 'cce/code-base)
#+end_src
@ -20,13 +22,14 @@
I like having line numbers when I'm programming.
#+begin_src emacs-lisp
(setq linum-delay t
linum-eager nil)
(add-hook 'prog-mode-hook 'linum-mode)
;; (setq linum-delay t
;; linum-eager nil)
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
#+end_src
Eldoc is useful wherever the major mode supports it
#+begin_src emacs-lisp
(global-eldoc-mode)
(diminish 'eldoc-mode)
#+end_src

View File

@ -50,6 +50,7 @@ SCHEDULED: <2022-05-27 Fri>
:PROPERTIES:
:ID: 20220611T182415.660603
:ROAM_REFS: https://github.com/NixOS/nixpkgs/pull/176978
:ROAM_ALIASES: beetcamp
:END:
:LOGBOOK:
- Note taken on [2022-06-11 Sat 18:24] \\
@ -75,7 +76,7 @@ python3Packages.buildPythonPackage {
format = "pyproject";
propagatedBuildInputs = with python3Packages; [ setuptools poetry requests cached-property pycountry python-dateutil ordered-set ]
propagatedBuildInputs = with python3Packages; [ setuptools poetry-core requests cached-property pycountry python-dateutil ordered-set ]
++ (lib.optional propagateBeets [ beets ]);
postInstall = ''
@ -110,6 +111,7 @@ python3Packages.buildPythonPackage {
* File Organization
:PROPERTIES:
:ID: music-file-organization
:ROAM_ALIASES: "Music File Organization"
:END:
I keep my music in =~/Music= and a few subdirectories underneath it so that i can use [[id:cce/syncthing][Syncthing]]'s filtering to narrow the [[id:3182614c-9122-4b01-ac3f-9f99e56bfdbd][Music]] i sync to devices with less storage like the [[id:cosmo_communicator][Cosmo Communicator]] or whatever.
@ -172,7 +174,7 @@ echo $TMPD
* Beets Configuration
#+begin_src yaml :tangle ~/Music/beets/config.yaml
plugins: fetchart embedart convert scrub replaygain lastgenre web acousticbrainz fetchart smartplaylist copyartifacts discogs bandcamp
plugins: fetchart embedart convert scrub replaygain lastgenre web fetchart smartplaylist copyartifacts discogs bandcamp
directory: /home/rrix/Music
library: /home/rrix/Music/beets/musiclibrary.blb
art_filename: albumart
@ -214,7 +216,7 @@ import:
log: /home/rrix/Music/beets/beet.log
#+end_src
I use =beetcamp=:
I use [[id:20220611T182415.660603][=beetcamp=]]:
#+begin_src yaml :tangle ~/Music/beets/config.yaml
bandcamp:

39
bitwarden-passwords.org Normal file
View File

@ -0,0 +1,39 @@
:PROPERTIES:
:ID: 20230201T121135.988658
:ROAM_ALIASES: Bitwarden
:END:
#+TITLE: Bitwarden on NixOS/Home Manager
#+filetags: :Project:
#+ARCOLOGY_KEY: cce/bitwarden
#+ARCOLOGY_ALLOW_CRAWL: t
I used [[id:cce/the_standard_unix_password_manager][The Standard UNIX Password Manager]] but I would prefer to stop caring about that PGP key. I set up [[id:20230201T121604.003311][vaultwarden]] on [[id:20211120T220054.226284][The Wobserver]] and this will talk to that. There's also a [[id:cce/a_basic_firefox_installation][Firefox]] addon available.
* Bitwarden CLI client on [[id:cce/my_nixos_configuration][Endpoint Configuration]]
#+ARROYO_HOME_MODULE: hm/bitwarden.nix
#+ARROYO_NIXOS_ROLE: endpoint
#+ARROYO_EMACS_MODULE: bitwarden
#+begin_src nix :tangle ~/arroyo-nix/hm/bitwarden.nix
{ pkgs, ... }:
{
home.packages = [ pkgs.bitwarden ];
programs.rbw = {
enable = true;
settings = {
email = "ryan@whatthefuck.computer";
pinentry = "qt";
base_url = "https://vault.whatthefuck.computer";
};
};
}
#+end_src
** NEXT add [[https://github.com/seanfarley/emacs-bitwarden/][emacs-bitwarden]] or similar wrapper around =rbw=
#+begin_src emacs-lisp :tangle ~/org/cce/bitwarden.el
#+end_src

View File

@ -156,12 +156,13 @@ Updating the Nixpkgs checkout can be by invoking something like =cce/update-nixp
(let ((path "/home/rrix/Code/nixpkgs/"))
(with-current-buffer (find-file-noselect path)
(let* ((channel-status (split-string
(plz "GET" "https://channels.nix.gsc.io/nixpkgs-unstable/latest")
(plz "GET" "https://channels.nix.gsc.io/nixos-23.05/latest")
" "))
(nixpkgs-unstable-ts (string-to-number (second channel-status)))
(nixpkgs-unstable (first channel-status)))
(magit-fetch-all nil)
(magit-merge-plain "origin/nixpkgs-unstable")
(shell-command "git fetch --all")
;; (magit-fetch-all nil)
(magit-merge-plain "origin/nixos-23.05")
(message "updated nixpkgs checkout to %s"
(format-time-string "%c" nixpkgs-unstable-ts))))))
(provide 'cce/nixpkgs)

View File

@ -7,10 +7,12 @@
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle aggressive-indent.el
#+ARROYO_EMACS_MODULE: aggressive-indent
#+ARCOLOGY_KEY: cce/aggressive-indent
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_EMACS_MODULE: aggressive-indent
#+ARROYO_MODULE_WANTS: cce/basic_emacs_coding_config.org
#+ARROYO_MODULE_WANTS: cce/diminish.org
Emacs has a package which will dynamically re-align code whenever I make changes to the buffer. For languages that don't use whitespace for defining context (python, makefile, for example), this is optimal and it does a good job showing me when I've made syntax errors. Sometimes it's a bit too annoying, but alas.
@ -18,5 +20,7 @@ Emacs has a package which will dynamically re-align code whenever I make changes
(provide 'cce/aggressive-indent)
(use-package aggressive-indent
:diminish "⮕"
:config (global-aggressive-indent-mode))
:config
(add-to-list 'aggressive-indent-excluded-modes 'shell-mode)
(global-aggressive-indent-mode))
#+end_src

View File

@ -1,7 +1,7 @@
:PROPERTIES:
:ID: cce/company_code_completion
:END:
#+TITLE: Company Code Completion
#+TITLE: Company Mode Code Completion
#+filetags: :Emacs:CCE:Coding:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle company.el
@ -44,3 +44,4 @@ These four combined give me basic completion in all buffers, based on words in t
(use-package company-prescient :init (company-prescient-mode +1))
#+END_SRC
#+ARROYO_MODULE_WANTS: cce/selectrum_etc.org
#+ARROYO_MODULE_WANTS: cce/diminish.org

View File

@ -9,37 +9,43 @@ Okay, so [[id:cce/selectrum_etc][Consult]] provides a composable, high performan
[[https://github.com/jgru/consult-org-roam/][jgru/consult-org-roam]] provides a bunch of nice features which should be bound in to my org-roam command prefix.. It's not in MELPA or anything, just another thing that expects me to use =straight-use-package= to load it --- well here is some fucked up stuff for providing it to [[id:arroyo/emacs][Arroyo Emacs]]'s init generator via =ARROYO_HOME_EPKGS=.
#+ARROYO_EMACS_MODULE: consult-org-roam
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARROYO_MODULE_WANTS: cce/evil_mode.org
#+ARROYO_MODULE_WANTS: cce/org_mode_installation.org
#+ARROYO_EMACS_MODULE: consult-org-roam
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+ARROYO_MODULE_WANTS: cce/org-roam.org
#+ARROYO_MODULE_WANTS: cce/selectrum_etc.org
#+ARCOLOGY_KEY: cce/consult-buffer-org-roam
#+ARCOLOGY_ALLOW_CRAWL: t
#+begin_src emacs-lisp :tangle consult-org-roam.el :results none
(condition-case nil
(use-package consult-org-roam
:init
(require 'consult-org-roam)
;; Activate the minor-mode
(consult-org-roam-mode 1)
;; restore behavior of consult-buffer overridden by consult-org-roam-buffer... prefer mine.
(consult-customize
consult--source-buffer
:items (lambda ()
(consult--buffer-query :sort 'visibility
:as #'buffer-name)))
:custom
(consult-org-roam-grep-func #'consult-ripgrep)
:config
;; Eventually suppress previewing for certain functions
(consult-customize
consult-org-roam-forward-links
:preview-key (kbd "M-."))
:bind (:map org-roam-prefix-map)
("b" . consult-org-roam-backlinks)
("/" . consult-org-roam-search)
:after (consult org-roam))
(error nil))
(use-package consult-org-roam
:diminish
:init
(message "Loading consult-org-roam HERE")
(require 'consult-org-roam)
;; Activate the minor-mode
(consult-org-roam-mode 1)
;; restore behavior of consult-buffer overridden by consult-org-roam-buffer... prefer mine.
:custom
(consult-org-roam-grep-func #'consult-ripgrep)
:config
;; Eventually suppress previewing for certain functions
(message "Trying to override consult-org-roam-buffer behavior HERE...")
(consult-org-roam-buffer--customize-source-buffer nil)
(consult-customize
consult-org-roam-forward-links
:preview-key (kbd "M-."))
:bind (:map org-roam-prefix-map)
("b" . consult-org-roam-backlinks)
("/" . consult-org-roam-search)
:hook
(after-cce . (lambda ()
(message "Trying to override consult-org-roam-buffer behavior HERE (after-cce)...")
(consult-org-roam-buffer--customize-source-buffer nil)))
:after (consult org-roam))
(provide 'cce/consult-org-roam)
#+end_src
@ -71,10 +77,6 @@ in epkgs.melpaBuild {
});
#+end_src
#+ARCOLOGY_KEY: cce/consult-buffer-org-roam
#+ARROYO_MODULE_WANTS: cce/org-roam.org
#+ARROYO_MODULE_WANTS: cce/selectrum_etc.org
#+begin_src emacs-lisp :tangle consult-org-roam.el :results none
(condition-case nil
(progn

35
cups_setup.org Normal file
View File

@ -0,0 +1,35 @@
:PROPERTIES:
:ID: 20230321T143139.441973
:END:
#+TITLE: My Brother Printer and CUPS Setup
#+filetags: :Project:
#+ARROYO_NIXOS_MODULE: nixos/cups.nix
#+ARROYO_NIXOS_EXCLUDE: droid
#+AUTO_TANGLE: t
#+begin_src nix :tangle ~/arroyo-nix/nixos/cups.nix
{ pkgs, ... }:
{
# environment.systemPackages = with pkgs; [ gscan2pdf skanlite gocr ];
services.printing.enable = true;
services.printing.drivers = [ pkgs.brlaser ];
hardware.printers.ensurePrinters = [
{
name = "brotha";
description = "Brother DCP-L2550DW";
deviceUri = "dnssd://Brother%20DCP-L2550DW%20series._ipp._tcp.local/?uuid=e3248000-80ce-11db-8000-b42200ae9c8e";
location = "tearoom";
model = "everywhere";
}
];
hardware.sane.enable = true;
services.saned.enable = true;
}
#+end_src
* NEXT gscan2pdf broken [[https://github.com/NixOS/nixpkgs/issues/223446][in nixpkgs-unstable]]
SCHEDULED: <2023-04-03 Mon>

View File

@ -4,7 +4,7 @@
:ROAM_ALIASES: Datasette
:END:
#+title: Datasette: An open source multi-tool for exploring and publishing data
#+filetags: :Archive:CCE:Development:Tools:
#+filetags: :Project:Archive:CCE:Development:Tools:
#+AUTO_TANGLE: t
#+ARCOLOGY_KEY: cce/datasette
#+ARCOLOGY_ALLOW_CRAWL: t
@ -19,7 +19,8 @@ Datasette is aimed at data journalists, museum curators, archivists, local gover
These could be used to generate [[id:1fb8fb45-fac5-4449-a347-d55118bb377e][org-mode]] files for [[id:1d917282-ecf4-4d4c-ba49-628cbb4bb8cc][The Arcology Project]] and my [[id:knowledge_base][Knowledge Base]]....
* iNaturalist to [[roam:Sqlite][Sqlite]]
* NEXT pull ~/DataExports from [[id:20211029T115928.954970][Virtuous Cassette]] and move to [[id:cce/syncthing][Syncthing]]
* Inaturalist to [[roam:Sqlite][Sqlite]]
:PROPERTIES:
:ID: 20220727T152924.019338
:END:

View File

@ -4,7 +4,7 @@
:ROAM_ALIASES: delve publicimageltd/delve
:END:
#+TITLE: publicimageltd/delve
#+filetags: :Archive:CCE:
#+filetags: :Project:Archive:CCE:
#+ARCOLOGY_KEY: cce/delve
#+AUTO_TANGLE: t
@ -21,12 +21,12 @@ Opening Delve the first time, you can browse your zettelkasten by ROAM_TAG, or u
#+END_QUOTE
#+begin_src emacs-lisp :tangle delve.el
(use-package lister)
(use-package delve
:config
(require 'delve-minor-mode)
(evil-set-initial-state 'delve-mode 'motion)
(delve-global-minor-mode))
;; (use-package lister)
;; (use-package delve
;; :config
;; (require 'delve-minor-mode)
;; (evil-set-initial-state 'delve-mode 'motion)
;; (delve-global-minor-mode))
(provide 'cce/delve)
#+end_src
@ -53,3 +53,6 @@ delve = epkgs.melpaBuild {
};
};
#+end_src
* NEXT Investigate patching failure to =(require 'delve)=
* NEXT Configure this with useful dashboards

57
diminish.org Normal file
View File

@ -0,0 +1,57 @@
:PROPERTIES:
:roam_refs: https://github.com/emacsmirror/diminish/blob/master/diminish.el#L129
:ID: 20220907T235417.715959
:END:
#+title: diminish/diminish.el at master · emacsmirror/diminish
#+filetags: :Archive:
#+ARCOLOGY_KEY: lionsrear/poetry/diminish.el
#+ARCOLOGY_ALLOW_CRAWL: t
[[file:archive.org][Archive]] [[id:Poetry][Poetry]] [[id:cce/emacs][Emacs]]
Just reading some code...
#+begin_src emacs-lisp
;; Plumber Bob was not from Seattle, my grey city, for rainy Seattle is a
;; city of interiors, a city of the self-diminished. When I moved here one
;; sunny June I was delighted to find that ducks and geese were common in
;; the streets. But I hoped to find a loon or two, and all I found were
;; ducks and geese. I wondered about this; I wondered why there were no
;; loons in Seattle; but my confusion resulted from my ignorance of the
;; psychology of rain, which is to say my ignorance of diminished modes.
;; What I needed, and lacked, was a way to discover they were there.
;;;###autoload
(defun diminished-modes ()
"Echo all active diminished or minor modes as if they were minor.
#+end_src
#+begin_src emacs-lisp
;; A human mind is a Black Forest of diminished modes. Some are dangerous;
;; most of the mind of an intimate is a secret stranger, and these diminished
;; modes are rendered more unpredictable by their long isolation from the
;; corrective influence of interaction with reality. The student of history
;; learns that this description applies to whole societies as well. In some
;; ways the self-diminished are better able to discern the night worker.
;; They are rendered safer by their heightened awareness of others'
;; diminished modes, and more congenial by the spare blandness of their own
;; mode lines. To some people rain is truly depressing, but others it just
;; makes pensive, and, forcing them indoors where they may not have the
;; luxury of solitude, teaches them to self-diminish. That was what I had
;; not understood when I was searching for loons among the ducks and geese.
;; Loons come to Seattle all the time, but the ones that like it learn to be
;; silent, learn to self-diminish, and take on the colors of ducks and geese.
;; Now, here a dozen years, I can recognize them everywhere, standing quietly
;; in line with the ducks and geese at the espresso counter, gazing placidly
;; out on the world through loon-red eyes, thinking secret thoughts.
#+end_src
I use diminish, extensively:
#+ARROYO_EMACS_MODULE: diminish
#+begin_src emacs-lisp :tangle ~/org/cce/diminish.el
(use-package diminish)
(provide 'cce/diminish)
#+end_src

View File

@ -6,7 +6,7 @@
#+filetags: :CCE:
#+ARCOLOGY_KEY: cce/direnv
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args :mkdirp yes
#+PROPERTY: header-args:emacs-lisp :tangle direnv.el
#+ARROYO_EMACS_MODULE: direnv
@ -38,6 +38,7 @@ Anyways it has an [[id:cce/emacs][Emacs]] package which works really well and re
(provide 'cce/direnv)
#+end_src
#+ARROYO_HOME_MODULE: hm/direnv.nix
#+begin_src nix :tangle ~/arroyo-nix/hm/direnv.nix
{pkgs, ...}:
@ -58,3 +59,40 @@ Anyways it has an [[id:cce/emacs][Emacs]] package which works really well and re
'';
}
#+end_src
With =direnv= activated, any directory with a =shell.nix= in it and an =.envrc= file that says =use nix= in it can be allowed to spawn development environments:
#+begin_src shell
cat ~/org/arcology-fastapi/.envrc
#+end_src
#+results:
: use nix
* Direnv [[id:arroyo/system-cache][arroyo-db]] integration
:PROPERTIES:
:ID: 20230526T105534.711282
:END:
One of the issues of doing [[id:cce/literate_programming][Literate Programming with Org Babel]] is that if I work inside of my [[id:cce/org-roam][org-roam]] directory the direnv stuff won't map to the tangled directory. If I add a =ARROYO_DIRENV_DIR= file property to a document it will use the directory environment from that directory instead of the org-roam directory:
#+begin_src emacs-lisp :results none
(with-eval-after-load "arroyo-db"
(add-to-list 'arroyo-db-keywords "ARROYO_DIRENV_DIR")
(defun direnv--directory ()
"Return the relevant directory for the current buffer, or nil."
(let* ((buffer (or (buffer-base-buffer) (current-buffer)))
(mode (buffer-local-value 'major-mode buffer))
(file-name (buffer-file-name buffer))
(arroyo-maybe (when (and file-name
(equal (file-name-extension file-name) "org"))
(arroyo-db-get "ARROYO_DIRENV_DIR" (expand-file-name file-name))))
(buffer-directory
(cond (arroyo-maybe
arroyo-maybe)
(file-name
(file-name-directory file-name))
((apply #'direnv--provided-mode-derived-p mode direnv-non-file-modes)
default-directory))))
buffer-directory)))
#+end_src

View File

@ -16,15 +16,55 @@
I'm trying something new, coming back to a modeline customization suite. This time, we find ourselves with the [[https://github.com/seagle0128/doom-modeline][Doom Mode Line]], which I use in a pretty "out of the box" configuration for now. I add icon representations for [[id:cce/exwm][EXWM]] buffers so that they're not just default "document" icons.
#+begin_src emacs-lisp
(use-package all-the-icons)
#+begin_src emacs-lisp :noweb yes
(use-package nerd-icons)
(use-package doom-modeline
:after all-the-icons
:after nerd-icons
:custom
(nerd-icons-font-family "Symbols Nerd Font Mono")
:config
(setq doom-modeline-unicode-fallback t
doom-modeline-enable-word-count nil)
(doom-modeline-mode 1))
(add-to-list 'all-the-icons-mode-icon-alist
'(exwm-mode all-the-icons-faicon "desktop"
:height 1.0 :face all-the-icons-purple))
doom-modeline-enable-word-count nil
doom-modeline-minor-modes t)
(doom-modeline-mode 1)
(add-to-list 'nerd-icons-mode-icon-alist
'(exwm-mode nerd-icons-faicon "nf-fa-desktop"
:height 1.0 :face all-the-icons-purple))
<<org-titles-modeline>>
)
#+end_src
* [[id:cce/org-roam][org-roam]] buffer titles in Doom Modeline
:PROPERTIES:
:ID: 20230717T093538.797067
:END:
This function overrides/extends the function which Doom Modeline uses to set the buffer title in the modeline. It queries the [[id:cce/org-roam][org-roam]] database for the file's title, and falls back to the ='auto= [[help:doom-modeline-buffer-file-name-style]] if there isn't one.
#+begin_src emacs-lisp :noweb-ref org-titles-modeline
(defun doom-modeline-buffer-file-name ()
"Propertize file name based on `doom-modeline-buffer-file-name-style'."
(let* ((buffer-file-name (file-local-name (or (buffer-file-name (buffer-base-buffer)) "")))
(buffer-file-truename (file-local-name
(or buffer-file-truename (file-truename buffer-file-name) "")))
(file-name
(when (equal major-mode 'org-mode)
(caar (org-roam-db-query [:select title :from files :where (= file $s1)]
(buffer-file-name)))))
(file-name-fallback
(if (doom-modeline-project-p)
(doom-modeline--buffer-file-name buffer-file-name buffer-file-truename 'shrink 'shrink 'hide)
(propertize "%b" 'face 'doom-modeline-buffer-file)))
(file-name
(propertize (or file-name file-name-fallback) 'face 'doom-modeline-buffer-file)))
(propertize (if (string-empty-p file-name)
(propertize "%b" 'face 'doom-modeline-buffer-file)
file-name)
'mouse-face 'mode-line-highlight
'help-echo (concat buffer-file-truename
(unless (string= (file-name-nondirectory buffer-file-truename)
(buffer-name))
(concat "\n" (buffer-name)))
"\nmouse-1: Previous buffer\nmouse-3: Next buffer")
'local-map mode-line-buffer-identification-keymap)))
#+end_src

View File

@ -5,11 +5,17 @@
#+TITLE: DrawingBot
#+FILETAGS: :Software:CCE:
#+ARCOLOGY_KEY: cce/drawingbot
#+ARCOLOGY_ALLOW_CRAWL: t
#+begin_quote
DrawingBotV3 is a software for converting images to line drawings for Plotters / Drawing Machines / 3D printers. It also serves as an application for visual artists to create stylised line drawings from images / video
#+end_quote
* DrawingBot V3 on NixOS
:PROPERTIES:
:ID: 20221228T201404.439331
:END:
#+ARROYO_HOME_MODULE: hm/drawingbot.nix
#+ARROYO_NIXOS_ROLE: endpoint

View File

@ -24,8 +24,7 @@ I use [[id:cce/emacs_and_the_language_server_protocol][Language Server Protocol]
(use-package elixir-mode
:config
(setq lsp-ui-flycheck-enable 1)
(setq lsp-clients-elixir-server-executable
'("~/Code/elixir-ls/language_server.sh"))
(setq lsp-elixir-server-command '("elixir-ls"))
:hook
(elixir-mode . lsp)
(elixir-mode . company-mode)

View File

@ -18,8 +18,8 @@
:init
(dashboard-setup-startup-hook)
(setq initial-buffer-choice (lambda () (get-buffer "*dashboard*"))
dashboard-banner-logo-title "Welcome to Your System"
dashboard-startup-banner "~/org/data/dashboard-logo.png"
dashboard-banner-logo-title "Welcome Home to the Arcology"
dashboard-startup-banner "~/org/data/arcology.png"
dashboard-center-content t
show-week-agenda-p t)
(setq dashboard-items '((recents . 5)

View File

@ -6,11 +6,14 @@
#+filetags: :CCE:Emacs:Code:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle evil-mode.el
#+ARROYO_EMACS_MODULE: evil-mode
#+ARCOLOGY_KEY: cce/evil-mode
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_EMACS_MODULE: evil-mode
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+begin_src emacs-lisp
(provide 'cce/evil-mode)
#+end_src
@ -60,6 +63,7 @@ Syndicate is evil bindings and support for org-mode.
(use-package evil-org
:ensure t
:after org
:diminish
:hook (org-mode . (lambda () (evil-org-mode)))
:init
(fset 'evil-redirect-digit-argument 'ignore)
@ -102,6 +106,22 @@ In my [[id:cce/text_editing_fundamental_opinions][Text Editing Fundamental Opini
(setq evil-respect-visual-line-mode t)
#+end_src
#+begin_src emacs-lisp
(use-package evil-args
:bind
(:map evil-normal-state-map
("L" . evil-forward-arg)
("H" . evil-backward-arg))
(:map evil-motion-state-map
("L" . evil-forward-arg)
("H" . evil-backward-arg))
(:map evil-inner-text-objects-map
("a" . evil-inner-arg))
(:map evil-inner-text-objects-map
("a" . evil-outer-arg)))
#+end_src
* visual line commands
#+begin_src emacs-lisp

View File

@ -4,15 +4,13 @@
#+TITLE: EXWM
#+filetags: :Emacs:CCE:EXWM:Mind:Bending:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle exwm.el
,#+ARROYO_EMACS_MODULE: exwm
#+ARROYO_EMACS_MODULE: exwm
#+ARCOLOGY_KEY: cce/exwm
#+CCE_PREDICATE: (cce/using-exwm)
#+CCE_PRIORITY: 20
#+ARCOLOGY_ALLOW_CRAWL: t
#+begin_src emacs-lisp
#+begin_src emacs-lisp :tangle ~/org/cce/exwm.el
(provide 'cce/exwm)
#+end_src
@ -27,13 +25,13 @@ It's configured with some simple quality-of-life improvements, outlined in short
- =S-p= brings up a simple shell command runner, I'd like to add =.desktop= support eventually.
- EXWM runs in =ido= support mode, which allows it to work with other things that interact with the minibuffer.
#+begin_src emacs-lisp :noweb yes
#+begin_src emacs-lisp :noweb yes :tangle ~/org/cce/exwm.el
(use-package exwm
:init
(setq exwm-debug nil)
:commands (exwm-enable)
:config
(setq exwm-workspace-number 2)
(setq exwm-workspace-number 6)
;; rename buffers to match window title
(defun cce/exwm-rename-buffer ()
(interactive)
@ -51,23 +49,44 @@ It's configured with some simple quality-of-life improvements, outlined in short
(exwm-input-set-key (kbd "s-k") #'other-window)
(exwm-input-set-key (kbd "s-r") #'exwm-reset)
(exwm-input-set-key (kbd "s-w") #'exwm-workspace-switch)
(exwm-input-set-key (kbd "s-o") #'evil-window-rotate-downwards)
(push (kbd "s-j") exwm-input-prefix-keys)
(push (kbd "s-k") exwm-input-prefix-keys)
(push (kbd "s-r") exwm-input-prefix-keys)
(push (kbd "s-o") exwm-input-prefix-keys)
(mapcar (lambda (it)
(exwm-input-set-key (kbd (format "s-%d" it))
`(lambda ()
(interactive)
(exwm-workspace-switch-create ,it))))
(number-sequence 0 exwm-workspace-number))
;; go to previously selected workspace
(defun cce/exwm-record-before-workspace-change (ws &optional force)
(setq cce-exwm-last-workspace exwm-workspace--current))
(advice-add #'exwm-workspace-switch :before #'cce/exwm-record-before-workspace-change)
(defun cce-exwm-workspace-back ()
(interactive)
(exwm-workspace-switch cce-exwm-last-workspace))
(exwm-input-set-key (kbd "s-<tab>") #'cce-exwm-workspace-back)
;; switch buffers on different displays
(setq exwm-workspace-show-all-buffers t)
(setq exwm-layout-show-all-buffers t)
;; xrandr
<<exwm-xrandr>>
(defvar cce-start-exwm t)
;; manage configurations
<<exwm-manage-configurations>>
;; startup handling
(defvar cce-start-exwm nil)
(defun cce/exwm-init-command-line-args ()
"hook for command-line-functions"
(if (setq command-line-args (delete command-line-args "--no-exwm"))
(setq cce-start-exwm nil)
(setq cce-start-exwm t)))
(if (setq command-line-args (delete command-line-args "--exwm"))
(setq cce-start-exwm t)
(setq cce-start-exwm nil)))
(add-to-list 'command-line-functions #'cce/exwm-init-command-line-args)
(defun cce/exwm-init (&rest args)
(when cce-start-exwm
(apply #'exwm-init args)))
(exwm-input--update-global-prefix-keys)
:hook
(exwm-update-class . cce/exwm-rename-buffer)
(exwm-update-title . cce/exwm-rename-buffer)
@ -94,11 +113,33 @@ EXWM also supports multiple monitors, using the fairly well supported =XRANDR= p
- [[id:cce/exwm_input_simulation][EXWM Input Simulation]]
- [[id:cce/exwm_should_ignore_plasma_notifications][EXWM should ignore Plasma notifications]]
- [[id:cce/picom][compton on EXWM startup]]
- [[id:20230221T102917.352842][Consult Buffer Source for EXWM Windows]]
* Rules for new Windows
#+begin_src emacs-lisp :noweb-ref exwm-manage-configurations
(unless (boundp 'exwm-manage-configurations) (setq exwm-manage-configurations nil))
(mapcar (lambda (it)
(add-to-list 'exwm-manage-configurations it))
(list
'((equal exwm-class-name "Cantata")
workspace 3)
'((equal exwm-class-name "Signal")
workspace 2)
'((equal exwm-class-name "Element")
workspace 2)
'((equal exwm-class-name "virt-manager")
workspace 5)
'((s-contains? "Computers :(" exwm-title)
workspace 2)
'((s-contains? "Picture-in-Picture" exwm-title)
floating nil)))
#+end_src
* Deeper Web Integration with Emacs
eventually move this in to the firefox integration page
#+begin_src emacs-lisp
#+begin_src emacs-lisp :tangle ~/org/cce/exwm.el
(use-package exwm-edit)
#+end_src

View File

@ -5,9 +5,12 @@
#+filetags: :Emacs:CCE:EXWM:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle exwm-input-simulation.el
#+ARROYO_EMACS_MODULE: exwm-input-simulation
#+ARROYO_MODULE_WANTS: cce/exwm.org
#+ARCOLOGY_KEY: cce/exwm-input-simulation
,#+ARROYO_EMACS_MODULE: exwm-input-simulation
,#+ARROYO_MODULE_WANTS: cce/exwm.org
#+ARCOLOGY_ALLOW_CRAWL: t
#+begin_src emacs-lisp
(provide 'cce/exwm-input-simulation)
@ -26,6 +29,7 @@
(,(kbd "C-n") . down)
(,(kbd "C-a") . home)
(,(kbd "C-e") . end)
(,(kbd "M-y") . ,(kbd "C-c"))
(,(kbd "C-y") . ,(kbd "C-v"))
(,(kbd "C-M-b") . ,(kbd "C-b"))))

View File

@ -5,9 +5,12 @@
#+filetags: :Emacs:CCE:EXWM:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle exwm-ignore-plasma.el
#+ARCOLOGY_KEY: cce/exwm-ignore-plasma
,#+ARROYO_EMACS_MODULE: exwm-ignore-plasma
,#+ARROYO_MODULE_WANTS: cce/exwm.org
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_EMACS_MODULE: exwm-ignore-plasma
#+ARROYO_MODULE_WANTS: cce/exwm.org
#+begin_src emacs-lisp :exports none
(provide 'cce/exwm-ignore-plasma)
@ -20,10 +23,12 @@ work. They don't really do much to identify themselves, =exwm--ewmh-state= is up
floating and management check in =exwm-manage--manage-window=.
#+begin_src emacs-lisp
(setq exwm-manage-configurations
'(((and (equal exwm-class-name "plasmashell")
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_NOTIFICATION exwm-window-type))
managed nil)
((and (equal exwm-class-name "plasmashell")
(memq xcb:Atom:_NET_WM_STATE_ABOVE exwm-window-type)))))
(unless (boundp 'exwm-manage-configurations) (setq exwm-manage-configurations nil))
(add-to-list 'exwm-manage-configurations
'((and (equal exwm-class-name "plasmashell")
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_NOTIFICATION exwm-window-type))
managed nil))
(add-to-list 'exwm-manage-configurations
'((and (equal exwm-class-name "plasmashell")
(memq xcb:Atom:_NET_WM_STATE_ABOVE exwm-window-type))))
#+end_src

View File

@ -3,11 +3,14 @@
:ROAM_ALIASES: feed2toot
:ROAM_REFS: https://gitlab.com/chaica/feed2toot https://feed2toot.readthedocs.io/en/latest/
:END:
#+TITLE: Posting Arcology Feeds to the Fediverse Automatically
#+TITLE: Posting Arcology Feeds to the Fediverse Automatically with feed2toot (deprecated)
#+filetags: :Project:CCE:Fediverse:
#+ARCOLOGY_KEY: arcology/feed2toot
#+ARCOLOGY_ALLOW_CRAWL: t
#+AUTO_TANGLE: t
#+begin_quote
Feed2toot automatically parses rss feeds, identifies new posts and posts them on the +Mastodon+ [[id:62538db5-d94a-47c3-9998-086ded91fd88][Fediverse]] social network.
#+end_quote
@ -60,7 +63,7 @@ buildPythonPackage rec {
So I have a few [[id:20211219T144255.001827][Arcology Sites]], each of these needs its own configuration file passed to the =feed2toot= invocation. This queries [[id:arcology/arroyo-page][Arroyo Arcology Generator]]'s [[id:arcology/arroyo/feed][arcology.arroyo.Feed]] to generate a file with each group of =(site, visibility)= of feeds in the database.
#+NAME: site-filter
#+begin_src emacs-lisp :var site-filter="lionsrear" :var site-domain="https://thelionsrear.com/" :results raw
#+begin_src emacs-lisp :var site-filter="lionsrear" :var site-domain="https://thelionsrear.com/" :results drawer
(setq arcology-sites '(("lionsrear" . "https://thelionsrear.com/")
("garden" . "https://arcology.garden/")
("cce" . "https://cce.whatthefuck.computer/")
@ -100,11 +103,14 @@ So I have a few [[id:20211219T144255.001827][Arcology Sites]], each of these nee
#+end_src
#+results: site-filter
:results:
~/arroyo-nix/files/feed2toot-uris-garden-private.txt
~/arroyo-nix/files/feed2toot-uris-lionsrear-public.txt
~/arroyo-nix/files/feed2toot-uris-garden-public.txt
~/arroyo-nix/files/feed2toot-uris-arcology-public.txt
~/arroyo-nix/files/feed2toot-uris-garden-public.txt
~/arroyo-nix/files/feed2toot-uris-lionsrear-unlisted.txt
~/arroyo-nix/files/feed2toot-uris-lionsrear-public.txt
~/arroyo-nix/files/feed2toot-uris-cce-public.txt
:end:
* INPROGRESS deploy to [[id:20211120T220054.226284][The Wobserver]]
:LOGBOOK:
@ -113,8 +119,8 @@ So I have a few [[id:20211219T144255.001827][Arcology Sites]], each of these nee
=feed2toot= operates with [[https://feed2toot.readthedocs.io/en/latest/configure.html#create-feed2toot-configuration][INI configuration files]] and luckily enough =nixpkgs= includes a way to convert =attrsets= to =ini= files in =lib.generators.toINI=; this is wrapped in a function which takes the basic per-instance configuration details including the uri-list which are generated above and then creates a [[roam:SystemD]] service manifest and timer to poll the site and post the toots. Easy peazy.
#+ARROYO_NIXOS_MODULE: nixos/feed2toot.nix
#+ARROYO_NIXOS_ROLE: server
,#+ARROYO_NIXOS_MODULE: nixos/feed2toot.nix
,#+ARROYO_NIXOS_ROLE: server
#+begin_src nix :tangle ~/arroyo-nix/nixos/feed2toot.nix :noweb yes
{ pkgs, lib, config, ... }:
@ -137,13 +143,18 @@ let
cache.cachefile = "/var/cache/feed2toot/${instance}.db";
lock.lock_file = "/run/feed2toot/${instance}.lock";
rss.uri_list = builtins.path { path = uriList; };
rss.toot = "NEW: {link} \\n {summary}";
rss.toot = "NEW by @rrix@notes.whatthefuck.computer: {link} \\n {summary}";
rss.toot_max_len = 10000;
hashtaglist.several_words_hashtags_list = tagListFile;
feedparser.accept_bozo_exceptions = true;
});
feeds = [
(mkFeed2TootIni {
instance = "garden";
visibility = "public";
uriList = ../files/feed2toot-uris-cce-public.txt;
})
(mkFeed2TootIni {
instance = "garden";
visibility = "public";
@ -194,12 +205,22 @@ in {
description = "Feeds to Toots";
after = ["pleroma.service"];
wantedBy = ["default.target"];
script = "${pkgs.feed2toot}/bin/feed2toot" +
(lib.concatMapStrings (feed: " -c " + feed) feeds);
# "-c ${gardenIni} -c ${lionsrearIni} -c ${engineIni}" ;
serviceConfig.User = "feed2toot";
serviceConfig.WorkingDirectory = "/srv/feed2toot";
startAt = "30min";
script =
lib.concatMapStrings
(feed: "\n${pkgs.feed2toot}/bin/feed2toot -c " + feed)
feeds;
serviceConfig = {
User = "feed2toot";
WorkingDirectory = "/srv/feed2toot";
};
};
systemd.timers.feed2toot = {
description = "Start feed2toot on the quarter-hour";
timerConfig = {
OnUnitActiveSec = "15 minutes";
OnStartupSec = "15 minutes";
};
wantedBy = [ "default.target" ];
};
}
#+end_src

348
feediverse.org Normal file
View File

@ -0,0 +1,348 @@
:PROPERTIES:
:ID: 20230125T143144.011175
:ROAM_REFS: https://github.com/edsu/feediverse/
:ROAM_ALIASES: Feediverse
:END:
#+TITLE: Posting Arcology Feeds to the Fediverse Automatically with Feediverse
#+filetags: :Project:CCE:Fediverse:
#+ARCOLOGY_KEY: arcology/feediverse
#+ARCOLOGY_ALLOW_CRAWL: t
#+AUTO_TANGLE: t
#+begin_quote
feediverse will read RSS/Atom feeds and send the messages as Mastodon posts. It's meant to add a little bit of spice to your timeline from other places. Please use it responsibly.
#+end_quote
I was not convinced that [[id:20221227T164309.780458][feed2toot]] was the right way to go about this and in trying to extend it, I found myself frustrated. Well, here's a simpler single-file solution. I extended [[id:1d917282-ecf4-4d4c-ba49-628cbb4bb8cc][The Arcology Project]] to expose a JSON list of feeds and their metadata and with my modified version of =feediverse= I can post all of my sites' toots with one command.
* =feediverse.py=
This is a lightly modified version of the referenced =feediverse.py= above, with my modifications distributed under the [[id:20220116T143655.499306][Hey Smell This]] license.
This thing is, basically, simple to operate. it's driven by a YAML configuration file:
#+begin_src yaml :tangle ~/Code/feediverse/config.yml.sample
tokens:
lionsrear: *lionsrear-creds
garden: *garden-creds
cce: *garden-creds
arcology: *garden-creds
feeds_index: https://thelionsrear.com/feeds.json
post_template: >-
NEW by @rrix@notes.whatthefuck.computer: {summary}
{url} {hashtags}
updated: '2023-01-25T06:13:50.343361+00:00'
url: https://notes.whatthefuck.computer
#+end_src
This file will be created the first time you run this command; in my case it's generated locally and then copied to my [[id:20211120T220054.226284][Wobserver]] in the NixOS declarations below.
#+begin_src python :noweb-ref config-load-save
def save_config(config, config_file):
copy = dict(config)
with open(config_file, 'w') as fh:
fh.write(yaml.dump(copy, default_flow_style=False))
def read_config(config_file):
config = {
'updated': datetime(MINYEAR, 1, 1, 0, 0, 0, 0, timezone.utc)
}
with open(config_file) as fh:
cfg = yaml.load(fh, yaml.SafeLoader)
if 'updated' in cfg:
cfg['updated'] = dateutil.parser.parse(cfg['updated'])
config.update(cfg)
return config
#+end_src
So the =/feeds.json= in the [[id:20220225T175638.482695][Arcology Router]] returns a list of objects, in here it's re-key'd to be a per-site dictionary and returned:
#+begin_src python :noweb-ref fetch-feeds
def fetch_dynamic_feeds(feeds_url):
feeds = requests.get(feeds_url,
headers={"User-Agent": "feediverse 0.0.1"}).json()
feeds_by_site = dict()
for feed in feeds:
feeds_by_site[feed['site']] = feeds_by_site.get(feed['site'], []) + [feed]
return feeds_by_site
#+end_src
With that loaded, it's possible to just loop over the sites, and then loop over each feed in the site to post new entries from them:
#+begin_src python :noweb-ref inner-loop
newest_post = config['updated']
per_site_feeds = fetch_dynamic_feeds(config['feeds_index'])
for site, feeds in per_site_feeds.items():
masto = Mastodon(
api_base_url=config['url'],
feature_set='pleroma',
client_id=config['tokens'][site]['client_id'],
client_secret=config['tokens'][site]['client_secret'],
access_token=config['tokens'][site]['access_token']
)
for feed in feeds:
if args.verbose:
print(f"fetching {feed['url']} entries since {config['updated']}")
for entry in get_feed(feed['url'], config['updated']):
newest_post = max(newest_post, entry['updated'])
if args.verbose:
print(entry)
if args.dry_run:
print("trial run, not tooting ", entry["title"][:50])
continue
masto.status_post(config['post_template'].format(**entry),
content_type='text/html',
visibility=feed['visibility'])
if not args.dry_run:
config['updated'] = newest_post.isoformat()
save_config(config, config_file)
#+end_src
All the feed-parsing stuff is more or less lifted directly from the original =feediverse=, but modified to just post the HTML directly to [[id:20221202T122135.502628][+Akkoma+ Pleroma]].
#+begin_src python :noweb-ref feed-parsing
def get_feed(feed_url, last_update):
feed = feedparser.parse(feed_url)
if last_update:
entries = [e for e in feed.entries
if dateutil.parser.parse(e['updated']) > last_update]
else:
entries = feed.entries
entries.sort(key=lambda e: e.updated_parsed)
for entry in entries:
yield get_entry(entry)
def get_entry(entry):
hashtags = []
for tag in entry.get('tags', []):
t = tag['term'].replace(' ', '_').replace('.', '').replace('-', '')
hashtags.append('#{}'.format(t))
summary = entry.get('summary', '')
content = entry.get('content', '') or ''
url = entry.id
return {
'url': url,
'link': entry.link,
'title': cleanup(entry.title),
'summary': cleanup(summary, strip_html=False),
'content': content,
'hashtags': ' '.join(hashtags),
'updated': dateutil.parser.parse(entry['updated'])
}
def cleanup(text, strip_html=True):
if strip_html:
html = BeautifulSoup(text, 'html.parser')
text = html.get_text()
text = re.sub('\xa0+', ' ', text)
text = re.sub(' +', ' ', text)
text = re.sub(' +\n', '\n', text)
text = re.sub('(\w)\n(\w)', '\\1 \\2', text)
text = re.sub('\n\n\n+', '\n\n', text, flags=re.M)
return text.strip()
#+end_src
Setting up the config file is a bit different than the upstream stuff because my version supports setting up multiple accounts on a single instance. I made the design decision to only support one fedi instance per feedi instance, if you want to run this on multiple fedi servers, you'll need to run more than one config file or just don't.
#+begin_src python :noweb-ref setup-config
def yes_no(question):
res = input(question + ' [y/n] ')
return res.lower() in "y1"
def setup(config_file):
url = input('What is your Fediverse Instance URL? ')
feeds_index = input("What is the arcology feed index URL? ")
tokens = dict()
for site in fetch_dynamic_feeds(feeds_index).keys():
print(f"Configuring for {site}...")
print("I'll need a few things in order to get your access token")
name = input('app name (e.g. feediverse): ') or "feediverse"
client_id, client_secret = Mastodon.create_app(
api_base_url=url,
client_name=name,
#scopes=['read', 'write'],
website='https://github.com/edsu/feediverse'
)
username = input('mastodon username (email): ')
password = input('mastodon password (not stored): ')
m = Mastodon(client_id=client_id, client_secret=client_secret, api_base_url=url)
access_token = m.log_in(username, password)
tokens[site] = {
'client_id': client_id,
'client_secret': client_secret,
'access_token': access_token,
}
old_posts = yes_no('Shall already existing entries be tooted, too?')
config = {
'name': name,
'url': url,
'feeds_index': feeds_index,
'tokens': tokens,
'post_template': '{title} {summary} {url}'
}
if not old_posts:
config['updated'] = datetime.now(tz=timezone.utc).isoformat()
save_config(config, config_file)
print("")
print("Your feediverse configuration has been saved to {}".format(config_file))
print("Add a line line this to your crontab to check every 15 minutes:")
print("*/15 * * * * /usr/local/bin/feediverse")
print("")
#+end_src
All of that is assembled together in to a single command which takes a =--dry-run=, =--verbose= and =--config= argument to operate:
#+begin_src python :tangle ~/Code/feediverse/feediverse.py :noweb yes :shebang #!/usr/bin/env python3
# Make sure to edit this in cce/feediverse.org !!!
import os
import re
import sys
import yaml
import argparse
import dateutil
import feedparser
import requests
from bs4 import BeautifulSoup
from mastodon import Mastodon
from datetime import datetime, timezone, MINYEAR
DEFAULT_CONFIG_FILE = os.path.join("~", ".feediverse")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-n", "--dry-run", action="store_true",
help=("perform a trial run with no changes made: "
"don't toot, don't save config"))
parser.add_argument("-v", "--verbose", action="store_true",
help="be verbose")
parser.add_argument("-c", "--config",
help="config file to use",
default=os.path.expanduser(DEFAULT_CONFIG_FILE))
args = parser.parse_args()
config_file = args.config
if args.verbose:
print("using config file", config_file)
if not os.path.isfile(config_file):
setup(config_file)
config = read_config(config_file)
<<inner-loop>>
<<fetch-feeds>>
<<feed-parsing>>
<<config-load-save>>
<<setup-config>>
if __name__ == "__main__":
main()
#+end_src
* Packaging =feediverse= in [[id:20221021T121120.541960][rixpkgs]]
This is pretty easy to get running; if you do this yourself, you'll want to override =src= to point to [[https://code.rix.si/rrix/feediverse]], but I don't like remembering to push my changes 😇
#+begin_src nix :tangle ~/arroyo-nix/pkgs/feediverse.nix
{ lib,
buildPythonPackage,
fetchPypi,
beautifulsoup4,
feedparser,
python-dateutil,
requests,
mastodon-py,
pyyaml,
python,
}:
buildPythonPackage rec {
pname = "feediverse";
version = "0.0.1";
src = /home/rrix/Code/feediverse;
propagatedBuildInputs = [
beautifulsoup4
feedparser
python-dateutil
requests
pyyaml
mastodon-py
];
meta = with lib; {
homepage = "https://code.rix.si/rrix/feediverse";
description = "feediverse will read RSS/Atom feeds and send the messages as Mastodon posts.";
license = licenses.mit;
maintainers = with maintainers; [ rrix ];
};
}
#+end_src
* Running =feediverse= on [[id:20211120T220054.226284][The Wobserver]]
Okay, with the configuration file generated and then copied on to the server (since it's mutated by the script...), I shove it in to the [[id:20221021T150631.404359][Arroyo Nix]] index and then set up an [[id:arroyo/nixos][Arroyo NixOS]] module to set up a service account and run it with a SystemD timer. This will be pretty straightforward if you've seen NixOS before.
#+ARROYO_NIXOS_MODULE: nixos/feediverse.nix
#+ARROYO_NIXOS_ROLE: server
#+begin_src nix :tangle ~/arroyo-nix/nixos/feediverse.nix
{ pkgs, lib, config, ... }:
{
ids.uids.feediverse = 902;
ids.gids.bots = 902;
users.groups.bots = {
gid = config.ids.gids.bots;
};
users.users.feediverse = {
home = "/srv/feediverse";
group = "bots";
uid = config.ids.uids.feediverse;
isSystemUser = true;
};
systemd.services.feediverse = {
description = "Feeds to Toots";
after = ["pleroma.service"];
wantedBy = ["default.target"];
script =
''
${pkgs.feediverse}/bin/feediverse -c ${config.users.users.feediverse.home}/feediverse.yml
'';
serviceConfig = {
User = "feediverse";
WorkingDirectory = config.users.users.feediverse.home;
};
};
systemd.timers.feediverse = {
description = "Start feediverse on the quarter-hour";
timerConfig = {
OnUnitActiveSec = "15 minutes";
OnStartupSec = "15 minutes";
};
wantedBy = [ "default.target" ];
};
}
#+end_src
* NEXT Consider making the config file immutable by storing the update timestamp in a different location

View File

@ -44,6 +44,7 @@ This [[id:09779ac0-4d5f-40db-a340-49595c717e03][noweb]] document constructs a cu
"privacy.trackingprotection.enabled" = true;
"privacy.donottrackheader.enabled" = true;
"privacy.globalprivacycontrol.enabled" = true;
"privacy.globalprivacycontrol.functionality_enabled" = true;
"reader.color_scheme" = "dark";
@ -59,6 +60,10 @@ This [[id:09779ac0-4d5f-40db-a340-49595c717e03][noweb]] document constructs a cu
"browser.aboutConfig.showWarning" = false;
"browser.sessionstore.warnOnQuit" = true;
"browser.newtabpage.activity-stream.showSponsored" = false;
"browser.newtabpage.activity-stream.showSponsoredTopSites" = false;
"toolkit.legacyUserProfileCustomizations.stylesheets" = true; # for userchrome and usercontent
"layout.css.prefers-color-scheme.content-override" = 2; # (ref:content-override)
};

View File

@ -31,28 +31,24 @@ in {
appName = "rrix's code with a cup of tea";
stateDir = "/srv/gitea";
domain = "code.rix.si";
rootUrl = "https://code.rix.si";
httpAddress = "127.0.0.1";
httpPort = 3009;
settings = {
server = {
DISABLE_REGISTRATION = true;
START_SSH_SERVER = true;
SSH_LISTEN_PORT = 2222;
SSH_PORT = 2222;
ENABLE_GZIP = true;
LANDING_PAGE = "explore";
};
ui.DEFAULT_THEME = "arc-green";
session.COOKIE_SECURE = true;
server.DOMAIN = "code.rix.si";
server.ENABLE_GZIP = true;
server.HTTP_ADDRESS = "127.0.0.1";
server.HTTP_PORT = 3009;
server.LANDING_PAGE = "explore";
server.ROOT_URL = "https://code.rix.si";
server.SSH_LISTEN_PORT = 2222;
server.SSH_PORT = 2222;
server.START_SSH_SERVER = true;
service.DISABLE_REGISTRATION = true;
federation.ENABLED = true;
metrics.ENABLED = true;
packages.ENABLED = false;
picture.ENABLE_FEDERATED_AVATAR = true;
session.COOKIE_SECURE = true;
time.DEFAULT_UI_LOCATION = config.time.timeZone;
ui.DEFAULT_THEME = "arc-green";
};
database = {
@ -64,13 +60,13 @@ in {
services.prometheus.scrapeConfigs = [
{
job_name = "gitea";
static_configs = [{ targets = ["${cfg.httpAddress}:${toString cfg.httpPort}"]; }];
static_configs = [{ targets = ["${cfg.settings.server.HTTP_ADDRESS}:${toString cfg.settings.server.HTTP_PORT}"]; }];
}
];
services.nginx.virtualHosts."code.rix.si" = {
locations."/" = {
proxyPass = "http://${cfg.httpAddress}:${toString cfg.httpPort}";
proxyPass = "http://${cfg.settings.server.HTTP_ADDRESS}:${toString cfg.settings.server.HTTP_PORT}";
extraConfig = ''
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

View File

@ -29,7 +29,8 @@ I use =gpg2= everywhere, including in Emacs.
This is for [[id:cce/home-manager][home-manager]]:
#+begin_src nix :tangle ~/arroyo-nix/hm/gnupg.nix
{pkgs, ...}:
{ pkgs, ... }:
{
programs.gpg.enable = true;
programs.gpg.settings = {
@ -55,6 +56,7 @@ This is for PAM in [[id:cce/my_nixos_configuration][My NixOS configuration]]:
#+ARROYO_NIXOS_EXCLUDE: waterboy
#+begin_src nix :tangle ~/arroyo-nix/nixos/gnupg-pam.nix
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.gnupg ];
security.pam.services.login.gnupg.enable = true;

View File

@ -11,7 +11,7 @@
#+ARCOLOGY_KEY: cce/gnus
#+CCE_ANSIBLE: gnus
#+CCE_PRIORITY: 70
#+filetags: :CCE:
#+filetags: :Project:CCE:
#+ARCOLOGY_ALLOW_CRAWL: t
From the Gnus website:
@ -180,21 +180,21 @@ in {
home.activation = {
gnus-newsrc =
pkgs.lib.mkActivationLocalLink (builtins.trace config)
pkgs.lib.mkActivationLocalLink config
"~/sync/private-files/.newsrc"
".newsrc";
gnus-newsrc_eld =
pkgs.lib.mkActivationLocalLink config
"~/sync/private-files/.newsrc.eld"
".newsrc.eld";
gnus-feeds =
pkgs.lib.mkActivationLocalLink config
"~/Maildir/endpoint/feeds"
"Maildir/feeds";
gnus-fastmail =
pkgs.lib.mkActivationLocalLink config
"~/Maildir/endpoint/fastmail"
"Maildir/fastmail";
# gnus-feeds =
# pkgs.lib.mkActivationLocalLink config
# "~/Maildir/endpoint/feeds"
# "Maildir/feeds";
# gnus-fastmail =
# pkgs.lib.mkActivationLocalLink config
# "~/Maildir/endpoint/fastmail"
# "Maildir/fastmail";
};
}
#+end_src
@ -214,9 +214,17 @@ Finally, this ugly function and sharp-quoted =setq= tries to find an IMAP which
"gmail/Inbox")
(t "fastmail/INBOX")))
(nnir-search-engine imap)
(nnimap-shell-program ,(cce/find-dovecot)))))
(nnimap-shell-program ,(cce/find-dovecot)))
;; (nnttrss "tt"
;; (nnttrss-address "https://feeds.whatthefuck.computer/api")
;; (nnttrss-user "rrix")
;; (nnttrss-password "NOPASSWORD")
;; )
))
#+end_src
* NEXT move [[id:cce/mbsync][mbsync]] here
* NEXT move [[id:cce/sending_mail_in_gnus][msmtp]] here
* Put All Together With Noweb
All of the code presented above is inserted in to a =use-package= block[fn:1:[[id:cce/configure_packaging][Configure Packaging]]].

179
gpd-pocket-3.org Normal file
View File

@ -0,0 +1,179 @@
:PROPERTIES:
:ID: 20230404T153703.708523
:END:
#+TITLE: GPD Pocket 3
#+filetags: :Project:
#+ARCOLOGY_KEY: cce/gpd-pocket-3
#+AUTO_TANGLE: t
These small 7-8 inch display laptops have been the most promising mobile [[id:0d968a4d-3c9d-4104-a158-e4982be6d28e][Linux]] devices for me, each with some fatal flaw that made it unlikely to survive a long time. But maybe this one is different. I own the [[id:6834cb8f-319f-4dd9-bade-2521417f584b][GPD Pocket]] which could not go in to deep sleep in linux, so it would always have a dead battery when I wanted to use it and the touchscreen did not function on it. I own the [[id:20230420T203015.828439][GPD Pocket 2]] which runs NixOS but has a soldered in eMMC chip that is just slightly too small to be useful for me. The GPD Pocket 3 is a convertable touch screen laptop which is maybe versatile enough and full of upgradable storage with m.2 nvme.
The lads at GPD are at it again. This one has a 360° rotating screen and active stylus support. It has a proprietary IO port at the back of the device that can have an extra USB port, or an HDMI capture card and USB gadget hub, or an RS232 serial device. Maybe even a [[https://p3-lte.wulige.com/#%E7%A1%AC%E4%BB%B6][4G cell card??]] one can hope...
Having a performant Emacs environment in a light form-factor is a thing I've been chasing for a decade or more, and this is the latest step. It fits in my 8" camera messenger bag and my bike basket. It's an ebook reader and a programming environment and a shitposting machine.
* NixOS on the GPD Pocket 3
:PROPERTIES:
:ID: 20230404T153725.517911
:END:
This thing has kind of been a pain to run Linux on, especially after I had a real deep [[roam:Brain-o]] moment where I had to wipe the disk. I'd rather not talk about it lol.
Things were working well before then, like the thing worked quite nicely, but installing the very same system build I had just deployed early in the week would cause the machine to panick when modesetting occurred. I had to downgrade the kernel to 5.15 to get it to boot reliably but there was a bunch of weird display behavior, this was a bit worrying. 6.2 works but ZFS support is still labeled "unstable" so I'll have to be careful to not jog this thing too hard until 6.2 stabilizes lol.
#+begin_src nix :tangle ~/arroyo-nix/nixos/gpd-pocket-3.nix
{ lib, pkgs, ... }:
{
#+END_SRC
Forcing 6.2 kernel and (unfortunately) ZFS Unstable will get everything working but I'm confused how it worked last week. Kernel 6.1 and 6.2 have working deep sleep, and 5.15 had some backlight control problems. Unless I am far from home, I can bootstrap a new system quickly enough in theory with [[id:cce/morph][Morph]] and [[id:cce/syncthing][Syncthing]], in theory. I sort of just played out that scenario I suppose. 5.15 is still a fuck and 6.2 is EOL, so I am carrying [[https://github.com/NixOS/nixpkgs/pull/236637][this open backport commit]] which bumps ZFS stable to a version which supports 6.3
#+begin_src nix :tangle ~/arroyo-nix/nixos/gpd-pocket-3.nix
# === gpd pocket 3 specific hax
# boot.zfs.enableUnstable = true;
# boot.kernelPackages = lib.mkForce pkgs.zfsUnstable.latestCompatibleLinuxPackages;
# git cherry-pick 900c093
boot.zfs.enableUnstable = false;
boot.kernelPackages = lib.mkForce pkgs.linuxPackages_6_3;
#+END_SRC
The display, as with all GPD Pockets is an 8 inch tablet display rotated 90° counter-clockwise, and so some work has to be done to rotate all of this, and the stylus coordinates and the accelerometer and whatnot. I had some real problems getting X11 to look decently without fractional scaling and I was having trouble getting the X11 config working, so this is my first machine running Wayland. I have a few things commented here for if upgrading my kernel or whatever breaks the display again during modesetting or whatever..
#+begin_src nix :tangle ~/arroyo-nix/nixos/gpd-pocket-3.nix
boot.kernelParams = [
"mem_sleep_default=deep"
"fbcon=rotate:1"
"video=DSI-1:panel_orientation=right_side_up"
];
services.udev.extraRules = ''
ACTION=="add|change", KERNEL=="event[0-9]*", ATTRS{name}=="GXTP7380:00 27C6:0113", ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0"
ACTION=="add|change", KERNEL=="event[0-9]*", ATTRS{name}=="GXTP7380:00 27C6:0113 Stylus", ENV{LIBINPUT_CALIBRATION_MATRIX}="1 0 0 0 1 0"
'';
services.udev.extraHwdb = ''
sensor:modalias:*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 1, 0, 0
'';
hardware.sensor.iio.enable = true;
services.xserver.videoDrivers = ["modesetting" "intel"];
services.xserver.displayManager.defaultSession = lib.mkForce "plasmawayland";
# services.xserver.displayManager.lightdm.enable = lib.mkForce false;
# services.xserver.displayManager.lightdm.enable = true;
# services.xserver.displayManager.autoLogin.enable = lib.mkForce false;
# systemd.defaultUnit = lib.mkForce "multi-user.target";
#+END_SRC
Make the sound work and the console legible.
#+begin_src nix :tangle ~/arroyo-nix/nixos/gpd-pocket-3.nix
boot.extraModprobeConfig = ''
options snd-intel-dspcfg dsp_driver=1
'';
hardware.enableRedistributableFirmware = true;
console.font = "solar24x32.psfu";
console.earlySetup = true;
#+END_SRC
Gotta have the soft keyboard since I'm actually goign to use this as a tablet for light web browsing. It still has to be enabled in System Settings, I need to automate the declarative setup of KDE and Plasma...
#+begin_src
environment.systemPackages = [
pkgs.maliit-framework
pkgs.maliit-keyboard
pkgs.wl-clipboard
];
#+END_SRC
Include the rotate script below:
#+begin_src nix :tangle ~/arroyo-nix/nixos/gpd-pocket-3.nix
imports = [ <arroyo/nixos/gpd-pocket-3-rotate.nix> ];
}
#+end_src
** Rotate Script
One of the side-effects of moving to Wayland is that the "Custom Shortcuts" system in [[id:cce/kde_is_a_base_for_my_emacs_desktop][KDE]] is not functional. There is a limited version of it in the main Shortcuts UI which lets you choose a =.desktop= file or shell script to run without arguments, so here I am writing a =.desktop= file.
I don't do a full rotation, and i use a neat little [[id:cce/kde_is_a_base_for_my_emacs_desktop][KDE]] command lie utility called =kscreen-doctor= to handle rotating the display on =kwin_wayland=: These numbers that come out of the first =CUR_ROT= pipeline are probably a bitfield or something, they're all base-2 even maybe? Who can say? They also differ depending on which KScreen backend you use...
#+begin_src shell :tangle ~/arroyo-nix/files/gpd-pocket-3-rotate.sh
STATUS_KSKB=QScreen
CUR_ROT=$(KSCREEN_BACKEND=$STATUS_KSKB kscreen-doctor --json | jq '.outputs[]|select(.name == "DSI-1").rotation')
# KWayland and QScreen don't return the same bitfield lol
case $STATUS_KSKB in
QScreen)
case $CUR_ROT in
8) # normal
kscreen-doctor output.DSI-1.rotation.right
;;
1) # 90 ccw
kscreen-doctor output.DSI-1.rotation.inverted
;;
# 8) # normal
# kscreen-doctor output.DSI-1.rotation.inverted
# ;;
# 4) # 90 ccw
# kscreen-doctor output.DSI-1.rotation.right
# ;;
esac
;;
KWayland)
case $CUR_ROT in
8) # normal
kscreen-doctor output.DSI-1.rotation.inverted
;;
4) # 90 ccw
kscreen-doctor output.DSI-1.rotation.right
;;
esac
;;
esac
#+end_src
Packaging this up is kind of ugly, i'm sure there is a more idiomatic way to ship a shell script with a desktop file. I should at least move this to [[id:20221021T121120.541960][rixpkgs]] eventually...
#+begin_src nix :tangle ~/arroyo-nix/nixos/gpd-pocket-3-rotate.nix
{ pkgs, ... }:
let
gpd-rotate-display = pkgs.writeShellApplication {
name = "gpd-rotate-display";
runtimeInputs = with pkgs; [ plasma5Packages.libkscreen jq ];
text = builtins.readFile <arroyo/files/gpd-pocket-3-rotate.sh>;
};
desktopItem = pkgs.makeDesktopItem {
name = "gpd-rotate-display";
desktopName = "Rotate Display";
categories = ["Utility"];
exec = "gpd-rotate-display";
};
gpd-rotate-display' = pkgs.stdenv.mkDerivation {
name = "gpd-rotate-display";
src = gpd-rotate-display;
installPhase = ''
mkdir -p $out/bin
cp $src/bin/gpd-rotate-display $out/bin/
cp --recursive "${desktopItem}/share" "$out/"
'';
};
in {
environment.systemPackages = [
gpd-rotate-display'
];
}
#+end_src
* NEXT consider swap back to Xorg
scaling the touch and wacom when i run xinput --scale command

View File

@ -135,8 +135,9 @@ I also should define program modules for a lot of these over the long term so th
home.username = "rrix";
home.homeDirectory = "/home/rrix";
home.language.base = "en_US";
home.language.time = "en_GB";
# set to UTF-8 or python shit breaks
home.language.base = "en_US.UTF-8";
home.language.time = "en_GB.UTF-8";
# for KDE
# https://userbase.kde.org/Session_Environment_Variables
@ -192,53 +193,59 @@ This uses [[id:arroyo/home-manager][Arroyo Home Manager]].
#+results: generate_imports
#+begin_example
hm/prompt.nix
hm/qud.nix
hm/smac.nix
hm/msmtp.nix
hm/emacs-helpers.nix
hm/direnv.nix
hm/applications.nix
hm/tabfs.nix
hm/firefox.nix
hm/contacts.nix
hm/ruby.nix
hm/defexpr.nix
hm/xmonad.nix
hm/git.nix
hm/python.nix
hm/gnupg.nix
hm/syncthing.nix
hm/pass.nix
hm/org-protocol.nix
hm/ssh_client.nix
hm/kde-config-basics.nix
hm/vsketch.nix
hm/mbsync-endpoint.nix
hm/fehbg.nix
hm/org-roam.nix
hm/beets.nix
hm/dovecot-shell-access.nix
hm/mpd.nix
hm/emacs-pager.nix
hm/shell-helpers.nix
hm/kde-config-appearance.nix
hm/i3wm.nix
hm/spell-check.nix
hm/deadgrep.nix
hm/3d-printing.nix
hm/pantalaimon.nix
hm/profile.nix
hm/supercollider.nix
hm/axidraw.nix
hm/datasette.nix
hm/morph.nix
hm/emacs.nix
hm/occluded_files.nix
hm/nix-update.nix
hm/cogmind.nix
hm/picom.nix
hm/applications.nix
hm/atuin.nix
hm/axidraw.nix
hm/bandcamp-dl.nix
hm/beets.nix
hm/bitwarden.nix
hm/cogmind.nix
hm/contacts.nix
hm/cpmtools.nix
hm/datasette.nix
hm/deadgrep.nix
hm/defexpr.nix
hm/direnv.nix
hm/dovecot-shell-access.nix
hm/drawingbot.nix
hm/emacs-helpers.nix
hm/emacs-pager.nix
hm/emacs.nix
hm/fehbg.nix
hm/firefox.nix
hm/git.nix
hm/gnupg.nix
hm/i3wm.nix
hm/kde-config-appearance.nix
hm/kde-config-basics.nix
hm/mbsync-endpoint.nix
hm/morph.nix
hm/mpd.nix
hm/msmtp.nix
hm/nix-update.nix
hm/occluded_files.nix
hm/org-fc.nix
hm/org-protocol.nix
hm/org-roam.nix
hm/pantalaimon.nix
hm/pass.nix
hm/picom.nix
hm/profile.nix
hm/prompt.nix
hm/python.nix
hm/qud.nix
hm/ruby.nix
hm/shell-helpers.nix
hm/smac.nix
hm/spell-check.nix
hm/ssh_client.nix
hm/supercollider.nix
hm/syncthing-tray.nix
hm/syncthing.nix
hm/tabfs.nix
hm/vsketch.nix
hm/xmonad.nix
#+end_example
* Task list to port =CCE_ANSIBLE= to =CCE_HOME_MODULE=

View File

@ -27,3 +27,4 @@ Welcome to the Complete Computing Environment.
- [[id:arroyo/emacs][Arroyo Emacs]]
- [[id:cce/my_nixos_configuration][My NixOS configuration]]
- [[id:20220116T143655.499306][Hey Smell This]]
- [[id:20230111T140523.582960][CCE and Emacs Update Feed]]

View File

@ -10,8 +10,7 @@
#+PROPERTY: header-args:emacs-lisp :tangle ivy-config.el
,#+ARROYO_EMACS_MODULE: ivy-config
#+CCE_PREDICATE: (not t)
#+CCE_PRIORITY: 10
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+begin_src emacs-lisp
(provide 'cce/ivy-config)

23
jellyfin.org Normal file
View File

@ -0,0 +1,23 @@
:PROPERTIES:
:ID: 20230220T204453.685476
:END:
#+TITLE: Jellyfin on the Wobserver
#+ARROYO_NIXOS_MODULE: nixos/jellyfin.nix
#+ARROYO_NIXOS_ROLE: server
#+AUTO_TANGLE: t
#+begin_src nix :tangle ~/arroyo-nix/nixos/jellyfin.nix
{ lib, ... }:
{
services.jellyfin.enable = true;
# so that metadata etc are legible to syncthing and others; consider adding jellyfin user to a service group...
systemd.services.jellyfin.serviceConfig.UMask = lib.mkForce "0002";
services.nginx.virtualHosts."media.whatthefuck.computer" = {
locations."/" = {
proxyPass = "http://127.0.0.1:8096";
};
};
}
#+end_src

View File

@ -63,6 +63,7 @@ I customize my KDE installation a fair bit both within [[id:cce/home-manager][ho
environment.systemPackages = (with pkgs.libsForQt5; [
breeze-gtk
kde-gtk-config
breeze-qt5
kdesu
@ -86,6 +87,7 @@ I customize my KDE installation a fair bit both within [[id:cce/home-manager][ho
partition-manager
gparted
plasma5Packages.kamoso
plasma5Packages.bismuth
]);
# auto login

View File

@ -1,30 +1,41 @@
:PROPERTIES:
:ID: cce/keyboardio_atreus
:ROAM_REFS: https://shop.keyboard.io/pages/atreus
:ROAM_ALIASES: "Keyboardio Atreus"
:END:
#+TITLE: Keyboardio Atreus
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:yaml :tangle roles/endpoint/tasks/atreus.yml
#+TITLE: What the hell is that keyboard on my laptop? The Keyboardio Atreus
#+ARCOLOGY_KEY: cce/atreus
#+ARCOLOGY_ALLOW_CRAWL: t
#+filetags: :CCE:
* The Keyboardio Atreus :ATTACH:
:PROPERTIES:
:ID: 690d03f5-abe7-4b0e-be94-086008b7fd7b
:END:
[[file:../data/69/0d03f5-abe7-4b0e-be94-086008b7fd7b/IMG_20201013_172314.jpg][file:~/org/data/69/0d03f5-abe7-4b0e-be94-086008b7fd7b/IMG_20201013_172314.jpg]]
The Keyboardio Atreus is a 44-key minimalist keyboard that is sculpted to fit the natural length of the fingers in a way that minimalist keyboards like the Planck can't. it has just enough keys to work with my weird layout, and i intend to use it as such. :) This one is equipped with Kailh BOX Brown switches and Laser GMK keycaps, I like the tactile bump and this thing can *crush* prose writing.
The Keyboardio Atreus is a minimalist 44-key keyboard that is sculpted to fit the natural length of the fingers in a way that minimalist keyboards like the Planck can't. it has just enough keys to be able to express most of the keys on a "full-sized" keyboard with a "phone tree" of layers. It's based on a keyboard designed by [[roam:Technomancy]], FOSS lisp extraordinaire and itinerant [[id:62538db5-d94a-47c3-9998-086ded91fd88][Fediverse]] shitposter.
I work my fingers like I expect to type QWERTY with much less finger-travel and much less risk of RSI. to get to numbers, symbols, and "action keys" like function keys, navigation, etc, by entering key-chords like you would with Ctrl, Alt, and the Windows or Super key. My right thumb's resting key gets me to a layer where I have a ten-key and access to common punctuation and braces, and it is close to Ctrl and Escape and Space. The left thumb is my shift key, and is close to Alt/Meta/Option, Super/Windows, and backspace. Other buttons take me to arrow keys, function keys, etc. One of my [[id:109_mental_models_explained][Mental Models]] for computing is fundamentally about modes and navigate through them (as in [[id:cce/emacs][Emacs]] major and minor modes). This is a hardware extension of this mental model which melds nicely when working in Emacs and using a [[roam:Tiling Window Manager]].
It sucks when I travel sometimes because I obviously don't have it built in to a laptop and it's not as comfortable or as smooth to use than sitting at my desk at home. So this keyboard layout is a sort of local-minima I've dug myself in to. It's also [[roam:Hashtag Aesthetic]] as frick and is fun to type on, and represents nearly the "end game" sort of build for the =/r/battlestations==/r/mechanicalkeyboards= Reddit Consumerist Poster I may have been in my 20s. Maybe this is just that exact kind of post. [[id:cce/cce][CCE]] and [[id:1d917282-ecf4-4d4c-ba49-628cbb4bb8cc][The Arcology Project]] are that exact kind of "post".
This Atreus is equipped with Kailh BOX Brown switches and Laser GMK keycaps, I can type on "tactile" keyboard switches without bottoming out, and this thing can *crush* prose writing while looking rad as hell, both of which acting as a huge multiplier of my descent in to [[id:1fb8fb45-fac5-4449-a347-d55118bb377e][org-mode]] and using this digital journal to think well.
In that sense, it is a physical representation of my folly. Some people learn DVORAK or COLEMAK and give up on using =vim=-style navigation vocabulary. Most people don't ever consider =vim=-style navigation vocabulary to be a threat and store their thoughts organized chronologically in Apple Notes or Google Docs. This is not a place of honor.
* The Keyboard and Layout :ATTACH:
:PROPERTIES:
:ID: 287ba93e-a2af-4093-a74b-85172edb2ab2
:END:
I use QWERTY, a custom symbol layer, and a mouse layer which I may not use. These screenshots were taken out of Chrysalis, the Keyboardio configurator on [2020-10-13].
I use QWERTY, a custom symbol layer, and a mouse layer which I may not use much.
Mostly this works on any computer, except I have to apply some [[id:20210814224010-my_custom_keyboard_layout][Xmodmap Hacks]] to set up matching braces on the left hand for =<>= and changing shifted version of =,./= to be much more useful =!?\=. ZMK might be able to handle this better, but that's not an option with most of my keyboards.
These screenshots were taken out of Chrysalis, the Keyboardio configurator on [2020-10-13].
There have been some minor changes since then but I am using QMK now so getting nice labelled images of the layout is not so simple.
(My [[id:20220523T234413.114460][site engine]] currently does not support image uploads, sorry.)
#+ATTR_ORG: :width 800
[[file:../data/28/7ba93e-a2af-4093-a74b-85172edb2ab2/Screenshot_20201013_164724.png][file:~/org/data/28/7ba93e-a2af-4093-a74b-85172edb2ab2/Screenshot_20201013_164724.png]]
@ -35,28 +46,21 @@ I use QWERTY, a custom symbol layer, and a mouse layer which I may not use. Thes
#+ATTR_ORG: :width 800
[[file:../data/28/7ba93e-a2af-4093-a74b-85172edb2ab2/Screenshot_20201013_164926.png][file:~/org/data/28/7ba93e-a2af-4093-a74b-85172edb2ab2/Screenshot_20201013_164926.png]]
[[id:20210814224010-my_custom_keyboard_layout][My Xmodmap Hacks]] are overlayed on this to create a full brace pair cluster on the left hand with the right hand entering symbol layer.
* So what is my endgame?
* Hardware Support
This thing with either a trackpoint or trackball.
This =UDEV= rule makes sure that the device can be accessed by users, this allows me to program the device without needing to become root. This "just works" on [[id:cce/my_nixos_configuration][My NixOS configuration]], though.
This thing except I have re-habitualized my typing so that my hands travel less "across" the keyboard, even this one i sometimes manage to play like a piano.
#+begin_src text :comments none :tangle cce/udev/90-keyboardio.rules
SUBSYSTEM=="tty", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="230[0-3]", TAG+="uaccess"
#+end_src
This thing but it has little legs that fold out so that it can sit in my lap and still be small enough to travel with or use with my laptop.
#+begin_src yaml
- name: udev rule installed
copy:
src: udev/90-keyboardio.rules
dest: /etc/udev/rules.d/90-keyboardio.rules
tags:
- udev
- atreus
register: keyboardio_udev
This but it's bluetooth and battery powered, running ZMK.
- name: udev refreshed
shell: udevadm trigger
when: keyboardio_udev.changed
#+end_src
This but the keys are aligned to match my finger-lengths based on my own measurements.
One of these days I'm going to teach myself enough PCB design and KiCad and Machining to produce this.
* File holder :noexport:
:PROPERTIES:
:ID: 690d03f5-abe7-4b0e-be94-086008b7fd7b
:END:

View File

@ -10,10 +10,11 @@
#+PROPERTY: header-args:emacs-lisp :tangle literate-programming.el
#+ARCOLOGY_KEY: cce/literate-programming
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_EMACS_MODULE: literate-programming
#+ARROYO_MODULE_WANTS: cce/org_mode_installation.org
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_MODULE_WANTS: cce/diminish.org
=org-tempo=[fn:1] provides easy templating in org-mode buffers and I use them to make it easier to write code for the [[id:cce/cce][CCE]]. I can tab across =<s= and =<q= to expand to source and quote blocks, along with many others (and it's customisable of course through =org-tempo-keywords-alist=.)
@ -58,6 +59,7 @@ Configure what languages I want to use for org-babel:
(gnuplot . t)
(shell . t)
(org . t)
(plantuml . t)
(js . t)))
#+end_src
@ -87,9 +89,14 @@ Finally, =org-edit-src= simply cannot steal my window configuration from me.
#+begin_src emacs-lisp
(use-package org-auto-tangle
:defer t
:diminish
:hook (org-mode . org-auto-tangle-mode))
#+end_src
#+begin_src emacs-lisp
(setq org-plantuml-executable-path "/nix/store/gyznjv622jqc8d1x56r7c4wp2rq8md7m-plantuml-1.2023.1/bin/plantuml")
#+end_src
* Footnotes
[fn:1] https://orgmode.org/org.html#Structure-Templates

504
matrix-feedbot.org Normal file
View File

@ -0,0 +1,504 @@
:PROPERTIES:
:ID: 20230331T181418.903306
:ROAM_ALIASES: "Matrix Feedbot"
:END:
#+TITLE: RSS Feed Bot Posting to Matrix.org
#+filetags: :Project:
#+ARCOLOGY_KEY: cce/matrix-feedbot
#+ARDCOLOGY_ALLOW_CRAWL: t
#+ARROYO_NIXOS_MODULE: nixos/feedbot.nix
#+ARROYO_NIXOS_ROLE: server
This is the sibling of [[id:20230125T143144.011175][Feediverse]], it's a small [[id:matrix_org_ecosystem][Matrix.org]] client which uses [[id:cce/python][Python]]'s =feedparser= library to post RSS and Atom feeds to a Matrix room. I used to run this myself and a few years ago I moved to Matrix's hosted "Neb" Bot solution since it could be configured by others. Well, they went and [[https://github.com/matrix-org/matrix-hookshot/issues/686][goofed it up]] and rather than make every feed I care about adhere 100% to a brittle parser, we'll go back to a known-working solution.
This is a [[id:cce/literate_programming][Literate Programming]] version of my old [[https://code.rix.si/rrix/matrix-feedbot][matrix-feedbot]] with some features added to it like being able to load some feeds from the =feeds.json= endpoint in the [[id:arcology/routing][Arcology Routing Logic]]/[[id:arroyo/feed-cache][Arroyo Feed Cache Generator]].
* Feeds to Post
:PROPERTIES:
:ID: 20230417T105045.604988
:END:
This is embedded in the configuration.nix which deploys the feed bot... As always, I am up to [[id:cce/literate_programming][Literate Programming]] shenanigans.
#+name: urls
| URL | Owner |
|------------------------------------------------------------------------------+---------|
| https://iliana.fyi/atom.xml | [[id:ab3f017f-062b-405d-a46e-f0ac338ebeb0][iliana]] |
| https://faust.land/all/feed.atom | [[id:7f451675-1db0-4093-9d8e-28cc5d597545][Maya]] |
| https://maya.land/feed.xml | [[id:7f451675-1db0-4093-9d8e-28cc5d597545][Maya]] |
| https://occult.institute/@faustland.rss | [[id:7f451675-1db0-4093-9d8e-28cc5d597545][Maya]] |
| https://dammit.nl/feeds/all.atom.xml | [[id:michiel_scholten][Michiel]] |
| https://data.bff.fm/shows/pulse-width-mornings.rss | [[roam:Torrie Fischer][Torrie]] |
| https://www.youtube.com/feeds/videos.xml?channel_id=UCvpCqRSI-9rPyT431QkRKig | [[roam:Torrie Fischer][Torrie]] |
| https://makerspacemanagers.com/?format=rss | [[id:99ad3cf8-1a38-422f-8107-0d6617bf2636][Will]] |
| https://willbradley.name/feed/ | [[id:99ad3cf8-1a38-422f-8107-0d6617bf2636][Will]] |
| https://christine.website/blog.rss | [[roam:Xe Iaso][Xe]] |
| https://blog.yaelwrites.com/rss/ | [[id:80e62a41-eb55-4141-acfa-3fe248dcdd7e][Yael]] |
| https://yaelwrites.com/index.xml | [[id:80e62a41-eb55-4141-acfa-3fe248dcdd7e][Yael]] |
#+NAME: mkFeeds
#+begin_src emacs-lisp :var tbl=urls :noweb-ref mkFeeds
(->> tbl
(--map (first it))
(--map (format "\"%s\"" it))
(s-join "\n"))
#+end_src
* The Script Itself
** The Worker Class and Loop
Look, this thing is pretty un-exciting. It's a =while= loop with a bunch of scaffolding to persist configuration, fetch feeds, and send messages. Each of those functionalities is broken out below with the core logical loop remaining in place here.
#+begin_src python :tangle ~/Code/feedbot2/matrix_feedbot/feedbot.py :noweb yes :mkdirp yes
import asyncio
import aiohttp
import feedparser
import os
from typing import Dict
import datetime
import time # i hate python!!
from nio import AsyncClient, MatrixRoom, RoomMessageText
<<YamlBackedDict>>
class Worker():
def __init__(self):
path = os.environ.get("FEEDBOT_CONFIG", "./cfg.yaml")
cred_path = os.environ.get("FEEDBOT_CREDENTIALS_CONFIG", "./creds.yaml")
cache_path = os.environ.get("FEEDBOT_CACHE", "./cache.yaml")
self.config = YamlBackedDict(path, self.stub_config)
self.credentials = YamlBackedDict(cred_path, self.stub_creds)
cache = { feed: set() for feed in self.config["feeds"] }
self.cache = YamlBackedDict(cfg_path=cache_path, stub_fn=self.stub_cache)
self.cache._dict = {**cache, **self.cache._dict}
self.client = AsyncClient(self.credentials["homeserver"],
self.credentials["username"])
self.last_fetch = datetime.datetime.fromtimestamp(0)
async def main(self) -> None:
await self.login()
self.client.add_event_callback(self.message_callback, RoomMessageText)
while True:
td = datetime.datetime.now() - self.last_fetch
if td > datetime.timedelta(hours=1):
print("refreshing...")
await self.maybe_fetch_feeds()
await self.maybe_fetch_dynamic_feeds()
self.cache.save()
self.last_fetch = datetime.datetime.now()
print("ahh...")
await self.client.sync(timeout=30*1000)
<<stub-functions>>
<<message>>
<<feed-fetch>>
async def login(self) -> None:
if self.credentials.get("access_token") is None:
login_resp = await self.client.login(self.credentials["password"])
self.credentials["access_token"] = login_resp.access_token
self.credentials["device_id"] = login_resp.device_id
self.credentials.save()
else:
self.client.access_token = self.credentials["access_token"]
self.client.device_id = self.credentials["device_id"]
for room_id in self.config["rooms"]:
await self.client.join(room_id)
def run():
w = Worker()
asyncio.get_event_loop().run_until_complete(w.main())
#+end_src
** Fetch and Parse Feeds Asynchronously
These functions, starting with =fetch_feed_url= create an =async= function which will handle feed parsing and whatnot all the way through sending the message. =maybe_fetch_dynamic_feeds= will reach out to the Arcology's feeds.json endpoint and iterate over each of those, and =maybe_fetch_feeds= will iterate over the statically defined ones.
#+begin_src python :noweb-ref feed-fetch
async def maybe_fetch_feeds(self):
feedurls = self.config["feeds"]
for feed in feedurls:
await self.fetch_feed_url(feed)
async def maybe_fetch_dynamic_feeds(self):
for feed_config in self.config['dynamic_urls']:
async with aiohttp.ClientSession() as session:
data = await self.fetch(session, feed_config)
data = yaml.safe_load(data) # it's json and json is yaml so hahaha
for feed in data:
self.cache[feed['url']] = self.cache.get(feed['url'], set())
await self.fetch_feed_url(feed['url'])
async def fetch_feed_url(self, feed):
"""
greetz to https://stackoverflow.com/questions/23847555/asynchronous-feedparser-requests
"""
async with aiohttp.ClientSession() as session:
data = await self.fetch(session, feed)
rss = feedparser.parse(data)
print(f"got {feed} w/ {len(rss['entries'])}")
def filter_old_entries(entry):
if entry['updated_parsed'].tm_year > 1969:
entry_time = datetime.datetime.fromtimestamp(time.mktime(entry['updated_parsed']))
if datetime.datetime.now() - entry_time < datetime.timedelta(hours=24) and entry['link'] not in self.cache[feed]:
return True
else:
return False
else:
return False
entries_filtered = filter(filter_old_entries, rss['entries'])
entries_sorted = sorted(entries_filtered, key=lambda entry: entry['updated_parsed'])
for entry in entries_sorted:
await self.send_message(rss, entry)
self.cache[feed].add(str(entry['link']))
# if a post is made, we need to save the cache so that we don't spam our friends
self.cache.save()
async def fetch(self, session, url):
async with session.get(url) as response:
return await response.text()
#+end_src
** Message Formatting and Sending
#+begin_src python :noweb-ref message
async def message_callback(self, room: MatrixRoom, event: RoomMessageText) -> None:
pass
async def send_message(self, feed, entry):
# construct message
html = ''.join([
'New in <a href="', feed['feed']['link'], '">',
feed['feed']['title'],
'</a>: <a href="', entry['link'], '">', entry.get('title', entry.get('link')), '</a>'
])
text = ''.join([
'New in', feed['feed']['title'],
': ', entry['link'], " - ", entry.get('title', entry.get('link'))
])
print(text)
print(html)
# TKTKTK configure which rooms a feed goes tooo.
# TKTKTK configure how often to scrape a feed
for room_id in self.config['rooms']:
print(await self.client.room_send(
room_id=room_id,
message_type="m.room.message",
content={"msgtype": "m.text",
"format": "org.matrix.custom.html",
"formatted_body": html,
"body": text },
))
#+end_src
** =YamlBackedDict=
I have this stupid config structure i made which is just used to load and persist a YAML file:
#+begin_src python :noweb-ref YamlBackedDict
import yaml
class YamlBackedDict():
def __init__(self, cfg_path: str, stub_fn):
self.path = cfg_path
self.stub_generator = stub_fn
self._dict = self.load()
def __setitem__(self, k, v):
self._dict[k] = v
def __getitem__(self, k):
return self._dict[k]
def __str__(self):
return str(self._dict)
def get(self, k, default=None):
return self._dict.get(k, default)
def stub(self):
cfg = self.stub_generator()
with open(self.path, 'w') as f:
yaml.dump(cfg, f)
return cfg
def load(self):
if not os.path.exists(self.path):
cfg = self.stub()
else:
with open(self.path, 'r') as f:
cfg = yaml.safe_load(f)
return cfg
def save(self):
with open(self.path, 'w') as f:
return yaml.safe_dump(self._dict, f)
#+end_src
The YAML files each have an un-documented schema because I am an asshole; because I am not an asshole, there is a function which will stub each of them when they are not existing, these are passed in to the constructor to =YamlBackedDict= and listed as part of the =Worker= class but if I do more work on this it should probably be sub-classes..
#+begin_src python :noweb-ref stub-functions
def stub_creds(ybd) -> Dict:
return dict(
username=input("Enter the Matrix username: "),
password=input("Enter the Matrix password: "),
homeserver=input("Enter the Matrix homserver URL: "),
)
def stub_config(ybd) -> Dict:
return dict(
rooms=[
input("Enter the first room ID to join (starts with ! not #): "),
],
feeds=[],
dynamic_urls=[],
)
def stub_cache(ybd) -> Dict:
# would be nice if this could include the set() logic in __init__ but...
return dict()
#+end_src
** To-do :noexport:
*** NEXT integrate =click=
*** INPROGRESS detangle
:LOGBOOK:
- State "INPROGRESS" from "NEXT" [2023-04-11 Tue 12:15]
:END:
*** NEXT feed -> roomlist mappings? so that my dev feeds can also go to my devlog rooms
*** NEXT commands in message_callback
*** INPROGRESS tag feeds based on fetch recency rather than using a sleep so that the commands don't block
:LOGBOOK:
- State "INPROGRESS" from "NEXT" [2023-04-01 Sat 00:23]
:END:
*** DONE store access_token in config
:LOGBOOK:
- State "DONE" from "NEXT" [2023-04-11 Tue 12:14]
:END:
*** DONE register bot user
:LOGBOOK:
- Note taken on [2023-04-11 Tue 10:50] \\
=docker exec -it matrix-synapse /opt/synapse/bin/python /opt/synapse/bin/register_new_matrix_user -c /data/homeserver.yaml= on fontkeming
- State "DONE" from "NEXT" [2023-04-11 Tue 10:50]
:END:
*** DONE split out the credentials loading from the configuration so that i don't commit those to the nix store
:LOGBOOK:
- State "DONE" from "NEXT" [2023-04-11 Tue 12:35]
:END:
* pyproject/poetry definition
I'll be a fool and use poetry for this even though I don't really need to.
#+begin_src toml :tangle ~/Code/feedbot2/pyproject.toml
[tool.poetry]
name = "matrix-feedbot"
version = "0.0.0"
description = "Send RSS feeds to a Matrix room"
license = "GPL-3.0-only"
authors = [
"Ryan Rix <code@whatthefuck.computer>"
]
packages = [
{ include = "matrix_feedbot" }
]
[tool.poetry.dependencies]
python = "^3.10"
matrix-nio = "^0.20"
feedparser = "^6.0.10"
pyyaml = "^6.0"
[tool.poetry.scripts]
feedbot = 'matrix_feedbot.feedbot:run'
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
#+end_src
** NEXT In theory this could support e2e but lol, it's fine. Maybe later.
* Deploy to [[id:20211120T220054.226284][The Wobserver]]
:PROPERTIES:
:ID: 20230411T153058.351319
:END:
:LOGBOOK:
- State "DONE" from "INPROGRESS" [2023-04-17 Mon 10:58]
- State "INPROGRESS" from "NEXT" [2023-04-11 Tue 14:50]
:END:
** Nix Shell setup
#+begin_src nix :tangle ~/Code/feedbot2/shell.nix :mkdirp yes
{ pkgs ? import <nixpkgs> {} }:
let
myPython = pkgs.python3.withPackages (ppkgs:
with ppkgs; [
feedparser
click
pyyaml
matrix-nio
]);
in
pkgs.mkShell {
packages = [
pkgs.poetry
myPython
];
}
#+end_src
** Package feedbot in [[id:20221021T121120.541960][rixpkgs]]
#+begin_src nix :tangle ~/arroyo-nix/pkgs/feedbot.nix
{ lib,
fetchFromGitHub,
python3Packages,
callPackage,
}:
python3Packages.buildPythonPackage {
pname = "matrix-feedbot";
version = "0.0.1";
src = /home/rrix/Code/feedbot2;
format = "pyproject";
propagatedBuildInputs = with python3Packages; [ matrix-nio feedparser pyyaml ];
buildInputs = with python3Packages; [ poetry-core ];
# checkInputs = with python3Packages; [];
meta = {
homepage = "https://cce.whatthefuck.computer/matrix-feedbot";
description = "Post RSS/Atom feeds to Matrix";
license = lib.licenses.agpl3Only;
maintainers = with lib.maintainers; [ rrix ];
};
}
#+end_src
** Deploy in [[id:arroyo/nixos][Arroyo NixOS]]
This is set up to take options; in theory some day someone else could use this... but for now it's mostly for my own benefit.
#+begin_src nix :tangle ~/arroyo-nix/nixos/feedbot.nix :noweb yes
{ lib, pkgs, config, ... }:
with lib; {
options.services.feedbot = {
enabled = mkOption {
type = types.bool;
default = true;
};
package = mkOption {
type = types.package;
default = pkgs.matrix-feedbot;
};
workDir = mkOption {
type = types.str;
default = "/srv/feedbot";
};
credentialsFileLocation = mkOption {
type = types.path;
default = "/srv/feedbot/creds.yaml";
};
cacheFileLocation = mkOption {
type = types.path;
default = "/srv/feedbot/cache.yaml";
};
rooms = mkOption {
type = types.listOf types.str;
default = [ "!THQSEcCQbqCZqLGUbG:kickass.systems" ];
};
dynamicFeedUrls = mkOption {
type = types.listOf types.str;
default = [ "https://thelionsrear.com/feeds.json" ];
};
feedUrls = mkOption {
type = types.listOf types.str;
default = [
<<mkFeeds()>>
];
};
};
config = {
users.groups.feedbot = {};
users.users.feedbot = {
createHome = true;
home = config.services.feedbot.workDir;
group = "feedbot";
isSystemUser = true;
};
systemd.services.feedbot = mkIf config.services.feedbot.enabled {
enable = true;
description = "Post RSS and Atom feeds to a Matrix room.";
after = [ "network.target" ];
script = "${config.services.feedbot.package}/bin/feedbot";
wantedBy = [ "default.target" ];
environment = {
FEEDBOT_CONFIG = pkgs.writeTextFile {
name = "feedbot.config.yaml";
text = generators.toYAML {} {
feeds = config.services.feedbot.feedUrls;
dynamic_urls = config.services.feedbot.dynamicFeedUrls;
rooms = config.services.feedbot.rooms;
};
};
FEEDBOT_CREDENTIALS_CONFIG = config.services.feedbot.credentialsFileLocation;
FEEDBOT_CACHE = config.services.feedbot.cacheFileLocation;
};
serviceConfig = {
RestartSec = 5;
Restart = "on-failure";
User = "feedbot";
};
};
};
}
#+end_src

View File

@ -39,90 +39,55 @@ Here's the one for getting things from my server to my laptop. Most folks who se
{
programs.mbsync.enable = true;
accounts.email.maildirBasePath = "/home/rrix/Maildir";
accounts.email.accounts.endpoint = {
accounts.email.accounts.fastmail = {
address = "ryan@whatthefuck.computer";
realName = "Ryan Rix (rrix)";
aliases = [ "ry@n.rix.si" "rrix@fastmail.com" ];
# aliases = [ "ry@n.rix.si" "rrix@fastmail.com" ];
userName = "rrix@fastmail.com";
passwordCommand = "${pkgs.rbw}/bin/rbw get fastmail_email_app";
maildir.path = "fastmail";
primary = false; # outbox goes through fastmail smtp
passwordCommand = "pass show fastmail_email_app";
imap.host = "fontkeming.fail";
imap.tls.enable = false;
imap = {
host = "mail.messagingengine.com";
};
mbsync = {
enable = true;
subFolders = "Verbatim";
groups = {
endpoint = {
channels = {
high-priority = {
extraConfig.Create = "near";
patterns = [
"fastmail/INBOX"
"fastmail/github"
"fastmail/Sent\\ Mail"
"fastmail/fedora/bugs"
];
};
low-priority = {
extraConfig = {
MaxMessages = 1000;
MaxSize = "10m";
Create = "near";
ExpireUnread = "no";
};
patterns = [
"fastmail/newsletters"
"fastmail/social"
"fastmail/emacsconf"
"fastmail/phoenix-lug"
"fastmail/RecruitingSpam"
"fastmail/Junk Mail"
];
};
feeds = {
patterns = [
"feeds/Art"
"feeds/Blogs"
"feeds/Brain"
"feeds/Motorsports"
"feeds/News"
"feeds/Self"
"feeds/Software"
"feeds/Tea"
"feeds/Tech"
"feeds/Videos"
"feeds/Longreads"
];
extraConfig = {
MaxSize = "10m";
Create = "near";
ExpireUnread = "no";
};
};
work = {
patterns = [
"crdigital/INBOX"
"crdigital/[Gmail]/Sent Mail"
];
extraConfig = {
MaxMessages = 1000;
MaxSize = "10m";
Create = "near";
ExpireUnread = "no";
};
};
};
};
};
extraConfig = {
account = {
Timeout = 120;
Tunnel = "ssh -q fontkeming /usr/libexec/dovecot/imap";
};
};
groups = {
all = {
channels = {
top = {
extraConfig.Create = "near";
patterns = [
"INBOX"
"1ml"
"1ml/bcz"
"1ml/friendsofsecurityplanner"
"Junk Mail"
"RecruitingSpam"
"Sent Mail"
"emacsconf"
"fedora/bugs"
"github"
"newsletters"
"phoenix-lug"
"social"
];
};
rest = {
extraConfig.Create = "near";
patterns = [
"*"
];
};
};
};
};
};
@ -131,3 +96,4 @@ Here's the one for getting things from my server to my laptop. Most folks who se
#+end_src
The last time I used =mbsync=, I experienced issues with mail IDs in my =newsrc.eld= file, which Gnus uses to store which lists I am subscribed too, and also functions as a cache for message and folder states. The latter caching was what caused these issues, I believe, but it was really difficult to debug it. If this happens again, I may switch to [[id:fa7e9d10-a98d-4036-a668-889bd1d3ea29][offlineimap]].

View File

@ -17,6 +17,7 @@ This is a simple [[id:cce/cce][CCE]] [[id:cce/home-manager][home-manager]] helpe
config: src: dest:
config.lib.dag.entryAfter ["writeBoundary"] ''
mkdir -p $(dirname ${dest})
$DRY_RUN_CMD test -e $HOME/${dest} || \
$DRY_RUN_CMD ln -s $VERBOSE_ARG \
${src} $HOME/${dest}

224
morph-wrapper.org Normal file
View File

@ -0,0 +1,224 @@
:PROPERTIES:
:ID: 20230530T120958.265094
:ROAM_ALIASES: "Morph Command Wrapper"
:END:
#+TITLE: Wrapping Morph commands for more ergonomic deployment
#+ARCOLOGY_KEY: cce/morph-wrapper
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_DIRENV_DIR: ~/Code/morph-wrapper/
#+AUTO_TANGLE: t
After [[id:20230529T205533.092875][I tried setting up deploy-rs and it (and flakes) is kind of not very good for what I am doing with my computers]] yesterday, I found that I still want to simplify my deploy tooling to make it easier to ship updates of my Nix systems to their hosts.
#+ATTR_HTML: :width 40em
#+CAPTION: a dogshit vince mcmahon meme i made showing the progression from morph, to flake experiments, and back to morph
[[https://files.fontkeming.fail/s/74KK77RDgfHQyLD/download/terrible-meme-morph-wrapper.png]]
I landed on a solution inspired by [[roam:Xe Iaso]]'s [[https://github.com/Xe/nixos-configs/blob/master/ops/metadata/hosts.toml][hosts.toml]] setup. See [[id:20230530T120902.994787][Deploying from my =hosts.toml= ]] for how this file is created, structured, and used in the =morph= commands themselves.
This page outlines a very simple script which ingests that =hosts.toml= file and provides a handful of options to make it easy for me to just specify hostnames and have the system figure out which manifest they should apply to and what to do with them.
We use =toml= and =click= and some builtins.
#+begin_src python :mkdirp yes :tangle ~/Code/morph-wrapper/morph_wrapper/wrapper.py
import toml
import click
import os
import socket
import subprocess
#+end_src
Short help options are good imo, [[https://click.palletsprojects.com/en/8.1.x/documentation/#help-parameter-customization][customize that]].
#+begin_src python :mkdirp yes :tangle ~/Code/morph-wrapper/morph_wrapper/wrapper.py
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
#+end_src
=deploy-targets= will print out the hostnames of all the hosts in the =hosts.toml= file suitable for using in [[id:20211130T215142.470274][arroyo-flood]] or so to interactively pick hostnames to deploy to.
#+begin_src
Usage: deploy-targets [OPTIONS]
print a list of all the hosts in the hosts.toml
Options:
-f FILENAME hosts.toml file path
-h, --help Show this message and exit.
#+end_src
#+begin_src python :mkdirp yes :tangle ~/Code/morph-wrapper/morph_wrapper/wrapper.py
@click.command(context_settings=CONTEXT_SETTINGS)
@click.option('-f', 'hosts_file',
envvar="HOSTS_TOML", type=click.File('r'),
help="hosts.toml file path",
default="/home/rrix/arroyo-nix/networks/hosts.toml")
def list_hosts(hosts_file):
"""
print a list of all the hosts in the hosts.toml
"""
network = toml.load(hosts_file)
for netname, host in get_all_hosts(network):
print(host)
#+end_src
=deploy= does the thing. If you try to deploy to a host which cannot be pinged, it will be skipped. This doesn't read =targetHost= from the Morph network file, but those are lined up for me. =-f= will override this behavior, this is useful to me when I am bootstrapping a node.
#+begin_src
Usage: deploy [OPTIONS] [HOSTS]...
build or deploy one or more hosts
Options:
-f FILENAME hosts.toml file path
--all deploy to all hosts in the manifest
--deploy / -b, --build choose whether to deploy or just build.
-a, --action TEXT choose the deploy action
-c, --confirm / -C, --no-confirm
ask before running morph commands
-h, --help Show this message and exit.
#+end_src
#+begin_src python :mkdirp yes :tangle ~/Code/morph-wrapper/morph_wrapper/wrapper.py
@click.command(context_settings=CONTEXT_SETTINGS)
@click.option('-f', 'hosts_file',
envvar="HOSTS_TOML",
help="hosts.toml file path",
type=click.File('r'),
default="/home/rrix/arroyo-nix/networks/hosts.toml")
@click.option('--all', 'deploy_all', is_flag=True, default=False,
help="deploy to all hosts in the manifest")
@click.option(' /-b', '--deploy/--build', 'do_deploy',
help="choose whether to deploy or just build.", is_flag=True, default=True)
@click.option('-a', '--action', 'deploy_action',
help="choose the deploy action", default="switch")
@click.option('-c/-C', '--confirm/--no-confirm', 'confirm',
help="ask before running morph commands", is_flag=True, default=False)
@click.option('-f', '--force/--no-force', 'force',
help="Don't skip unavailable hosts", is_flag=True, default=False)
@click.argument('hosts', nargs=-1)
def wrap(hosts_file, deploy_all, hosts, do_deploy, deploy_action, confirm, force):
"""
build or deploy one or more hosts
"""
network = toml.load(hosts_file)
if deploy_all:
hosts = [h for net,h in get_all_hosts(network)]
elif len(hosts) == 0:
hosts = (socket.gethostname(),)
subnets_to_deploy = get_pairs(network, hosts)
for network, host in subnets_to_deploy:
if do_deploy:
if force or host_available(host):
cmd = f"morph deploy --on={host} --passwd ~/arroyo-nix/networks/{network}.nix {deploy_action}"
else:
click.echo(f"{host} is unavailable, skipping...")
continue
else:
cmd = f"morph build --on={host} ~/arroyo-nix/networks/{network}.nix"
click.echo(f"Prepared to run '{cmd}'")
if confirm:
input("or hit ctrl-c... ")
os.system(cmd)
def host_available(hostname: str) -> bool:
proc = subprocess.run(f"ping -w 1 -c 1 {hostname}", shell=True, capture_output=True)
return proc.returncode == 0
#+end_src
And these ugly list-comprehensions help to munge the TOML file in to a form the python commands here would like to use.
#+begin_src python :mkdirp yes :tangle ~/Code/morph-wrapper/morph_wrapper/wrapper.py
def get_all_hosts(network):
return [
(name, host)
for name, net in network.items()
for host in net['hosts'].keys()
]
def get_pairs(network, hosts):
return [
(netname, hostname)
for netname, subnet in network.items()
for hostname in hosts
if hostname in subnet['hosts'].keys()
]
#+end_src
This is made available to my system builds in my [[id:20221021T121120.541960][rixpkgs]] overlay, and added like this:
#+ARROYO_NIXOS_MODULE: nixos/morph-wrapper.nix
#+begin_src nix :tangle ~/arroyo-nix/nixos/morph-wrapper.nix
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.morph-wrapper ];
}
#+end_src
So now when I make changes I can type =deploy -b= in to my nearest terminal to see my local system's build come together, then =deploy= to deploy it to this machine, then =deploy $hostnames= to deploy it to any number of my hostnames or =deploy --all= to deploy it everywhere.
* Shell Environment and Pyproject manifest
This uses =poetry= and =poetry2nix= to generate a python application and nix derivation for use in my systems, a =shell.nix= is provided as well:
#+begin_src toml :mkdirp yes :tangle ~/Code/morph-wrapper/pyproject.toml
[tool.poetry]
name = "morph-wrapper"
version = "0.1.0"
description = ""
authors = ["Ryan Rix <code@whatthefuck.computer>"]
include = []
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.dependencies]
python = "^3.10"
toml = "^0.10.2"
click = "^8.1.3"
[tool.poetry.scripts]
deploy = 'morph_wrapper.wrapper:wrap'
deploy-targets = 'morph_wrapper.wrapper:list_hosts'
#+end_src
#+begin_src nix :tangle ~/Code/morph-wrapper/shell.nix
{ pkgs ? import <nixpkgs> {} }:
let
python-with-my-packages = pkgs.python3.withPackages (p: with p; [
toml
click
]);
in
pkgs.mkShell {
packages = [
python-with-my-packages
pkgs.poetry
];
}
#+end_src
#+begin_src nix :tangle ~/Code/morph-wrapper/default.nix
{ pkgs ? import <nixpkgs> {},
poetry2nix ? pkgs.poetry2nix,
stdenv ? pkgs.stdenv,
python ? pkgs.python3 }:
poetry2nix.mkPoetryApplication {
inherit python;
projectDir = ./.;
propagatedBuildInputs = [];
}
#+end_src

616
morph.org
View File

@ -16,38 +16,316 @@ Morph is a tool for managing existing NixOS hosts - basically a fancy wrapper ar
Interestingly, it seems like I can just use my [[id:cce/nixops][NixOps]] laptop profile...? stealin' it! that's nice.
* Deploying My Laptops
In the embeds you'll learn how I pick the hostnames for my computers.
* Deploying from my =hosts.toml=
:PROPERTIES:
:ID: 20230530T120902.994787
:END:
Morph is fine to use, but it's a little bit unergonomic, especially if i want to blast out builds to a bunch of hosts. I am taking a cue from [[https://xeiaso.net/][Xe Iaso]] and moving toward defining my host configurations in a =hosts.toml= file. For now, it only has the bare necessities to generate deployment networks for each of my roles, but it could be extended with other things like SSH host keys, or encrypted secrets in the near future. I'm also planning to write a little python script so that I can type to my computer =deploy virtuous-cassette= and have that roll out rather than the complicated [[id:20220912T114451.341788][Shell Spell]] =morph deploy --on=virtuous-cassette --passwd ~/arroyo-nix/networks/laptops.nix switch=.
#+begin_src nix :tangle ~/arroyo-nix/networks/mkNetwork.nix
{ pkgs, networks }:
let
mkHost = rollConfig: hostname: config:
let hostConfig = ./. + "/../hosts/${hostname}";
in
{
imports = [ rollConfig hostConfig ];
deployment.targetHost = (if config ? target then config.target else hostname);
deployment.targetUser = (if config ? user then config.user else "rrix");
} // (if config ? stateVersion then {
system.stateVersion = config.stateVersion;
} else {});
mkNetwork = subnet:
let
network = networks."${subnet}";
roleConfig = ./. + "/${network.config}";
mkHost' = mkHost roleConfig;
in
{
network.pkgs = pkgs;
network.description = network.description;
network.enableRollback = (if network ? enableRollback then network.enableRollback else true);
} // builtins.mapAttrs mkHost' network.hosts;
in mkNetwork
#+end_src
this =mkNetwork= function is easy to operate as you can see below; it provides reasonable defaults so that my Tailscale-backed hosts can just be added to the network with a single line. Bootstrapping hosts is as simple as adding the local DHCP address as the =target= key and setting the =user= for the first SSH.
* Deploying My Laptops and Desktop
:PROPERTIES:
:ID: cce/morph-laptops
:END:
My laptops are installed through my [[id:cce/nixos_automatic_partitioning_installer][NixOS Automatic Partitioning Installer]] and carry [[id:cce/my_nixos_configuration][My NixOS configuration for laptops]], the "endpoint configuration".
#+begin_src nix :tangle ~/arroyo-nix/networks/laptops.nix :mkdirp yes
#+begin_src nix :tangle ~/arroyo-nix/networks/endpoints.nix
let
endpointCfg = ../roles/endpoint;
# nixpkgsPin = (import ../versions.nix {}).nixpkgs;
# pkgs = import (builtins.fetchTarball nixpkgsPin) {};
pkgs = import <nixpkgs> {};
in {
network.pkgs = pkgs;
network.description = "my laptops";
network.enableRollback = true;
allNetworks = pkgs.lib.importTOML ./hosts.toml;
mkNetwork = import ./mkNetwork.nix { inherit pkgs; networks = allNetworks; };
in mkNetwork "endpoints"
#+end_src
meadow-crush = {config, pkgs, ...}:
{
imports = [ endpointCfg ../hosts/meadow-crush ];
deployment.targetHost = "meadow-crush";
deployment.targetUser = "root";
system.stateVersion = "22.05";
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
[endpoints]
description = "my laptops and desktop"
enableRollback = true
config = "../roles/endpoint"
#+end_src
** Rose Quine
:PROPERTIES:
:ID: 20230328T191051.959009
:END:
#+begin_export html
<iframe style="border: 0; width: 200px; height: 200px;" src="https://bandcamp.com/EmbeddedPlayer/album=1563537773/size=large/bgcol=ffffff/linkcol=2ebd35/minimal=true/track=1268670717/transparent=true/" seamless><a href="https://theflashbulb.bandcamp.com/album/our-simulacra">Our Simulacra by The Flashbulb</a></iframe>
#+end_export
Rose Quine is my [[id:20230404T153703.708523][GPD Pocket 3]].
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
[endpoints.hosts.rose-quine]
# target = "rose-quine"
# stateVersion = "23.05"
#+end_src
#+begin_src nix :tangle ~/arroyo-nix/hosts/rose-quine/default.nix :mkdirp yes
{ config, pkgs, lib, ... }:
{
imports = [ <arroyo/nixos/gpd-pocket-3.nix> ];
networking.hostName = "rose-quine";
system.stateVersion = "23.05";
services.xserver.dpi = 280;
services.tailscale.authKey = "tskey-auth-knLBN35CNTRL-ignbakuis45bC5m5mrvX95o4DW9JHoRV8";
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.grub.enable = true;
boot.loader.grub.gfxmodeBios = "1200x1920x32";
boot.loader.systemd-boot.enable = lib.mkForce false;
# boot.loader.systemd-boot.consoleMode = "max";
networking.hostId = "3f5dbbf9"; # required for zfs use
boot.zfs.devNodes = "/dev/mapper"; # (ref:devNodes)
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true; };
"root" = { name = "root"; device = "/dev/nvme0n1p3"; preLVM = true; };
};
# === from hardware-configuration.nix
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "tank/root";
fsType = "zfs";
};
virtuous-cassette = {config, pkgs, ...}:
{
imports = [ endpointCfg ../hosts/virtuous-cassette ];
deployment.targetHost = "virtuous-cassette";
system.stateVersion = "22.05";
fileSystems."/home" =
{ device = "tank/home";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "tank/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/9FDC-2C40";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/455bbc40-e01c-4137-b593-a05b6220ce6b"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp175s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp174s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
}
#+end_src
*** NEXT derivation for [[https://github.com/wimpysworld/umpc-ubuntu/blob/master/data/umpc-display-rotate.c][umpc-display-rotate.c]]
*** NEXT split and document all this out in to an import on [[roam:GPD Pocket 3 Support]] page
** Window Smoke
:PROPERTIES:
:ID: 20230225T145612.522017
:END:
#+begin_export html
<iframe style="border: 0; width: 200px; height: 200px;" src="https://bandcamp.com/EmbeddedPlayer/album=1436740419/size=large/bgcol=ffffff/linkcol=2ebd35/minimal=true/track=130097483/transparent=true/" seamless><a href="https://theflashbulb.bandcamp.com/album/seven-quarantine-poems">Seven Quarantine Poems by The Flashbulb</a></iframe>
#+end_export
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
[endpoints.hosts.window-smoke]
# target = "window-smoke"
# stateVersion = "22.11"
# user = "rrix"
#+end_src
Window Smoke is my desktop. It runs my [[id:cce/my_nixos_configuration][Endpoint Configuration]] and some of [[id:20230225T150449.622645][My NixOS Tower Customizations]]
#+begin_src nix :tangle ~/arroyo-nix/hosts/window-smoke/default.nix :mkdirp yes
{ lib, config, ... }:
{
imports = [ ./hardware-configuration.nix ../../roles/desktop ];
boot.enableVFIO = true;
networking.hostName = "window-smoke";
system.stateVersion = "22.11"; #
# boot.loader.grub.efiInstallAsRemovable = true;
# boot.loader.grub.efiSupport = true;
# boot.loader.grub.device = "nodev";
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.systemd-boot.enable = true;
services.xserver.dpi = 110;
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" "wl" ];
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
services.tailscale.authKey = "tskey-auth-k38z9b3CNTRL-DeWdeU2Zt4ccxM2RqHduzbu9h2D7mmP74";
networking.hostId = "141e1b4f"; # required for zfs use
boot.zfs.devNodes = lib.mkForce "/dev/disk/by-id/";
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true; };
"root" = { name = "root"; device = "/dev/nvme0n1p3"; preLVM = true; };
};
fileSystems."/" =
{ device = "window-smoke/root";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "window-smoke/home";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "window-smoke/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/12CA-451F";
fsType = "vfat";
};
fileSystems."/media" =
{ device = "tank/media";
fsType = "zfs";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/26776a6d-4e53-4e39-b0e5-5a540ce78406"; }
];
}
#+end_src
** Virtuous Cassette
:PROPERTIES:
:ID: 20211029T115928.954970
:END:
#+begin_export html
<iframe style="border: 0; width: 200px; height: 200px;" src="https://bandcamp.com/EmbeddedPlayer/album=3533678702/size=large/bgcol=ffffff/linkcol=2ebd35/minimal=true/track=1697170446/transparent=true/" seamless><a href="https://theflashbulb.bandcamp.com/album/love-as-a-dark-hallway">Love As A Dark Hallway by The Flashbulb</a></iframe>
#+end_export
Virtuous Cassette is my [[roam:Framework Laptop]].
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
[endpoints.hosts.virtuous-cassette]
stateVersion = "23.05"
target = "192.168.69.71"
user = "root"
#+end_src
=hosts/tres-ebow/default.nix= replaces the =generated.nix=, basically, for my [[id:6834cb8f-319f-4dd9-bade-2521417f584b][GPD Pocket]]:
#+begin_src nix :tangle ~/arroyo-nix/hosts/virtuous-cassette/default.nix :mkdirp yes
{
imports = [ <arroyo/nixos/framework-laptop.nix> ];
networking.hostName = "virtuous-cassette";
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.enable = true;
boot.loader.systemd-boot.enable = false;
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true; };
"root" = { name = "root"; device = "/dev/nvme0n1p3"; preLVM = true; };
};
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
powerManagement.cpuFreqGovernor = "powersave";
# ===8<--- everything below here will change if i ever reinitialize the host!
services.tailscale.authKey = "tskey-auth-k1WxJ97CNTRL-6Rp5sqDZxM1yAH7mvKp9T1dj1Ps4iKYDY";
networking.hostId = "291fe33d"; # required for zfs use
fileSystems."/" =
{ device = "host/root";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "host/home";
fsType = "zfs";
};
fileSystems."/media" =
{ device = "host/landfill";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "host/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/CD54-B840";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/ddfce221-2d29-4882-9c66-1669ea60bc49"; }
];
}
#+end_src
@ -56,7 +334,17 @@ in {
:ID: cce/morph-meadow-crush
:END:
=hosts/meadow-crush/default.nix= replaces the =generated.nix=, basically, for my [[id:6834cb8f-319f-4dd9-bade-2521417f584b][GPD Pocket]]:
Meadow Crush is my [[id:6834cb8f-319f-4dd9-bade-2521417f584b][GPD Pocket 2]]; I don't use this right now but it's still running a viable NixOS if I need it in a Situation.
#+begin_export html
<iframe style="border: 0; width: 200px; height: 200px;" src="https://bandcamp.com/EmbeddedPlayer/album=1889307725/size=large/bgcol=ffffff/linkcol=2ebd35/minimal=true/track=1231014309/transparent=true/" seamless><a href="https://theflashbulb.bandcamp.com/album/arboreal">Arboreal by The Flashbulb</a></iframe>
#+end_export
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
# [endpoints.hosts.meadow-crush]
# target = "meadow-crush"
# stateVersion = "22.05"
#+end_src
#+begin_src nix :tangle ~/arroyo-nix/hosts/meadow-crush/default.nix :mkdirp yes
{
@ -68,11 +356,6 @@ in {
services.tailscale.authKey = "tskey-kqvV5P3CNTRL-K3bdvSJcUreG8nrGcDKXCh";
# networking.wireguard.interfaces.wg0 = {
# privateKeyFile = "/etc/wireguard-key/meadow-crush.key";
# ips = ["10.10.10.4/32"];
# };
networking.hostId = "c9ec7cad"; # required for zfs use
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/mmcblk0p2"; preLVM = true; };
@ -87,57 +370,6 @@ in {
}
#+end_src
I pull [[file:nixlib/hosts/meadow-crush/hardware-configuration.nix]] with nixops:
#+begin_example
nixops scp --from meadow-crush /etc/nixos/hardware-configuration.nix nixlib/hosts/meadow-crush/hardware-configuration.nix
#+end_example
I put my Wireguard configuration on the device (for now) using nixops scp
#+begin_example
nixops ssh meadow-crush mkdir -p /etc/wireguard-key/ && \
nixops scp --to meadow-crush wireguard/meadow-crush.key /etc/wireguard-key/meadow-crush.key && \
nixops ssh meadow-crush chown 400 /etc/wireguard-key/meadow-crush.key
#+end_example
I need to make sure this stays in sync with my [[id:nixos_justdoit][JustDoIt]] script!
** Virtuous Cassette
:PROPERTIES:
:ID: 20211029T115928.954970
:END:
Virtuous Cassette is my [[roam:Framework Laptop]].
=hosts/tres-ebow/default.nix= replaces the =generated.nix=, basically, for my [[id:6834cb8f-319f-4dd9-bade-2521417f584b][GPD Pocket]]:
#+begin_src nix :tangle ~/arroyo-nix/hosts/virtuous-cassette/default.nix :mkdirp yes
{
imports = [ ./hardware-configuration.nix ];
networking.hostName = "virtuous-cassette";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# networking.wg-quick.interfaces.wg0 = {
# privateKeyFile = "/etc/wireguard-key/virtuous-cassette.key";
# address = ["10.10.10.13/32" "2620:fc:c000:0:1000::d/128"];
# };
# networking.wg-quick.interfaces.wg1 = {
# privateKeyFile = "/etc/wireguard-key/virtuous-cassette.key";
# address = ["10.10.10.13/32" "2620:fc:c000:0:1000::d/128"];
# };
services.tailscale.authKey = "tskey-kMJ8ZX2CNTRL-tDGQZ1dZQLZ9hnuGRgKXS";
networking.hostId = "754ccef7"; # required for zfs use
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true; };
"root" = { name = "root"; device = "/dev/nvme0n1p3"; preLVM = true; };
};
}
#+end_src
** NEXT implement [[https://christine.website/blog/nixos-encrypted-secrets-2021-01-20][nixos encrypted secrets]] and make these safe! maybe [[https://christine.website/blog/my-wireguard-setup-2021-02-06][hosts.toml]] for a lot of this too...
* Deploying My [[id:20220131T152041.472624][NixOS Set Top Box]]
@ -147,21 +379,17 @@ Virtuous Cassette is my [[roam:Framework Laptop]].
#+begin_src nix :tangle ~/arroyo-nix/networks/settop.nix :mkdirp yes
let
settopCfg = ../roles/settop;
# nixpkgsPin = (import ../versions.nix {}).nixpkgs;
# pkgs = import (builtins.fetchTarball nixpkgsPin) {};
pkgs = import <nixpkgs> {};
in {
network.pkgs = pkgs;
network.description = "my settop";
network.enableRollback = true;
allNetworks = pkgs.lib.importTOML ./hosts.toml;
mkNetwork = import ./mkNetwork.nix { inherit pkgs; networks = allNetworks; };
in mkNetwork "settop"
#+end_src
tres-ebow = {config, pkgs, ...}:
{
imports = [ settopCfg ../hosts/tres-ebow ];
deployment.targetHost = "10.0.0.167";
};
}
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
[settop]
description = "my kodi box"
enableRollback = true
config = "../roles/settop"
#+end_src
** Tres Ebow
@ -169,50 +397,82 @@ in {
:ID: cce/morph-tres-ebow
:END:
#+begin_export html
<iframe style="border: 0; width: 200px; height: 200px;" src="https://bandcamp.com/EmbeddedPlayer/album=3533678702/size=large/bgcol=ffffff/linkcol=2ebd35/minimal=true/track=1431497952/transparent=true/" seamless><a href="https://theflashbulb.bandcamp.com/album/love-as-a-dark-hallway">Love As A Dark Hallway by The Flashbulb</a></iframe>
#+end_export
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
[settop.hosts.tres-ebow]
# target = "tres-ebow"
target = "192.168.69.69"
user = "root"
# will probably reinstall soon
stateVersion = "23.05"
#+end_src
Tres Ebow is my Thinkpad Yoga gen 3 -- a decent 2-in-1 with [[id:25942086-23fa-4fff-938d-a7a9c0fa7365][very un-Lenovo serviceability]], and due to ordering error and soldered RAM, only 4 GiB of RAM. awkward. it'll be a fine kodi box.
#+begin_src nix :tangle ~/arroyo-nix/hosts/tres-ebow/default.nix :mkdirp yes
{ config, lib, ... }:
{
imports = [ ./hardware-configuration.nix ];
networking.hostName = "tres-ebow";
boot.loader.systemd-boot.enable = true;
boot.loader.grub.efiSupport = true;
boot.loader.grub.device = "nodev";
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.enable = true;
boot.loader.systemd-boot.enable = false;
services.xserver.dpi = 207;
# networking.wg-quick.interfaces.wg0 = {
# privateKeyFile = "/etc/wireguard-key/tres-ebow.key";
# address = ["10.10.10.2/32" "2620:fc:c000:0:1000::b/128"];
# };
# networking.wg-quick.interfaces.wg1 = {
# privateKeyFile = "/etc/wireguard-key/tres-ebow.key";
# address = ["10.10.10.2/32" "2620:fc:c000:0:1000::b/128"];
# };
services.tailscale.authKey = "tskey-kGxjxy1CNTRL-ZoepgcGatEA78ezQKX5VVb";
networking.hostId = "389acda5"; # required for zfs use
boot.zfs.devNodes = lib.mkForce "/dev/disk/by-uuid"; # (ref:devNodes)
networking.hostId = "c9ec7cad"; # required for zfs use
boot.initrd.luks.devices = {
"swap" = { name = "swap"; device = "/dev/nvme0n1p2"; preLVM = true; };
"root" = { name = "root"; device = "/dev/nvme0n1p3"; preLVM = true; };
};
services.tailscale.authKey = "tskey-auth-kjuYea5CNTRL-YApNAAdxe5aucWNb823g1aNCwTK11pVTA";
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "host/root";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "host/home";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "host/nix";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/CB62-8263";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/4f1751ef-0ddd-4005-b69c-daafc518e9df"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp2s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "balanced";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
hardware.enableRedistributableFirmware = true;
}
#+end_src
I pull [[file:nixlib/hosts/tres-ebow/hardware-configuration.nix]] with nixops:
#+begin_example
nixops scp --from tres-ebow /etc/nixos/hardware-configuration.nix nixlib/hosts/tres-ebow/hardware-configuration.nix
#+end_example
I put my Wireguard configuration on the device (for now) using nixops scp
#+begin_example
nixops ssh tres-ebow mkdir -p /etc/wireguard-key/ && \
nixops scp --to tres-ebow wireguard/tres-ebow.key /etc/wireguard-key/tres-ebow.key && \
nixops ssh tres-ebow chown 400 /etc/wireguard-key/tres-ebow.key
#+end_example
I need to make sure this stays in sync with my [[id:nixos_justdoit][JustDoIt]] script!
* Deploying [[id:20211120T220054.226284][The Wobserver]]
:PROPERTIES:
:ID: 20221112T153200.008557
@ -220,20 +480,17 @@ I need to make sure this stays in sync with my [[id:nixos_justdoit][JustDoIt]] s
#+begin_src nix :tangle ~/arroyo-nix/networks/wobserver.nix :mkdirp yes
let
serverCfg = ../roles/server;
pkgs = import <nixpkgs> {};
in {
network.pkgs = pkgs;
network.description = "my wobserver";
network.enableRollback = true;
allNetworks = pkgs.lib.importTOML ./hosts.toml;
mkNetwork = import ./mkNetwork.nix { inherit pkgs; networks = allNetworks; };
in mkNetwork "wobserver"
#+end_src
terra-firma = {config, pkgs, ...}:
{
imports = [ serverCfg ../hosts/terra-firma ];
deployment.targetHost = "terra-firma";
system.stateVersion = "22.11";
};
}
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
[wobserver]
description = "the wobserver and friends"
enableRollback = true
config = "../roles/server"
#+end_src
** Terra Firma
@ -241,12 +498,18 @@ in {
:ID: 20221112T130047.292304
:END:
#+begin_export html
<iframe style="border: 0; width: 200px; height: 200px;" src="https://bandcamp.com/EmbeddedPlayer/album=78877835/size=large/bgcol=ffffff/linkcol=2ebd35/minimal=true/track=2552183726/transparent=true/" seamless><a href="https://theflashbulb.bandcamp.com/album/opus-at-the-end-of-everything">Opus At The End Of Everything by The Flashbulb</a></iframe>
#+end_export
Terra Firma is my [[id:20211120T220054.226284][Wobserver]] hosted by [[id:7fea3caa-5fa0-415a-96c7-45a1d64512fb][Wobscale Technologies]] in Seattle, WA.
#+begin_src nix :tangle ~/arroyo-nix/hosts/terra-firma/default.nix :mkdirp yes
{
imports = [ ./hardware-configuration.nix ];
system.stateVersion = "22.11";
networking.hostName = "terra-firma";
boot.loader.grub.enable = true;
# boot.loader.grub.device = "/dev/sde";
@ -317,3 +580,86 @@ Terra Firma is my [[id:20211120T220054.226284][Wobserver]] hosted by [[id:7fea3c
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
#+end_src
** Last Bank
:PROPERTIES:
:ID: 20230506T010603.522707
:END:
#+begin_export html
<iframe style="border: 0; width: 200px; height: 200px;" src="https://bandcamp.com/EmbeddedPlayer/album=4030854985/size=large/bgcol=ffffff/linkcol=2ebd35/minimal=true/track=3639413635/transparent=true/" seamless><a href="https://theflashbulb.bandcamp.com/album/hardscrabble">Hardscrabble by The Flashbulb</a></iframe>
#+end_export
Last Bank is my [[id:20230429T140217.184029][New Homelab Build]], a living-room server that will be proxied through [[id:7fea3caa-5fa0-415a-96c7-45a1d64512fb][Wobscale Technologies]] in Seattle, WA. It's going to replace [[id:20221112T130047.292304][terra-firma]].
#+begin_src toml :tangle ~/arroyo-nix/networks/hosts.toml
[wobserver.hosts.last-bank]
#+end_src
#+begin_src nix :tangle ~/arroyo-nix/hosts/last-bank/default.nix :mkdirp yes
{ lib, config, ... }:
{
networking.hostName = "last-bank";
system.stateVersion = "23.05";
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sda";
services.tailscale.authKey = "tskey-auth-kzWZMt1CNTRL-48JC1bwTin5b1crXxBcti5Qru3zf8wC3";
networking.hostId = "56c334f2"; # required for zfs use
boot.zfs.devNodes = "/dev/disk/by-uuid"; # (ref:devNodes)
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "isci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "host/root";
fsType = "zfs";
};
fileSystems."/nix" =
{ device = "host/nix";
fsType = "zfs";
};
fileSystems."/home" =
{ device = "tank/home";
fsType = "zfs";
};
fileSystems."/media" =
{ device = "tank/media";
fsType = "zfs";
};
fileSystems."/srv" =
{ device = "tank/srv";
fsType = "zfs";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/19C9-747A";
fsType = "vfat";
};
swapDevices =
[ { device = "/dev/disk/by-uuid/554d8e90-f4ea-49dc-b057-c69d0385bbc6"; }
];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.eno2.useDHCP = lib.mkDefault true;
# networking.interfaces.eno3.useDHCP = lib.mkDefault true;
# networking.interfaces.eno4.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
#+end_src

View File

@ -46,10 +46,10 @@ Here the strings are basically just taken out of [[id:arroyo/nixos][Arroyo NixOS
../../nixos/boot.nix
../../nixos/cachix.nix
../../nixos/clight.nix
../../nixos/cups.nix
../../nixos/direnv.nix
../../nixos/emacs.nix
../../nixos/fonts.nix
../../nixos/framework-laptop.nix
../../nixos/gnupg-pam.nix
../../nixos/home-manager.nix
../../nixos/japanese.nix
@ -58,6 +58,7 @@ Here the strings are basically just taken out of [[id:arroyo/nixos][Arroyo NixOS
../../nixos/laptop.nix
../../nixos/location.nix
../../nixos/mopidy.nix
../../nixos/morph-wrapper.nix
../../nixos/nix-path.nix
../../nixos/nixos-builder.nix
../../nixos/nixpkgs.nix
@ -69,6 +70,7 @@ Here the strings are basically just taken out of [[id:arroyo/nixos][Arroyo NixOS
../../nixos/syncthing.nix
../../nixos/tailscale.nix
../../nixos/vulfpeck.nix
../../nixos/waydroid.nix
../../nixos/xmodmap.nix
../../nixos/yubikey.nix
../../nixos/zfs.nix

View File

@ -115,7 +115,10 @@ I use [[https://letsencrypt.org/][Lets Encrypt]] for my DNS, I really like 'em.
}
#+end_src
* INPROGRESS static sites
* INPROGRESS wobserver static sites
:PROPERTIES:
:ID: 20221223T171929.934471
:END:
:LOGBOOK:
- State "INPROGRESS" from "NEXT" [2022-11-12 Sat 19:41]
:END:
@ -139,10 +142,11 @@ I use [[https://letsencrypt.org/][Lets Encrypt]] for my DNS, I really like 'em.
"kickass.systems".root = "/srv/static-sites/kickass.systems/_site";
# see akkoma.org
"notes.whatthefuck.computer" = {
root = "/srv/static-sites/notes.whatthefuck.computer/_site";
locations."/atom.xml".proxyPass = "https://granary.io/url?url=http://notes.whatthefuck.computer/&input=html&output=atom&hub=https://bridgy-fed.superfeedr.com/";
locations."/rss.xml".proxyPass = "https://granary.io/url?url=http://notes.whatthefuck.computer/&input=html&output=rss&hub=https://bridgy-fed.superfeedr.com/";
# root = "/srv/static-sites/notes.whatthefuck.computer/_site"; #
# locations."/atom.xml".proxyPass = "https://granary.io/url?url=http://notes.whatthefuck.computer/&input=html&output=atom&hub=https://bridgy-fed.superfeedr.com/";
# locations."/rss.xml".proxyPass = "https://granary.io/url?url=http://notes.whatthefuck.computer/&input=html&output=rss&hub=https://bridgy-fed.superfeedr.com/";
};
"whatthefuck.computer" = {

View File

@ -3,6 +3,9 @@
:END:
#+title: CCE in Nix On Droid
#+ARCOLOGY_KEY: cce/nix-on-droid
#+ARCOLOGY_ALLOW_CRAWL: t
I'd like to get parts of my [[id:cce/cce][CCE]] running on [[id:20220817T205401.021191][t184256/nix-on-droid]] so that I can have my [[id:cce/emacs][Emacs]] [[id:a7420bb9-395f-4afa-92fb-8eaa0b8a4cd8][Tools]] like [[id:2e31b385-a003-4369-a136-c6b78c0917e1][SRS]] and [[id:cce/org-roam][org-roam]] running on it.
* =nix-on-droid.nix=
@ -16,8 +19,8 @@ This uses [[id:arroyo/home-manager][Arroyo Home Manager]] to generate a list of
{ pkgs, ... }:
{
environment.packages = [ pkgs.vim ];
system.stateVersion = "22.05";
environment.packages = with pkgs; [ vim openssh ];
system.stateVersion = "22.11";
nix.nixPath = [
"nixpkgs=/data/data/com.termux.nix/files/home/.nix-defexpr/channels/nixpkgs/"
@ -51,10 +54,20 @@ This uses [[id:arroyo/home-manager][Arroyo Home Manager]] to generate a list of
<<home_manager_imports()>>
];
programs.ssh.matchBlocks = {
virtuous-cassette = {
hostname = "100.96.6.32";
user = "builder";
identitiesOnly = true;
identityFile = "~/.ssh/id_rsa";
};
programs.ssh.matchBlocks.builder = {
hostname = "100.96.6.32";
user = "builder";
window-smoke = {
hostname = "100.79.48.59";
user = "builder";
identitiesOnly = true;
identityFile = "~/.ssh/id_rsa";
};
};
};
}
@ -68,29 +81,35 @@ This uses [[id:arroyo/home-manager][Arroyo Home Manager]] to generate a list of
#+results: home_manager_imports
#+begin_example
hm/prompt.nix
hm/emacs-helpers.nix
hm/contacts.nix
hm/git.nix
hm/python.nix
hm/gnupg.nix
hm/org-roam.nix
hm/emacs-pager.nix
hm/shell-helpers.nix
hm/spell-check.nix
hm/deadgrep.nix
hm/profile.nix
hm/direnv.nix
hm/emacs-helpers.nix
hm/emacs-pager.nix
hm/emacs.nix
hm/git.nix
hm/gnupg.nix
hm/morph.nix
hm/nix-update.nix
hm/atuin.nix
hm/emacs.nix
hm/org-fc.nix
hm/org-roam.nix
hm/profile.nix
hm/prompt.nix
hm/python.nix
hm/shell-helpers.nix
hm/spell-check.nix
hm/ssh_client.nix
#+end_example
* Using machines running [[id:cce/my_nixos_configuration][My NixOS configuration]] to as builders for nix-on-droid
Based on the [[https://github.com/t184256/nix-on-droid/wiki/Use-a-remote-builder-with-qemu][Nix On Droid wiki examples]]:
#+ARROYO_NIXOS_MODULE: nixos/nixos-builder.nix
#+ARROYO_NIXOS_ROLE: endpoint
#+ARROYO_NIXOS_ROLE: server
[[id:20211029T115928.954970][Virtuous Cassette]] is set up with a =builder= user and =aarch64= =binfmt= emulation:
#+begin_src nix :tangle ~/arroyo-nix/nixos/nixos-builder.nix
{ ... }:
@ -103,6 +122,47 @@ hm/ssh_client.nix
initialPassword = "changeme!";
};
nix.trustedUsers = [ "builder" ];
nix.settings.trusted-users = [ "builder" ];
}
#+end_src
* Bootstrapping the build setup
On the droid side, it's configured to use this as the builder and SSH to the host over [[id:20220811T124742.042180][Tailscale]]:
=nix.conf=:
#+begin_src conf
builders-use-substitutes = true
builders = ssh://virtuous-cassette;ssh://window-smoke
#+end_src
=.ssh/config=
#+begin_src conf
Host virtuous-cassette
HostName 100.96.6.32
User builder
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa
Host window-smoke
HostName 100.79.48.59
User builder
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa
#+end_src
- set up ssh: =nix-shell -p openssh git= then =ssh-keygen= then =ssh-copy-id builder=; git is used in =nix-on-droid build=
- set up directories: =ln -s /storage/emulated/0/org ~/org= then =ln -s /storage/emulated/0/arroyo-nix ~/arroyo-nix=
- [[https://nix-community.github.io/home-manager/index.html#sec-install-standalone][install]] home-manager channel (only used for bootstrap, subsequent builds will use [[id:cce/version_pins][Nix Version Pins]])
- then finally =nix-on-droid build -f ~/arroyo-nix/nix-on-droid.nix -I arroyo=$HOME/arroyo-nix=
Termux app properties should be set on the Cosmo and other devices with a hardware keyboard:
#+begin_src conf
# extra-keys-style = none doesn't work...
extra-keys = []
back-key = escape
ctrl-space-workaround = true
#+end_src

View File

@ -16,12 +16,12 @@ I use [[https://pipewire.org/][PipeWire]] because it implements [[id:jack_audio_
#+begin_src nix :tangle ~/arroyo-nix/nixos/audio.nix
{ pkgs, ... }:
{
environment.systemPackages = [ pkgs.qjackctl ];
with pkgs; {
environment.systemPackages = [ qjackctl easyeffects ];
hardware.bluetooth = {
enable = true;
package = pkgs.bluez5;
package = bluez5;
settings = {
General = { Enable = "Source,Sink,Media,Socket"; };
};

View File

@ -10,19 +10,19 @@ Just use =systemd-boot= and UEFI. Use plymouth.
#+ARROYO_NIXOS_ROLE: endpoint
#+begin_src nix :tangle ~/arroyo-nix/nixos/boot.nix
{ pkgs, ... }:
{ lib, pkgs, ... }:
let
vulf_mono = (pkgs.callPackage ../lib/vulfpeck.nix {});
in
{
boot.loader.systemd-boot.enable = true;
boot.loader.systemd-boot.enable = lib.mkDefault true;
boot.loader.efi.canTouchEfiVariables = true;
boot.plymouth = {
enable = true;
font = "${vulf_mono}/share/fonts/truetype/Desktop/VulfMono-Regular.otf";
logo = /home/rrix/org/data/dashboard-logo.png;
logo = /home/rrix/org/data/arcology.png;
# TODO: 2021-07 package plymouth-theme-hotdog
};

View File

@ -7,6 +7,7 @@
#+filetags: :Archive:CCE:Hardware:
#+ARCOLOGY_KEY: cce/nixos-laptop-framework
#+ARCOLOGY_ALLOW_CRAWL: t
#+AUTO_TANGLE: t
[[file:archive.org][Archive]]
@ -18,20 +19,31 @@ I also enable LVFS's testing repository so that i can have LVFS support for Fram
The only other thing to consider is to make sure the kernel is new enough to support the WiFi 6 chipsets.
#+ARROYO_NIXOS_MODULE: nixos/framework-laptop.nix
#+ARROYO_NIXOS_ROLE: endpoint
This can't just be blindly included in all my endpoints since it defines kernel params, but here's how it could be:
: #+ARROYO_NIXOS_MODULE: nixos/framework-laptop.nix
: #+ARROYO_NIXOS_ROLE: endpoint
It's actually just included directly in the [[id:20211029T115928.954970][Virtuous Cassette]] morph host manifest.
#+begin_src nix :tangle ~/arroyo-nix/nixos/framework-laptop.nix
{ pkgs, ... }:
{
boot.kernelParams = [ "mem_sleep_default=deep" ];
boot.kernelPackages = pkgs.linuxPackages_5_15;
services.fwupd.enable = true;
services.fwupd.enableTestRemote = true;
# boot.kernelPackages = pkgs.linuxPackages_5_15;
services.fwupd = {
enable = true;
extraRemotes = ["lvfs-testing"];
# per Frame.work LVFS docs
uefiCapsuleSettings = {
DisableCapsuleUpdateOnDisk = true;
};
};
hardware.rasdaemon.enable = true;
boot.loader.systemd-boot.memtest86.enable = true;
# services.fprintd.enable = true;
services.xserver.dpi = 204;
}
#+end_src

View File

@ -6,9 +6,11 @@
Bits and Bobbins not worth showing anywhere else. This will need a =mkIf= if I ever support my desktop or server!
#+ARROYO_NIXOS_MODULE: nixos/laptop.nix
#+AUTO_TANGLE: t
#+ARROYO_NIXOS_ROLE: endpoint
#+ARROYO_NIXOS_ROLE: settop
#+begin_src nix :tangle ~/arroyo-nix/nixos/laptop.nix
{ pkgs, ... }:
{ lib, pkgs, ... }:
{
powerManagement.enable = true;
@ -20,16 +22,23 @@ Bits and Bobbins not worth showing anywhere else. This will need a =mkIf= if I e
};
services.resolved = {
enable = true;
fallbackDns = [ "10.10.10.1" "209.251.245.117" "8.8.8.8" ];
fallbackDns = [ "100.89.170.115" "100.100.100.100" "8.8.8.8" ];
};
hardware.mcelog.enable = true;
hardware.cpu.intel.updateMicrocode = true;
hardware.video.hidpi.enable = true;
# each machine in my morph file sets config.services.xserver.dpi too
# fonts.optimizeForVeryHighDPI = lib.mkDefault false;
services.xserver.upscaleDefaultCursor = lib.mkDefault true;
services.xserver.videoDrivers = [ "modesetting" ];
hardware.opengl.extraPackages32 = [ pkgs.pkgsi686Linux.vaapiIntel ];
# these aren't laptop...
# use trackpoint with wheel emulation
hardware.trackpoint = {
enable = true;
@ -51,8 +60,6 @@ Bits and Bobbins not worth showing anywhere else. This will need a =mkIf= if I e
];
};
hardware.opengl.extraPackages32 = [ pkgs.pkgsi686Linux.vaapiIntel ];
virtualisation.docker = {
enable = true;
autoPrune.enable = true;
@ -64,6 +71,7 @@ Bits and Bobbins not worth showing anywhere else. This will need a =mkIf= if I e
boot.binfmt.emulatedSystems = [ "aarch64-linux" "armv6l-linux" ];
hardware.rtl-sdr.enable = true;
boot.supportedFilesystems = [ "ntfs" ];
}
#+end_src

264
nixos-tower.org Normal file
View File

@ -0,0 +1,264 @@
:PROPERTIES:
:ID: 20230225T150449.622645
:ROAM_ALIASES: "NixOS Tower Customizations"
:END:
#+TITLE: My NixOS Tower
#+filetags: :Project:
#+AUTO_TANGLE: t
#+ARCOLOGY_KEY: cce/nixos-tower
#+ARCOLOGY_ALLOW_CRAWL: t
Window Smoke is a run of the mill [[id:cce/my_nixos_configuration][Endpoint]] managed within [[id:arroyo/arroyo][Arroyo Systems Management]], with a small wrinkle: it has an Nvidia GTX 1060 graphics card attached to it and a 2tb SATA SSD with Windows 10. For the longest time, this machine has primarily booted to Windows and served as a gaming machine.
Well, I want to put the CPU cycles to use in more ways especially now that I am building the Git edge-version of [[id:cce/emacs][Emacs]] within [[id:arroyo/emacs][Arroyo Emacs]] for both =amd64= and =aarch64= every time I bump my [[id:cce/version_pins][Nix Version Pins]]. I have also been having some somewhat annoying reliability issues cropping up with [[id:20211029T115928.954970][Virtuous Cassette]] so having a backup environment will feel alright.
This page isn't an [[id:arroyo/arroyo][Arroyo Module]] per se, but a NixOS morph role which is included in to [[id:20230225T145612.522017][Window Smoke]], my desktop tower.
My desktop setup is very much inspired by my good friend [[id:ff7b41c0-3bab-47f3-aba6-08527f95e319][kalessin]]'s: A long USB cable, a long display cable, and long power cord connect a monitor and USB hub attached to a sit/stand desktop on casters to my desktop tower sitting in the corner of the room. The desk is spacious and easy to move while still having a full size display and a powerful machine attached to it. This has served me really well, especially considering that my monitor, a [[https://www.rtings.com/monitor/reviews/dell/u3818dw][Dell U3818DW wide-screen display]], has a USB-C input with alt-mode Display Port support. I can plug [[id:20211029T115928.954970][Virtuous Cassette]] in to the display and it swaps over my display *and* the USB hub attached to it. This plug-and-play setup has served me really well for the last few years.
* El 🅱lan
**This is disabled right now because =vfio-pci= was not robust enough. See [[id:20230527T132537.128761][Okay maybe I was wrong about 6.x]]**
How much farther could I take it though?
The last time I visited kalessin he showed me something that I thought was quite remarkable: his desktop would virtualize Windows 10 with his graphics card directly forwarded to the VM so that his entire Steam library would run without having to consider any Proton shenanigans[fn:1]. I thought that was pretty impressive and it's got my brain going in this direction. His machine is an AMD threadripper and AMD GPU and the host runs Arch, but in theory this should work well enough with Intel, Nvidia, and NixOS, right? And if it is good, maybe I'll finally get around to refreshing my desktop with a bit more ram and a bit better GPU... As long as I don't have to deal with the Nvidia X11 drivers or Nouveau ever again.
#+begin_src plantuml :file data/20/230225T150449.622645/desktop-diagram.png
skinparam linetype polyline
package "Tower" {
[Intel iGPU]
[RTX 1060]
cloud "NixOS" {
[libvirtd windows10 domain] --> "gamer mode"
[plasma desktop] --> "goblin mode"
}
[Motherboard USB Controller] -> [plasma desktop]
[Intel iGPU] -> [plasma desktop]
[PCIe USB Controller] -> [libvirtd windows10 domain]
[RTX 1060] -> [libvirtd windows10 domain]
[1tb NVMe] -> [plasma desktop]
[2tb SATA SSD] -> [libvirtd windows10 domain]
}
package "Desk" {
node "Dell U3818DW" {
interface HDMI2
interface "USB in 1"
interface DP
interface "USB in 2"
interface "Type-C DP"
"USB out" --> "USB in 1" : when HDMI2 active
"USB out" --> "USB in 2" : when DP active
}
"Type-C DP" --> [laptop] : forwards USB out when active
"USB out" <-- [keyboard, mouse, etc]
HDMI2 --> [Intel iGPU]
DP --> [RTX 1060]
"USB in 1" --> [Motherboard USB Controller]
"USB in 2" --> [PCIe USB Controller]
}
' hidden lines for node ordering/positioning
[keyboard, mouse, etc] -[hidden]d- [Motherboard USB Controller]
[keyboard, mouse, etc] -[hidden]d- "USB out"
[Type-C DP] -[hidden]l- [laptop]
[RTX 1060] -[hidden]d- [libvirtd windows10 domain]
[PCIe USB Controller] -[hidden]d- [libvirtd windows10 domain]
[Motherboard USB Controller] -[hidden]d- [plasma desktop]
[Intel iGPU] -[hidden]d- [plasma desktop]
[1tb NVMe] -[hidden]d- [plasma desktop]
[2tb SATA SSD] -[hidden]d- [plasma desktop]
' [HDMI2] -[hidden]l- [USB out]
[Intel iGPU] -[hidden]r- [1tb NVMe]
#+end_src
#+results:
[[attachment:desktop-diagram.png]]
The four cables between the Tower and Desk are cable-tied together with a power cable which drives the monitor, peripherals, etc. With proper nudging, I can move my Windows 10 installation in to =QEMU-KVM= and have access to gamer mode and goblin mode side by side, rather than dual-booting and dealing with Nvidia-X11.
* Setting up VFIO PCI Passthrough for virtualizing GPU accelerated Windows
:PROPERTIES:
:ID: 20230530T001233.513103
:END:
**This is disabled right now because =vfio-pci= was not robust enough. See [[id:20230527T132537.128761][Okay maybe I was wrong about 6.x]]**
I started by reading the [[https://wiki.archlinux.org/title/PCI_passthrough_via_OVMF#Setting_up_IOMMU][Arch Linux docs]] as well as [[https://wiki.gentoo.org/wiki/GPU_passthrough_with_libvirt_qemu_kvm][Gentoo's]] on setting this up.
Most of the work here came in enabling =VT-d= and =VT-x= in the BIOS, and collating the devices properly. =VT-x= is the general "Intel hardware virtualization" support which lets =qemu-kvm= work, a bunch of CPU instructions and support for entering in to code that thinks it is in *ring 0* when it is not, it's really clear in whether this works or not, and whether it's enabled or not. =VT-d= is the Intel-specific technical name for an virtualization-aware "IOMMU", basically allowing the OS to re-map hardware memory to main-memory addresses and in to the VMs' space. Your motherboard has to support it too, but if they do your VM can have PCI devices attached to it. My Intel i7-7700k and Asus 270AR motherboard both claimed to support VT-d but it was a bear to find that it was under a different firmware configuration menu than the VT-x feature was.[fn:2] I spent quite some time trying to debug this after mistaking the generic "intel virtualization" option to only by =VT-x=, looking in ARK whether my motherboard chipset and CPU supported VT-d, spelunking the menu, eating dinner, getting lost in the woods, etc etc.
but with that enabled, it should be possible to see which *IOMMU groups* your hardware is set in to, hopefully the groupings make sense. =qemu-kvm= can only forward an entire IOMMU group, so maybe move some stuff around in the chassis if they group oddly. Here we see IOMMU group 1 has my Nvidia card in it, and the PCIe Controller it's plugged in to.
#+begin_src shell :results drawer :session *piss*
nix-shell -p pciutils
for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V);
do
echo "IOMMU Group ${g##*/}:";
for d in $g/devices/*;
do
echo -e "\t$(lspci -k -nns ${d##*/})";
done;
done | grep -A15 "IOMMU Group 1:"
#+end_src
#+results:
:results:
IOMMU Group 1:
00:01.0 PCI bridge [0604]: Intel Corporation 6th-10th Gen Core Processor PCIe Controller (x16) [8086:1901] (rev 05)
Subsystem: ASUSTeK Computer Inc. Device [1043:872f]
Kernel driver in use: pcieport
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GP106 [GeForce GTX 1060 6GB] [10de:1c03] (rev a1)
Subsystem: eVga.com. Corp. Device [3842:6267]
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau
01:00.1 Audio device [0403]: NVIDIA Corporation GP106 High Definition Audio Controller [10de:10f1] (rev a1)
Subsystem: eVga.com. Corp. Device [3842:6267]
Kernel driver in use: vfio-pci
Kernel modules: snd_hda_intel
IOMMU Group 2:
00:02.0 VGA compatible controller [0300]: Intel Corporation HD Graphics 630 [8086:5912] (rev 04)
DeviceName: Onboard IGD
Subsystem: ASUSTeK Computer Inc. Device [1043:872f]
:end:
You can see that I have already instructed the system to use =vfio-pci= as the kernel driver to use for them. This is done below.
Start out making sure this nvidia thing has no chance of loading:
#+begin_src nix :noweb-ref nouveau
boot.blacklistedKernelModules = [
"nouveau"
];
#+end_src
With this terminal output, the following NixOS configuration can be created. It will 1) tell the Linux kernel to refuse loading the =nouveau= graphics driver for my X11 session 2) enable the IOMMU in the kernel 3) configure the "stub" =vfio-pci= module to attach to the devices I want forwarded to the VM 4) modify my =initrd= to load =vfio-pci= and attach it to my Nvidia driver early in the boot process before [[roam:UDEV]] can auto-configure anything. I only needed to do this last part on the graphics card, the ethernet controller and USB controller do not need this treatment. You'll notice these IDs in the IOMMU Groups script-let or in the output of =lspci -k -nn=
#+begin_src nix :noweb-ref vfio
boot.kernelParams = [
"intel_iommu=on"
# nvidia gtx 1060, realtek pcie ethernet controller
"vfio-pci.ids=10de:1c03,10de:10f1,10ec:8168,1b73:1100"
# "efifb=off"
];
boot.initrd.availableKernelModules = [ "vfio-pci" ];
boot.initrd.preDeviceCommands = ''
echo "Enabling vfio-pci"
# USB controller, GPU, GPU audio, Eth
DEVS="0000:02:00.0 0000:01:00.0 0000:01:00.1 0000:06:00.0"
for DEV in $DEVS; do
echo "vfio-pci" > /sys/bus/pci/devices/$DEV/driver_override
done
modprobe -i vfio-pci
'';
boot.kernelPackages = config.boot.zfs.package.latestCompatibleLinuxPackages;
#+end_src
But make sure to see [[id:20230725T140119.217568][the heading below]] where I have to fix this. It's enabled by default on [[id:20230225T145612.522017][Window Smoke]], if I want to disable all the VFIO stuff I just have to go set =config.boot.enableVFIO = false= in the host configuration.
I make the VFIO stuff optional, and then configure =libvirtd= in a pretty bog-standard way. Instruct NixOS to start the service, install virt-manager to set up the VM by hand ... but I would like to make this declarative some day.
#+begin_src nix :tangle ~/arroyo-nix/roles/desktop/default.nix :mkdirp yes :noweb yes
{ config, lib, pkgs, ... }:
{
options = {
boot.enableVFIO = lib.mkEnableOption {
name = "vfio-pci passthrough";
};
};
config = lib.mkIf config.boot.enableVFIO
{
<<nouveau>>
virtualisation.libvirtd = {
enable = true;
onBoot = "start";
onShutdown = "shutdown";
};
environment.systemPackages = with pkgs; [ virt-manager ];
<<vfio>>
};
}
#+end_src
This is essentially what is happening in Alexander Bakker's [[https://alexbakker.me/post/nixos-pci-passthrough-qemu-vfio.html][Notes on PCI Passthrough on NixOS using QEMU and VFIO]] blog post/literate configuration. I'll have to consider setting up =Looking Glass= and =Scream= soon, though it's not a big concern once I have the USB routing done.
** Fixing =vfio-pci= after 6.0.4 et al broke it
:PROPERTIES:
:ID: 20230725T140119.217568
:END:
Sooo, the [[id:20230520T205431.962021][patch which landed in 6.0.4]] which broke =vfio-pci= got backported to 5.15, I'm going to just revert it and let loose the dogs of war, though I am not looking foward to compiling my desktop's kernel for the rest of existence. At least NixOS makes this easy...
This is included in the optional =boot.enableVFIO= optioned section of the role configuration along with the VFIO configuration itself.
#+begin_src nix :noweb-ref vfio
boot.kernelPatches = [
# {
# name = "revert-vfio-breakage";
# patch = /home/rrix/org/cce/data/20/230530T001233.513103/v3-3-3-vfio-pci-Remove-console-drivers.patch;
# }
];
#+end_src
This patch reverts [[https://github.com/torvalds/linux/commit/d173780620792c725506b0f3c5ec52c7fbac1db0][torvalds/linux@d173780620792c725506b0f3c5ec52c7fbac1db0]]:
#+begin_src patch :tangle /home/rrix/org/cce/data/20/230530T001233.513103/v3-3-3-vfio-pci-Remove-console-drivers.patch :comments none
diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
index a0d69ddaf90d..756d049bd9cf 100644
--- a/drivers/vfio/pci/vfio_pci_core.c
+++ b/drivers/vfio/pci/vfio_pci_core.c
@@ -10,7 +10,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/aperture.h>
#include <linux/device.h>
#include <linux/eventfd.h>
#include <linux/file.h>
@@ -1793,10 +1794,6 @@ static int vfio_pci_vga_init(struct vfio_pci_core_device *vdev)
if (!vfio_pci_is_vga(pdev))
return 0;
- ret = aperture_remove_conflicting_pci_devices(pdev, vdev->vdev.ops->name);
- if (ret)
- return ret;
-
ret = vga_client_register(pdev, vfio_pci_set_decode);
if (ret)
return ret;
#+end_src
** Running Windows 10 in =libvirtd=
Instruct it to use /dev/sda or something in /dev/disk/by-uuid/ as the "system image" but be careful if you delete the domain that you don't let =libvirtd= try to =rm /dev/sda= ... it offered to, i'm not sure it actually would have, but that is spooky action.
UEFI boot support via OVMF is installed by default in the =virtualisation.libvirt= module, but the =virt-manager= GUI will BIOS boot by default. Change the boot mode in "overview configuration" in the *install/setup phase*, it's not editable once the VM is created in =libvirtd=..
Then attach PCI devices for the Nvidia card, a USB-3 PCIe card, an Ethernet PCIe card. The virtualized Windows will have its own USB ports exposed on the back of my case, it won't need to rely on bridge networking but will be connected directly to my switch, and the desktop will be displayed in front of me through the GPU and not the SPICE virtual display.
Forwarding USB devices one by one is fine during setup and fiddling around, but the USB controller will allow me to run another USB cable to my display and use the display as a KVM+USB switch between the host OS and the guest OS. I am waiting on the cables and controller to be delivered, it's been snowy this month.
** NEXT record video of boot + swapover + art of rally @ 60FPS + swap back
** NEXT Investigate declarative libvirtd domains
* NEXT what else should only be installed here?
- CUDA toolkit
- kind of want to play with stable diffusion on local GPU
* Footnotes
[fn:1] That said, since I have been using the [[id:20220810T163745.293071][SteamDeck]] I am much less concerned with Proton compatibility in general... Worth not having to consider it all the time though and having a Windows machine at my finger tips.
[fn:2] I should write down which menu since it was a PITA to find but woops i'm typing on this machine right now!

View File

@ -37,7 +37,7 @@ The Wobserver in this equation is the "social hub" of an Arroyo System. [[id:c75
This is a [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][NixOS]] configuration which is dynamically extended with [[id:arroyo/arroyo][Arroyo Systems Management]] modules. It behaves like [[id:cce/my_nixos_configuration][My NixOS configuration]] and is pushed to machines using [[id:cce/morph][Morph]]. It can also be built [[id:20220218T213149.100848][in QEMU]] below.
#+begin_src nix :tangle ~/arroyo-nix/roles/server/default.nix :noweb yes :mkdirp yes
{ pkgs, lib, ... }:
{ config, pkgs, lib, ... }:
rec {
imports = [
@ -47,12 +47,17 @@ rec {
home-manager.users.rrix.imports = [
<<arroyo_home-manager_imports()>>
];
home-manager.users.rrix.home.stateVersion = "22.11";
system.stateVersion = lib.mkDefault "22.11";
home-manager.users.rrix = {
home.stateVersion = config.system.stateVersion;
# don't ship pinentry-qt
services.gpg-agent.pinentryFlavor = lib.mkForce "curses";
};
services.openssh.enable = true;
home-manager.users.rrix.services.syncthing.tray.enable = lib.mkForce false;
boot = {
kernelParams = [ "console=ttyS0" "boot.shell_on_fail" ];
loader.timeout = 5;
@ -73,24 +78,35 @@ rec {
#+results: arroyo_nixos_imports
#+begin_example
../../nixos/akkoma.nix
../../nixos/arcology-config.nix
../../nixos/cachix.nix
../../nixos/cups.nix
../../nixos/emacs.nix
../../nixos/feedbot.nix
../../nixos/feediverse.nix
../../nixos/gitea.nix
../../nixos/gnupg-pam.nix
../../nixos/home-manager.nix
../../nixos/jellyfin.nix
../../nixos/location.nix
../../nixos/morph-wrapper.nix
../../nixos/nextcloud.nix
../../nixos/nginx.nix
../../nixos/nix-path.nix
../../nixos/nixos-builder.nix
../../nixos/nixpkgs.nix
../../nixos/postgresql.nix
../../nixos/restic.nix
../../nixos/rixpkgs.nix
../../nixos/rrix.nix
../../nixos/ssh_client.nix
../../nixos/syncthing.nix
../../nixos/tailscale.nix
../../nixos/ttrss.nix
../../nixos/vaultwarden.nix
../../nixos/wobservability.nix
../../nixos/zfs.nix
../../nixos/wobserver-docker.nix
#+end_example
#+NAME: arroyo_home-manager_imports
@ -151,6 +167,17 @@ NixOS modules:
- [[id:20220210T155158.671084][From Wireguard to Tailscale]]
- [[id:20220526T143555.660133]["The manual appears to depend on the location of Nixpkgs"]]
- [[id:20221021T115008.329657][Arroyo Nix Support]]
- [[id:20221106T113721.266425][CCE in Nix On Droid]]
- [[id:20221130T103851.207871][Gitea on NixOS]]
- [[id:20221202T122017.620403][Self-Hosting on the Fediverse with Akkoma]]
- [[id:20221202T124113.404212][Docker Containers on the Wobserver]]
- [[id:20230125T143144.011175][Posting Arcology Feeds to the Fediverse Automatically with Feediverse]]
- [[id:20230201T121604.003311][Storing passwords securely with vaultwarden]]
- [[id:20230220T204453.685476][Jellyfin on the Wobserver]]
- [[id:20230310T155744.804329][Tiny-Tiny RSS]]
- [[id:20230321T143139.441973][My Brother Printer and CUPS Setup]]
- [[id:20230331T181418.903306][RSS Feed Bot Posting to Matrix.org]]
- [[id:20230530T120958.265094][Wrapping Morph commands for more ergonomic deployment]]
- [[id:47ff77f9-3eae-43eb-886c-7513d05f047f][Secure Backup Infrastructure]]
- [[id:arcology/poetry][Arcology Poetry Pyproject]]
- [[id:arroyo/emacs][Arroyo Emacs Generator]]

View File

@ -9,7 +9,7 @@
#+ARCOLOGY_ALLOW_CRAWL: t
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle cce/nixos.el
#+PROPERTY: header-args:emacs-lisp
#+PROPERTY: header-args:yaml :tangle cce/roles/endpoint/tasks/nixos.yml
#+ARROYO_MODULE_WANTS: cce/company_code_completion.org
@ -18,7 +18,7 @@
Nix is a [[id:a7420bb9-395f-4afa-92fb-8eaa0b8a4cd8][Tool]] for building [[id:0d968a4d-3c9d-4104-a158-e4982be6d28e][Linux]] systems in a declarative idempotent method and is a good fit for the [[id:cce/cce][CCE]], I think when moving past [[id:fedora_linux][Fedora Linux]].
#+begin_src emacs-lisp
#+begin_src emacs-lisp :tangle nixos.el
(provide 'cce/nixos)
(use-package nix-mode)
(use-package nixpkgs-fmt)
@ -42,6 +42,8 @@ Nix is a [[id:a7420bb9-395f-4afa-92fb-8eaa0b8a4cd8][Tool]] for building [[id:0d9
(find-file)))
#+end_src
* Installing Nix on non-NixOS machines
#+begin_src yaml
- name: /nix exists
file:
@ -76,17 +78,62 @@ if [ -e /home/rrix/.nix-profile/etc/profile.d/nix.sh ]; then . /home/rrix/.nix-p
#+ARROYO_NIXOS_MODULE: nixos/nixpkgs.nix
#+begin_src nix :tangle ~/arroyo-nix/nixos/nixpkgs.nix
{ ... }:
{ pkgs, config, ... }:
{
# less nix crap
nix.gc.automatic = true;
nix.gc.dates = "23:30";
nix.gc.options = "--delete-older-than 30d";
nix.gc = {
automatic = true;
dates = "03:30";
options = "--delete-older-than 30d";
persistent = true;
};
nix.distributedBuilds = true;
nix.buildMachines = builtins.filter (e: e.hostName != config.networking.hostName) [
# { hostName = "virtuous-cassette";
# maxJobs = 6;
# sshUser = "builder";
# systems = [
# "x86_64-linux"
# "aarch64-linux"
# ];
# }
{ hostName = "window-smoke";
maxJobs = 6;
sshUser = "builder";
systems = [
"x86_64-linux"
"i686-linux"
"aarch64-linux"
];
}
{ hostName = "last-bank";
maxJobs = 32;
sshUser = "builder";
systems = [
"x86_64-linux"
"i686-linux"
"aarch64-linux"
];
}
] ;
nix.settings.trusted-users = ["rrix" "root" "@wheel"];
nix.settings.extra-experimental-features = [ "flakes" "nix-command" ];
# hahaha! yes
nixpkgs.config = { allowUnfree = true; };
environment.systemPackages = with pkgs; [
nix-tree
nix-du
nurl
];
}
#+end_src
** DONE remove the nixpkgs.config.permittedInsecurePackages from =nix.conf=..
SCHEDULED: <2022-12-27 Tue>
:LOGBOOK:
- State "DONE" from "NEXT" [2023-01-09 Mon 18:41]
:END:

View File

@ -43,7 +43,7 @@ My =org-roam= configuration is basically pedestrian, I can hit =<SPC>r= to get t
#+ARROYO_EMACS_MODULE: org-roam
#+begin_src emacs-lisp
(use-package emacsql-sqlite3)
; (use-package emacsql-sqlite3)
(use-package buttercup)
(defun cce/org-roam-mode-hook ()
(setq-local completion-at-point-functions

View File

@ -5,12 +5,13 @@
#+filetags: :Emacs:CCE:Org:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle org-mode.el
#+ARROYO_EMACS_MODULE: org-mode
#+ARCOLOGY_KEY: cce/org-mode
#+ARCOLOGY_ALLOW_CRAWL: t
#+CCE_PREDICATE: t
#+CCE_PRIORITY: 40
#+ARROYO_EMACS_MODULE: org-mode
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+begin_src emacs-lisp
(provide 'cce/org-mode)

View File

@ -4,17 +4,13 @@
:ROAM_ALIASES: pam-u2f
:END:
#+TITLE: Unlock Computer With Yubikey
#+ARCOLOGY_KEY: cce/pam-u2f
#+ARCOLOGY_ALLOW_CRAWL: t
#+filetags: :Project:CCE:
#+filetags: :CCE:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:yaml :tangle roles/endpoint/tasks/pam-u2f.yml
#+CCE_ANSIBLE: pam-u2f
#+CCE_ROLES: endpoint
#+CCE_PRIORITY: 20
#+CCE_PREDICATE: (not (cce/using-termux))
,#+ARCOLOGY_KEY: cce/pam-u2f
,#+ARCOLOGY_ALLOW_CRAWL: t
I can use =pam-u2f= to unlock my computer with a Yubikey that I keep on my belt.

View File

@ -10,7 +10,7 @@
#+PROPERTY: header-args:emacs-lisp :tangle exwm-xcompmgr.el
#+ARROYO_EMACS_MODULE: exwm-xcompmgr
,#+ARROYO_MODULE_WANTS: cce/exwm.org
#+ARROYO_MODULE_WANTS: cce/exwm.org
#+ARROYO_HOME_MODULE: hm/picom.nix
#+ARROYO_NIXOS_ROLE: endpoint
#+ARCOLOGY_ALLOW_CRAWL: t
@ -24,27 +24,39 @@ First commit to xcompmgr was in 2003 and there are still people running non-comp
#+end_quote
([[https://twitter.com/mjg59/status/1205679548127272960][Matthew Garrett on Twitter]])
* Starting =picom= in Emacs
i use picom, a simple X11 compositor that works with [[id:cce/exwm][EXWM]] or [[id:20211206T133651.674012][i3wm]] or [[id:20220421T100313.402598][XMonad]], and have it start after EXWM does, rather than through [[id:cce/home-manager][home-manager]] because KDE's kwin doesn't like to compete for the compositor. I provide a custom backend to prevent =mpv= from tearing.[fn:1]
#+begin_src emacs-lisp
(defun cce/run-picom ()
(interactive)
(when (executable-find "picom")
(start-process "picom" " *picom*" "picom" "--vsync" "--backend=glx" "-i 0.9")))
; (add-hook 'exwm-init-hook #'cce/run-picom)
(add-hook 'after-init-hook #'cce/run-picom)
(start-process "picom" " *picom*" "picom" "--vsync" "--backend=glx")))
;; "-i 0.9"
(add-hook 'exwm-init-hook #'cce/run-picom)
; (add-hook 'after-init-hook #'cce/run-picom)
#+end_src
=picom= comes from [[id:cce/home-manager][home-manager]] and needs a working [[id:cce/nixgl][NixGL]].
* Starting =picom= on login with systemd
=picom= comes from [[id:cce/home-manager][home-manager]] and needs a working [[id:cce/nixgl][NixGL]] on non-nixos desktops. Rather than manage it with Emacs, let's just use home-manager now that I am running [[id:20220421T100313.402598][XMonad]].
#+begin_src nix :tangle ~/arroyo-nix/hm/picom.nix
{ pkgs, ... }:
let mkNixGLWrapper = pkgs.lib.mkNixGLWrapper;
let
myPicom = pkgs.lib.mkNixGLWrapper { name="picom"; pkg=pkgs.picom; };
in
{
home.packages = [(mkNixGLWrapper { name="picom"; pkg=pkgs.picom; })];
systemd.user.services.picom.serviceConfig.enable = false;
home.packages = [ myPicom ];
services.picom = {
enable = false;
package = myPicom;
backend = "glx";
# inactiveOpacity = 0.9;
vSync = true;
};
}
#+end_src

View File

@ -5,21 +5,27 @@
#+title: PostgreSQL on the Wobserver
#+FILETAGS: :Project:Wobserver:CCE:
My go-to multi-write database server is postgres. I like how it has JSON columns and indexes in a (somewhat) ergonomic form.
#+ARCOLOGY_KEY: cce/postgres
#+ARCOLOGY_ALLOW_CRAWL: t
My go-to multi-write database server is postgres. I like how it has JSON columns and indexes in a (somewhat) ergonomic form. This is a pretty basic setup.
#+ARROYO_NIXOS_MODULE: nixos/postgresql.nix
#+ARROYO_NIXOS_ROLE: server
#+begin_src nix :tangle ~/arroyo-nix/nixos/postgresql.nix
{ ... }:
{ pkgs, ... }:
{
services.postgresql = {
enable = true;
package = pkgs.postgresql_14;
settings = {
wal_level = "replica";
archive_mode = "on";
archive_command = "test ! -f /srv/pgsql/archive/wal/%f && cp %p /srv/pgsql/archive/wal/%f";
statement_timeout = 60*1000;
};
};
# backup weekly

44
profile_vars.org Normal file
View File

@ -0,0 +1,44 @@
:PROPERTIES:
:ID: configuring_profile_variables
:END:
#+TITLE: Configuring Profile Variables
#+filetags: :Emacs:CCE:Shells:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:nix :tangle ~/arroyo-nix/hm/profile.nix
#+AUTO_TANGLE: t
#+ARROYO_HOME_MODULE: hm/profile.nix
#+CCE_PREDICATE: nil
#+CCE_PRIORITY: 40
#+begin_src nix
{ ... }:
{
home.sessionVariables = {
#+end_src
I live in [[id:20211120T145109.615732][Eugene, OR]], USA, Earth. This used to be a UTC setup, but it's really hard to make that work sanely, so I don't.
#+begin_src nix :tangle no
TZ = "America/Los_Angeles";
# TODO: make this conditional on "normal linux";
# TZDIR = "/usr/share/zoneinfo";
#+end_src
The =PATH= environment variable is important to a Linux desktop -- if it's set in the =bash_profile= loading stage, it's used by various process/command execution tools to resolve binary names. If it's a thing that I want to run often, its executable files should be in =PATH=. A lot of these are explored in their own modules more thoroughly, visible by running [[elisp:(deadgrep "cce/bash")]] from here.
#+BEGIN_SRC nix
PATH = "~/.npm/bin:~/.local/bin:~/bin:$PATH";
#+END_SRC
I use =emacsclient= as my =EDITOR= value, a common idiom variable which shell scripts and simple command-line programs use to open a user's preferred editor. Setting it as =emacsclient= especially from within EXWM and =shell-mode= is nice, because the file signaled to be editied is just opened up in the current Emacs window.
#+BEGIN_SRC nix
EDITOR = "emacsclient";
#+END_SRC
#+begin_src nix
};
}
#+end_src

View File

@ -7,15 +7,18 @@
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle lisp-core.el
#+ARROYO_EMACS_MODULE: lisp-core
#+ARCOLOGY_KEY: cce/lisp-core
#+CCE_PRIORITY: 62
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_MODULE_WANTS: cce/evil_mode.org
#+ARROYO_MODULE_WANTS: cce/code_formatting_aggressively.org
#+ARCOLOGY_ALLOW_CRAWL: t
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+begin_src emacs-lisp
(provide 'cce/lisp-core)
(use-package evil-lispy)
(use-package evil-lispy
:diminish)
(defun cce/lisp-like-mode-hook ()
(aggressive-indent-mode -1)
(evil-lispy-mode))

View File

@ -26,6 +26,12 @@ high-chaos organization here... replacing [[id:cce/ivy_and_counsel][Ivy and Coun
(use-package vertico
:init
(vertico-mode)
(setq completion-in-region-function
(lambda (&rest args)
(apply (if vertico-mode
#'consult-completion-in-region
#'completion--in-region)
args)))
:bind
("C-x C-z" . 'vertico-repeat))

View File

@ -43,8 +43,6 @@ I use =msmtp= in the meantime, it is a forwarding mail agent which can be config
primary = true;
passwordCommand = "pass show fastmail_email_app";
msmtp = {
enable = true;
extraConfig = {logfile = "/tmp/msmtp.log";};
@ -56,28 +54,6 @@ I use =msmtp= in the meantime, it is a forwarding mail agent which can be config
tls = { useStartTls = true; };
};
};
accounts.email.accounts.crdig = {
address = "ryan.rix.consultant@consumer.org";
realName = "Ryan Rix (rrix)";
aliases = [];
userName = "ryan.rix.consultant@consumer.org";
primary = false;
passwordCommand = "pass show crdigital/email_app_passwd";
msmtp = {
enable = true;
extraConfig = {logfile = "/tmp/msmtp.log";};
};
smtp = {
host = "smtp.gmail.com";
port = 587;
tls = { useStartTls = true; };
};
};
}
#+end_src

78
shell_vars.org Normal file
View File

@ -0,0 +1,78 @@
:PROPERTIES:
:ID: 9ce3cedf-7f1b-45e0-aa12-e1bd7d739cbb
:END:
#+TITLE: Configuring Shell Variables
#+filetags: :Emacs:CCE:Shells:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle shell-vars.el
#+PROPERTY: header-args:nix :tangle ~/arroyo-nix/hm/prompt.nix
#+ARROYO_MODULE_WANTS: cce/emacs_shell_mode_is_good_enough.org
#+ARROYO_EMACS_MODULE: shell-vars
#+CCE_PREDICATE: nil
#+CCE_PRIORITY: 40
#+AUTO_TANGLE: t
While [[id:configuring_profile_variables][Configuring Profile Variables]] concerns itself primarily with some basic configurations that goes in to =~/.bash_profile=, this document concerns itself with things that go in my =~/.bashrc=, things which are run by every new interactive bash shell process, rather than being run by the system once and inherited by sub-processes.
#+ARROYO_HOME_MODULE: hm/prompt.nix
#+begin_src nix :noweb yes
{ ... }:
{
programs.bash.enable = true;
#+end_src
I use [[id:20220906T101932.011701][Atuin]] for shell search history right now.
I cribbed my =PS1= from [[id:f4d0be16-1f68-4598-a02c-0327759e034c][Tor]] a long time ago, it is a simple on that simply puts a smiley-face if the previous command returned successfully, and a frown-face if the previous command returned an error-code.
#+begin_src nix :noweb yes
home.sessionVariables = {
PS1 = ''\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w \[\033[00m\]\`if [ \$? == 0 ]; then echo \:\); else echo \:\(; fi\` $ '';
};
}
#+end_src
That =PS1= will prevent [[id:cce/emacs][Emacs]]'s command-interpreter ("comint") from working properly. One must set [[help:comint-prompt-regexp][comint-prompt-regexp]] to make it behave properly:
#+begin_src emacs-lisp
(defun cce/fixup-comint ()
(interactive)
(setq-local comint-prompt-regexp "^[^#$%>)(\n]*[#$%>)(] +"))
(add-hook 'shell-mode-hook #'cce/fixup-comint)
(provide 'cce/shell-vars)
#+end_src
Eshell "smart" mode
#+begin_src emacs-lisp
(require 'em-smart)
(setq eshell-where-to-jump 'begin)
(setq eshell-review-quick-commands nil)
(setq eshell-smart-space-goes-to-end t)
(evil-define-key 'insert 'eshell-mode-map (kbd "M-a") #'eshell-bol)
(defun eshell/lcd (&optional directory)
(if (file-remote-p default-directory)
(with-parsed-tramp-file-name default-directory nil
(eshell/cd (tramp-make-tramp-file-name
(tramp-file-name-method v)
(tramp-file-name-user v)
nil
(tramp-file-name-host v)
nil
(or directory "")
(tramp-file-name-hop v))))
(eshell/cd directory)))
#+end_src
Eshell can now "emulate a terminal"
#+begin_src emacs-lisp
(use-package eat
:hook
(eshell-load . eat-eshell-mode)
(eshell-load . eat-eshell-visual-command-mode))
#+end_src

View File

@ -17,6 +17,7 @@
#+BEGIN_SRC emacs-lisp
(use-package which-key
:diminish
:config
(which-key-mode))
(defhydra hydra-help (:columns 4)

View File

@ -31,10 +31,14 @@ Anki is the go-to digital solution for general study these days, I use org-drill
:custom
(org-fc-directories '("~/org/"))
(org-fc-review-history-file (expand-file-name "~/org/org-fc-reviews.tsv"))
(org-fc-shuffle-positions nil)
<<org-fc-contexts>>
:config
(require 'org-fc-hydra)
(defalias 'srs #'org-fc-dashboard)
<<org-fc-customization>>
(evil-define-minor-mode-key '(normal insert emacs) 'org-fc-review-flip-mode
(kbd "RET") 'org-fc-review-flip
(kbd "n") 'org-fc-review-flip
@ -50,6 +54,8 @@ Anki is the go-to digital solution for general study these days, I use org-drill
(kbd "q") 'org-fc-review-quit))
#+end_src
This gets crammed in =overrides= to be in the =epkgs= "index" in [[id:arroyo/emacs][Arroyo Emacs]] definition:
#+ARROYO_HOME_EPKGS: overrides/org-fc.nix
#+begin_src nix :tangle ~/arroyo-nix/overrides/org-fc.nix
org-fc = let
@ -77,6 +83,8 @@ in epkgs.melpaBuild {
};
#+end_src
This probably doesn't need to be here...
#+ARROYO_HOME_MODULE: hm/org-fc.nix
#+begin_src nix :tangle ~/arroyo-nix/hm/org-fc.nix
{ pkgs, ... }:
@ -87,6 +95,9 @@ in epkgs.melpaBuild {
#+end_src
* Some Custom SRS contexts
:PROPERTIES:
:ID: 20230508T223733.992116
:END:
Sometimes it's nice to focus on one thing at a time. =org-fc= gives us custom contexts and here's how I use it:
@ -96,12 +107,43 @@ Sometimes it's nice to focus on one thing at a time. =org-fc= gives us custom co
(setq org-fc-custom-contexts
'((japanese . (:filter (and (tag "japanese")
(tag "vocabulary"))))
(buddhism . (:filter (tag "Buddhism")))
(buddhism . (:filter (and (not (tag "vocabulary"))
(tag "Buddhism"))))
(trivia . (:filter (tag "trivia")))
(kanji . (:filter (or (tag "jokugo") (tag "kanji"))))
(poetry . (:filter (tag "poem")))
(tokipona . (:filter (tag "tokipona")))
(row . (:filter (not (tag "vocabulary"))))))
(row . (:filter (and
(not (tag "Buddhism"))
(not (tag "vocabulary")))))))
#+end_src
* Some =org-fc= hacks
I have a =node_modules= directory with a Node package used for some of my [[id:cce/literate_programming][Literate Programming]] shenanigans and it includes a directory with a =.org= suffix. This modifies the find command to exclude those.
#+begin_src emacs-lisp :noweb-ref org-fc-customization
(defun org-fc-awk--find (paths)
"Generate shell code to search PATHS for org files.
Matches all .org files ignoring ones with names don't start with
a '.' to exclude temporary / backup files.
With the '-L' option, 'find' follows symlinks."
(format
"find -L %s -type f -name \"*.org\" -not -name \".*\" -print0"
(mapconcat
(lambda (path) (shell-quote-argument (expand-file-name path)))
paths " ")))
#+end_src
I add a customization option which allows me to do my reviews in smaller bursts. it makes it easier to come back to things which I have forgotten; if i have a stack I haven't touched in Too Long, it'll take a really long time to retain because i will get through 40 or 80 or them and the ones i have to repeat will be at the bottom of the pile. Adjusting this down lets me get through my stacks faster.
#+begin_src emacs-lisp :noweb-ref org-fc-customization
(defcustom org-fc-review-count 30
"if numeric, truncate reviews to this many positions")
(defun org-fc--truncate-reviews (oldfn &rest args)
(take org-fc-review-count (apply oldfn args)))
(advice-add 'org-fc-index-positions :around 'org-fc--truncate-reviews)
#+end_src
* Cards to Add

View File

@ -10,7 +10,7 @@
#+ARCOLOGY_KEY: cce/super-p
#+ARROYO_EMACS_MODULE: super-p
#+ARCOLOGY_ALLOW_CRAWL: t
,#+ARROYO_MODULE_WANTS: cce/exwm.org
#+ARROYO_MODULE_WANTS: cce/exwm.org
#+begin_src emacs-lisp :exports none
(provide 'cce/super-p)
@ -27,6 +27,6 @@ Super-p to run commands without dumping output to a buffer. Super-Shift-P calls
(interactive (list (read-shell-command "Run: $ ")))
(async-shell-command command (generate-new-buffer " *async command*")))
; (exwm-input-set-key (kbd "s-p") #'background-shell-command)
(exwm-input-set-key (kbd "s-p") #'background-shell-command)
(global-set-key (kbd "s-p") #'background-shell-command)
#+END_SRC

30
syncthing-tray.org Normal file
View File

@ -0,0 +1,30 @@
:PROPERTIES:
:ID: 20230220T220556.588418
:ROAM_ALIASES: syncthingtray syncthing-tray "Syncthing Tray"
:END:
#+TITLE: Controlling Syncthing on my Endpoints
#+ARCOLOGY_KEY: cce/syncthing-tray
#+ARCOLOGY_ALLOW_CRAWL: t
A shortcoming of the [[id:arroyo/arroyo][Arroyo Systems Management]] data model is that I can't have modules in the same file with different roles: If I were to install [[id:cce/syncthing][Syncthing]]'s tray files in the Syncthing page, it pulls in a whole Qt and KDE Plasma environment on to my server! So I define it here. [[id:09fa0674-ad3b-43c5-8d7c-6b532346a772][open threads]]
So this is the tray module for [[id:cce/syncthing][Syncthing]] which is installed in [[id:cce/my_nixos_configuration][My NixOS configuration]] for endpoints.
#+ARROYO_HOME_MODULE: hm/syncthing-tray.nix
#+ARROYO_NIXOS_ROLE: endpoint
#+AUTO_TANGLE: t
#+begin_src nix :tangle ~/arroyo-nix/hm/syncthing-tray.nix
{ lib, pkgs, ... }:
{
services.syncthing.tray.enable = true;
systemd.user.services.syncthingtray.Service.ExecStart = lib.mkForce "${pkgs.syncthingtray}/bin/syncthingtray --wait";
systemd.user.services.syncthingtray.Unit.After = lib.mkForce ["graphical-session-pre.target"];
systemd.user.services.syncthingtray.Unit.Requires = lib.mkForce [];
home.packages = [ pkgs.syncthingtray ];
}
#+end_src
I modify the =systemd= configuration to wait for the Plasma tray to become available since there is no =tray.target= which the default configuration relies on.

View File

@ -17,7 +17,7 @@ I have a lot of data exposed in my Syncthing; this laptop, with my entire Music
Syncthing is installed with [[id:cce/home-manager][home-manager]], and bootstrapped manually, copying IDs around in some way. it's a bit of a pain and i'd like to have a better configuration generator some day, or at least documentation of this bootstrap process...
This is straightforward:
This is straightforward; [[id:20230220T220556.588418][Syncthing Tray]] is installed elsewhere.
#+ARROYO_HOME_MODULE: hm/syncthing.nix
#+begin_src nix :tangle ~/arroyo-nix/hm/syncthing.nix
@ -25,11 +25,6 @@ This is straightforward:
{
services.syncthing.enable = true;
services.syncthing.extraOptions = ["--gui-address=http://0.0.0.0:8384"];
services.syncthing.tray.enable = true;
home.packages = [ pkgs.syncthingtray ];
systemd.user.services.syncthingtray.Service.ExecStart = lib.mkForce "${pkgs.syncthingtray}/bin/syncthingtray --wait";
systemd.user.services.syncthingtray.Unit.After = lib.mkForce ["graphical-session-pre.target"];
systemd.user.services.syncthingtray.Unit.Requires = lib.mkForce [];
}
#+end_src
@ -45,18 +40,26 @@ I poke a hole in the firewall in [[id:cce/my_nixos_configuration][My NixOS confi
}
#+end_src
* Dealing with Syncthing Conflicts
:PROPERTIES:
:ID: 20230111T141211.153590
:END:
I have some functions which help deal with conflicts:
#+ARROYO_EMACS_MODULE: syncthing
#+begin_src emacs-lisp :tangle ~/org/cce/syncthing.el
(defun cce/syncthing-deconflict--possible-pairs (dir)
(->> (f-directories dir)
(append (list dir))
(--map (f-glob "*sync-conflict*.org" it))
(-flatten)
(--map (list it (replace-regexp-in-string (rx (seq (literal ".sync-conflict") (one-or-more (not ".")) )) "" it)))))
(defun cce/syncthing-deconflict (&optional dir)
(interactive "D")
(let* ((dir (or dir org-roam-directory))
(possible-pairs
(->> (f-directories org-roam-directory)
(--map (f-glob "*sync-conflict*.org" it))
(-flatten)
(--map (list it (replace-regexp-in-string (rx (seq (literal ".sync-conflict") (one-or-more (not ".")) )) "" it)))))
(possible-pairs (cce/syncthing-deconflict--possible-pairs dir))
(stale-conflict-files ; source doesn't exist or was moved elsewhere.
(--remove (file-exists-p (second it)) possible-pairs))
(ediff-candidates ; source does exist and should be ediff'd

View File

@ -5,12 +5,13 @@
#+filetags: :Emacs:CCE:
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle text-editing.el
#+ARROYO_EMACS_MODULE: text-editing
#+ARCOLOGY_KEY: cce/text-editing
#+ARCOLOGY_ALLOW_CRAWL: t
#+CCE_PREDICATE: t
#+CCE_PRIORITY: 10
#+ARROYO_EMACS_MODULE: text-editing
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+begin_src emacs-lisp
(provide 'cce/text-editing)
@ -35,6 +36,7 @@ really what I need is an [[id:39e7910b-1ab2-47e3-ad0e-f6680f6a362b][Emacs 'data-
(visual-line-mode 1)
(auto-fill-mode -1))
(add-hook 'text-mode-hook #'cce/text-mode-hook)
(diminish 'visual-line-mode)
#+end_src
#+begin_src emacs-lisp

View File

@ -17,6 +17,8 @@
#+CCE_PRIORITY: 30
#+AUTO_TANGLE: t
(These days I use [[id:20230201T121135.988658][Bitwarden]] and [[id:20230201T121604.003311][vaultwarden]] but maintain this until I'm confident that I won't need any of my "deprecated" passwords.)
#+ARROYO_EMACS_MODULE: pass
#+ARROYO_HOME_MODULE: hm/pass.nix
#+ARROYO_NIXOS_EXCLUDE: waterboy

View File

@ -16,8 +16,8 @@ Those code could really use a re-factor already, and I just wrote it! toggles li
#+begin_src emacs-lisp :tangle toggle-theme.el :mkdirp yes :results none
(provide 'cce/toggle-theme)
(setq cce/light-theme 'ef-spring)
(setq cce/dark-theme 'ef-autumn)
(setq cce/light-theme 'ef-cyprus)
(setq cce/dark-theme 'ef-bio)
(defun cce/switch-dark-theme ()
"Enable dark theme in Firefox, KDE and Emacs"
(interactive)

87
tt-rss.org Normal file
View File

@ -0,0 +1,87 @@
:PROPERTIES:
:ID: 20230310T155744.804329
:ROAM_ALIASES: ttrss tt-rss
:END:
#+TITLE: Tiny-Tiny RSS
#+ARROYO_NIXOS_MODULE: nixos/ttrss.nix
#+ARROYO_NIXOS_ROLE: server
#+AUTO_TANGLE: t
#+begin_src nix :tangle ~/arroyo-nix/nixos/ttrss.nix
{ pkgs, ... }:
let
wallabag = pkgs.stdenv.mkDerivation rec {
pname = "tt-rss-plugin-wallabag";
version = "2.0.0";
src = pkgs.callPackage pkgs.lib.pkgVersions.ttrss_wallabag {};
installPhase = ''
mkdir -p $out/wallabag_v2
cp -r wallabag_v2/* $out/wallabag_v2/
'';
};
large_apod = pkgs.stdenv.mkDerivation rec {
pname = "tt-rss-plugin-large-apod";
version = "0.0.1";
src = pkgs.callPackage pkgs.lib.pkgVersions.large_apod {};
installPhase = ''
mkdir -p $out/large_apod
cp -r large_apod/* $out/large_apod
'';
};
readability = pkgs.stdenv.mkDerivation rec {
pname = "tt-rss-plugin-af_readability";
version = "0.0.1";
src = pkgs.callPackage pkgs.lib.pkgVersions.ttrss_readability {};
installPhase = ''
mkdir -p $out/af_readability
cp -r ./* $out/af_readability
'';
};
in {
services.tt-rss = {
enable = true;
database = {
type = "pgsql";
};
logDestination = "syslog";
root = "/srv/tt-rss";
selfUrlPath = "https://feeds.whatthefuck.computer";
virtualHost = "feeds.whatthefuck.computer";
pluginPackages = [
wallabag
large_apod
readability
];
plugins = [
"auth_internal"
"note"
"wallabag_v2"
"large_apod"
"af_readability"
];
};
}
#+end_src
#+ARROYO_EMACS_MODULE: ttrss
#+begin_src emacs-lisp :tangle ~/org/cce/ttrss.el
(use-package elfeed)
(use-package elfeed-protocol
:config
(setq elfeed-use-curl t)
(elfeed-set-timeout 36000)
(setq elfeed-protocol-ttrss-maxsize 200)
; (setq elfeed-feeds '("ttrss+https://user:pass@feeds.whatthefuck.computer" ))
(elfeed-protocol-enable)
)
#+end_src

View File

@ -2,14 +2,16 @@
:ID: cce/undo_tree
:ROAM_ALIASES: undo-tree
:END:
#+TITLE: Undo and Redo with a tree
#+TITLE: Emacs Undo and Redo with a tree
#+PROPERTY: header-args :mkdirp yes :results none
#+PROPERTY: header-args:emacs-lisp :tangle undo-tree.el
#+ARROYO_EMACS_MODULE: undo-tree
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
#+ARROYO_MODULE_WANTS: cce/diminish.org
#+ARCOLOGY_KEY: cce/undo-tree
#+ARCOLOGY_ALLOW_CRAWL: t
#+CCE_PREDICATE: t
#+CCE_PRIORITY: 10
#+begin_src emacs-lisp
(provide 'cce/undo-tree)
@ -34,7 +36,6 @@ It's simple and having it around is cheap and easy.
#+CAPTION: a text-visualization of undo-tree's tree view. Four events sprout from a single point where I did multiple undo actions and I am partway down a new timeline.
[[file:../data/11/b9070e-f1ab-44b5-a204-9662cc146ace/undo-tree.png][file:data/11/b9070e-f1ab-44b5-a204-9662cc146ace/undo-tree.png]]
#+ARROYO_MODULE_WANTS: cce/configure_packaging.org
* Screenshots :ATTACH:
:PROPERTIES:
:ID: 11b9070e-f1ab-44b5-a204-9662cc146ace

View File

@ -65,6 +65,8 @@ handled a little bit differently due to one having a process filter and the othe
#+BEGIN_SRC emacs-lisp
(use-package xterm-color
:commands xterm-color-colorize-buffer xterm-color-test
:autoload xterm-color-filter
:config
(setenv "TERM" "xterm-256color")
(setq compilation-environment '("TERM=xterm-256color"))
@ -80,5 +82,5 @@ handled a little bit differently due to one having a process filter and the othe
(shell-mode . (lambda ()
(add-hook 'comint-preoutput-filter-functions
'xterm-color-filter nil t)))
(compilation-start . #'cce/compilation-start-hook))
(compilation-start . cce/compilation-start-hook))
#+END_SRC

60
vaultwarden.org Normal file
View File

@ -0,0 +1,60 @@
:PROPERTIES:
:ID: 20230201T121604.003311
:ROAM_ALIASES: vaultwarden
:END:
#+TITLE: Storing passwords securely with vaultwarden
#+ARCOLOGY_KEY: cce/vaultwarden
#+ARCOLOG_ALLOW_CRAWL: t
Running Vaultwarden on [[id:20211120T220054.226284][The Wobserver]] isn't so hard thanks to [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][Nixpkgs]]. This is a self-hosted [[id:20230201T121135.988658][Bitwarden]] server.
This is all pretty basic, set up a [[id:cce/wobserver/postgres][PostgreSQL]] DB, setup the service, set up an [[id:e4998eda-d14a-48ee-9661-3d7d1bead53c][Nginx Frontend]] -- if you set =DATA_FOLDER= to something custom, however, you need to override the =systemd= service definition to allow writing to that directory. It'll be pretty upset and difficult to debug if you don't do this, ask me how I know...
I also had to set up =SMTP= configuration to activate my user ... Eventually [[id:20211120T220054.226284][The Wobserver]] needs to support sending mails like this through AWS or SendGrid or something, but for now I just set up a [[roam:Fastmail]] app-password for my account and shoved those in the DB. Yikes.
#+ARROYO_NIXOS_MODULE: nixos/vaultwarden.nix
#+ARROYO_NIXOS_ROLE: server
#+AUTO_TANGLE: t
#+begin_src nix :tangle ~/arroyo-nix/nixos/vaultwarden.nix
{ pkgs, config, ... }:
let
cfg = config.services.vaultwarden;
in
{
services.postgresql.ensureDatabases = ["vaultwarden"];
services.postgresql.ensureUsers = [
{
name = "vaultwarden";
ensurePermissions = {
"DATABASE vaultwarden" = "ALL PRIVILEGES";
};
}
];
services.vaultwarden = {
enable = true;
# backupDir = "/srv/vaultwarden/backup"; # only for sqlite
dbBackend = "postgresql";
config = {
DATABASE_URL = "postgresql://vaultwarden@%2Frun%2Fpostgresql/vaultwarden";
DATA_FOLDER = "/srv/vaultwarden/data";
SIGNUPS_ALLOWED = false;
SIGNUPS_DOMAINS_WHITELIST = "whatthefuck.computer,rix.si";
DOMAIN = "https://vault.whatthefuck.computer";
ROCKET_ADDRESS = "127.0.0.1";
ROCKET_PORT = 8222;
};
environmentFile = "/srv/vaultwarden/private.env";
};
systemd.services.vaultwarden.serviceConfig.ReadWritePaths = [ cfg.config.DATA_FOLDER ];
services.nginx.virtualHosts."vault.whatthefuck.computer" = {
locations."/" = {
proxyPass = "http://127.0.0.1:${toString cfg.config.ROCKET_PORT}";
};
};
}
#+end_src

View File

@ -14,7 +14,7 @@
To update this document:
- Call [[id:20220526T160150.431487][cce/update-nixpkgs-checkout]] to update nixpkgs and then possibly resolve merge conflicts myself.
- =M-o i= will call =nix-update-branch-revs= to fetch the latest revision for modules using =builtins.fetchGit=.[fn:1]
- =M-o i= will call =nix-update-branch-revs= to fetch the latest revision for modules using =builtins.fetchGit=.[fn:1:This is required because I couldn't get =nix-update-decls= to update the revs of these without also populating a =sha256= key which will not be valid in a =builtins.fetchGit= invocation. Both [[id:nix_community_emacs_overlay][nix-community/emacs-overlay]] and [[id:cce/home-manager][home-manager]] are loaded in situations where there is no pre-existing [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][nixpkgs]] to invoke, so they have to use this "impure" invocation.]
- =C-u M-o o= will call =nix-update-decls= to update the =rev= and =sha256= for the rest. Note the prefix argument which will force =nix-prefetch-git= to fetch the latest revisions of the default (or specified) branch.
To understand why/how read on:
@ -66,14 +66,18 @@ homeManager = _: builtins.fetchGit {
By structuring these invocations like this it is possible to write a function contained in my [[id:20220913T104837.013589][nix-update]] page which will iterate over all the call sections and update the =builtins.fetchGit= entities, and then update the revisions and =sha256= of the rest of the document, and safely tangle the new values out on save. This is probably a useful pattern in developing [[id:128ab0e8-a1c7-48bf-9efe-0c23ce906a48][Hypermedia]] in org-mode.
[fn:1] This is required because I couldn't get =nix-update-decls= to update the revs of these without also populating a =sha256= key which will not be valid in a =builtins.fetchGit= invocation. Both [[id:nix_community_emacs_overlay][nix-community/emacs-overlay]] and [[id:cce/home-manager][home-manager]] are loaded in situations where there is no pre-existing [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][nixpkgs]] to invoke, so they have to use this "impure" invocation.
* NEXT update my [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711][NixOS]] version pins and deploy
SCHEDULED: <2023-01-03 Tue .+2w>
SCHEDULED: <2023-08-10 Thu .+2w>
:PROPERTIES:
:LAST_REPEAT: [2022-12-20 Tue 13:15]
:LAST_REPEAT: [2023-07-27 Thu 15:37]
:END:
:LOGBOOK:
- State "DONE" from "NEXT" [2023-07-27 Thu 15:37]
- State "DONE" from "INPROGRESS" [2023-06-20 Tue 08:07]
- State "INPROGRESS" from "NEXT" [2023-06-19 Mon 15:42]
- State "DONE" from "NEXT" [2023-05-29 Mon 12:54]
- State "DONE" from "NEXT" [2023-04-18 Tue 10:39]
- State "DONE" from "NEXT" [2023-03-29 Wed 10:33]
- State "DONE" from "NEXT" [2022-12-20 Tue 13:15]
CLOCK: [2022-12-20 Tue 10:26]--[2022-12-20 Tue 13:15] => 2:49
- State "DONE" from "NEXT" [2022-11-07 Mon 12:15]
@ -86,29 +90,33 @@ CLOCK: [2022-12-20 Tue 10:26]--[2022-12-20 Tue 13:15] => 2:49
{ ... }:
{
# fetchGit
<<homeManager>>
<<emacsOverlay>>
# fetchTarball
<<nixpkgs>>
# github
<<nixgl>>
<<mastodon>>
# tabfs
<<tabfs>>
# org libraries
<<consult-org-roam>>
<<ox-rss>>
<<org-fc>>
<<delve>>
<<tabfs>>
<<cpmtools>>
<<tuhc>>
# pythons
<<beetcamp>>
<<bandcamp-dl>>
<<mopidy-bandcamp>>
<<jisho-api>>
<<twitter-to-sqlite>>
<<inaturalist-to-sqlite>>
<<ttrss>>
}
#+end_src
@ -118,17 +126,18 @@ Right now I am running off a branch of [[id:c75d20e6-8888-4c5a-ac97-5997e2f1c711
** Update [[id:cce/home-manager][home-manager]] by hand
#+CALL: prefetch-git-rev(REPO="nix-community/home-manager", BRANCH="master")
#+CALL: prefetch-git-rev(REPO="nix-community/home-manager", BRANCH="release-23.05")
#+NAME: prefetch-hm
#+results:
: "e7eba9cc46547ae86642ad3c6a9a4fb22c07bc26"
: "07c347bb50994691d7b0095f45ebd8838cf6bc38"
#+begin_src nix :noweb-ref homeManager :noweb yes
homeManager = _: builtins.fetchGit {
url = "https://github.com/nix-community/home-manager.git";
allRefs = true;
rev =
<<prefetch-hm()>>
<<prefetch-hm()>>
;
};
#+end_src
@ -139,7 +148,7 @@ homeManager = _: builtins.fetchGit {
#+NAME: prefetch-em
#+results:
: "a201dcf3d712cf6d3934b396d523041781ff9589"
: "01c076bb6f9fd34630f4c87cfab18ea4e85ef819"
#+NAME: emacsOverlay
#+begin_src nix :noweb yes
@ -164,9 +173,9 @@ builds from https://codeberg.org/martianh/mastodon.el/commits/branch/main
#+begin_src nix :noweb-ref mastodon
mastodon = { pkgs, ... }: pkgs.fetchgit {
url = "https://codeberg.org/martianh/mastodon.el";
rev = "d9c0d7eeea02c27173ed000af7c560ca978125ea";
sha256 = "1fsbpfdssjwfgx8cpl512y6x29q9660v6p0s51r0w2bvdqbqqm92";
# date = "2022-12-11T21:30:28+00:00";
rev = "20dec8871c9bb5f5e418bfc197e7533b5e3065e3";
sha256 = "15cfjny99yw5frdp8nlyazlwgscvfvbinsj0fbdfprxf50k2zjs6";
# date = "2023-07-25T14:17:18+02:00";
};
#+end_src
@ -176,9 +185,9 @@ mastodon = { pkgs, ... }: pkgs.fetchgit {
nixGL = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "guibou";
repo = "nixGL";
rev = "7165ffbccbd2cf4379b6cd6d2edd1620a427e5ae";
sha256 = "1wc85xqnq2wb008y9acb29jbfkc242m9697g2b8j6q3yqmfhrks1";
# date = "2022-08-24T20:56:02+02:00";
rev = "489d6b095ab9d289fe11af0219a9ff00fe87c7c5";
sha256 = "03kwsz8mf0p1v1clz42zx8cmy6hxka0cqfbfasimbj858lyd930k";
# date = "2023-06-04T21:57:57+02:00";
};
#+end_src
@ -189,9 +198,9 @@ tabfs-rev = "09d57f94b507f68ec5e16f53b1cc868fbaf6cceb";
tabfs-fetch = {pkgs, ...}: pkgs.fetchFromGitHub {
owner = "osnr";
repo = "TabFS";
rev = "09d57f94b507f68ec5e16f53b1cc868fbaf6cceb";
sha256 = "0pnzq44plbs358l8lzxzlx35p2c5izvjaqbff5f1fj093wk92wiw";
# date = "2022-02-02T00:56:15-05:00";
rev = "e056ff9073470192ef4c8498aaa7e722edae87c2";
sha256 = "1xbnx30m6dcd10i5xrma5q0azky5w6hgas500ginqg9s9skgciiw";
# date = "2023-03-02T15:45:33-05:00";
};
#+end_src
@ -202,9 +211,9 @@ consult-org-roam-rev = "268f436858e1ea3b263782af466a54e4d603a7d2";
consult-org-roam = {pkgs, ...}: pkgs.fetchFromGitHub {
owner = "jgru";
repo = "consult-org-roam";
rev = "96c95e5a14378cc6fc9c22981f5bfd9e18c419f6";
sha256 = "1mjz73sv2hkirlsr3hmjfivknwydb4yjf90kk5a4zwmhcs3vlh8q";
# date = "2022-11-20T08:18:09+01:00";
rev = "2ca42a1c1641a29f1447d35be01bd1fda368a9e2";
sha256 = "142fra7wap6dfwd4c82j7z3nk1yw78slrwhjx6vkiql8ylbiw5fi";
# date = "2023-05-28T10:55:47+02:00";
};
#+end_src
@ -216,10 +225,10 @@ ox-rss = rec {
rev = "83dc898fa5493925b01716e5dd495d5e07c3d41a";
url = "https://gitlab.com/nsavage/ox-rss.git/";
src = { pkgs, ... }: pkgs.fetchgit {
rev = "83dc898fa5493925b01716e5dd495d5e07c3d41a";
rev = "3b8bbe8a392bbb04f17bf426400c53283fd3647a";
url = "https://gitlab.com/nsavage/ox-rss.git/";
sha256 = "0513kixv9bgkignmji95m3rskn6px6c0fack4zdl61qq09fg8w6h";
# date = "2021-06-06T07:25:35-04:00";
sha256 = "02k9mbi3shjzpmc2z6w5ypjvxq9mlnw6qjkrs8bi10fqsw6fjkpq";
# date = "2023-01-22T11:36:35+00:00";
};
};
#+end_src
@ -232,9 +241,9 @@ org-fc = rec {
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "l3kn";
repo = "org-fc";
rev = "973a16a9561f1ed2fd7e4c5c614b5e5d15715b12";
sha256 = "07cjswmfwc1r11m77pp58rcpbxi3hayv2pnfrqz4zk4kvyb2zw2i";
# date = "2022-09-27T20:31:27+02:00";
rev = "7ab1791dfa6aa6ca252a69d8f43d5b5e8c841190";
sha256 = "0hq11kp4l5qs0jgcvjfhggdr31jyl6mcgaj5c8dwr9x7b8awnh6j";
# date = "2023-05-14T13:41:04+02:00";
};
};
#+end_src
@ -248,7 +257,8 @@ cpmtools = {
owner = "lipro-cpm4l";
repo = "cpmtools";
rev = "e534e20c15973a9559e981efb498a102020e5db7";
sha256 = "sha256-jKC0uh3sGVUJsiTrOa28h+fF4Ja6Yiwzw5Tqfj9oik4=";
sha256 = "0klad0zpxsllqcrjqqmsjvhcbrw7pjnkksr4n84ma6gc3nxb984c";
# date = "2020-07-26T12:24:37+02:00";
};
};
#+end_src
@ -262,8 +272,9 @@ beetcamp = {
src = { pkgs, ... }: pkgs.fetchFromGitHub {
repo = "beetcamp";
owner = "snejus";
rev = "118d4239bd570a59997f13ac0920e6e92890ac67";
sha256 = "sha256-yrlpgLdNEzlWMY7Cns0UE93oEbpkOoYZHGLpui6MfC0=";
rev = "a3b6e7417982a8e68cba8e3e9323924bb8f0bc82";
sha256 = "03s7iffrvgmdnrbvb403hnfky13i0ia3phh08c8bqn84y4lq065q";
# date = "2023-05-20T12:35:13+01:00";
};
};
#+end_src
@ -277,7 +288,7 @@ mopidy-bandcamp = {
src = { python3Packages, ... }: python3Packages.fetchPypi {
version = "1.1.5";
pname = "Mopidy-Bandcamp";
sha256 = "sha256-wg9zcOKfZQRhpyA1Cu5wvdwKpmrlcr2m9mrqBHgUXAQ=";
sha256 = "012w2iw09skayskbswp5dak0mp5xf3p0ld90lxhh8rczw9q763y2";
};
};
#+end_src
@ -292,8 +303,9 @@ delve = {
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "publicimageltd";
repo = "delve";
rev = "9a3e2675ef76865e9ffd95bb49ae1c8307cbfcc1";
sha256 = "sha256-gZcSHJnLW8/IYIdGIsU2vnzZFpyTLk3TxLr0dxR0O0Q=";
rev = "f06bd7b1d8759a041601a2b8a870e60151cb750c";
sha256 = "1b9wf45y600vcf9747d36mnb9mrkaqbn6dwsqr5mik41dgxcw13l";
# date = "2023-03-27T09:59:51+02:00";
};
};
#+end_src
@ -306,8 +318,9 @@ jisho-api = {
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "pedroallenrevez";
repo = "jisho-api";
rev = "b80bff460a0f6826232cafce68cb75ef83543a23";
sha256 = "sha256-3oEhr/kXesxp5vnELlciaizq88Jwzw2ahTgooA946Pc=";
rev = "9d52dcd8a3fab23d1fadd2c9305008705b3bdb7f";
sha256 = "1sdjs640dxwxxxrg76pkrq8gvk5nf220dl39r7ljk6rkc9w64ljz";
# date = "2022-01-12T00:31:34+00:00";
};
};
#+end_src
@ -321,7 +334,8 @@ inaturalist-to-sqlite = {
owner = "dogsheep";
repo = "inaturalist-to-sqlite";
rev = "d888c7c2f02aa0dfb1559603f02357cd0089da11";
sha256 = "sha256-2YKGGzkRJJ68kj1h8Di8weY0cDGTnOkI1DZ2aqNsy0c=";
sha256 = "0iybdjinlxinsh4fk74k65q39rn1phwg0q9xjay9w90i74dqd0nr";
# date = "2020-10-21T17:08:29-07:00";
};
};
#+end_src
@ -335,10 +349,68 @@ twitter-to-sqlite = {
owner = "dogsheep";
repo = "twitter-to-sqlite";
rev = "f09d611782a8372cfb002792dfa727325afb4db6";
sha256 = "sha256-ICAs/DOcyMA0DBEaMk/KG2tsMIDl3MKfP1CdtVXQIls=";
sha256 = "0nr2s1avb7ah7ygw5p75h0q6qsqvr97k46hi1hsc1j4w6gy2q810";
# date = "2021-12-26T10:08:40-08:00";
};
};
#+end_src
** [[id:20230205T132148.236178][bandcamp-dl]]
#+begin_src nix :noweb-ref bandcamp-dl
bandcamp-dl = {
version = "0.0.1";
src = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "iliana";
repo = "bandcamp-dl";
rev = "5b434a8401f51397e4cc7c9bce87f6f137d3ec90";
sha256 = "1kqjnsmdpw4mv4f68fxfyclcimn4r6n4fxp5gz838l0dyc7kzqmv";
# date = "2023-04-08T22:16:38+00:00";
};
};
#+end_src
** NEXT [[id:20220506T155905.773161][vsketch and vpype]] dependencies
** NEXT automate fetchFromPyPi or move to GH fetchers
** [[id:20230310T155744.804329][tt-rss]] plugins
#+begin_src nix :noweb-ref ttrss
large_apod = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "joshp23";
repo = "TTRSS-APOD-Fix";
rev = "d6233f7a9031eaa07649d6b4777525524827f9de";
sha256 = "11vi81vha3sv9nq36ipxisrnrk5y38582f2nk7qg057d6jm9jw0f";
# date = "2017-06-25T13:52:41-04:00";
};
ttrss_wallabag = { pkgs, ... }: pkgs.fetchFromGitHub {
owner = "joshp23";
repo = "ttrss-to-wallabag-v2";
rev = "49ade5a1a216de74e42c4942ffa9cbf1bf426bec";
sha256 = "09rspawg0by5fk1x5b3b3smzqp4zw93h8c7zdxr63z6wjs41ba0j";
# date = "2021-03-14T01:26:43-05:00";
};
# https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-af-readability
ttrss_readability = { pkgs, ... }: pkgs.fetchgit {
url= "https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-af-readability";
rev = "cdc97d886cb7085f9c44a1796ee4bbbf57534d06";
sha256 = "sha256-Pbwp+s4G+mOwjseiejb0gbHpInc2lvR+sv85sRP/DVg=";
# date = "2021-03-14T01:26:43-05:00";
};
#+end_src
** [[id:20230629T103219.772151][Unofficial Homestuck Collection in NixOS]]
#+begin_src nix :noweb-ref tuhc
homestuck = rec {
pname = "unofficial-homestuck-collection";
version = "2.0.7";
src = { ... }: builtins.fetchurl {
url = "https://github.com/Bambosh/unofficial-homestuck-collection/releases/download/v${version}/The-Unofficial-Homestuck-Collection-${version}.AppImage";
sha256 = "sha256:00xcc020wn25fw4r2pdr4llljbckm52nv2hw3ihf1kx2fvrqc7y9";
name = "${pname}-${version}.AppImage";
};
};
#+end_src

View File

@ -131,6 +131,7 @@ buildPythonPackage rec {
] ++ plugins;
postPatch = ''
substituteInPlace pyproject.toml --replace 'matplotlib = { version = ">=3.3.2,<3.6.0", optional = true }' 'matplotlib = { version = ">=3.3.2,<3.8.0", optional = true }'
substituteInPlace pyproject.toml --replace 'pnoise = "^0.1.0"' 'pnoise = "^0.2.0"'
substituteInPlace pyproject.toml --replace 'setuptools = "^51.0.0"' 'setuptools = "^61.0.0"'
'';
@ -392,7 +393,7 @@ buildPythonPackage rec {
postPatch = ''
substituteInPlace pyproject.toml --replace 'vpype = {extras = ["all"], git = "https://github.com/abey79/vpype", rev = "${vpype-rev}"}' 'vpype = "^1.11.0a0"' \
--replace 'Shapely = {extras = ["vectorized"], version = "1.8.2"}' 'Shapely = {extras = ["vectorized"], version = "1.8.4"}'
--replace 'Shapely = {extras = ["vectorized"], version = "1.8.2"}' 'Shapely = {extras = ["vectorized"], version = "^2.0"}'
sed -i '/PySide2/d' pyproject.toml # no idea why there isnt a dist-info written...
'';
@ -522,7 +523,7 @@ buildPythonPackage rec {
propagatedBuildInputs = [ numpy scipy ];
checkInputs = [ pytest ];
nativeCheckInputs = [ pytest ];
checkPhase = ''
pytest test
'';
@ -595,6 +596,8 @@ buildPythonPackage rec {
, anyio
, buildPythonPackage
, fetchFromGitHub
, rustc
, cargo
, rustPlatform
, setuptools-rust
, pythonOlder
@ -634,11 +637,11 @@ buildPythonPackage rec {
'';
nativeBuildInputs = [
cargo
rustc
] ++ (with rustPlatform; [
cargoSetupHook
maturinBuildHook
rust.cargo
rust.rustc
]);
propagatedBuildInputs = [
@ -649,7 +652,7 @@ buildPythonPackage rec {
rm -rf watchfiles
'';
checkInputs = [
nativeCheckInputs = [
dirty-equals
pytest-mock
pytest-timeout

View File

@ -100,8 +100,8 @@ let
in
{
fonts = {
fontconfig.defaultFonts.monospace = ["Vulf Mono" "Deja Vu Sans Mono"];
fontconfig.defaultFonts.sansSerif = ["Vulf Sans" "Deja Vu Sans"];
fontconfig.defaultFonts.monospace = ["Vulf Mono" "Deja Vu Sans Mono" "Noto Color Emoji" ];
fontconfig.defaultFonts.sansSerif = ["Vulf Sans" "Deja Vu Sans" "Noto Color Emoji" ];
fonts = [ vulf_mono vulf_sans ];
};
}

114
waydroid.org Normal file
View File

@ -0,0 +1,114 @@
:PROPERTIES:
:ID: 20230526T152316.126977
:ROAM_ALIASES: Waydroid
:ROAM_REFS: https://nixos.wiki/wiki/WayDroid
:END:
#+TITLE: Waydroid on NixOS is pretty simple
#+ARROYO_NIXOS_MODULE: nixos/waydroid.nix
#+ARROYO_NIXOS_ROLE: endpoint
#+begin_src nix :tangle ~/arroyo-nix/nixos/waydroid.nix
{ pkgs, ... }:
{
imports = [ ./waydroid-passthroughbrowser.nix ];
virtualisation = {
waydroid.enable = true;
lxd.enable = true;
};
environment.systemPackages = [ pkgs.wl-clipboard ];
}
#+end_src
Then in an shell:
#+begin_src shell
sudo waydroid init -s GAPPS
sudo systemctl start waydroid-container
waydroid session start
#+end_src
Download latest F-droid from https://f-droid.org/ and install it
#+begin_src shell
waydroid app install ~/Downloads/F-Droid.apk
#+end_src
#+begin_src shell
waydroid prop set persist.waydroid.multi_windows false
#+end_src
#+results:
* Waydroid Passthrough Browser
:PROPERTIES:
:ID: 20230607T162645.250968
:END:
[[https://git.kj7rrv.com/kj7rrv/passthroughbrowser][passthroughbrowser]] is a simple solution to opening links from Android apps in the system browser by setting up a small HTTP server. I'll use it in waydroid configurations in a custom derivation:
#+AUTO_TANGLE: t
#+begin_src nix :tangle ~/arroyo-nix/pkgs/passthroughbrowser.nix
# https://git.kj7rrv.com/kj7rrv/passthroughbrowser.git
{ lib, stdenv,
makeDesktopItem,
fetchFromGitea,
buildPythonPackage,
flask,
... }:
let
desktopItem = makeDesktopItem {
name = "passthroughbrowser";
desktopName = "Waydroid Passthrough Browser";
categories = ["Utility"];
exec = "passthrough_browser";
};
in buildPythonPackage {
name = "passthroughbrowser";
version = "0.0.1";
format = "simple";
src = fetchFromGitea {
domain = "git.kj7rrv.com";
owner = "kj7rrv";
repo = "passthroughbrowser";
rev = "11ab0f695b6dae4ebee06fa75d6e2796713add98";
sha256 = "sha256-JSbGsWL3kEYw4uUIUgXi7XuXYFQ0Nxkz+fZbvxfpn1o=";
};
propagatedBuildInputs = [
flask
];
installPhase = ''
mkdir -p $out/bin $out/share/passthroughbrowser
cp $src/server.py $out/bin/passthrough_browser
cp $src/PassThroughBrowser.apk $out/share/passthroughbrowser
cp --recursive "${desktopItem}/share" "$out/"
substituteInPlace $out/bin/passthrough_browser \
--replace "app.run(host='192.168.250.1', port=8888)" \
"import os; app.run(host=os.environ.get('PASSTHROUGH_HOST', '192.168.240.1'), port=8888)"
'';
}
#+end_src
#+begin_src nix :tangle ~/arroyo-nix/nixos/waydroid-passthroughbrowser.nix
{ pkgs, ... }:
{
home-manager.users.rrix = {
home.packages = [
pkgs.passthroughbrowser
];
home.sessionVariables = {
PASSTHROUGH_HOST = "192.168.240.1";
};
};
}
#+end_src

View File

@ -217,7 +217,7 @@ rec {
config = ../files/xmonad.hs;
};
<<plasma-xmonad>>
# <<plasma-xmonad>>
}
#+end_src
@ -239,9 +239,11 @@ systemd.user.services.plasma-xmonad = {
Service.Restart="on-failure";
};
home.activation.plasma-xmonad = ''
systemctl --user mask plasma-kwin_x11.service
systemctl --user daemon-reload
systemctl --user enable plasma-xmonad.service
# systemctl --user mask plasma-kwin_x11.service
# systemctl --user daemon-reload
# back to kwin ...
systemctl --user unmask plasma-kwin_x11.service
systemctl --user disable plasma-xmonad.service
'';
#+end_src

View File

@ -12,6 +12,7 @@
#+ARROYO_EMACS_MODULE: yasnippet
#+ARROYO_MODULE_WANTS: cce/company_code_completion.org
#+ARROYO_MODULE_WANTS: cce/diminish.org
I need to put my =~/.emacs.d/snippets/= in here so that it's reproduceable. but for now, this minimal setup is good enough.
@ -20,6 +21,7 @@ I need to put my =~/.emacs.d/snippets/= in here so that it's reproduceable. but
(use-package yasnippet-snippets :demand)
(use-package yasnippet
:after company
:diminish
:config
(add-to-list 'company-backends 'company-yasnippet t)
(yas-global-mode))