mirror of
https://git.sr.ht/~magic_rb/website
synced 2024-11-28 11:06:15 +01:00
Changes
Signed-off-by: Magic_RB <magic_rb@redalder.org>
This commit is contained in:
parent
35c8893dc8
commit
6b441371bf
|
@ -1,5 +1,14 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: "Ubuntu Medium";
|
||||||
|
src: url(/ttf/ubuntu-medium.ttf) format("truetype");
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
font-family: "monospace";
|
font-family: "Ubuntu Medium";
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding: 0 0 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
|
@ -7,3 +16,45 @@ code {
|
||||||
background: #ACACAC;
|
background: #ACACAC;
|
||||||
padding: 0.1rem;
|
padding: 0.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#table-of-contents {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content :is(h1, h2, h3, h4, h5, h6) {
|
||||||
|
display: inline;
|
||||||
|
border-bottom: 0.15rem solid #165578;
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 0.1rem;
|
||||||
|
line-height: 1.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#organizer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content p {
|
||||||
|
flex-basis: auto;
|
||||||
|
text-align: justify;
|
||||||
|
text-justify: inter-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
flex-basis: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 768px) {
|
||||||
|
#organizer {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
flex-basis: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
flex-basis: 10%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
BIN
assets/ttf/ubuntu-medium.ttf
Normal file
BIN
assets/ttf/ubuntu-medium.ttf
Normal file
Binary file not shown.
|
@ -1,6 +1,5 @@
|
||||||
#+TITLE: Emacs, the Journey to an Operating System
|
#+TITLE: Emacs, the Journey to an Operating System
|
||||||
* Emacs, the Journey to an Operating System
|
* The Age without Emacs
|
||||||
** The Age without Emacs
|
|
||||||
It's the 12th of February, I'm playing Factorio on my laptop, when the bell rings and not long
|
It's the 12th of February, I'm playing Factorio on my laptop, when the bell rings and not long
|
||||||
after my Biology teacher enters the classroom, I quickly save and exit out of Factorio. After the
|
after my Biology teacher enters the classroom, I quickly save and exit out of Factorio. After the
|
||||||
usual formalities I sit down and open my editor, so that I can take notes during the lesson. As
|
usual formalities I sit down and open my editor, so that I can take notes during the lesson. As
|
||||||
|
@ -17,11 +16,11 @@
|
||||||
and how painful my existence was. Let's go over the different pain points I now, in retrospect,
|
and how painful my existence was. Let's go over the different pain points I now, in retrospect,
|
||||||
realize existed.
|
realize existed.
|
||||||
|
|
||||||
*** The Pain
|
** The Pain
|
||||||
If you're an Emacs veteran, you surely have already noticed everything I'll point out in the
|
If you're an Emacs veteran, you surely have already noticed everything I'll point out in the
|
||||||
next few paragraphs, but please do read on as I present my unique view on the issues.
|
next few paragraphs, but please do read on as I present my unique view on the issues.
|
||||||
|
|
||||||
**** Multiple Editors
|
*** Multiple Editors
|
||||||
Let's start with the most obvious one, during "A day in the Life of Me", I would switch between
|
Let's start with the most obvious one, during "A day in the Life of Me", I would switch between
|
||||||
3 different editors, being, in increasing order of time spent in each, VSCode, CLion and Vim.
|
3 different editors, being, in increasing order of time spent in each, VSCode, CLion and Vim.
|
||||||
This brings with it many issues, including but not limited to: keybindings, plugins/addons,
|
This brings with it many issues, including but not limited to: keybindings, plugins/addons,
|
||||||
|
|
79
blog/on-databases-docker-and-nix.org
Normal file
79
blog/on-databases-docker-and-nix.org
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#+TITLE: On Docker Databases and Nixos
|
||||||
|
While learning Hashicorp Nomad+Vault+Consul, I decided that I'd convert all the Docker containers I use currently,
|
||||||
|
into their Nix-ified forms. In other words, I'd rewrite the ones I had, but I'd based them on NixOS, a truly
|
||||||
|
declarative enviroment, unlike /ehm/ all the other base images... Well, I didn't realize how *hard* it is to
|
||||||
|
"dockerize" databases, databases are inherently programs, which deal almost exclusively with state, as opposed to Nix
|
||||||
|
and Docker, which are both declarative systems (one of them is trying and failing really hard).
|
||||||
|
|
||||||
|
** Configuration
|
||||||
|
Configuration is a rather big part of what systems administrator(DevOps engineer for the cool kids) does, one must
|
||||||
|
correctly configure a program, most of the time dynamically. And because this is such an important thing, it baffles
|
||||||
|
me, why 90% of all containers primarily use and support environment variables. I get that it's a convenient way to do
|
||||||
|
it, it's simple widely supported, uniform, all around great, but *really* cumbersome. Say your config file looks like
|
||||||
|
this:
|
||||||
|
|
||||||
|
#+BEGIN_SRC conf
|
||||||
|
# stripped down Gitea configuration, I kept the parts that nicely illustrate my point
|
||||||
|
[server]
|
||||||
|
APP_DATA_PATH = /data/gitea
|
||||||
|
ROOT_URL = https://gitea.redalder.org/
|
||||||
|
DOMAIN = gitea.redalder.org
|
||||||
|
|
||||||
|
[database]
|
||||||
|
DB_TYPE = postgres
|
||||||
|
HOST = database-postgres
|
||||||
|
NAME = gitea
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
The config has two sections, =server= and =database=, each of these sections has =n= key-value pairs. This has
|
||||||
|
structure, it has multiple layers and configuration files can get much, much more complex than that. Now, for the
|
||||||
|
sake of argument, let's imagine that we want to "environment-ize" this config. The natural, and frankly only way to
|
||||||
|
do this is to essentially flatten the config file, so we'd get something like this:
|
||||||
|
|
||||||
|
#+BEGIN_SRC conf
|
||||||
|
SERVER_APP_DATA_PATH="/data/gitea"
|
||||||
|
SERVER_ROOT_URL="https://gitea.redalder.org/"
|
||||||
|
SERVER_DOMAIN="gitea.redalder.org"
|
||||||
|
|
||||||
|
DATABASE_DB_TYPE="postgres"
|
||||||
|
DATABASE_HOST="database-postgres"
|
||||||
|
DATABASE_NAME="gitea"
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
Now, you might think that this is completely fine, even reasonable, but let me explain to you why that is horrible.
|
||||||
|
First of, there is no imposed structure and structure is always good, nothing is preventing you from mixing the
|
||||||
|
=server= and =database= sections and while a "good" admin should not do that, it's best if they don't even have the
|
||||||
|
ability. Next depending on the parser, which parses this "configuration", you might encounter issues when you leave
|
||||||
|
out =""=, some are better at this than others, but once again, it's an implicit rule, which is bad. I hope you're
|
||||||
|
starting to understand the bigger picture, implicitness is *bad*, period. It introduces unnecessary mistakes that
|
||||||
|
could have been avoided if just the computer yelled at you. So why not give it the option to do that?
|
||||||
|
|
||||||
|
** Configuration and Databases
|
||||||
|
Now, it's finally time to combine databases with configuration. What we get is an all out war between immutable,
|
||||||
|
declarative environments holding stateful and infinitely changing data. You must make sure that your configuration
|
||||||
|
gets applied only at first start, so you must keep state yourself! In a Docker container! Madness! Then comes the
|
||||||
|
joy of updating the configuration. Say you give your user the option to specify the default authentication method
|
||||||
|
([[https://hub.docker.com/_/postgres][PostgreSQL]]), the user specifies that they want =scram-sha-256=, that's nice and all, so you apply it, but *only* on
|
||||||
|
the first boot. Why? Because now that the value is in the config file, if the user changed it, you'd have to figure
|
||||||
|
out *if* they changed it and then update the configuration file and that's really hard. The user might have gone into
|
||||||
|
where they store the state for PostgreSQL and manually changed the config file, they might have even completely
|
||||||
|
deleted your configuration and replaced it with their own? What should you do? Most Docker containers just take the
|
||||||
|
easy way out and do as PostgreSQL does and I don't blame them, there is nothing really that you can do.
|
||||||
|
|
||||||
|
** Nix - The Solution?
|
||||||
|
Similar to some good literature, this rant has gone full circle. We're back at the start, back on the topic of
|
||||||
|
Nix. How can Nix save us? By removing unnecessary state. The mutable configuration file? Gone, it's immutable
|
||||||
|
now. Not knowing whether a setting changed? Poof, gone too, Nix is fully declarative, which means it identifies
|
||||||
|
*everything* by a sha256 hash in addition to its developer configured name. Nix also serves as a single point of
|
||||||
|
truth, which means even if the user modifies the config files, they will be overwritten before they are used
|
||||||
|
again. This makes mix ups are impossible. Messy and flat "configuration" files? Solved too, the Nix expression language can be
|
||||||
|
as flat or as deep as you need it to be, you can create complex APIs with functions and all that jazz. Basically Nix
|
||||||
|
is awesome!
|
||||||
|
|
||||||
|
** Conclusion
|
||||||
|
The take-away from this rant, is that the best course of action is to figure out either how to completely replace
|
||||||
|
Docker and all the other container runtimes with something based on Nix, but since I'm a realist, I propose another
|
||||||
|
possible solution. We must get Nix to nicely work with Docker, so instead of clumsy environment variables, you'd
|
||||||
|
write your configuration in the form of Nix expressions and build a new docker image based on one common base. This
|
||||||
|
ensure that all configuration would be properly hashed and declarative, while allowing for much more complex config
|
||||||
|
files than environment variables or even templates.
|
92
make.el
92
make.el
|
@ -5,11 +5,101 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
(load-file "./org-thtml/ox-thtml.el")
|
(load-file "./org-thtml/ox-thtml.el")
|
||||||
(require 'org)
|
(require 'org)
|
||||||
|
(require 'ox)
|
||||||
|
(require 'ox-html)
|
||||||
|
|
||||||
(dolist (d '("public_html"))
|
(dolist (d '("public_html"))
|
||||||
(unless (file-exists-p d)
|
(unless (file-exists-p d)
|
||||||
(make-directory d)))
|
(make-directory d)))
|
||||||
|
|
||||||
|
;; https://alhassy.github.io/AlBasmala.html#Floating-TOC
|
||||||
|
(advice-add 'org-html--translate :before-until 'display-toc-as-toc)
|
||||||
|
(defun display-toc-as-toc (phrase info)
|
||||||
|
(when (equal phrase "Table of Contents")
|
||||||
|
"<a>
|
||||||
|
TOC
|
||||||
|
</a>"))
|
||||||
|
|
||||||
|
;; https://github.com/alphapapa/unpackaged.el#export-to-html-with-useful-anchors
|
||||||
|
(advice-add #'org-export-get-reference :override #'unpackaged/org-export-get-reference)
|
||||||
|
|
||||||
|
(defun unpackaged/org-export-get-reference (datum info)
|
||||||
|
"Like `org-export-get-reference', except uses heading titles instead of random numbers."
|
||||||
|
(let ((cache (plist-get info :internal-references)))
|
||||||
|
(or (car (rassq datum cache))
|
||||||
|
(let* ((crossrefs (plist-get info :crossrefs))
|
||||||
|
(cells (org-export-search-cells datum))
|
||||||
|
;; Preserve any pre-existing association between
|
||||||
|
;; a search cell and a reference, i.e., when some
|
||||||
|
;; previously published document referenced a location
|
||||||
|
;; within current file (see
|
||||||
|
;; `org-publish-resolve-external-link').
|
||||||
|
;;
|
||||||
|
;; However, there is no guarantee that search cells are
|
||||||
|
;; unique, e.g., there might be duplicate custom ID or
|
||||||
|
;; two headings with the same title in the file.
|
||||||
|
;;
|
||||||
|
;; As a consequence, before re-using any reference to
|
||||||
|
;; an element or object, we check that it doesn't refer
|
||||||
|
;; to a previous element or object.
|
||||||
|
(new (or (cl-some
|
||||||
|
(lambda (cell)
|
||||||
|
(let ((stored (cdr (assoc cell crossrefs))))
|
||||||
|
(when stored
|
||||||
|
(let ((old (org-export-format-reference stored)))
|
||||||
|
(and (not (assoc old cache)) stored)))))
|
||||||
|
cells)
|
||||||
|
(when (org-element-property :raw-value datum)
|
||||||
|
;; Heading with a title
|
||||||
|
(unpackaged/org-export-new-title-reference datum cache))
|
||||||
|
;; NOTE: This probably breaks some Org Export
|
||||||
|
;; feature, but if it does what I need, fine.
|
||||||
|
(org-export-format-reference
|
||||||
|
(org-export-new-reference cache))))
|
||||||
|
(reference-string new))
|
||||||
|
;; Cache contains both data already associated to
|
||||||
|
;; a reference and in-use internal references, so as to make
|
||||||
|
;; unique references.
|
||||||
|
(dolist (cell cells) (push (cons cell new) cache))
|
||||||
|
;; Retain a direct association between reference string and
|
||||||
|
;; DATUM since (1) not every object or element can be given
|
||||||
|
;; a search cell (2) it permits quick lookup.
|
||||||
|
(push (cons reference-string datum) cache)
|
||||||
|
(plist-put info :internal-references cache)
|
||||||
|
reference-string))))
|
||||||
|
|
||||||
|
(defun unpackaged/org-export-new-title-reference (datum cache)
|
||||||
|
"Return new reference for DATUM that is unique in CACHE."
|
||||||
|
(cl-macrolet ((inc-suffixf (place)
|
||||||
|
`(progn
|
||||||
|
(string-match (rx bos
|
||||||
|
(minimal-match (group (1+ anything)))
|
||||||
|
(optional "--" (group (1+ digit)))
|
||||||
|
eos)
|
||||||
|
,place)
|
||||||
|
;; HACK: `s1' instead of a gensym.
|
||||||
|
(-let* (((s1 suffix) (list (match-string 1 ,place)
|
||||||
|
(match-string 2 ,place)))
|
||||||
|
(suffix (if suffix
|
||||||
|
(string-to-number suffix)
|
||||||
|
0)))
|
||||||
|
(setf ,place (format "%s--%s" s1 (cl-incf suffix)))))))
|
||||||
|
(let* ((title (org-element-property :raw-value datum))
|
||||||
|
(ref (url-hexify-string (substring-no-properties title)))
|
||||||
|
(parent (org-element-property :parent datum)))
|
||||||
|
(while (--any (equal ref (car it))
|
||||||
|
cache)
|
||||||
|
;; Title not unique: make it so.
|
||||||
|
(if parent
|
||||||
|
;; Append ancestor title.
|
||||||
|
(setf title (concat (org-element-property :raw-value parent)
|
||||||
|
"--" title)
|
||||||
|
ref (url-hexify-string (substring-no-properties title))
|
||||||
|
parent (org-element-property :parent parent))
|
||||||
|
;; No more ancestors: add and increment a number.
|
||||||
|
(inc-suffixf ref)))
|
||||||
|
ref)))
|
||||||
|
|
||||||
(defvar org-publish-project-alist)
|
(defvar org-publish-project-alist)
|
||||||
(setq org-publish-project-alist
|
(setq org-publish-project-alist
|
||||||
`(("blog-org"
|
`(("blog-org"
|
||||||
|
@ -28,7 +118,7 @@
|
||||||
:base-directory ,(expand-file-name "assets/")
|
:base-directory ,(expand-file-name "assets/")
|
||||||
:publishing-directory ,(expand-file-name "public_html/")
|
:publishing-directory ,(expand-file-name "public_html/")
|
||||||
:recursive t
|
:recursive t
|
||||||
:base-extension "\\(jpg\\|gif\\|png\\|css\\|js\\|el\\|nb\\|ipynb\\|pdf\\|xml\\)"
|
:base-extension "\\(ttf\\|jpg\\|gif\\|png\\|css\\|js\\|el\\|nb\\|ipynb\\|pdf\\|xml\\)"
|
||||||
:publishing-function org-publish-attachment)
|
:publishing-function org-publish-attachment)
|
||||||
("blog"
|
("blog"
|
||||||
:components ("blog-org" "blog-assets"))))
|
:components ("blog-org" "blog-assets"))))
|
||||||
|
|
|
@ -2,17 +2,14 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
{{:include "head.html"}}
|
{{:include "head.html"}}
|
||||||
<body>
|
<body>
|
||||||
|
<div id="organizer">
|
||||||
<div id="layout" class="pure-g">
|
<div class="sidebar">{{org-html-toc 2 info}}</div>
|
||||||
<div class="content pure-u-1 pure-u-md-2-3">
|
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
{{:if with-title}}<h1>{{title}}</h1>{{:endif}}
|
{{:if with-title}}<h1>{{title}}</h1>{{:endif}}
|
||||||
{{:if date}}<div class="post-meta">Published on {{format-time-string "%b %d, %Y" date}}</div>{{:endif}}
|
{{:if date}}<div class="post-meta">Published on {{format-time-string "%b %d, %Y" date}}</div>{{:endif}}
|
||||||
{{contents}}
|
{{contents}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sidebar"></div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue