feed.xml 247 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015
  1. <?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>GNUcode.me</title><id>https://gnucode.me/feed.xml</id><subtitle>Recent Posts</subtitle><updated>2024-04-18T01:18:57Z</updated><link href="https://gnucode.me/feed.xml" rel="self" /><link href="https://gnucode.me" /><entry><title>OpenBSD's Philosophy</title><id>https://gnucode.me/openbsds-philosophy.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2024-04-17T18:00:00Z</updated><link href="https://gnucode.me/openbsds-philosophy.html" rel="alternate" /><content type="html">&lt;p&gt;I have talked about OpenBSD before in this blog, and I recently
  2. watched a talk by OpenBSD's leader Theo de Raadt about &lt;code&gt;pledge ()&lt;/code&gt; and
  3. &lt;code&gt;arc4random()&lt;/code&gt;. He described OpenBSD's design philosophy so well, that
  4. I wanted to write it down. You should definitely take some time to
  5. hear Theo speak. He's entertaining, and his talks are super awesome!&lt;/p&gt;&lt;p&gt;So a long time ago (early 90s ?), a cracker (1) broke into Theo's
  6. OpenBSD's syslog. This got Theo to examine OpenBSD's source code to
  7. fix any lingering bugs, and he found a lot. He realized that trying
  8. to constantly examine source code to prevent bugs is a never ending
  9. process. He wanted to ensure code quality got better over time. He
  10. envision an operating system that that enforced code correctness like
  11. the below ASCII art shows.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;__________________________
  12. | Poorly written programs |
  13. | crash on OpenBSD. |
  14. | ---------------------- |
  15. | | Correctly written | |
  16. | | programs run well | |
  17. | | on OpenBSD. | |
  18. | ---------------------- |
  19. ---------------------------&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;He wondered if he could create features to slightly narrow the things
  20. that applications could do. When poorly written programs run on
  21. OpenBSD, they crash in deterministic ways, but correct programs work
  22. just fine. Theo also made sure that &amp;quot;mitigations&amp;quot;, or checks to ensure
  23. a program's correctness, &lt;em&gt;cannot&lt;/em&gt; be turned off on OpenBSD. If a user
  24. or a project manager has a problem with an application not working on
  25. OpenBSD due to a toggleable security feature, then the user or project
  26. manager will just turn off the feature. So to ensure that programs
  27. abide by the mitigations, OpenBSD enforces their security policies.&lt;/p&gt;&lt;p&gt;OpenBSD also makes it easy to use their security features. If they
  28. introduce a policy that is manatory, they try to make the API easy to
  29. use. If you create a security policy that is hard for the programmer
  30. to use, then the security policy won't be used.&lt;/p&gt;&lt;p&gt;When OpenBSD creates a new mitigation, their application porters port
  31. 3rd party software packages to OpenBSD. Typically these changes find
  32. their way into the upstream packages. What's awesome is that usually
  33. other operating systems start to use OpenBSD mitigations on their
  34. systems 5 years after OpenBSD introduced them. Windows, Mac, and
  35. Linux applications all benefit from the strict standards that OpenBSD
  36. creates. Theo's talks gave two examples for this: &lt;code&gt;pledge ()&lt;/code&gt; and
  37. &lt;code&gt;arc4random ()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Here's a question for you. How do you get random data? Well you read
  38. &lt;code&gt;/dev/random&lt;/code&gt; of course. Simple. Easy. Done. That used to be how
  39. things were handled. Apparently reading from &lt;code&gt;/dev/random&lt;/code&gt; has some
  40. limitations that Theo mentioned. Can you read from &lt;code&gt;/dev/random&lt;/code&gt;
  41. inside the kernel? Inside a library? In your libc? Reading from
  42. &lt;code&gt;/dev/random&lt;/code&gt; is not perfect. Theo wanted to make something better.&lt;/p&gt;&lt;p&gt;OpenBSD created &lt;code&gt;arc4random ()&lt;/code&gt; as a better source of entropy. It is
  43. a C function that almost any application can call (even the kernel),
  44. most of the time. This lets many applications, libraries, etc. easily
  45. use random numbers. What's surprizing to me is that many operating
  46. systems use &lt;code&gt;arc4random ()&lt;/code&gt; or a function like it, so that more
  47. applictions can easily request random data. This function (or one
  48. like it) exists on your Android phone, iPhone, iMac, and sort of on
  49. Linux thanks to OpenBSD.&lt;/p&gt;&lt;p&gt;What's &lt;code&gt;pledge ()&lt;/code&gt; ? Oh ho, let me tell you! Let's take a look at a
  50. typical program.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-C&quot;&gt;int main () {
  51. initialize_stuff();
  52. for (;;) {
  53. ;; let's run the program
  54. }
  55. }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Most programs have an initialization phase followed by a loop, in
  56. which the application runs. The OpenBSD team realized that the
  57. initialize phase uses most of the system calls. After the initialize
  58. phase, the program typically needs less system calls. OpenBSD's
  59. &lt;code&gt;pledge ()&lt;/code&gt; was created in response to this pattern present in most
  60. programs.&lt;/p&gt;&lt;p&gt;&lt;code&gt;pledge ()&lt;/code&gt; is a security call, by which an application tells the
  61. kernel, &amp;quot;I pledge to only do these things and no other.&amp;quot; For example,
  62. &amp;quot;I pledge to only output text&amp;quot;. Or &amp;quot;I pledge to only access the
  63. internet and output text.&amp;quot; If the application tries to do something
  64. that it has pledged not to do, then OpenBSD kills the application.&lt;/p&gt;&lt;p&gt;A really interesting blog post that talks about this is at
  65. &lt;a href=&quot;https://justine.lol/pledge/&quot;&gt;justine's blog&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;After watching two of Theo's talks, I am fairly convinced that his
  66. design goals are slowly working to make all POSIX operating systems
  67. more correct and secure. I used to dual boot Guix System and OpenBSD,
  68. but unfortunately my spare SSD busted. So for now I am only using
  69. Guix System. I personally prefer to use Guix System for my linode
  70. server (that powers this blog), because Guix makes it easy to manage
  71. servers.&lt;/p&gt;&lt;p&gt;I wish that the Guix developers could one day create Guix OpenBSD
  72. System, but I have been told that Guix System assumes your libc is
  73. &lt;code&gt;glibc&lt;/code&gt; and that OpenBSD cannot currently make isolated build
  74. environments as well as Linux can. Also fun fact OpenBSD is not
  75. currently working on reproducible builds. :)&lt;/p&gt;&lt;p&gt;My two only minor complaints with OpenBSD currently are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;I wish OpenBSD supported Wayland. This may happen in 6 months to a
  76. year. Fingers crossed.&lt;/li&gt;&lt;li&gt;A better filesystem: OpenBSD's FFS (fast file system) works, but it
  77. is possible to lose data in a crash. Filesystems are &lt;em&gt;really&lt;/em&gt; hard
  78. to get right. Kent Overstreet has been working on bcachefs for
  79. almost a decade now, and it might soon become one of Linux's best
  80. filesystems (my opinion), so I don't blame OpenBSD for not trying to
  81. create a new next generational filesystem. Anybody want to spend 10
  82. years of their life creating an awesome filesystem that will
  83. probably only work well on OpenBSD? One might be able to port
  84. HammerFS to OpenBSD, and a basic read-only port does exist.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If you want to try OpenBSD, give it a shot! It works really well on
  85. most lenovo laptops and most desktop machines.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Nerdy computer people like me use the word &amp;quot;hacker&amp;quot; to mean someone
  86. who builds computer programs, and a &amp;quot;cracker&amp;quot; is someone who breaks
  87. into computer systems.&lt;/li&gt;&lt;/ol&gt;</content></entry><entry><title>The Hurd on Bare Metal Update</title><id>https://gnucode.me/the-hurd-on-bare-metal-update.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2024-01-07T19:00:00Z</updated><link href="https://gnucode.me/the-hurd-on-bare-metal-update.html" rel="alternate" /><content type="html">&lt;h1&gt;Running the Hurd on Bare Metal&lt;/h1&gt;&lt;p&gt;So apparently, you can run X on the Hurd, and I am currently daily
  88. driving the Hurd. It's not perfect. Once a month or so the Hurd will
  89. lock up completely, and I will have to hard shutoff the machine and
  90. deal with filesystem corruption. But it does work! You will need to
  91. read the whole &lt;a href=&quot;https://www.debian.org/ports/hurd/hurd-install&quot;&gt;Debian wiki&lt;/a&gt; page. There are sections that mention how
  92. to upgrade to the unstable distribution, setting up X, and the correct
  93. upgrade procedure:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# apt update
  94. # apt upgrade --without-new-pkgs
  95. # apt full-upgrade&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let's install some packages and set up X.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# apt install i3 xinit pinentry-gnome3
  96. # Tell X to let any user startx (it is better to let only console
  97. # users to start X, but that is not working for me.
  98. # apt dpkg-reconfigure x11-common xserver-xorg-legacy&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Create a keyboard shortcut to kill X, because X may get stuck.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /etc/X11/xorg.conf.d/xorg-ctrl-backspace.conf
  99. Section &amp;quot;InputDevice&amp;quot;
  100. Identifier &amp;quot;Generic KeyBoard&amp;quot;
  101. Driver &amp;quot;kbd&amp;quot;
  102. Option &amp;quot;XkbOptions&amp;quot; &amp;quot;terminate:ctrl_alt_bksp&amp;quot;
  103. EndSection&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If, I am running X, then the best way to shutdown the computer, is to
  104. first kill X, then from the console execute &lt;code&gt;sudo halt&lt;/code&gt;. I tried to
  105. issue &lt;code&gt;sudo halt&lt;/code&gt; from an &lt;code&gt;xterm&lt;/code&gt;, and that caused some filesystem
  106. corruption on my &lt;code&gt;/home&lt;/code&gt; partition.&lt;/p&gt;&lt;p&gt;So what works?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Emacs 29.1&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Gnus&lt;/li&gt;&lt;li&gt;magit&lt;/li&gt;&lt;li&gt;erc&lt;/li&gt;&lt;li&gt;org-mode&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;git send-email&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;netsurf web browser&lt;/p&gt;&lt;p&gt;I &amp;quot;ported&amp;quot; it via hard-coding &lt;code&gt;PATHMAX&lt;/code&gt;, which is not an ideal
  107. solution, but at least I have a web browser that can render simple
  108. websites like Wikipedia.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;ffmpeg&lt;/p&gt;&lt;p&gt;I actually use &lt;code&gt;recordmydesktop --no-sound --fps 2&lt;/code&gt; on the Hurd
  109. machine. This does actually work. I tried
  110. using ffmpeg on my Guix System to add audio to the file, but the
  111. audio is out of sync with the video. I'm not sure why.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://mail.gnu.org/archive/html/bug-hurd/2023-03/msg00021.html&quot;&gt;terrible-mdns-responder&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Sergey created this as a way to easily ssh into his hurd box from a
  112. GNU/Linux machine. I use it like so: &lt;code&gt;ssh joshua@pippin.local&lt;/code&gt;,
  113. and I can ssh into my Hurd machine without having to know its IP
  114. address. It's pretty cool!&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;i3&lt;/p&gt;&lt;p&gt;i3 is probably the slickest window manager out there! Since the
  115. Hurd is currently X only, I might as well use something light-weight
  116. that I like.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;pastebinit&lt;/p&gt;&lt;p&gt;It would be nice if netsurf would work with a pastebin, but it's
  117. not. So the &lt;code&gt;pastebinit&lt;/code&gt; command works.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;ikiwiki&lt;/p&gt;&lt;p&gt;I can update the GNU Hurd wiki entirely using the Hurd. That's
  118. awesome!&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;strong&gt;Gotchas&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;There are some gotchas when running the Hurd.&lt;/p&gt;&lt;p&gt;If, &lt;code&gt;/home&lt;/code&gt; or &lt;code&gt;/&lt;/code&gt; are readonly, then X will refuse to start and will
  119. not tell you why. So, my &lt;code&gt;.bashrc&lt;/code&gt; has this in it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat .profile | grep -A 15 'tell me'
  120. # tell me if / or /home are writeable or not.
  121. echo -n '/ is '
  122. myroot=$(fsysopts / | awk '{ print $2 }')
  123. myroot=${myroot:2}
  124. echo $myroot
  125. echo -n '/home is '
  126. myhome=$(fsysopts /home | awk '{ print $2 }')
  127. myhome=${myhome:2}
  128. echo $myhome
  129. if [ $myhome == &amp;quot;writable&amp;quot; ]; then
  130. echo &amp;quot;starting X&amp;quot;;
  131. else
  132. echo &amp;quot;NOT starting X&amp;quot;;
  133. fi&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When I have filesystem corruption, I need to umount &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;/home&lt;/code&gt;
  134. and run fsck on them. Then reboot. Most of the time the Hurd can
  135. auto run fsck for you, but sometimes it is so bad that you must do it
  136. yourself.&lt;/p&gt;&lt;p&gt;When you have to fsck the filesystem, here is how to do it. You have
  137. to login via &lt;code&gt;root&lt;/code&gt;, then &lt;code&gt;umount /home &amp;amp;&amp;amp; umount /&lt;/code&gt;. Then run
  138. &lt;code&gt;fsck.ext2 /dev/hd0s1 &amp;amp;&amp;amp; fsck.ext2 /dev/hd0s6&lt;/code&gt;. Now reboot.&lt;/p&gt;&lt;p&gt;I also cannot shutoff the machine from a terminal inside X. I first
  139. have to kill X, and then shutoff the machine from the console.&lt;/p&gt;&lt;p&gt;Also, &lt;code&gt;apt&lt;/code&gt; is apparently not the best tool to install various
  140. packages. It is actually better to use &lt;code&gt;aptitude&lt;/code&gt;. &lt;code&gt;# apt install elpa-magit&lt;/code&gt; fails, but &lt;code&gt;#aptitude install elpa-magit&lt;/code&gt; somehow works.
  141. I do not know why.&lt;/p&gt;&lt;p&gt;This is kind of new, but &lt;code&gt;sudo&lt;/code&gt; is failing:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ sudo ls
  142. malloc(): invalid size (unsorted)
  143. Aborted&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I would love to get haunt running on the Hurd, and it does run! But
  144. it fails to build this blog. At first it was that &lt;code&gt;guile-commonmark&lt;/code&gt;
  145. was not installed. Then it was that haunt could not find
  146. &lt;code&gt;guile-commonmark&lt;/code&gt;. The fix was pretty easy. In the haunt source
  147. code directory:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ export GUILE_LOAD_PATH=/usr/local/share/guile/site/3.0&amp;quot;
  148. $ ./configure&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So that helped me build haunt correctly and it could find
  149. guile-commonmark. But then it needed guile-reader installed as well.
  150. Now I can't build guile-reader.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ autoreconf -vif
  151. autoreconf: error: automake failed with exit status: 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And of course the &lt;code&gt;./configure&lt;/code&gt; in the guile-reader directory failed
  152. too.&lt;/p&gt;</content></entry><entry><title>The Hurd on Bare Metal</title><id>https://gnucode.me/the-hurd-on-bare-metal.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-08-13T14:00:00Z</updated><link href="https://gnucode.me/the-hurd-on-bare-metal.html" rel="alternate" /><content type="html">&lt;p&gt;This blog post was written on a Debian GNU/Hurd system on a IBM ThinkPad T43
  153. with 1.5 GB of RAM. (It was edited on Guix System (running linux)). Apparently
  154. running Emacs on the hurd in the console is actually quite stable. This post
  155. will describe my attempt to make this T43 be my daily laptop. Let’s see
  156. how far I can get with that eh?&lt;/p&gt;&lt;p&gt;tl;dr Debian GNU/Hurd is shockingly stable. If you are an emacs wiz,
  157. then you will feel right at home.&lt;/p&gt;&lt;p&gt;The first thing to notice after you login to the Hurd is that you can
  158. easily switch virtual consoles via &lt;code&gt;Alt-&amp;lt;right-arrow&amp;gt;&lt;/code&gt;. It is
  159. actually pretty awesome that you can do this. I know literally every
  160. other OS has this, but it is cool to have Emacs open in one console,
  161. and have another program running on another console; switching
  162. between them feels beautiful.&lt;/p&gt;&lt;p&gt;Another thing to notice is that &lt;code&gt;mount&lt;/code&gt; does not work. Let's explore that shall
  163. we?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /etc/mtab | awk '{ print $1 &amp;quot; &amp;quot; $2 &amp;quot; &amp;quot; $3 }'
  164. /dev/hd0s1 / ext2fs
  165. none /run /hurd/tmpfs
  166. none /run/lock /hurd/tmpfs
  167. /dev/hd0s6 /home /hurd/ext2fs
  168. proc /proc /hurd/procfs&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Actually &lt;code&gt;/etc/mtab&lt;/code&gt; is a symlink to &lt;code&gt;/proc/mounts&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ls -lha /etc/mtab
  169. lrwxr-xr-x 1 root root 12 Apr 10 12:14 /etc/mtab -&amp;gt; /proc/mounts&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It looks like the Hurd labels MBR partitions slightly differently from Linux. It
  170. appears that the Hurd uses &lt;code&gt;/dev/hd0s1&lt;/code&gt;, &lt;code&gt;dev/hd0s2&lt;/code&gt;, and so on.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;echo $pw | sudo -S fdisk -l /dev/hd0
  171. Disk /dev/hd0: 37.26 GiB, 40007761920 bytes, 78140160 sectors
  172. Units: sectors of 1 * 512 = 512 bytes
  173. Sector size (logical/physical): 512 bytes / 512 bytes
  174. I/O size (minimum/optimal): 512 bytes / 512 bytes
  175. Disklabel type: dos
  176. Disk identifier: 0x1ab32a1b
  177. Device Boot Start End Sectors Size Id Type
  178. /dev/hd0s1 2048 26681343 26679296 12.7G 83 Linux
  179. /dev/hd0s2 26683390 78139391 51456002 24.5G 5 Extended
  180. /dev/hd0s5 26683392 28682239 1998848 976M 82 Linux swap / Solaris
  181. /dev/hd0s6 28684288 78139391 49455104 23.6G 83 Linux&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It looks like a good place to start learning how to use the Hurd is
  182. via &lt;code&gt;https://www.debian.org/ports/hurd/hurd-install&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;So the file that describes my network interfaces is here:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /etc/network/interfaces
  183. # This file describes the network interfaces available on your system
  184. # and how to activate them. For more information, see interfaces(5).
  185. source /etc/network/interfaces.d/*
  186. # The loopback network interface
  187. auto lo
  188. iface lo inet loopback
  189. # The primary network interface
  190. auto /dev/eth0
  191. iface /dev/eth0 inet dhcp&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So it looks like i should definitely read &lt;code&gt;man 5 interfaces&lt;/code&gt; at some
  192. point. And the Debian Hurd guide mentions that I should add name
  193. servers to my /etc/resolv.conf file. I am not certain why it says
  194. that I should do that though, but I went ahead and added OpenDNS’ name
  195. servers.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /etc/resolv.conf
  196. nameserver 172.16.112.1
  197. cat /etc/resolv.conf
  198. nameserver 172.16.112.1
  199. nameserver 208.67.222.222
  200. nameserver 208.67.220.220&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok, so it seems like &lt;code&gt;pfinit&lt;/code&gt; is still the default GNU Hurd &lt;code&gt;TPC/IP&lt;/code&gt;
  201. translator, which is based on an old Linux TCP/IP driver (&lt;code&gt;lwip&lt;/code&gt; or
  202. &lt;code&gt;rumpkernel&lt;/code&gt; may one day replace it). Apparently my internet
  203. connectivity can be found by quering &lt;code&gt;/servers/socket/2&lt;/code&gt; (for IPv4)
  204. and &lt;code&gt;/servers/socket/26&lt;/code&gt; (for IPv6).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# fsysopts /servers/socket/2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you run the above command you will see that the ethernet device
  205. that the Hurd uses is &lt;code&gt;/dev/eth0&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The Hurd has a stateless (stateful is better) ethernet filter. For example, here
  206. is how to disable ssh access:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# settrans -c /dev/eth0f /hurd/eth-filter \
  207. -i /dev/eth0 -r &amp;quot;not port 22&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I could then, tell the pfinit translator to use &lt;code&gt;/dev/eth0f&lt;/code&gt; instead
  208. of &lt;code&gt;/dev/eth0&lt;/code&gt; via (I think this how you would do it):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# fsysopts /server/socket/2 --interface=/dev/eth0f&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is course is not persistant across reboots. I would probably
  209. need to replace &lt;code&gt;/dev/eth0&lt;/code&gt; in &lt;code&gt;/etc/network/interfaces&lt;/code&gt; with
  210. &lt;code&gt;/dev/eth0f&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;The Hurd lets you mount cd drives as a regular user. I should be able
  211. to look at the files in my CD drive via:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cd /dev
  212. # ./MAKEDEV cd0
  213. # settrans /media/cdrom0 /hurd/is09660fs /dev/cd0
  214. $ cd /media/cdrom0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Apparently the Hurd does have a network filesystem translator
  215. (&lt;code&gt;/hurd/nfs&lt;/code&gt;), but I believe that that translator only supports
  216. NFSv2. So it may not be as performanent as one might want or support
  217. the latest NSF features.&lt;/p&gt;&lt;p&gt;Since I installed the stable Hurd release from 2021, the guide
  218. recommends that if I want a stable environment, then I can just
  219. configure apt to use the apt sources from 2021. That should let me
  220. have a fairly stable Hurd distro. So let’s try that.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /etc/apt/apt.conf.d/99ignore-valid-until
  221. Acquire::Check-Valid-Until &amp;quot;false&amp;quot;;
  222. cat /etc/apt/sources.list
  223. deb [trusted=yes] https://snapshot.debian.org/archive/debian-ports/20210812T100000Z sid main
  224. deb [trusted=yes] https://snapshot.debian.org/archive/debian-ports/20210812T100000Z unreleased main
  225. deb-src [trusted=yes check-valid-until=no] https://snapshot.debian.org/archive/debian/20210812T100000Z sid main&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This mostly worked, but apt gave a warning about the debian gpg key
  226. had expired.&lt;/p&gt;&lt;p&gt;Well let’s try to upgrade anyway.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# apt update &amp;amp;&amp;amp; apt upgrade&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That seemed to work.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# apt install debian-ports-archive-keyring
  227. # apt update
  228. # apt upgrade
  229. # apt install git git-email
  230. $ git config --global user.name &amp;quot;Joshua Branson&amp;quot;
  231. $ git config --global user.email &amp;quot;jbranso@dismail.de&amp;quot;
  232. $ cd; git clone https://notabug.org/jbranso/prog&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I suppose that it is time to follow &lt;a href=&quot;https://drewdevault.com/2019/12/30/dotfiles.html&quot;&gt;Drew Devault’s guide&lt;/a&gt; on how to
  233. manage your home directory’s configuration files as a git repository.&lt;/p&gt;&lt;p&gt;I should also read the &lt;a href=&quot;https://www.debian.org/ports/hurd/hurd-doc-translator&quot;&gt;hurd-doc-translator&lt;/a&gt; webpage.&lt;/p&gt;&lt;p&gt;Apparently, the Hurd’s translators transform data into different data.
  234. The usual case, is that a translator translates bits of the filesystem
  235. into different data, and what is awesome is that translators run in
  236. userspace. Most of the time translators will need to get data from
  237. hardware, and they will request the kernel to help them get this data.
  238. There are some exceptions: &lt;code&gt;/dev/zero&lt;/code&gt; does not need hardware data, so
  239. a read from &lt;code&gt;dev/zero&lt;/code&gt; is entirely run in userspace.&lt;/p&gt;&lt;p&gt;There are two kinds of translators: active and passive. An active
  240. translator is currently running. You can change its settings or kill
  241. it via the &lt;code&gt;settrans -a&lt;/code&gt; command. The &lt;code&gt;-a&lt;/code&gt; refers to the &lt;strong&gt;active&lt;/strong&gt;
  242. translator. So &lt;code&gt;settrans -a file.txt&lt;/code&gt; will try to kill the userspace
  243. translator process. If you start a translator via the &lt;code&gt;-a&lt;/code&gt; option,
  244. then the translator is not persistant accross reboot. For that reason,
  245. most of the time you do not want the &lt;code&gt;-a&lt;/code&gt; option, which is what
  246. settrans by default does.&lt;/p&gt;&lt;p&gt;If you are ever curious to know if a filesystem node has an attached translator,
  247. then you can find out via this command:&lt;code&gt;showtrans NODE&lt;/code&gt;. It will tell you what
  248. passive translators are set at a filesystem node.&lt;/p&gt;&lt;p&gt;Let's take a walk through some basic Hurd translators.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;settrans [OPTIONS...] NODE [TRANSLATOR ARGS...]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For example, I can have a text file like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat ~/Documents/hello.txt
  249. boring text document.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s set the &lt;code&gt;hello&lt;/code&gt; translator on that filesystem node.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;settrans -a ~/Documents/hello.txt /hurd/hello
  250. cat ~/Documents/hello.txt
  251. Hello, world!&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s see that the file system options are for the &lt;code&gt;/hurd/hello&lt;/code&gt;
  252. translator:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;fsysopts ~/Documents/hello.txt
  253. /hurd/hello --contents='Hello, world!
  254. '&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I can modify the &lt;code&gt;contents&lt;/code&gt; of the hello translator via:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;fsysopts ~/Documents/hello.txt --contents=&amp;quot;Hello Joshua
  255. &amp;quot;
  256. cat ~/Documents/hello.txt
  257. Hello Joshua&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice that we changed the options for that translator without having
  258. to restart it with normal user privledges.&lt;/p&gt;&lt;p&gt;Now let’s make the hello translator go away:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;settrans -a ~/Documents/hello.txt
  259. cat ~/Documents/hello.txt
  260. boring text document.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s try to stack these translators eh?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;settrans gnucode.me /hurd/httpfs http://gnucode.me
  261. ls gnucode.me/installing-wordpress.html
  262. gnucode.me/installing-wordpress.html
  263. settrans -c xml /hurd/xmfls ~/gnucode.me/feed.xml
  264. cd
  265. ls&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here the ls command apparently hanged. &lt;code&gt;C-c&lt;/code&gt; ended said hanging, but
  266. the Hurd locked up on me. I actually saw an error message that said
  267. something like “kbd queue full.” And then my keyboard become
  268. unresponsive. After a few hours, I pressed “Ctrl-Alt-Del,” and that
  269. saved my bacon. That killed the hurd console, and it let me switch to
  270. a virtual console. That enabled me to shut down the hurd gracefully.
  271. BUT…What went wrong? Why did &lt;code&gt;ls&lt;/code&gt; hang?&lt;/p&gt;&lt;p&gt;Well here is a clue:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ls ~/gnucode.me/feed.xml
  272. ls: cannot access feed.xml': No such file or directory&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well, httpfs does not expose feed.xml. It does not recognize that as part of the
  273. gnucode.me website. &lt;code&gt;httpfs&lt;/code&gt; only lists webpages that are listed on
  274. &lt;code&gt;index.html&lt;/code&gt;. So &lt;code&gt;~/gnucode.me/feed.xml&lt;/code&gt; does not translate to the local the
  275. filesystem. If I had to guess, I would say that xmlfs tries to run but does not
  276. check if its underlying file exists.&lt;/p&gt;&lt;p&gt;I should also mention that I am using a very minimal &lt;code&gt;.emacs.d/init.el&lt;/code&gt;. It is
  277. possible to get doom emacs to run on the Hurd, but the last time that I tried
  278. it, emacs locked up on me. I was forced to do a hard shutdown, which resulted in
  279. filesystem corruption and I had to re-install. So for now, I am using a very
  280. simple and minimal emacs. You can actually install some emacs packages via apt.
  281. Just search for &lt;code&gt;apt search magit&lt;/code&gt; to get you started.&lt;/p&gt;&lt;p&gt;I would like to try running i3 on the hurd at some point, because that
  282. is a very light-weight window manager, but I have not yet tried
  283. setting up X to run. Partly because I only have 1.5GB of RAM, and I
  284. have heard that X tends to lock up or be really slow on the Hurd.&lt;/p&gt;&lt;p&gt;Surprizingly the Hurd only uses about &lt;code&gt;161MB&lt;/code&gt; of RAM, when I run emacs
  285. on the console.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;What I have done so far&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Emacs
  286. I would love to remap control and caps, but I am not certain how
  287. to do that in the console.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Irc (via Erc)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Gnus my email client
  288. But I still need to set up the ability to send email.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Packages to install (glibc-doc-reference) requires enabling non-free
  289. packages:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# apt install gnupg emacs surfraw msmtp glibc-doc glibc-doc-reference&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Trying to create/open a file in emacs that ends in *.gpg crashes
  290. Emacs. I have no idea why.&lt;/p&gt;&lt;p&gt;Currently, msmtp cannot securely send email, because it cannot decrypt
  291. the encrypted file that has my password.&lt;/p&gt;&lt;p&gt;My Hurd machine also has my “jbranso@dismail.de” gpg key. I was able
  292. to import the data via an ssh session.&lt;/p&gt;&lt;p&gt;I was actually surprized that the debian wiki mentioned this command:
  293. &lt;code&gt;service ssh restart&lt;/code&gt; and not a systemd specific command, but
  294. apparently &lt;code&gt;man service&lt;/code&gt; is the manual that I want to read.
  295. Apparently ssh is already running. I verified this with:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;echo $pw1 | sudo -S service --status-all | grep ssh
  296. [ + ] ssh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I really should set up Sergey's terrible MDNS responder, so that I can ssh in
  297. the Hurd more easily, but that is a task that I will set for a later date. I
  298. should also possibly update my hard drive to a larger drive. I think the current
  299. one has 100GB or so. Maybe less. And it might not be a bad idea to set up an SSD
  300. or DVD drive via the CD-ROM bay and try the rumpdisk out. I would also like to
  301. be able to publish my blog from the Hurd too, but I have been unsuccessful to
  302. install Haunt on my Hurd box. I should also try to install Guix on it, but I am
  303. concerned about hard drive space at the moment.&lt;/p&gt;&lt;p&gt;Anyway, you can take a look at my &lt;a href=&quot;https://notabug.org/jbranso/hurd-home&quot;&gt;hurd
  304. home&lt;/a&gt; git directory if you like. Safe
  305. travels!&lt;/p&gt;</content></entry><entry><title>Setting up Chimera Linux</title><id>https://gnucode.me/setting-up-chimera-linux.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-08-09T11:59:00Z</updated><link href="https://gnucode.me/setting-up-chimera-linux.html" rel="alternate" /><content type="html">&lt;p&gt;My friend ownes a &lt;a href=&quot;https://www.raptorcs.com/TALOSII/&quot;&gt;Talos II&lt;/a&gt;, and he wanted some help setting it up. We have
  306. decided on setting up &lt;a href=&quot;https://chimera-linux.org/&quot;&gt;Chimera Linux&lt;/a&gt;. Since Chimera Linux is new, we also installed the guix package manager as well. This blog post today is more of documentation and less story telling. You have been warned.&lt;/p&gt;&lt;h1&gt;upgrading chimera linux&lt;/h1&gt;&lt;pre&gt;&lt;code&gt;doas apk update
  307. doas apk upgrade&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;DONE Getting X applications and gdm to run on chimera&lt;/h1&gt;&lt;p&gt;All Talos II machines have trouble running X, when a discrete GPU is installed.
  308. Basically the Talos II has an on board GPU, which when combined with an AMD GPU,
  309. X does not know which GPU to use. &lt;a href=&quot;https://wiki.raptorcs.com/wiki/Troubleshooting/GPU#Xorg_will_not_start_.2F_crashes_when_a_discrete_GPU_is_installed&quot;&gt;click here&lt;/a&gt; to read more on the raptor wiki.&lt;/p&gt;&lt;p&gt;I did have trouble getting my friend’s Talos II to start gdm and X, but an
  310. update to chimera linux fixed the gdm issue. The below sections are for others
  311. that are using a Talos II with an AMD GPU. You do need to configure X to
  312. disable the onboard GPU and/or tell GDM to select a GPU at runtime.&lt;/p&gt;&lt;h2&gt;raptor pdf user’s guide:&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://wiki.raptorcs.com/w/images/e/e3/T2P9D01_users_guide_version_1_0.pdf&quot;&gt;https://wiki.raptorcs.com/w/images/e/e3/T2P9D01_users_guide_version_1_0.pdf&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;raptor wiki ways to fix this&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Tell GDM to ignore a GPU&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In this case ignore the crappy onboard GPU.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; lspci | grep VGA
  313. 0005:02:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics Family (rev 41)
  314. 0030:01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Ellesmere [Radeon Pro WX 7100]
  315. cat /etc/udev/udev.conf
  316. # see udev.conf(5) for details
  317. #
  318. # udevd is also started in the initrd. When this file is modified you might
  319. # also want to rebuild the initrd, so that it will include the modified configuration.
  320. #udev_log=info
  321. #children_max=
  322. #exec_delay=
  323. #event_timeout=180
  324. #timeout_signal=SIGKILL
  325. #resolve_names=early
  326. TAG-=&amp;quot;seat&amp;quot;, ENV{ID_FOR_SEAT}==&amp;quot;drm-pci-0005_02_00_0&amp;quot;
  327. TAG-=&amp;quot;seat&amp;quot;, ENV{ID_FOR_SEAT}==&amp;quot;graphics-pci-0005_02_00_0&amp;quot;
  328. Do this to re-generate the initramfs.
  329. `doas apk fix linux-lts`&lt;/code&gt;&lt;/pre&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Xorg will not start / crashes when a discrete GPU is installed&lt;/p&gt;&lt;p&gt;We chose to do the workaround 2: select a desired GPU at runtime, which means
  330. that if we change the slot of the GPU, then we will have to re-create the Xorg
  331. configuration file.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;lspci | grep VGA
  332. 0005:02:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics Family (rev 41)
  333. 0030:01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Ellesmere [Radeon Pro WX 7100]
  334. cat /etc/X11/xorg.conf.d/21-gpu-driver.conf
  335. # AST2500
  336. Section &amp;quot;Device&amp;quot;
  337. Identifier &amp;quot;GPU0&amp;quot;
  338. Driver &amp;quot;modesetting&amp;quot;
  339. BusID &amp;quot;PCI:2@5:0:0&amp;quot;
  340. VendorName &amp;quot;ASpeed Corporation&amp;quot;
  341. EndSection
  342. # WX7100
  343. Section &amp;quot;Device&amp;quot;
  344. Identifier &amp;quot;GPU1&amp;quot;
  345. Driver &amp;quot;modesetting&amp;quot; # or amdgpu if you have xf86-video-amdgpu installed
  346. BusID &amp;quot;PCI:1@48:0:0&amp;quot;
  347. VendorName &amp;quot;AMD Corporation&amp;quot;
  348. EndSection
  349. # this is absolutely necessary, it tells xorg which GPU to use for the screen
  350. Section &amp;quot;Screen&amp;quot;
  351. Identifier &amp;quot;Screen0&amp;quot;
  352. Device &amp;quot;GPU1&amp;quot;
  353. EndSection&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;upgrade the openBMC bios/firmware and disable onboard GPU via&lt;/p&gt;&lt;p&gt;I decided not to do this one. It's way too complicated. See the raptor wiki if you don't believe me.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;Where to find X logs&lt;/h2&gt;&lt;p&gt;&lt;em&gt;var/log/gdm/greeter.log
  354. /var/lib/gdm&lt;/em&gt;.local/share/xorg/Xorg.1.log&lt;/p&gt;&lt;h2&gt;toggling gdm to use X/wayland&lt;/h2&gt;&lt;p&gt;This does not appear to work.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /etc/gdm/custom.conf | grep 'Wayland'
  355. #WaylandEnable=false
  356. WaylandEnable=true&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;DONE install icewm, and put that in ~/.xinitrc &amp;amp; startx&lt;/h2&gt;&lt;p&gt;Originally this did not work, because X refused to start. But after I upgraded
  357. Chimera linux one day, it worked.&lt;/p&gt;&lt;h1&gt;Setting up Bitcoin knots/bitcoin core&lt;/h1&gt;&lt;p&gt;My friend is an avid bitcoin user. He wanted me to help him set up bitcoin on
  358. his Talos II. If possible, he wanted me to set up bitcoin-knots, which was
  359. forked from bitcoin-core.&lt;/p&gt;&lt;h2&gt;github repo for bitcoin-knots&lt;/h2&gt;&lt;p&gt;The github repo has lots of good information to help me out:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://bitcoinknots.org/#download&quot;&gt;https://bitcoinknots.org/#download&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/bitcoinknots/bitcoin&quot;&gt;https://github.com/bitcoinknots/bitcoin&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/bitcoinknots/bitcoin/tree/23.x-knots/doc&quot;&gt;https://github.com/bitcoinknots/bitcoin/tree/23.x-knots/doc&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/bitcoinknots/bitcoin/blob/23.x-knots/doc/build-unix.md&quot;&gt;https://github.com/bitcoinknots/bitcoin/blob/23.x-knots/doc/build-unix.md&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/bitcoinknots/bitcoin/blob/23.x-knots/doc/build-freebsd.md&quot;&gt;https://github.com/bitcoinknots/bitcoin/blob/23.x-knots/doc/build-freebsd.md&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/bitcoinknots/bitcoin/blob/23.x-knots/doc/dependencies.md&quot;&gt;https://github.com/bitcoinknots/bitcoin/blob/23.x-knots/doc/dependencies.md&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I can get help from webchat.freenode.net #bitcoin-dev&lt;/p&gt;&lt;p&gt;luke-jr says that I can compile bitcoin knots from source fairly easily.&lt;/p&gt;&lt;p&gt;download a release. Install dependencies:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://download.qt.io/official_releases/qt/&quot;&gt;https://download.qt.io/official_releases/qt/&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;doas apk add libevent &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;./configure gmake &amp;amp;&amp;amp; gmake check &amp;amp;&amp;amp; gmake install&lt;/code&gt;&lt;/p&gt;&lt;h2&gt;NO Packaging bitcoin knots for chimera linux&lt;/h2&gt;&lt;p&gt;q66 is NOT ok with me packaging bitcoin-coin for chimera linux, because it
  360. depends on qt5, which is soon to be replaced by qt6. So why bother packaging
  361. qt5 when qt6 is soon to supplant it?&lt;/p&gt;&lt;p&gt;This is the documentation for packaging in chimera.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/chimera-linux/cports&quot;&gt;https://github.com/chimera-linux/cports&lt;/a&gt;
  362. &lt;a href=&quot;https://github.com/chimera-linux/chimerautils&quot;&gt;https://github.com/chimera-linux/chimerautils&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Alternatively I can package bitcoin knots for guix and install&lt;/h2&gt;&lt;p&gt;guix on chimera linux. And guix already has qt packaged. Do they have
  363. 5.15.2 packaged? Why yes they do: They have qtbase version 5.15.8.&lt;/p&gt;&lt;p&gt;I have not packaged bitcoin-knots for guix yet. Instead my friend decided to
  364. run bitcoin-core.&lt;/p&gt;&lt;h2&gt;DONE Or I can just install bitcoin-core from guix and run that&lt;/h2&gt;&lt;h1&gt;guix stuff&lt;/h1&gt;&lt;h2&gt;installing guix on chimera linux&lt;/h2&gt;&lt;p&gt;You can install guix via these commands:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh
  365. doas chmod u+x guix-install.sh
  366. doas ./guix-install.sh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Add in the export line so I can use the guix binaries.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat ~/.profile
  367. #!/usr/bin/bash
  368. export GUIX_LOCPATH=&amp;quot;$HOME/.guix-profile/lib/locale&amp;quot;
  369. gnome-shell --wayland&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;starting the guix daemon manually&lt;/h2&gt;&lt;pre&gt;&lt;code&gt; ~root/.config/guix/current/bin/guix-daemon &amp;amp;#x2013;build-users-group=guixbuild&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;set up guix daemon via dinit&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;cat /etc/dinit.d/guix-daemon
  370. # guix-daemon service
  371. type = process
  372. # run this command as root
  373. run-as = root
  374. command = /root/.config/guix/current/bin/guix-daemon --build-users-group=guixbuild
  375. # depends-on = bar
  376. # waits-for = baz
  377. # uncomment this next line once you know this works
  378. # before = login.target
  379. before = network.target&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://davmac.org/projects/dinit/man-pages-html/dinitcheck.8.html&quot;&gt;https://davmac.org/projects/dinit/man-pages-html/dinitcheck.8.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://davmac.org/projects/dinit/man-pages-html/dinit-service.5.html&quot;&gt;https://davmac.org/projects/dinit/man-pages-html/dinit-service.5.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;So if you cannot get the daemon to autostart, then this will&lt;/p&gt;&lt;p&gt;&lt;code&gt;doas dinitctl start guix-daemon&lt;/code&gt; work.&lt;/p&gt;</content></entry><entry><title>Afterboot OpenBSD</title><id>https://gnucode.me/afterboot-openbsd.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-04-28T23:00:00Z</updated><link href="https://gnucode.me/afterboot-openbsd.html" rel="alternate" /><content type="html">&lt;h1&gt;set up doas&lt;/h1&gt;&lt;p&gt;Let’s make any user that is in the group “wheel” able to execute privledged
  380. commands.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# cat /etc/examples/doas.conf | sed 's/keepenv/persist keepevn/' &amp;gt; /etc/doas.conf&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;install packages&lt;/h1&gt;&lt;pre&gt;&lt;code&gt;# pkg_add emacs dino netsurf dino git fish mpv firefox gpg \
  381. hack-fonts pkg_add isync evince libreoffice xfce4-terminal \
  382. xfce4-screenshooter xfce4-dict i3&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When I installed isync, I got a message that said,
  383. the following rcscripts were installed: /etc/rc.d/saslauthd
  384. apparently openbsd’s packaged isync, lets you set up a daemon to periodically
  385. fetch your email. looking at the file, I’m not sure what it is.&lt;/p&gt;&lt;p&gt;Well I could list all of the packages that I minually installed, it is actually
  386. much easier to create a list of packages.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;pkg_info -mz | tee openbsd-pkg-list&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, when I want to re-install those packages I can just do this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# pkg_add -l list&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;clone my various repos&lt;/h1&gt;&lt;pre&gt;&lt;code&gt;cd ~/
  387. git clone https://notabug.org/jbranso/prog
  388. cd prog
  389. mkdir -p gnu/guix/
  390. cd gnu/guix
  391. git clone https://notabug.org/jbranso/guix
  392. mv guix guix-src
  393. git clone https://notabug.org/jbranso/guix-config&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;update my OpenBSD install&lt;/h1&gt;&lt;p&gt;&lt;code&gt;# doas syspatch&lt;/code&gt;&lt;/p&gt;&lt;h1&gt;enable softupdates&lt;/h1&gt;&lt;p&gt;Unless you are using really old ancient hardware, you should enable softupdates.&lt;/p&gt;&lt;p&gt;change&lt;/p&gt;&lt;p&gt;&lt;code&gt;43434930490.a / ffs rw 1 1&lt;/code&gt;&lt;/p&gt;&lt;p&gt;to&lt;/p&gt;&lt;p&gt;&lt;code&gt;43434930490.a / ffs rw,softdep 1 1&lt;/code&gt;&lt;/p&gt;&lt;h1&gt;window manager stuff&lt;/h1&gt;&lt;h2&gt;modify my ~/.xsession&lt;/h2&gt;&lt;p&gt;auto start xfce, prefer utf-8, set up a background color, and lock X after some
  394. inactivity.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat ~/.xsession
  395. # prefer UTF-8 whenever possible
  396. export LC_CTYPE=&amp;quot;en_US.UTF-8&amp;quot;
  397. # use UTF-8 everywhere
  398. export LANG=en_US.UTF-8
  399. # specify location of kshrc
  400. export ENV=$HOME/.kshrc
  401. # set your background color
  402. xsetroot -solid dimgray
  403. xidle -delay 5 -sw -program &amp;quot;/usr/X11R6/bin/xlock -mode flag&amp;quot; \
  404. -timeout 300
  405. exec i3&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;set up polybar for i3&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://forum.endeavouros.com/t/tutorial-easy-setup-endeavour-xfce-i3-tiling-window-manager/13171&quot;&gt;https://forum.endeavouros.com/t/tutorial-easy-setup-endeavour-xfce-i3-tiling-window-manager/13171&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# doas pkg_add polybar
  406. $ mkdir ~/.config/polybar
  407. $ cp /usr/local/share/examples/polybar/config ~/.config/polybar&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This &lt;a href=&quot;https://github.com/polybar/polybar/wiki/Fonts&quot;&gt;wiki page&lt;/a&gt; has a lot of details about setting up fonts.&lt;/p&gt;&lt;p&gt;More information is in my &lt;a href=&quot;https://notabug.org/jbranso/openbsd-home/src/master/.config/polybar&quot;&gt;polybar config&lt;/a&gt;.&lt;/p&gt;&lt;h1&gt;If this is a laptop with a battery, then install this&lt;/h1&gt;&lt;p&gt;&lt;a href=&quot;https://dataswamp.org/~solene/2022-03-21-openbsd-cool-frequency.html&quot;&gt;https://dataswamp.org/~solene/2022-03-21-openbsd-cool-frequency.html&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# doas pkg_add obsdfreqd
  408. # rcctl enable obsdfreqd
  409. # rcctl stop apmd
  410. # rcctl disable apmd
  411. # rcctl start obsdfreqd&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;set up doom emacs&lt;/h1&gt;&lt;p&gt;(I also need to ensure that &lt;code&gt;~/prog/gnu/guix/&lt;/code&gt; exists because my emacs looks for
  412. some guix snippets).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git clone --depth 1 https://github.com/doomemacsdoomemacs ~/.config/emacs
  413. ~/.config/emacs/bin/doom install&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;add doom emacs to path&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat ~/.profile
  414. # $OpenBSD: dot.profile,v 1.8 2022/08/10 07:40:37 tb Exp $
  415. #
  416. # sh/ksh initialization
  417. #
  418. PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/home/joshua/.config/emacs/bin
  419. export PATH HOME TERM&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;copy my ~/ config files&lt;/h1&gt;&lt;p&gt;cp .authinfo.gpg, .ssh, .mbsyncrc, .gnupg/&lt;/p&gt;&lt;p&gt;cp documents to ~/&lt;/p&gt;&lt;h1&gt;import my gpg keys from my usb stick.&lt;/h1&gt;&lt;p&gt;&lt;code&gt;gpg --import ./dismail.de.gpg.key.asc&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;git config --global commit.gpgsign true&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;gpg --list-secret-keys --keyid-format=long&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Copy the really long alphanumeric word from the above command. It'll
  420. look something like:&lt;/p&gt;&lt;p&gt;62A42A3CC13497D626FZ686C750BCFEF3A5E1572&lt;/p&gt;&lt;p&gt;&lt;code&gt;git config --global user.signingkey &amp;lt;your alphanumeric word&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;h2&gt;set up pinentry&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;pkg_add pinentry-dmenu&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are two things that you need to do to set up pinentry-dmenu, so that when I
  421. need to sign commits or decrypt stuff, the pinentry-dmenu popup happens.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;set up gpg agent&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat ~/.gnupg/gpg-agent.conf
  422. pinentry-program /usr/local/bin/pinentry-dmenu
  423. default-cache-ttl 3600&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;man gpg-agent&lt;/code&gt; says to do this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;You should always add the following lines to your .bashrc or whatever
  424. initialization file is used for all shell invocations:
  425. cat ~/.profile | grep GPG_TTY
  426. GPG_TTY=$(tty)
  427. export GPG_TTY&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;start a dbus session&lt;/p&gt;&lt;p&gt;This is only needed if you want to use pinentry-gnome3&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat ~/.xsession | grep dbus
  428. # start a dbus session, which I believe gpg needs to for graphical pinentry
  429. # I found this command in /usr/local/share/doc/pkg-readmes/dbus
  430. if [ -x /usr/local/bin/dbus-launch -a -z &amp;quot;${DBUS_SESSION_BUS_ADDRESS}&amp;quot; ]; then
  431. eval `dbus-launch --sh-syntax --exit-with-x11`&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If you have difficulty getting pinentry to work, here are some steps to
  432. manually get pinentry to work:&lt;/p&gt;&lt;p&gt;in a fish terminal a type in:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gpgconf --kill gpg-agent
  433. set GPG_TTY $(tty)
  434. export GPG_TTY
  435. git commit -m &amp;quot;my commit message&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;change &lt;code&gt;/etc/motd&lt;/code&gt;&lt;/h1&gt;&lt;p&gt;I once set an invalid option up in /etc/fstab that threw me in a root shell with
  436. only root mounted. All of a sudden vi would not work. That below command is
  437. how to fix it: &lt;code&gt;export TERM=vt200&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /etc/motd
  438. OpenBSD 7.2 (GENERIC.MP) #7: Sat Feb 25 14:07:58 MST 2023
  439. Welcome to OpenBSD: The proactively secure Unix-like operating system.
  440. Please use the sendbug(1) utility to report bugs in the system.
  441. Before reporting a bug, please try to reproduce it with the latest
  442. version of the code. With bug reports, please try to ensure that
  443. enough information to reproduce the problem is enclosed, and if a
  444. known fix for it exists, include that as well.
  445. If you are having trouble using vi in the console try this:
  446. export TERM=vt200;&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;install haunt on OpenBSD&lt;/h1&gt;&lt;p&gt;&lt;code&gt;doas pkg_add guile info&lt;/code&gt;&lt;/p&gt;&lt;p&gt;First install guile-commonmark:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ cd ~/prog/guile
  447. $ git clone git clone https://github.com/OrangeShark/guile-commonmark
  448. $ cd guile-commonmark
  449. # export AUTOCONF_VERSION=2.71
  450. # export export AUTOMAKE_VERSION=1.16.5
  451. # doas pkg_add autoconf automake&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Why am I seeing 2 aclocal binaries? No idea.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ls /usr/local/bin/aclocal*
  452. ls /usr/local/bin/automake*
  453. /usr/local/bin/aclocal
  454. /usr/local/bin/aclocal-1.16
  455. /usr/local/bin/automake
  456. /usr/local/bin/automake-1.16&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Arsen on irc helped me figure out the next incantation.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;AUTOMAKE=automake-1.16 ACLOCAL=aclocal-1.16 ./bootstrap
  457. ./configure
  458. make
  459. make check
  460. # make install&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s install haunt&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git clone https://git.dthompson.us/haunt.git
  461. cd haunt
  462. AUTOMAKE=automake-1.16 ACLOCAL=aclocal-1.16 ./bootstrap
  463. ./configure
  464. make
  465. make check
  466. # make install&lt;/code&gt;&lt;/pre&gt;</content></entry><entry><title>OpenBSD's hotplugd rocks!</title><id>https://gnucode.me/openbsds-hotplugd-rocks.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-04-13T11:41:00Z</updated><link href="https://gnucode.me/openbsds-hotplugd-rocks.html" rel="alternate" /><content type="html">&lt;p&gt;My last post talked about how I broke my OpenBSD laptop by telling OpenBSD that
  467. my usbstick was essential to the boot process, and then, when I booted the
  468. laptop, I did not have that usb stick mounted. That caused some problems. I
  469. since learned that the preferred way of automounting a usb stick under OpenBSD
  470. is with &lt;code&gt;hotplugd&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://man.openbsd.org/hotplugd&quot;&gt;hotplugd&lt;/a&gt; is OpenBSD’s automounting functionality, and it’s actually super simple
  471. and easy. Just put your scripts at &lt;code&gt;/etc/hotplugd/attach&lt;/code&gt; and
  472. &lt;code&gt;/etc/hotplugd/detach&lt;/code&gt;. And the man page gives you an example shell script, but
  473. since I am not a big fan of &lt;code&gt;sh&lt;/code&gt; (its syntax is confusing), I decided to write
  474. my attach script in &lt;a href=&quot;https://www.gnu.org/software/guile/&quot;&gt;GNU Guile&lt;/a&gt;. Writing that script made me want to write more
  475. scripts in &lt;a href=&quot;https://scsh.net/&quot;&gt;scheme shell&lt;/a&gt;, but I the last time I tried to install the scheme shell
  476. on OpenBSD, it failed to compile.&lt;/p&gt;&lt;p&gt;Anyway, it is really easy to write your own script. &lt;code&gt;hotplugd&lt;/code&gt; will call your
  477. script like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;attach &amp;lt;number&amp;gt; &amp;lt;label&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;code&gt;&amp;lt;number&amp;gt;&lt;/code&gt; is one of the numbers in the table below and &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is a
  478. short descriptive string of the device.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;|---+------------------------------------|
  479. | 0 | generic, no special info |
  480. |---+------------------------------------|
  481. | 1 | CPU (carries resource utilization) |
  482. |---+------------------------------------|
  483. | 2 | disk drive |
  484. |---+------------------------------------|
  485. | 3 | network interface |
  486. |---+------------------------------------|
  487. | 4 | tape device |
  488. |---+------------------------------------|
  489. | 5 | serial line interface |
  490. |---+------------------------------------|&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I am only really interested in &lt;code&gt;2&lt;/code&gt; and &lt;code&gt;3&lt;/code&gt;. Here is how I debbuged my attach
  491. script, and you can easily do the same.&lt;/p&gt;&lt;p&gt;First find out what &lt;code&gt;sd&lt;/code&gt; device your usb stick is. Before you put in your usb
  492. stick type in:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sysctl hw.disknames
  493. hw.disknames=sd0:ec557d42f5cbfa41,sd1:5583d235b610c8a2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now put in your usb stick and run the same command.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sysctl hw.disknames
  494. hw.disknames=sd0:ec557d42f5cbfa41,sd1:5583d235b610c8a2,sd2:&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So now I know that my usb stick is sd2. Let’s do a disklabel command on it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# disklabel sd2
  495. # /dev/rsd2c:
  496. type: SCSI
  497. disk: SCSI disk
  498. label: USB Flash Drive
  499. duid: 0000000000000000
  500. flags:
  501. bytes/sector: 512
  502. sectors/track: 63
  503. tracks/cylinder: 255
  504. sectors/cylinder: 16065
  505. cylinders: 1887
  506. total sectors: 30326784
  507. boundstart: 0
  508. boundend: 30326784
  509. 16 partitions:
  510. # size offset fstype [fsize bsize cpg]
  511. c: 14.5G 0 unused
  512. i: 14.5G 2048 MSDOS&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice from the output that this label is “USB Flash Drive”. That is the label
  513. that hotplugd will send to your attach script.&lt;/p&gt;&lt;p&gt;If you want a usb stick that is read-able/writeable accross all operating
  514. systems, currently you will want to use the &lt;a href=&quot;https://wiki.archlinux.org/title/FAT&quot;&gt;vfat&lt;/a&gt; filesystem. That is what the
  515. output above shows. The &lt;code&gt;fstype&lt;/code&gt; of &lt;code&gt;MSDOS&lt;/code&gt; is a vfat filesystem. This usb stick
  516. is what I will use when I want to copy data between different OS-es (I do want
  517. an &lt;a href=&quot;https://www.openbsd.org/faq/faq14.html#softraidCrypto&quot;&gt;encrypted OpenBSD-specific usb stick&lt;/a&gt; to store my gpg keys, but I have not yet
  518. set that up). According to some of the smart people on the &lt;code&gt;#openbsd&lt;/code&gt; irc
  519. channel, if you have such a usb stick, then the &lt;code&gt;i&lt;/code&gt; filesystem partition is the
  520. one that you want to mount to read the data. And we see that above as well (&lt;code&gt;c&lt;/code&gt;
  521. is code for the whole drive. &lt;code&gt;/dev/rsd2c&lt;/code&gt; is how you access the whole and raw
  522. disk).&lt;/p&gt;&lt;p&gt;Ok, so now that you know what arguments that &lt;code&gt;hotplugd&lt;/code&gt; will send your script,
  523. go ahead and write your basic script. It probably won’t be perfect, which is ok.
  524. To test it, type in &lt;code&gt;su&lt;/code&gt; in your terminal to get to root account, and then test
  525. your script in the exact same way that OpenBSD will use your script (&lt;code&gt;#&lt;/code&gt; means
  526. that you are currently the root user):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# ./attach 2 &amp;quot;USB Flash Drive&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You will probably get some weird errors, and that’s ok. After you have run your
  527. attach script, and it seemed to have no errors, verify that it properly mounted
  528. with:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mount
  529. /dev/sd1a on / type ffs (local, softdep)
  530. /dev/sd1k on /home type ffs (local, nodev, nosuid, softdep)
  531. /dev/sd1d on /tmp type ffs (local, nodev, nosuid, softdep)
  532. /dev/sd1f on /usr type ffs (local, nodev, softdep)
  533. /dev/sd1g on /usr/X11R6 type ffs (local, nodev, softdep)
  534. /dev/sd1h on /usr/local type ffs (local, nodev, wxallowed, softdep)
  535. /dev/sd1j on /usr/obj type ffs (local, nodev, nosuid, softdep)
  536. /dev/sd1i on /usr/src type ffs (local, nodev, nosuid, softdep)
  537. /dev/sd1e on /var type ffs (local, nodev, nosuid, softdep)
  538. /dev/sd2i on /mnt/usb type msdos (local, nodev, noexec)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And it look like I properly mounted my usb stick (the last line says it was).&lt;/p&gt;&lt;p&gt;One thing that users might find confusing is that OpenBSD passes in &lt;code&gt;2&lt;/code&gt;, but
  539. Guile accepted the &lt;code&gt;2&lt;/code&gt; as a string.&lt;/p&gt;&lt;p&gt;My simple &lt;a href=&quot;https://notabug.org/jbranso/prog/src/master/gnu/guile/scripts/attach&quot;&gt;attach script&lt;/a&gt; works for me. It will only auto mount vfat filesystems,
  540. and I am pretty sure that weird things will happen if I plug in two usb sticks
  541. at once, but it works.&lt;/p&gt;</content></entry><entry><title>Accidentally Deleting fstab</title><id>https://gnucode.me/accidentally-deleting-fstab.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-04-05T20:00:00Z</updated><link href="https://gnucode.me/accidentally-deleting-fstab.html" rel="alternate" /><content type="html">&lt;p&gt;The end of my previous blog post was a bit of a cliff hanger:&lt;/p&gt;&lt;p&gt;I did have a great time the next day. I was hoping to automount my usb
  542. stick on boot. So I added this beauty to my &lt;code&gt;/etc/fstab&lt;/code&gt;.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;sd1i /mnt/usb msdos rw 1 2&lt;/code&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The next time I booted it threw me into a rescue shell with only &lt;code&gt;/&lt;/code&gt; mounted.&lt;/p&gt;&lt;p&gt;This is the story of how I fixed a broken fstab on OpenBSD. The day began like
  543. any other. It was cold and dark as I arose to play with my new OpenBSD
  544. computer. It was time to reboot! That magical moment when OpenBSD &lt;a href=&quot;https://www.openbsd.org/innovations.html&quot;&gt;relinks the
  545. kernel at boot&lt;/a&gt;. How cool is that?&lt;/p&gt;&lt;p&gt;My admiration for this world class operating continues to rise as it boots, and
  546. OpenBSD proudly slaps me in the face (I did not write down the OpenBSD error
  547. message, but this is essentially what it said):&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;mount cannot find device sd1i. You are now in a resque shell.&lt;/p&gt;&lt;p&gt;root&amp;gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Hmmm. Well that’s a bummer. It looks like I had told OpenBSD that that usb stick
  548. was necesary for boot. I also did not have the usb stick plugged in, and OpenBSD
  549. needed me to write &lt;code&gt;/dev/sd1i&lt;/code&gt; not &lt;code&gt;sd1i&lt;/code&gt;. It might be a good project idea to
  550. add &lt;a href=&quot;https://man.openbsd.org/opendev&quot;&gt;opendev&lt;/a&gt; support to OpenBSD’s mount. Any takers?&lt;/p&gt;&lt;p&gt;Anyway, to fix this, I attempted to delete that last line from &lt;code&gt;/etc/fstab&lt;/code&gt;. I
  551. tried to type out &lt;code&gt;cd /etc/&lt;/code&gt;. Instead I got gibberish. Testing the keyboard a
  552. bit, I noticed that the keyboard was in the qwerty layout. I use dvorak. And my
  553. laptop keyboard physically shows a dvorak keyboard layout. It’s really hard to
  554. type correctly on a keyboard when pressing “‘,.pyf” is “qwerty”. Well let’s
  555. change my keyboard layout (notice that all commands below are run as the &lt;code&gt;root&lt;/code&gt;
  556. user. The &lt;code&gt;#&lt;/code&gt; means you are running as a root user).&lt;/p&gt;&lt;p&gt;I painstakingly typed out the following command.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# wsconctl keyboard.encoding=us.dvorak&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Awesome, that is an improvement. Let’s change &lt;code&gt;/etc/fstab&lt;/code&gt;. The following
  557. commands did not work, because the shell could not find the binary:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;nano /etc/fstab&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;vim /etc/fstab&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;vi /etc/fstab&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Well that’s weird. Is &lt;code&gt;/usr/bin&lt;/code&gt; not mounted?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# mount
  558. /dev/sd1a on / type ffs (ro)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Oh great! I only have &lt;code&gt;/&lt;/code&gt; mounted! So my commands are limited, and &lt;code&gt;/&lt;/code&gt; is
  559. mounted read only. So even if I find a text editor that I can use, I cannot
  560. modify &lt;code&gt;/etc/fstab&lt;/code&gt;. How do I mount &lt;code&gt;/&lt;/code&gt; read-write? According to the irc people
  561. who helped me out, this is how: you update the mount information based on what
  562. &lt;code&gt;/etc/fstab&lt;/code&gt; says.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# mount -uvw /
  563. # mount
  564. /dev/sd1a on / type ffs (rw)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Awesome, &lt;code&gt;fstab&lt;/code&gt; is editable! I tried to edit &lt;code&gt;/etc/fstab&lt;/code&gt; but &lt;code&gt;vi&lt;/code&gt; was not
  565. available, probably because &lt;code&gt;vi&lt;/code&gt; is located in &lt;code&gt;/usr&lt;/code&gt;, which is not yet mounted.&lt;/p&gt;&lt;p&gt;What I should have done was &lt;code&gt;mount -U&lt;/code&gt;. This just mounts all mount points
  566. listed in &lt;code&gt;/etc/fstab&lt;/code&gt;. I did not read that option in the manpage yet. So I
  567. decided to manually try to guess which filesytem was which.&lt;/p&gt;&lt;p&gt;Well let’s print out human read-able file sizes of my filesystem partitions and
  568. that will give me some clue which filesystem is which. (please note that I am
  569. intentionally removing the offsets).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# disklabel -h sd1
  570. 16 partitions:
  571. # size offset fstype [fsize bsize cpg]
  572. a: 1.0G 4.2BSD 2048 16384 12960
  573. b: 8.0G swap
  574. c: 931.5G unused
  575. d: 4.0G 4.2BSD 2048 16384 12960
  576. e: 19.5G 4.2BSD 2048 16384 12960
  577. f: 30.0G 4.2BSD 2048 16384 12960
  578. g: 1.0G 4.2BSD 2048 16384 12960
  579. h: 20.0G 4.2BSD 2048 16384 12960
  580. i: 3.0G 4.2BSD 2048 16384 12960
  581. j: 6.0G 4.2BSD 2048 16384 12960
  582. k: 300.0G 4.2BSD 4096 32768 26062&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok. Clearly the 300G is my &lt;code&gt;/home&lt;/code&gt;. I can mount that now.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# mount /dev/sd1k /home&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok. How do I mount &lt;code&gt;/usr&lt;/code&gt; so that I have text editors? I don’t really know which
  583. partition is which. I guess I will just guess. Eventually I did correctly mount
  584. &lt;code&gt;/usr&lt;/code&gt;, so now I should have access to some text editors! So now I could edit
  585. &lt;code&gt;fstab&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# vim /etc/fstab
  586. vim: unknown command&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok. vim is not installed. Let’s try vi.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# vi /etc/fstab
  587. vi: unknown terminal type&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So vi doesn’t run on the console? That’s odd. Ok. Lets see what &lt;code&gt;head&lt;/code&gt;
  588. shows me:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# head /etc/fstab
  589. 5583d235b610c8a2.a / ffs rw,softdep 1 1
  590. 5583d235b610c8a2.k /home ffs rw,softdep,nodev,nosuid 1 2
  591. 5583d235b610c8a2.d /tmp ffs rw,softdep,nodev,nosuid 1 2
  592. 5583d235b610c8a2.f /usr ffs rw,softdep,nodev 1 2
  593. 5583d235b610c8a2.g /usr/X11R6 ffs rw,softdep,nodev 1 2
  594. 5583d235b610c8a2.h /usr/local ffs rw,wxallowed,softdep,nodev 1 2
  595. 5583d235b610c8a2.j /usr/obj ffs rw,softdep,nodev,nosuid 1 2
  596. 5583d235b610c8a2.i /usr/src ffs rw,softdep,nodev,nosuid 1 2
  597. 5583d235b610c8a2.e /var ffs rw,softdep,nodev,nosuid 1 2
  598. 5583d235b610c8a2.b none swap sw&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hey would you look at that! There is no line with &lt;code&gt;/mnt/usb&lt;/code&gt;. I should be able
  599. to just overwrite &lt;code&gt;fstab&lt;/code&gt; with the output of &lt;code&gt;head&lt;/code&gt;. Please do NOT copy or
  600. execute the following command:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# head /etc/fstab &amp;gt; /etc/fstab&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I wish I had read the irc chat before I had executed the above command. In the
  601. words of a wise sage, “the redirection happens before head runs, so you’ll just
  602. get a blank file.” And that is exactly what happened. &lt;code&gt;/etc/fstab&lt;/code&gt; was empty.
  603. Now how do I mount filesystem partitions in the correct locations? “Out of the
  604. frying pan and into the fire.”&lt;/p&gt;&lt;p&gt;Some of the people on irc mentioned that &lt;code&gt;/var/backups&lt;/code&gt; should have a copy of my
  605. &lt;code&gt;fstab&lt;/code&gt;. Unfortunately, that backup command had not run yet. This was a fresh
  606. OpenBSD install afterall.&lt;/p&gt;&lt;p&gt;One of the people on the OpenBSD chat showed me this &lt;a href=&quot;https://github.com/openbsd/src/blob/master/sbin/disklabel/editor.c#L91&quot;&gt;link&lt;/a&gt;, which was super
  607. helpful, because it shows you the default size of the various partitions that
  608. the auto installer sets up. With that information, I was able to re-mount all my various
  609. partitions. Then someone on irc chat gave me this beauty of a command:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# mount | awk '{ print $1 &amp;quot; &amp;quot; $3 &amp;quot; &amp;quot; $5 &amp;quot; rw 0 0&amp;quot;}' &amp;gt; /etc/fstab&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That created my &lt;code&gt;fstab&lt;/code&gt; for me! Let’s check it out!&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# cat /etc/fstab
  610. sd1.a / ffs rw 1 1
  611. sd1.k /home ffs rw 1 2
  612. sd1.d /tmp ffs rw 1 2
  613. sd1.f /usr ffs rw 1 2
  614. sd1.g /usr/X11R6 ffs rw 1 2
  615. sd1.h /usr/local ffs rw 1 2
  616. sd1.j /usr/obj ffs rw 1 2
  617. sd1.i /usr/src ffs rw 1 2
  618. sd1.e /var ffs rw 1 2
  619. sd1.b none swap sw&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hmm, well the mount options are absent, and it is NOT using UIDs…But this
  620. should be enough to boot into a complete system. So I rebooted. Upon reboot, I
  621. was able to change the mount points to UIDs and copy the proper mount options
  622. from my desktop OpenBSD. I then very quickly set up &lt;a href=&quot;https://man.openbsd.org/hotplugd&quot;&gt;hotplugd&lt;/a&gt;, which I will
  623. explain next time. Until then!&lt;/p&gt;</content></entry><entry><title>Libreboot Full Disk encryption on OpenBSD</title><id>https://gnucode.me/libreboot-full-disk-encryption-on-openbsd.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-03-30T23:00:00Z</updated><link href="https://gnucode.me/libreboot-full-disk-encryption-on-openbsd.html" rel="alternate" /><content type="html">&lt;p&gt;So I previously talked about my &lt;a href=&quot;http://gnucode.me/installing-openbsd-on-a-vm.html&quot;&gt;interest&lt;/a&gt; &lt;a href=&quot;http://gnucode.me/dual-booting-openbsd-guix-system.html&quot;&gt;in OpenBSD&lt;/a&gt;. Well last week, I
  624. have been more and more impressed with OpenBSD, especially after watching
  625. &lt;a href=&quot;https://undeadly.org/cgi?action=article;sid=20230325163416&quot;&gt;Theo’s recent talk&lt;/a&gt;. I recently installed OpenBSD on my desktop, and I was
  626. satisfied. There are some things that I knew how to do on GNU Guix that I do not
  627. yet know how to do on OpenBSD. For example, there is a minor issue with the
  628. sound being a bit wonky but that is not a deal breaker.&lt;/p&gt;&lt;p&gt;A few days ago I switched to OpenBSD on my laptop. So now, with the exception of
  629. my PinePhone, all of my computing devices are using OpenBSD. The OpenBSD
  630. installer is getting support for autoencrypting your hard drive, but I wanted to
  631. document the manual set up process if I ever decide to set up a RAID+ecryption.
  632. I do not believe the installer will support RAID+encryption anytime soon.&lt;/p&gt;&lt;p&gt;The real problem was trying to get libreboot to even recognize the OpenBSD usb
  633. installer stick. The best method to boot OpenBSD on libreboot is to use the
  634. seaBIOS payload. I could NOT get this to work. I must have booted and rebooted
  635. 10+ times trying to get this to work. I even opened up a grub command line
  636. prompt, and it could not SEE the usb stick. &lt;a href=&quot;https://misc.openbsd.narkive.com/auaZDqBe/bsd-rd-fails-to-boot-up-on-libreboot-x200-how-to-find-out-why&quot;&gt;Others have reported this problem.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In grub you can get a feel for what partitions are available via:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;grub&amp;gt; ls
  637. (hd0) (hd0,msdos1)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This seems to only show my GNU/Linux Guix System partition. That’s not a good
  638. sign. There is another way to check. I can type out the following
  639. &lt;code&gt;set root=(hd0,msdos1)/&lt;/code&gt;&lt;/p&gt;&lt;p&gt;and then press TAB:&lt;/p&gt;&lt;p&gt;I was able to see &lt;code&gt;/bin&lt;/code&gt;, &lt;code&gt;/boot&lt;/code&gt;, &lt;code&gt;/etc&lt;/code&gt;, etc. Going into &lt;code&gt;/var&lt;/code&gt;, I saw
  640. &lt;code&gt;guix/&lt;/code&gt;. So clearly &lt;code&gt;hd0&lt;/code&gt; is my current SSD that has GNU/Linux Guix System. And
  641. grub and libreboot did NOT see the OpenBSD usb stick. I kept rebooting, tried
  642. searching for the OpenBSD stick, and finally the grub console showed me
  643. something other than &lt;code&gt;(hd0,msdos1)&lt;/code&gt;. I think I have to use the right-most usb
  644. port. I think that is the secret.&lt;/p&gt;&lt;p&gt;Technically, &lt;a href=&quot;https://notabug.org/swiftgeek/libreboot/src/master/docs/bsd/openbsd.md&quot;&gt;grub can boot
  645. OpenBSD&lt;/a&gt;,
  646. at least grub as packaged by Libreboot, but that is NOT advisable. And grub's
  647. ability to boot OpenBSD may disappear at any moment. Seeing no other option, I
  648. typed in this command to boot OpenBSD via grub:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;grub&amp;gt; kopenbsd (usb0)/7.2/amd64/bsd.rd
  649. grub&amp;gt; boot&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And OpenBSD started booting! Woo hoo! At the OpenBSD installer I typed in “s”
  650. to exit to the shell so that I could set up full disc encryption.&lt;/p&gt;&lt;p&gt;Before we get to the disc encryption, let me give a quick overview of how
  651. OpenBSD sets up partitions. OpenBSD supports both MBR and GPT partitions, which
  652. divide the physical disc into sections (MBR is old; GPT is the modern way to do
  653. it, and most people will want GPT on newer machines so for the rest of this blog
  654. post I will just talk about GPT). All operating systems recognize and use GPT
  655. partitions. Linux will install its filesystem partitions into seperate GPT
  656. partitions, which means that a &amp;quot;partition&amp;quot; in Linux means the GPT
  657. partition and the filesystem partion. Here's a handy graphic:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;|--------------+------------+----------------|
  658. | | Linux | |
  659. |--------------+------------+----------------|
  660. | GPT partiton | filesystem | mount location |
  661. | | partition | |
  662. |--------------+------------+----------------|
  663. | /dev/sda1 | ext4 | / |
  664. | /dev/sda2 | btrfs | /etc |
  665. | /dev/sda3 | xfs | /boot |
  666. | ... | ... | ... |
  667. | /dev/sda128 | vfat | /boot/efi |
  668. | | | |
  669. | /dev/sdb1 | ext4 | /data |
  670. |--------------+------------+----------------|&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;OpenBSD is a little different. It uses one big GPT partition, and then it
  671. further splits up that one big GPT partition into filesystem partitions, which
  672. can be examined via &lt;a href=&quot;https://man.openbsd.org/disklabel&quot;&gt;disklabel&lt;/a&gt;. So in
  673. OpenBSD &lt;code&gt;sd0&lt;/code&gt; and &lt;code&gt;sd1&lt;/code&gt; refer to the first and second hard drive. &lt;code&gt;/dev/sd0c&lt;/code&gt;
  674. refers to the one big GPT partition and &lt;code&gt;/dev/sd0a&lt;/code&gt; by convention is the &lt;code&gt;/&lt;/code&gt;
  675. partition. &lt;code&gt;/dev/sd0b&lt;/code&gt; is swap by convention and &lt;code&gt;d&lt;/code&gt; through &lt;code&gt;p&lt;/code&gt; could refor to
  676. any other arbitrary mount point. So &amp;quot;partition&amp;quot; in OpenBSD may refer to the GPT
  677. partion or the filesystem partitions.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;|--------------+-------------+----------------|
  678. | | OpenBSD | |
  679. |--------------+-------------+----------------|
  680. | GPT partiton | filesystem | mount location |
  681. | | partition | |
  682. | | (FFS) | |
  683. |--------------+-------------+----------------|
  684. | /dev/sd01 | /dev/sd0a | / |
  685. | /dev/sd01 | /dev/sd0b | swap |
  686. | /dev/sd01 | /dev/sd0c | not mounted |
  687. | /dev/sd01 | /dev/sd0d | /home |
  688. | | ... | |
  689. | /dev/sd01 | /dev/sd0e | /tmp |
  690. | | | |
  691. | /dev/sd11 | /dev/sd1i | /data |
  692. |--------------+-------------+----------------|&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I would highly recommend the OpenBSD
  693. &lt;a href=&quot;https://www.openbsd.org/faq/faq14.html#intro&quot;&gt;faq&lt;/a&gt; page about this (as well as
  694. the disklabel man page), which will also act as a more official version of this
  695. blog post. Now on with the blog post!&lt;/p&gt;&lt;p&gt;Let’s figure out which drive is my usb stick, and which drive is my SSD with
  696. Guix on it. Please note that I did not write the output of this command down.
  697. Your output might look different.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sysctl hw.disknames
  698. hw.disknames=sd0:ec557d42f5cbfa41,sd1:&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I typed in the next two commands to try to get a feel for which drive was my
  699. SSD.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;doas disklabel sd0
  700. doas disklabel sd1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I forget what the above commands output-ed, but looking at the output I was able
  701. to determine that &lt;code&gt;sd0&lt;/code&gt; was my GNU/Linux Guix System. Now it was time to set up a
  702. &lt;a href=&quot;https://www.openbsd.org/faq/faq14.html#softraidFDE&quot;&gt;full disc encryption&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cd /dev &amp;amp;&amp;amp; sh MAKEDEV sd0
  703. dd if=/dev/urandom of=/dev/rsd0c bs=1m&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That second command took 8+ hours to complete. It wrote random data on the
  704. whole SSD. That way, if an attacker ever stole my hard drive, when they
  705. examined my hard drive, they would not see:&lt;/p&gt;&lt;p&gt;00000000EncryptedData0000000EncryptedData000000&lt;/p&gt;&lt;p&gt;Instead they would see&lt;/p&gt;&lt;p&gt;RandomDataRandomDataRandomDataRandomDataRandomDataRandomData&lt;/p&gt;&lt;p&gt;where only the 2nd and 5th =RandomData= are actually my encrypted files. Trying
  706. to figure what is data and what is just random ones and zeros would be really
  707. hard. However, I should probably ask on &lt;code&gt;#openbsd&lt;/code&gt; irc to make sure that I
  708. wrote the right command. Is there a way to search your raw hard drive for a
  709. section of disc that is just 10,000 zeros?&lt;/p&gt;&lt;p&gt;Anway, let’s partition the &lt;code&gt;sd0&lt;/code&gt; drive and format it as a RAID. Random encrypted
  710. data will go to &lt;code&gt;sd0&lt;/code&gt;. OpenBSD will read files from the unencrypted &lt;code&gt;sd1&lt;/code&gt;,
  711. which will be encrypted and stored on &lt;code&gt;sd0&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;fdisk -iy sd0
  712. sd0&amp;gt; *a* *a*
  713. sd0&amp;gt;size: [ ... ] ***
  714. sd0&amp;gt; FS type: *RAID*
  715. sd0&amp;gt; *w*
  716. sd0&amp;gt; *q*&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This next command will ask you for a passphrase. If you use an alternative
  717. keyboard layout, then make your command use numbers and special characters on
  718. the 1-9 section. That way you can still type in the secret password on boot,
  719. because OpenBSD changes your keyboard layout after you unlock your encrypted
  720. volumes.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bioctl -c C -l sd0a softraid0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s set up &lt;code&gt;sd1&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cd /dev &amp;amp;&amp;amp; sh MAKEDEV sd1
  721. dd if=/dev/zero of=/dev/rsd1c bs=1m count=1
  722. exit&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will return us to the main installer. When the installer asks you which
  723. hard drive to install OpenBSD on, I said &lt;code&gt;sd1&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[...]
  724. Available disks are: sd0 sd1.
  725. Which disk is the root disk? ('?' for details) [sd0] *sd1*&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that was that! I did a few things to set up &lt;code&gt;XFCE&lt;/code&gt;, which I quickly
  726. abandoned in favor of i3, and I was off to the races. Then I realized that my
  727. full-disk decryption passphrase was pretty weak. Basically, because I use a
  728. physical &lt;a href=&quot;https://en.wikipedia.org/wiki/Dvorak_keyboard_layout&quot;&gt;dvorak keyboard
  729. layout&lt;/a&gt;, and OpenBSD uses
  730. the standard &lt;a href=&quot;https://en.wikipedia.org/wiki/QWERTY&quot;&gt;qwerty&lt;/a&gt; layout when you type
  731. in the password to decrypt the disk, my initial full disk encryption password
  732. was just numbers. Now, I wanted to change it to my normal password.&lt;/p&gt;&lt;p&gt;Apparently you can do so while the encrypted volume &lt;a href=&quot;https://dev.to/nabbisen/openbsd-disk-encryption-change-passphrase-4i8l&quot;&gt;is
  733. mounted&lt;/a&gt;!
  734. I made sure that I changed the keyboard layout to the standard qwerty, when I typed in
  735. the new passphase.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; doas bioctl -P sd1 # I was using the dvorak layout here&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In another terminal I typed in:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; setxkbmap -layout us&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then I moved to the terminal that was asking me to change the full disk
  736. encryption password.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; Old Passphrase: # I typed in the numbers
  737. New Passphrase: # I typed in an awesome password
  738. Confirm Passphrase: # I typed it in again.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let's get back to dvorak:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; setxkbmap -layout dvorak&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That's better. I did have a great time the next day. I was hoping to
  739. automatically automount my usb stick on boot. So I added this beauty to my
  740. &lt;code&gt;/etc/fstab&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;code&gt;sd2i /mnt/usb msdos rw 1 2&lt;/code&gt;&lt;/p&gt;&lt;p&gt;The next time I booted it threw me into a rescue shell with only &lt;code&gt;/&lt;/code&gt; mounted.
  741. That was a wild ride to fix, bit I will explain how I fixed that next time!&lt;/p&gt;</content></entry><entry><title>Installing Fedora on Power9</title><id>https://gnucode.me/installing-fedora-on-power9.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-03-06T13:30:00Z</updated><link href="https://gnucode.me/installing-fedora-on-power9.html" rel="alternate" /><content type="html">&lt;p&gt;My friend has a &lt;a href=&quot;https://www.raptorcs.com/TALOSII/&quot;&gt;TalosII&lt;/a&gt; machine. He currently uses void linux, but void has
  742. dropped their &lt;a href=&quot;https://en.wikipedia.org/wiki/Power_ISA&quot;&gt;Power ISA&lt;/a&gt; support. So I convinced him to give Debian Gnu/Linux a
  743. try. First we downloaded the &lt;a href=&quot;https://www.debian.org/&quot;&gt;debian&lt;/a&gt; image:&lt;/p&gt;&lt;p&gt;We navigated our way around the website to download a &lt;a href=&quot;https://cdimage.debian.org/debian-cd/current/ppc64el/iso-dvd/&quot;&gt;complete debian DVD image&lt;/a&gt;,
  744. which was about 5 GB. We then tried to figure out how to &lt;a href=&quot;https://www.debian.org/CD/verify&quot;&gt;verify the installer
  745. image&lt;/a&gt;, which basically means, to check that the file we downloaded was not
  746. malware.&lt;/p&gt;&lt;p&gt;Well let’s first import the debian GPG keys:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gpg --keyserver hkp://keyserver.ubuntu.com --recv-key \
  747. &amp;quot;1046 0DAD 7616 5AD8 1FBC 0CE9 9880 21A9 64E6 EA7D&amp;quot;
  748. gpg --keyserver hkp://keyserver.ubuntu.com --recv-key \
  749. &amp;quot;DF9B 9C49 EAA9 2984 3258 9D76 DA87 E80D 6294 BE9B&amp;quot;
  750. gpg --keyserver hkp://keyserver.ubuntu.com --recv-key \
  751. &amp;quot;F41D 3034 2F35 4669 5F65 C669 4246 8F40 09EA 8AC3&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s double check that we have those signing keys:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gpg --list-keys | grep debian
  752. uid [ unknown] Debian CD signing key &amp;lt;debian-cd@lists.debian.org&amp;gt;
  753. uid [ unknown] Debian CD signing key &amp;lt;debian-cd@lists.debian.org&amp;gt;
  754. uid [ unknown] Debian Testing CDs Automatic Signing Key &amp;lt;debian-cd@lists.debian.org&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sweet. Now what? How do we actually and practically, via what commands,
  755. verify the installer images? Well the debian page is not specific about
  756. what to do next. So I had to searching the internet for how to verify debian
  757. images. And I found this awesome &lt;a href=&quot;https://danilodellaquila.com/en/blog/how-to-verify-authenticity-of-downloaded-debian-iso-images&quot;&gt;blog post&lt;/a&gt;. Here’s how we do it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;wget https://cdimage.debian.org/debian-cd/current/ppc64el/iso-dvd/SHA512SUMS
  758. wget https://cdimage.debian.org/debian-cd/current/ppc64el/iso-dvd/SHA512SUMS.sign
  759. gpg --verify SHA512SUMS.sign
  760. gpg --verify SHA512SUMS.sign SHA512SUMS
  761. sha512sum -c SHA512SUMS 2&amp;gt;/dev/null | grep debian-11.6.0-ppc64el-netinst.iso
  762. debian-11.6.0-ppc64el-netinst.iso: OK&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We then tried to boot the usb debian power image. That failed to boot. Then we
  763. tried burning that image to a DVD. That did not work.&lt;/p&gt;&lt;p&gt;So I am guessing that Debian GNU/Linux will work on power, BUT the graphical
  764. installer does not currently work on Debian (I found out later that the Debian
  765. ncuruses installer does work on power).&lt;/p&gt;&lt;p&gt;My friend then installed Ubuntu server. Ubuntu server's installer actually
  766. worked! Then we just turned Ubuntu server into a Xubuntu like environment via
  767. command like: &lt;code&gt;sudo apt install xfce -y&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Then we rebooted and everything worked! Well, &lt;code&gt;Gnome&lt;/code&gt; did not. And &lt;code&gt;Xubuntu&lt;/code&gt; did
  768. not, but then we used &lt;code&gt;gdm&lt;/code&gt; to log into &lt;code&gt;xfce&lt;/code&gt; desktop. That worked flawlessly.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;netsurf&lt;/code&gt; web browser also worked really well! Which meant we could use any
  769. website that had virtually no javascript.&lt;/p&gt;&lt;p&gt;Then I thought, it would be great to have a modern web browser working on my
  770. friend’s desktop...&lt;/p&gt;&lt;p&gt;Well it looks like Firefox can run on Power9!&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.talospace.com/search/label/Firefox&quot;&gt;https://www.talospace.com/search/label/Firefox&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The latest blog post says that you can run Firefox version 110 on
  771. Power9. You can either add in a &lt;code&gt;--disable-webrtc&lt;/code&gt; in your
  772. &lt;code&gt;.mozconfig&lt;/code&gt; or you can compile Firefox with a tiny patch.&lt;/p&gt;&lt;p&gt;AND nonguix has a recipe for building Firefox. Let’s see if I can
  773. just install &lt;code&gt;guix&lt;/code&gt; set up the &lt;code&gt;nonguix channel&lt;/code&gt; and build Firefox that way!&lt;/p&gt;&lt;p&gt;If the nonguix packaged Firefox doesn’t work, then I can try to set
  774. build firefox from source via this video:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Hx42tyEWPxk&quot;&gt;https://www.youtube.com/watch?v=Hx42tyEWPxk&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Devaun was also a possiblity. That is a fork of debian that does not use
  775. &lt;code&gt;systemd&lt;/code&gt;. My friend is not a big fan of systemd.&lt;/p&gt;&lt;p&gt;I was also told that Fedora is probably the easiest linux distribution, in which
  776. to run GNU/Linux on Power9.&lt;/p&gt;&lt;p&gt;Well installing Fedora was actually easy. The installer just worked.
  777. (Apparently Debian GNU/Linux disables the ast driver by default, which means a
  778. VGA display will not work). And I have a working Firefox. Apparently I can run
  779. a slightly older version of firefox that has a &lt;a href=&quot;https://copr.fedorainfracloud.org/coprs/sharkcz/talos/&quot;&gt;working javascript JIT.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;My friend now has a working Xfce desktop courtesy from &lt;a href=&quot;https://getfedora.org/&quot;&gt;Fedora GNU/Linux&lt;/a&gt;. My only
  780. concern is that this &lt;a href=&quot;https://www.talospace.com/2022/12/fedora-37-mini-review-on-blackbird-and.html&quot;&gt;blog post&lt;/a&gt; seems to suggest that updating Fedora on a Power9
  781. machine is going to be quite annoying. I would not want to have to re-install
  782. Fedora every time they upgrade. I personally no longer have any issues upgrading
  783. my laptop to my distro latest release, because I have found that GNU Guix System
  784. just works really well. And if an upgrade breaks, then I can always roll back
  785. to the previous known working system during the boot process.&lt;/p&gt;&lt;p&gt;It looks like Fedora can support something like this:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://sysguides.com/install-fedora-36-with-snapper-and-grub-btrfs/&quot;&gt;https://sysguides.com/install-fedora-36-with-snapper-and-grub-btrfs/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Maybe it is already enabled by default. Who knows.&lt;/p&gt;&lt;p&gt;I would personally love to recommend my friend to use GNU Guix System, but
  786. currently you cannot boot Guix System from Power9. The next step for me in this
  787. journey to help my friend set up his TalosII is to make sure his AMDGPU works.
  788. This &lt;a href=&quot;https://wiki.raptorcs.com/wiki/Troubleshooting/GPU,&quot;&gt;wiki article&lt;/a&gt; should help with that.&lt;/p&gt;&lt;p&gt;Also from the &lt;code&gt;#talos-workstation&lt;/code&gt; chat log on irc, I found out that the Linux
  789. kernel is having some issues with the graphics drivers on Power9. Currently the
  790. user is required to do some manual fiddling. However those workarounds should
  791. not be necessary by kernel 6.3ish. So until my friend runs Linux 6.3, he will
  792. probably have the best desktop experience in Xfce or KDE. Gnome has some minor
  793. issues apparently.&lt;/p&gt;</content></entry><entry><title>Creating New Build Systems</title><id>https://gnucode.me/creating-new-build-systems.html</id><author><name>Mitchell Schmeisser &lt;mitchellschmeisser@librem.one&gt;</name><email>jbranso@dismail.de</email></author><updated>2023-02-24T12:00:00Z</updated><link href="https://gnucode.me/creating-new-build-systems.html" rel="alternate" /><content type="html">&lt;p&gt;In Guix each package must specify a so-called &lt;code&gt;build-system&lt;/code&gt;, which
  794. knows how to bring a package from its inputs to deployment.
  795. Build systems are responsible for setting up the environment and performing
  796. build actions within that environment. The most ubiquitous of these is the
  797. &lt;a href=&quot;https://www.gnu.org/software/automake/manual/html_node/GNU-Build-System.html&quot;&gt;&lt;code&gt;gnu-build-system&lt;/code&gt;&lt;/a&gt;.
  798. Guix builds packages using this build system via the usual
  799. &lt;code&gt;./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;/code&gt; process.&lt;/p&gt;&lt;p&gt;Any package can alter its build system by removing some steps or
  800. adding extra ones. This is extremely common and almost every package
  801. makes some adjustment to the build process. A &lt;code&gt;build-system&lt;/code&gt; in Guix
  802. hides away some of the common configuration choices. For example, there is
  803. no need to specify &lt;code&gt;make&lt;/code&gt; or &lt;code&gt;gcc&lt;/code&gt; as native inputs when using the &lt;code&gt;gnu-build-system&lt;/code&gt;,
  804. because they are added implicitly when a package is lowered into a &lt;em&gt;bag&lt;/em&gt;.&lt;/p&gt;&lt;h2&gt;Anatomy of a Guix Build System&lt;/h2&gt;&lt;p&gt;The job of a build system is to compile our &lt;em&gt;packages&lt;/em&gt; into &lt;em&gt;bags&lt;/em&gt;.
  805. Bags are a lower level representation of a package without all the bells and whistles
  806. (Makes sense since we are implementing them here),
  807. the bags are further refined to derivations which are used by the
  808. build daemon to create an isolated environment suitable for our
  809. &lt;em&gt;build phases&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Below is how guix defines a build system.
  810. It's surprisingly simple with just three items, two of which are for human consumption.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define-record-type* &amp;lt;build-system&amp;gt; build-system make-build-system
  811. build-system?
  812. (name build-system-name) ; symbol
  813. (description build-system-description) ; short description
  814. (lower build-system-lower)) ; args ... -&amp;gt; bags&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The last field &lt;code&gt;lower&lt;/code&gt; is a function which takes the list of arguments
  815. given in the &lt;code&gt;(package ... (arguments ...))&lt;/code&gt; field.
  816. The keyword arguments that we are allowed to supply when writing the
  817. package are defined by the build-system.&lt;/p&gt;&lt;h1&gt;Code Strata&lt;/h1&gt;&lt;p&gt;Guix builds are implemented in two parts.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Code that compiles &lt;code&gt;packages-&amp;gt;derivations&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Derivations are the language the Guix Daemon speaks.
  818. They describe everything about how to &lt;em&gt;derive&lt;/em&gt; our package
  819. from the inputs to the environment and all the code on how to drive
  820. the build tools.
  821. This code is run in a poorly defined &amp;quot;user&amp;quot; environment.
  822. Guix produces derivations that actually can be influenced by
  823. undeclared aspects of the environment, like manually installed Guile
  824. packages or code added with the `-L` flag.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The guix daemon runs the builder code in as isolated and reproducible build environment to produce the package from its inputs.&lt;/p&gt;&lt;p&gt;This code is executed in an explicitly defined build environment
  825. with nothing being introduced from the host.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Code that runs in the host environment &lt;em&gt;stages&lt;/em&gt; code, which will run in isolation.
  826. This is where G-Expressions really shine.
  827. They provide the syntax to describe this relationship.&lt;/p&gt;&lt;h1&gt;Build Phases&lt;/h1&gt;&lt;p&gt;All programs are built more or less the same way.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Unpack the source code.&lt;/p&gt;&lt;p&gt;Whether it's tarball or a version controlled repository, the guix daemon must
  828. copy the software's source tree into our build environment.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Patch the shebangs.&lt;/p&gt;&lt;p&gt;Many projects contain scripts written to aid the build process.
  829. In Linux, executable scripts can contain a so-called &lt;em&gt;shebang&lt;/em&gt;,
  830. which contains an absolute path to the program, which is meant to
  831. interpret it: e.g. &lt;code&gt;#!/bin/sh&lt;/code&gt;. Most distributions provide a
  832. POSIX compliant shell interpreter at this location. Guix System does not do this.
  833. Instead, Guix System's &lt;code&gt;sh&lt;/code&gt; is yet another component in the store, so all of these files must
  834. be patched to point to the new location, which is only known at
  835. build time. We cannot rely on our &lt;code&gt;PATH&lt;/code&gt; to store this information,
  836. because the Linux kernel does not respect such things.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Configure the build.&lt;/p&gt;&lt;p&gt;Whether it is autotools or CMake or ninja, etc., if you are relying
  837. on tools from the host system, then you have a step, which enables the
  838. host system to tell you where to find those tools.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Patch the generated shebangs.&lt;/p&gt;&lt;p&gt;Sometimes the configure phases creates scripts, which run during the build phase,
  839. these often contain references to &lt;code&gt;/bin/sh&lt;/code&gt;, and so guix must patch these scripts as well.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Build!&lt;/p&gt;&lt;p&gt;That's right folks we are off to the races, and the program is building.
  840. Usually this takes the form of a call to &lt;code&gt;make&lt;/code&gt;, with a handful of
  841. flags and last minute definitions, but there are other more &lt;em&gt;exotic&lt;/em&gt; methods.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Test.&lt;/p&gt;&lt;p&gt;Now that guix built our software, we should test it before we sent software
  842. updates to users. This helps the guix project catch and eleminate software
  843. bugs before they impact guix users. Not all packages have tests, and guix
  844. developers occasionally disables some packages' testsuites, but the
  845. guix policy is to run the software's testsuite, if it is exists.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Install.&lt;/p&gt;&lt;p&gt;Now that we've verified everything works as expected, it is time to run
  846. &lt;code&gt;make install&lt;/code&gt; or the equivalent. This phase copies our build artifacts into
  847. their final resting place in the store.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Validate the Installation.&lt;/p&gt;&lt;p&gt;Here guix checks that our outputs do not contain any component paths, which
  848. are not specified by the package inputs. That would lead to incomplete
  849. deployment, harm &lt;a href=&quot;https://reproducible-builds.org/&quot;&gt;reproducible builds&lt;/a&gt;,
  850. and would be &amp;quot;bad&amp;quot;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There are more steps, but they are not universally applicable.
  851. Of course no generic model, such as this, captures all the chaos of the
  852. world, and every package has exceptions to it.&lt;/p&gt;&lt;p&gt;Guix implements &lt;em&gt;build phases&lt;/em&gt; as a list of lambdas.
  853. As such our package can modify this list and add/delete/replace
  854. lambdas as they require. It is so common Guix provides a syntax
  855. for manipulating build phases: &lt;code&gt;modify-phases&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;A build system contains a default set of phases called &lt;code&gt;%standard-phases&lt;/code&gt;.
  856. Every build system starts with the &lt;code&gt;gnu-build-system&lt;/code&gt;, &lt;code&gt;%standard-phases&lt;/code&gt;,
  857. and modifies it to their needs.
  858. It is then provided to the packages using that build system.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;cmake-build-system&lt;/code&gt; is nearly identical to the &lt;code&gt;gnu-build-system&lt;/code&gt;
  859. except two phases.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;;;
  860. ;; Excerpt from `guix/build/cmake-build-system.scm`
  861. ;;
  862. (define %standard-phases
  863. ;; Everything is the same as the GNU Build System, except for the `configure'
  864. ;; and 'check' phases.
  865. (modify-phases gnu:%standard-phases
  866. (delete 'bootstrap)
  867. (replace 'check check)
  868. (replace 'configure configure)))&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;The Zephyr Build System&lt;/h2&gt;&lt;p&gt;Zephyr uses &lt;code&gt;cmake&lt;/code&gt; to perform &lt;em&gt;physical component composition&lt;/em&gt;.
  869. It searches the filesystem and generates scripts, which the toolchain will
  870. use to successfully combine those components into a firmware image.&lt;/p&gt;&lt;p&gt;The fact that Zephyr provides this mechanism is one reason I chose to
  871. target zephyr in the first place.&lt;/p&gt;&lt;p&gt;This separation of projects in an embedded context is a really great thing.
  872. It brings many of the advantages to the Linux world such as
  873. code re-use, smaller binaries, more efficient cache/RAM usage, etc.
  874. It also allows us to work as independent groups and compose
  875. contributions from many teams.&lt;/p&gt;&lt;p&gt;It also brings all of the complexity. Suddenly all of the problems
  876. that plague traditional deployment now apply to our embedded
  877. system. The fact that the libraries are statically linked at compile
  878. time instead of dynamically at runtime is simply an implementation detail.&lt;/p&gt;&lt;p&gt;We now have dependencies which we must track and compose in the correct environments.
  879. The Zephyr Project offers a tool to help manage this new complexity: &lt;a href=&quot;https://docs.zephyrproject.org/latest/develop/west/index.html&quot;&gt;The West Meta-tool&lt;/a&gt;!
  880. To call it a &amp;quot;meta-tool&amp;quot; is an abuse of language. It is not even meta
  881. enough to bootstrap itself and relies on &lt;a href=&quot;https://docs.zephyrproject.org/latest/develop/getting_started/index.html&quot;&gt;other package managers&lt;/a&gt; to get
  882. started.
  883. In fact, it is not even suitable for managing multiple embedded projects as a composition!
  884. The project recommends &lt;a href=&quot;https://docs.zephyrproject.org/latest/build/sysbuild/index.html&quot;&gt;Yet Another Tool&lt;/a&gt; for this very common use case.&lt;/p&gt;&lt;p&gt;In fact, West does not really bring anything new to the table, and we can
  885. replace it in the same way we can replace every other language specific package
  886. manager, like node (js), Cabol (haskell), Dub (D), etc. &lt;strong&gt;PUTTING SOFTWARE ON
  887. THE SYSTEM IS THE JOB OF THE PACKAGE MANAGER!&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;West is the way it is for a reason. It is very practical to design the package
  888. manager in this way, because it enables Windows users to access the build
  889. environment. A more in-depth discussion on the material conditions, which lead
  890. to this or that design decision of the West tool is beyond the scope of this
  891. post. Let's instead explain how to provide a meta-tool and bootstrap complex
  892. embedded systems, from the ground up, in a flexible, composable, and
  893. &lt;em&gt;reproducible&lt;/em&gt; way.&lt;/p&gt;&lt;h1&gt;Why not use &lt;code&gt;cmake-build-system&lt;/code&gt;?&lt;/h1&gt;&lt;p&gt;A fair question! Zephyr's CMake scripts require additional information
  894. about the build to be provided at configure time. Most tedius for
  895. zephyr-packages is the &lt;code&gt;ZEPHYR_MODULES&lt;/code&gt; variable, which must be formatted and
  896. passed to CMake on the command line.&lt;/p&gt;&lt;h1&gt;Host Side&lt;/h1&gt;&lt;p&gt;Our job at this level is to take packages described using the &lt;code&gt;package&lt;/code&gt; syntax and
  897. lower it into a derivation that the guix-daemon can understand.&lt;/p&gt;&lt;p&gt;Here is the derivation for building hello world for the &lt;code&gt;frdm_k64f&lt;/code&gt; (hashes removed for brevity).
  898. The &lt;code&gt;package&lt;/code&gt; syntax provides a human friendly veneer over this garbage.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;Derive
  899. ([(&amp;quot;debug&amp;quot;,&amp;quot;/gnu/store/...-zephyr-hello-world-newlib-frdm-k64f-3.1.0-0.zephyr--debug&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;)
  900. ,(&amp;quot;out&amp;quot;,&amp;quot;/gnu/store/...-zephyr-hello-world-newlib-frdm-k64f-3.1.0-0.zephyr-&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;)]
  901. ,[(&amp;quot;/gnu/store/...-newlib-nano-3.3.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  902. ,(&amp;quot;/gnu/store/...-hal-nxp-3.1.0-0.708c958.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  903. ,(&amp;quot;/gnu/store/...-make-4.3.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  904. ,(&amp;quot;/gnu/store/...-findutils-4.8.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  905. ,(&amp;quot;/gnu/store/...-grep-3.6.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  906. ,(&amp;quot;/gnu/store/...-sed-4.8.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  907. ,(&amp;quot;/gnu/store/...-ld-wrapper-0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  908. ,(&amp;quot;/gnu/store/...-bash-minimal-5.1.8.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  909. ,(&amp;quot;/gnu/store/...-hal-cmsis-5.8.0-0.093de61.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  910. ,(&amp;quot;/gnu/store/...-gawk-5.1.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  911. ,(&amp;quot;/gnu/store/...-gzip-1.10.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  912. ,(&amp;quot;/gnu/store/...-python-six-1.16.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  913. ,(&amp;quot;/gnu/store/...-zephyr-3.1.0-0.zephyr--checkout.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  914. ,(&amp;quot;/gnu/store/...-linux-libre-headers-5.10.35.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  915. ,(&amp;quot;/gnu/store/...-python-3.9.9.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  916. ,(&amp;quot;/gnu/store/...-diffutils-3.8.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  917. ,(&amp;quot;/gnu/store/...-arm-zephyr-eabi-nano-toolchain-12.1.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  918. ,(&amp;quot;/gnu/store/...-python-pyelftools-0.28.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  919. ,(&amp;quot;/gnu/store/...-guile-3.0.7.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  920. ,(&amp;quot;/gnu/store/...-python-dateutil-2.8.2.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  921. ,(&amp;quot;/gnu/store/...-patch-2.7.6.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  922. ,(&amp;quot;/gnu/store/...-gcc-10.3.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  923. ,(&amp;quot;/gnu/store/...-bzip2-1.0.8.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  924. ,(&amp;quot;/gnu/store/...-dtc-1.6.1.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  925. ,(&amp;quot;/gnu/store/...-gcc-cross-sans-libc-arm-zephyr-eabi-12.1.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  926. ,(&amp;quot;/gnu/store/...-cmake-minimal-3.21.4.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  927. ,(&amp;quot;/gnu/store/...-python-pyyaml-6.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  928. ,(&amp;quot;/gnu/store/...-python-packaging-21.3.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  929. ,(&amp;quot;/gnu/store/...-arm-zephyr-eabi-binutils-2.38.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  930. ,(&amp;quot;/gnu/store/...-glibc-2.33.drv&amp;quot;,[&amp;quot;out&amp;quot;,&amp;quot;static&amp;quot;])
  931. ,(&amp;quot;/gnu/store/...-qemu-7.2.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  932. ,(&amp;quot;/gnu/store/...-ninja-1.10.2.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  933. ,(&amp;quot;/gnu/store/...-tar-1.34.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  934. ,(&amp;quot;/gnu/store/...-xz-5.2.5.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  935. ,(&amp;quot;/gnu/store/...-binutils-2.37.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  936. ,(&amp;quot;/gnu/store/...-python-pykwalify-1.7.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  937. ,(&amp;quot;/gnu/store/...-zephyr-3.1.0-0.zephyr-.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  938. ,(&amp;quot;/gnu/store/...-glibc-utf8-locales-2.33.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  939. ,(&amp;quot;/gnu/store/...-gdb-arm-zephyr-eabi-12.1.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  940. ,(&amp;quot;/gnu/store/...-module-import-compiled.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  941. ,(&amp;quot;/gnu/store/...-file-5.39.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  942. ,(&amp;quot;/gnu/store/...-python-pyparsing-3.0.6.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  943. ,(&amp;quot;/gnu/store/...-python-docopt-0.6.2.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  944. ,(&amp;quot;/gnu/store/...-arm-zephyr-eabi-sdk-0.15.0.drv&amp;quot;,[&amp;quot;out&amp;quot;])
  945. ,(&amp;quot;/gnu/store/...-coreutils-8.32.drv&amp;quot;,[&amp;quot;out&amp;quot;])]
  946. ,[&amp;quot;/gnu/store/...-zephyr-hello-world-newlib-frdm-k64f-3.1.0-0.zephyr--builder&amp;quot;,&amp;quot;/gnu/store/...-module-import&amp;quot;]
  947. ,&amp;quot;x86_64-linux&amp;quot;,&amp;quot;/gnu/store/...-guile-3.0.7/bin/guile&amp;quot;,[&amp;quot;--no-auto-compile&amp;quot;
  948. ,&amp;quot;-L&amp;quot;,&amp;quot;/gnu/store/...-module-import&amp;quot;
  949. ,&amp;quot;-C&amp;quot;,&amp;quot;/gnu/store/...-module-import-compiled&amp;quot;
  950. ,&amp;quot;/gnu/store/...-zephyr-hello-world-newlib-frdm-k64f-3.1.0-0.zephyr--builder&amp;quot;]
  951. ,[(&amp;quot;debug&amp;quot;,&amp;quot;/gnu/store/...-zephyr-hello-world-newlib-frdm-k64f-3.1.0-0.zephyr--debug&amp;quot;)
  952. ,(&amp;quot;out&amp;quot;,&amp;quot;/gnu/store/...-zephyr-hello-world-newlib-frdm-k64f-3.1.0-0.zephyr-&amp;quot;)])&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Lowering packages to bags&lt;/h3&gt;&lt;p&gt;We must provide the build system with a function which the following lambda form.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(lambda* (name #:key #:allow-other-keys) ...)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means it takes one required argument &lt;code&gt;name&lt;/code&gt; and any amount of keys.
  953. Individual procedures can specify keys they are interested in such as
  954. &lt;code&gt;inputs&lt;/code&gt; or &lt;code&gt;outputs&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Which keys are ultimately supported is defined by our &lt;code&gt;lower&lt;/code&gt; function
  955. and our &lt;em&gt;build phases&lt;/em&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;;; Use module-ref instead of referencing the variables directly
  956. ;; to avoid circular dependencies.
  957. (define %zephyr-build-system-modules
  958. `((mfs build zephyr-build-system)
  959. ,@%cmake-build-system-modules))
  960. (define default-zephyr-base
  961. (module-ref (resolve-interface '(mfs packages zephyr))
  962. 'zephyr))
  963. (define default-zephyr-sdk
  964. (module-ref (resolve-interface '(mfs packages zephyr))
  965. 'arm-zephyr-eabi-sdk))
  966. (define default-ninja
  967. (module-ref (resolve-interface '(gnu packages ninja))
  968. 'ninja))
  969. (define default-cmake
  970. (module-ref (resolve-interface '(gnu packages cmake))
  971. 'cmake-minimal))
  972. (define* (lower name
  973. #:key source inputs native-inputs outputs system target
  974. (zephyr default-zephyr-base)
  975. (sdk default-zephyr-sdk)
  976. (ninja default-ninja)
  977. (cmake default-cmake)
  978. #:allow-other-keys
  979. #:rest arguments)
  980. &amp;quot;Return a bag for NAME.&amp;quot;
  981. (define private-keywords `(#:zephyr #:inputs #:native-inputs #:target))
  982. (bag
  983. (name name)
  984. (system system)
  985. (target target)
  986. (build-inputs `(,@(if source `((&amp;quot;source&amp;quot; ,source)) '())
  987. ,@`((&amp;quot;cmake&amp;quot; ,cmake))
  988. ,@`((&amp;quot;zephyr-sdk&amp;quot; ,sdk))
  989. ,@`((&amp;quot;zephyr&amp;quot; ,zephyr))
  990. ,@`((&amp;quot;ninja&amp;quot; ,ninja))
  991. ,@native-inputs
  992. ,@(standard-packages)))
  993. ;; Inputs need to be available at build time
  994. ;; since everything is statically linked.
  995. (host-inputs inputs)
  996. (outputs outputs)
  997. (build zephyr-build)
  998. (arguments (strip-keyword-arguments private-keywords arguments))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here our &lt;code&gt;lower&lt;/code&gt; function provides default values for the packages
  999. every zephyr package needs, the SDK, CMake, and &lt;code&gt;ZEPHYR_BASE&lt;/code&gt; and adds
  1000. them to the build-inputs.&lt;/p&gt;&lt;p&gt;Notice we also strip out some keywords, which do not get passed to the
  1001. build function, because they get included as part of the broader
  1002. abstractions the build system provides.&lt;/p&gt;&lt;p&gt;At this step it would be great to have a parser which could work out
  1003. the required sdk from a &lt;code&gt;.config,&lt;/code&gt; but this requires compiling the kconfig,
  1004. which requires at least the sdk cmake files.
  1005. There might be a way to make it happen, but until then if a board needs a different
  1006. sdk, then they can specify it in an argument keyword.&lt;/p&gt;&lt;h3&gt;Lowering Bags to Derivations&lt;/h3&gt;&lt;p&gt;Here is the definition for the actual build procedure. There is a lot
  1007. of abstract trickery going on here, so do not worry if you don't understand it,
  1008. I barely understand it!
  1009. It's mostly copy and pasted from the CMake build system.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define* (zephyr-build name inputs
  1010. #:key guile source
  1011. board
  1012. (outputs '(&amp;quot;out&amp;quot;)) (configure-flags ''())
  1013. (search-paths '())
  1014. (make-flags ''())
  1015. (out-of-source? #t)
  1016. (tests? #f)
  1017. (test-target &amp;quot;test&amp;quot;)
  1018. (parallel-build? #t) (parallel-tests? #t)
  1019. (validate-runpath? #f)
  1020. (patch-shebangs? #t)
  1021. (phases '%standard-phases)
  1022. (system (%current-system))
  1023. (substitutable? #t)
  1024. (imported-modules %zephyr-build-system-modules)
  1025. ;; The modules referenced here contain code
  1026. ;; which will be staged in the build environment with us.
  1027. ;; Our build gexp down below will only be able to access this code
  1028. ;; and we must be careful not to reference anything else.
  1029. (modules '((zephyr build zephyr-build-system)
  1030. (guix build utils))))
  1031. &amp;quot;Build SOURCE using CMAKE, and with INPUTS. This assumes that SOURCE
  1032. provides a 'CMakeLists.txt' file as its build system.&amp;quot;
  1033. ;; This is the build gexp. It handles staging values from our host
  1034. ;; system into code that our build system can run.
  1035. (define build
  1036. (with-imported-modules imported-modules
  1037. #~(begin
  1038. (use-modules #$@(sexp-&amp;gt;gexp modules))
  1039. #$(with-build-variables inputs outputs
  1040. #~(zephyr-build #:source #+source
  1041. #:system #$system
  1042. #:outputs %outputs
  1043. #:inputs %build-inputs
  1044. #:board #$board
  1045. #:search-paths '#$(sexp-&amp;gt;gexp
  1046. (map search-path-specification-&amp;gt;sexp
  1047. search-paths))
  1048. #:phases #$(if (pair? phases)
  1049. (sexp-&amp;gt;gexp phases)
  1050. phases)
  1051. #:configure-flags #$(if (pair? configure-flags)
  1052. (sexp-&amp;gt;gexp configure-flags)
  1053. configure-flags)
  1054. #:make-flags #$make-flags
  1055. #:out-of-source? #$out-of-source?
  1056. #:tests? #$tests?
  1057. #:test-target #$test-target
  1058. #:parallel-build? #$parallel-build?
  1059. #:parallel-tests? #$parallel-tests?
  1060. #:validate-runpath? #$validate-runpath?
  1061. #:patch-shebangs? #$patch-shebangs?
  1062. #:strip-binaries? #f)))))
  1063. (mlet %store-monad ((guile (package-&amp;gt;derivation (or guile (default-guile))
  1064. system #:graft? #f)))
  1065. (gexp-&amp;gt;derivation name build
  1066. #:system system
  1067. #:target #f
  1068. #:graft? #f
  1069. #:substitutable? substitutable?
  1070. #:guile-for-build guile)))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally we define our build system which the package definitions can reference.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define zephyr-build-system
  1071. (build-system
  1072. (name 'zephyr)
  1073. (description &amp;quot;The standard Zephyr build system&amp;quot;)
  1074. (lower lower)))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Easy right?&lt;/p&gt;&lt;h1&gt;Build Side&lt;/h1&gt;&lt;p&gt;The build side is not as complex as you might initially expect.
  1075. Our build system is almost exactly the same as the CMake build system
  1076. except our configure phase passes different values to CMake.
  1077. Our job is much easier.&lt;/p&gt;&lt;h3&gt;Locating Modules&lt;/h3&gt;&lt;p&gt;Zephyr CMake requires the zephyr &lt;em&gt;modules&lt;/em&gt; which are needed for the
  1078. build to be supplied on the command line.
  1079. Unfortunately for us, the
  1080. &lt;a href=&quot;https://docs.zephyrproject.org/3.1.0/develop/application/index.html#important-build-vars&quot;&gt;documentation&lt;/a&gt;
  1081. is wrong, and the &lt;code&gt;ZEPHYR_MODULES&lt;/code&gt; environment variable is not honored.
  1082. Thus we must implement some other solution for locating modules, until
  1083. this that is fixed.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Input Scanning&lt;/strong&gt; - Lucky for us we are keeping detailed information
  1084. about our dependencies. It is a simple matter to write a file tree
  1085. walker which collects all the zephyr modules in our inputs.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define* (find-zephyr-modules directories)
  1086. &amp;quot;Return the list of directories containing zephyr/module.yml found
  1087. under DIRECTORY, recursively. Return the empty list if DIRECTORY is
  1088. not accessible.&amp;quot;
  1089. (define (module-directory file)
  1090. (dirname (dirname file)))
  1091. (define (enter? name stat result)
  1092. ;; Skip version control directories.
  1093. ;; Shouldn't be in the store but you never know.
  1094. (not (member (basename name) '(&amp;quot;.git&amp;quot; &amp;quot;.svn&amp;quot; &amp;quot;CVS&amp;quot;))))
  1095. (define (leaf name stat result)
  1096. ;; Add module root directory to results
  1097. (if (and (string= &amp;quot;module.yml&amp;quot; (basename name))
  1098. (string= &amp;quot;zephyr&amp;quot; (basename (dirname name))))
  1099. (cons (module-directory name) result)
  1100. result))
  1101. (define (down name stat result) result)
  1102. (define (up name stat result) result)
  1103. (define (skip name stat result) result)
  1104. (define (find-modules directory)
  1105. (file-system-fold enter? leaf down up skip error
  1106. '() (canonicalize-path directory)))
  1107. (append-map find-modules directories))
  1108. (define (zephyr-modules-cmake-argument modules)
  1109. &amp;quot;Return a proper CMake list from MODULES, a list of filepaths&amp;quot;
  1110. (format #f &amp;quot;-DZEPHYR_MODULES='~{~a~^;~}'&amp;quot; modules))
  1111. &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here are two functions. The first one &lt;code&gt;find-zephyr-modules&lt;/code&gt; walks a
  1112. list of directories (package inputs) and returns a list of every module it finds.
  1113. The second one is just for syntactic convenience when writing the CMake invokation.
  1114. This is also slightly more robust than West's module discovery, because it allows for
  1115. a single repository to provide multiple modules which are not &lt;em&gt;technically&lt;/em&gt; required
  1116. to be at the top level.&lt;/p&gt;&lt;p&gt;From here we just need to provide alternate implementations of &lt;code&gt;configure&lt;/code&gt; and &lt;code&gt;install&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define* (configure #:key outputs (configure-flags '())
  1117. inputs (out-of-source? #t)
  1118. build-type
  1119. #:allow-other-keys)
  1120. &amp;quot;Configure the given package.&amp;quot;
  1121. (let* ((out (assoc-ref outputs &amp;quot;out&amp;quot;))
  1122. (abs-srcdir (getcwd))
  1123. (srcdir (if out-of-source?
  1124. (string-append &amp;quot;../&amp;quot; (basename abs-srcdir))
  1125. &amp;quot;.&amp;quot;)))
  1126. (format #t &amp;quot;source directory: ~s (relative from build: ~s)~%&amp;quot;
  1127. abs-srcdir srcdir)
  1128. (when out-of-source?
  1129. (mkdir &amp;quot;../build&amp;quot;)
  1130. (chdir &amp;quot;../build&amp;quot;))
  1131. (format #t &amp;quot;build directory: ~s~%&amp;quot; (getcwd))
  1132. ;; this is required because zephyr tries to optimize
  1133. ;; future calls to the build scripts by keep a cache.
  1134. (setenv &amp;quot;XDG_CACHE_HOME&amp;quot; (getcwd))
  1135. (let ((args `(,srcdir
  1136. ,@(if build-type
  1137. (list (string-append &amp;quot;-DCMAKE_BUILD_TYPE=&amp;quot;
  1138. build-type))
  1139. '())
  1140. ;; enable verbose output from builds
  1141. &amp;quot;-DCMAKE_VERBOSE_MAKEFILE=ON&amp;quot;
  1142. ,(zephyr-modules-cmake-argument
  1143. (find-zephyr-modules (map cdr inputs)))
  1144. ,@configure-flags)))
  1145. (format #t &amp;quot;running 'cmake' with arguments ~s~%&amp;quot; args)
  1146. (apply invoke &amp;quot;cmake&amp;quot; args))))
  1147. (define* (install #:key outputs #:allow-other-keys)
  1148. (let* ((out (string-append (assoc-ref outputs &amp;quot;out&amp;quot;) &amp;quot;/lib/firmware&amp;quot;))
  1149. (dbg (string-append (assoc-ref outputs &amp;quot;debug&amp;quot;) &amp;quot;/share/zephyr&amp;quot;)))
  1150. (mkdir-p out)
  1151. (mkdir-p dbg)
  1152. (copy-file &amp;quot;zephyr/.config&amp;quot; (string-append dbg &amp;quot;/config&amp;quot;))
  1153. (copy-file &amp;quot;zephyr/zephyr.map&amp;quot; (string-append dbg &amp;quot;/zephyr.map&amp;quot;))
  1154. (copy-file &amp;quot;zephyr/zephyr.elf&amp;quot; (string-append out &amp;quot;/zephyr.elf&amp;quot;))
  1155. (copy-file &amp;quot;zephyr/zephyr.bin&amp;quot; (string-append out &amp;quot;/zephyr.bin&amp;quot;))))
  1156. ;; Define new standard-phases
  1157. (define %standard-phases
  1158. (modify-phases cmake:%standard-phases
  1159. (replace 'configure configure)
  1160. (replace 'install install)))
  1161. ;; Call cmake build with our new phases
  1162. (define* (zephyr-build #:key inputs (phases %standard-phases)
  1163. #:allow-other-keys #:rest args)
  1164. (apply cmake:cmake-build #:inputs inputs #:phases phases args))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;One thing to note is the &amp;quot;debug&amp;quot; output. This exists so we don't
  1165. retain references to our build environment and make the file system
  1166. closure huge. If you put all of the build outputs in the same store
  1167. path, then the deployment closure will grow from 2MB to 833MB.&lt;/p&gt;&lt;h1&gt;Defining Zephyr Packages&lt;/h1&gt;&lt;p&gt;Now that we have a proper build system, it's time to define some packages!&lt;/p&gt;&lt;h3&gt;Zephyr Base&lt;/h3&gt;&lt;p&gt;Zephyr base contains the Zephyr source code. It is equivalent (in my mind
  1168. anyway) to the linux kernel, in that packages' definitions' specifications,
  1169. which target the linux kernel, can be minimal.&lt;/p&gt;&lt;p&gt;The selection of operating system actually comes from the toolchain. For
  1170. example, we build linux packages with the &lt;a href=&quot;https://www.gnu.org/software/autoconf/manual/autoconf-2.65/html_node/Specifying-Target-Triplets.html&quot;&gt;gnu
  1171. triplet&lt;/a&gt;.
  1172. When we select the &lt;code&gt;arm-linux-gnueabihf,&lt;/code&gt; we are specifying our operating system.&lt;/p&gt;&lt;p&gt;It is the same for Zephyr. When we build for zephyr we use the &lt;code&gt;arm-zephyr-eabi&lt;/code&gt;
  1173. toolchain. However, unlike linux applications, zephyr applications are
  1174. embedded firmware images and are generally statically linked.
  1175. Thus this package just consists of its source code and is not compiled directly.
  1176. We cannot compile it now because applications/modules provide the required Kconfig
  1177. options.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define-public zephyr
  1178. (let ((version &amp;quot;3.1.0&amp;quot;)
  1179. (commit &amp;quot;zephyr-v3.1.0&amp;quot;))
  1180. (package
  1181. (name &amp;quot;zephyr&amp;quot;)
  1182. (version version)
  1183. (home-page &amp;quot;https://zephyrproject.org&amp;quot;)
  1184. (source (origin (method git-fetch)
  1185. (uri (git-reference
  1186. (url &amp;quot;https://github.com/zephyrproject-rtos/zephyr&amp;quot;)
  1187. (commit commit)))
  1188. (file-name (git-file-name name version))
  1189. (sha256
  1190. (base32 &amp;quot;1yl5y9757xc3l037k3g1dynispv6j5zqfnzrhsqh9cx4qzd485lx&amp;quot;))
  1191. (patches
  1192. ;; this patch makes this package work in a symlinked profile
  1193. (search-patches &amp;quot;zephyr-3.1-linker-gen-abs-path.patch&amp;quot;))))
  1194. (build-system copy-build-system)
  1195. (arguments
  1196. `(#:install-plan
  1197. '((&amp;quot;.&amp;quot; &amp;quot;zephyr-workspace/zephyr&amp;quot;))
  1198. #:phases
  1199. (modify-phases %standard-phases
  1200. (add-after 'unpack 'patch-cmake-scripts
  1201. (lambda* _
  1202. (format #t &amp;quot;~a~&amp;amp;&amp;quot; (getcwd))
  1203. ;; Some cmake scripts assume the presence of a
  1204. ;; git repository in the source directory.
  1205. ;; We will just hard-code that information now
  1206. (substitute* &amp;quot;CMakeLists.txt&amp;quot;
  1207. ((&amp;quot;if\\(DEFINED BUILD_VERSION\\)&amp;quot; all)
  1208. (format #f &amp;quot;set(BUILD_VERSION \&amp;quot;~a-~a\&amp;quot;)~&amp;amp;~a&amp;quot;
  1209. ,version ,commit all))))))))
  1210. (propagated-inputs
  1211. (list python-3
  1212. python-pyelftools
  1213. python-pykwalify
  1214. python-pyyaml
  1215. python-packaging))
  1216. (native-search-paths
  1217. (list (search-path-specification
  1218. (variable &amp;quot;ZEPHYR_BASE&amp;quot;)
  1219. (files '(&amp;quot;zephyr-workspace/zephyr&amp;quot;)))))
  1220. (synopsis &amp;quot;Source code for zephyr rtos&amp;quot;)
  1221. (description &amp;quot;Zephyr rtos source code.&amp;quot;)
  1222. (license license:apsl2))))
  1223. (define-public zephyr-3.2.0-rc3
  1224. (package (inherit zephyr)
  1225. (version &amp;quot;3.2.0-rc3&amp;quot;)
  1226. (source (origin (method git-fetch)
  1227. (uri (git-reference
  1228. (url &amp;quot;https://github.com/zephyrproject-rtos/zephyr&amp;quot;)
  1229. (commit &amp;quot;v3.2.0-rc3&amp;quot;)))
  1230. (file-name (git-file-name &amp;quot;zephyr&amp;quot; version))
  1231. (sha256
  1232. (base32 &amp;quot;06ksd9zj4j19jq0zg3lms13jx0gxzjc41433zgb91cnd2cqmn5cb&amp;quot;))
  1233. (patches
  1234. (search-patches &amp;quot;zephyr-3.1-linker-gen-abs-path.patch&amp;quot;))))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here we use the &lt;code&gt;copy-build-system&lt;/code&gt; which takes a list of source destination
  1235. pairs. In our case, we just copy everything to the output directory, but not
  1236. before patching some files to accomodate our special environment.&lt;/p&gt;&lt;p&gt;While developing this I wanted to test some toolchain/board features
  1237. on the latest release of Zephyr. I included an example of that package
  1238. definition to show how we can easily accomodate side by side package
  1239. variants and experiment without breaking anything.&lt;/p&gt;&lt;h3&gt;Modules&lt;/h3&gt;&lt;p&gt;It's finally time to define some firmware!
  1240. Zephyr packages some examples in &lt;code&gt;$ZEPHYR_BASE/samples&lt;/code&gt; including a
  1241. basic hello world. The k64 development board is already supported
  1242. by Zephyr so building the example is trivial.&lt;/p&gt;&lt;p&gt;In order to actually target the k64 we need to two modules, the NXP
  1243. hardware abstraction layer, and CMSIS.
  1244. Looking at &lt;code&gt;$ZEPHYR_BASE/west.yml&lt;/code&gt; we can see the repositories
  1245. and commits which contain these modules. This is how West does
  1246. dependency management.&lt;/p&gt;&lt;p&gt;Defining these packages is not so bad (see footnote 1).&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define-public hal-cmsis
  1247. (package
  1248. (name &amp;quot;hal-cmsis&amp;quot;)
  1249. (version &amp;quot;5.8.0&amp;quot;)
  1250. (home-page &amp;quot;https://developer.arm.com/tools-and-software/embedded/cmsis&amp;quot;)
  1251. (source (origin
  1252. (method git-fetch)
  1253. (uri (git-reference
  1254. (url &amp;quot;https://github.com/zephyrproject-rtos/cmsis&amp;quot;)
  1255. (commit &amp;quot;093de61c2a7d12dc9253daf8692f61f793a9254a&amp;quot;)))
  1256. (file-name (git-file-name name version))
  1257. (sha256
  1258. (base32 &amp;quot;0f7cipnwllna7iknsnz273jkvrly16yr6wm4y2018i6njpqh67wi&amp;quot;))))
  1259. (build-system zephyr-module-build-system)
  1260. (arguments `(#:workspace-path &amp;quot;/modules/hal/cmsis&amp;quot;))
  1261. (synopsis &amp;quot;Zephyr module providing the Common Microcontroller
  1262. Software Interface Standard&amp;quot;)
  1263. (description &amp;quot;Zephyr module providing the Common Microcontroller
  1264. Software Interface Standard&amp;quot;)
  1265. (license license:apsl2)))
  1266. (define-public hal-nxp
  1267. (package
  1268. (name &amp;quot;hal-nxp&amp;quot;)
  1269. (version &amp;quot;3.1.0&amp;quot;)
  1270. (home-page &amp;quot;https://nxp.com&amp;quot;)
  1271. (source (origin
  1272. (method git-fetch)
  1273. (uri (git-reference
  1274. (url &amp;quot;https://github.com/zephyrproject-rtos/hal_nxp&amp;quot;)
  1275. (commit &amp;quot;708c95825b0d5279620935a1356299fff5dfbc6e&amp;quot;)))
  1276. (file-name (git-file-name name version))
  1277. (sha256
  1278. (base32 &amp;quot;1c0i26bpk6cyhr1q4af183jclfmxshv4d15i7k3cz7brzb12m8q1&amp;quot;))))
  1279. (build-system zephyr-module-build-system)
  1280. (arguments `(#:workspace-path &amp;quot;/modules/hal/nxp&amp;quot;))
  1281. (native-search-paths
  1282. (list (search-path-specification
  1283. (variable &amp;quot;ZEPHYR_MODULES&amp;quot;)
  1284. (files `(,(string-append %zephyr-workspace-name module-path)))
  1285. (separator &amp;quot;;&amp;quot;))))
  1286. (synopsis &amp;quot;Zephyr module for NXP Hardware Abstraction Layer&amp;quot;)
  1287. (description &amp;quot;Provides sources for NXP HAL zephyr module&amp;quot;)
  1288. (license license:bsd-3)))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With these two modules defined we can write &lt;code&gt;zephyr-hello-world-frdm-k64f&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Hello world&lt;/h3&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define-public zephyr-hello-world-frdm-k64f
  1289. (package
  1290. (name &amp;quot;zephyr-hello-world-frdm-k64f&amp;quot;)
  1291. (version (package-version zephyr))
  1292. (home-page &amp;quot;https://zephyrproject.org&amp;quot;)
  1293. (source (file-append (package-source zephyr)
  1294. &amp;quot;/samples/hello_world&amp;quot;))
  1295. (build-system zephyr-build-system)
  1296. (arguments
  1297. '(#:configure-flags '(&amp;quot;-DBOARD=frdm_k64f&amp;quot;)))
  1298. (outputs '(&amp;quot;out&amp;quot; &amp;quot;debug&amp;quot;))
  1299. (inputs
  1300. (list hal-cmsis
  1301. hal-nxp))
  1302. (synopsis &amp;quot;Hello world example from Zephyr Project&amp;quot;)
  1303. (description &amp;quot;Sample package for zephyr project&amp;quot;)
  1304. (license license:apsl2)))&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Building&lt;/h3&gt;&lt;p&gt;Our above definition can be built using the following:
  1305. When testing package definitions, I use the &lt;code&gt;-L&lt;/code&gt; flag to point to the local
  1306. repository to load the new packages. I will be omitting that flag as
  1307. if I had ~guix pull~ed successfully from &lt;a href=&quot;https://github.com/paperclip4465/guix-zephyr&quot;&gt;guix-zephyr&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;guix build zephyr-hello-world-frdm-k64f
  1308. /gnu/store/...-zephyr-hello-world-frdm-k64f-3.1.0-debug
  1309. /gnu/store/...-zephyr-hello-world-frdm-k64f-3.1.0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This actually doesn't fully test our toolchain. The hello world
  1310. example, by default, will use a zephyr provided
  1311. minimal implementation of the C library and will not link against
  1312. newlib.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define-public zephyr-hello-world-newlib-frdm-k64f
  1313. (package
  1314. (inherit zephyr-hello-world-frdm-k64f)
  1315. (name &amp;quot;zephyr-hello-world-newlib-frdm-k64f&amp;quot;)
  1316. (arguments
  1317. (substitute-keyword-arguments (package-arguments zephyr-hello-world-frdm-k64f)
  1318. ((#:configure-flags flags)
  1319. `(append
  1320. '(&amp;quot;-DCONFIG_MINIMAL_LIBC=n&amp;quot;
  1321. &amp;quot;-DCONFIG_NEWLIB_LIBC=y&amp;quot;)
  1322. ,flags))))))
  1323. guix build zephyr-hello-world-newlib-frdm-k64f
  1324. /gnu/store/...-zephyr-hello-world-newlib-frdm-k64f-3.1.0-debug
  1325. /gnu/store/...-zephyr-hello-world-newlib-frdm-k64f-3.1.0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Woohoo!&lt;/p&gt;&lt;h1&gt;Further Musings&lt;/h1&gt;&lt;p&gt;One thing I learned while going through the pains of getting this
  1326. working is that even though the components are &amp;quot;modular&amp;quot; there is
  1327. still a lot rigid interdependencies, especially on the zephyr base.
  1328. Just having two versions of Zephyr in the code base made component
  1329. composition fragile.
  1330. Modules rely on specific features from the kernel.
  1331. This is hidden from developers normally by west automagically walking
  1332. the `west.yml` of all of the declared dependencies recursively to
  1333. discover the graph.&lt;/p&gt;&lt;p&gt;While there are many benefits to a modularized build system, a monolithic build
  1334. system, like Zephyr, does have many benefits too.&lt;/p&gt;&lt;p&gt;Part of the problem comes from the domain itself. If you really want to be able
  1335. to target the most resource constrained systems and deal with the &amp;quot;industrial
  1336. mess&amp;quot; that comes from every board being unique, you have to be as generic and
  1337. flexible as possible, which is hard in a guix-like modular build system.&lt;/p&gt;&lt;p&gt;Superficially the problem is solved in the same way Linux solved it, using
  1338. device trees and having a very stable userland interface. However, unlike Linux
  1339. where the device tree is compiled to a binary blob and interpreted by drivers at
  1340. runtime, Zephyr device trees are compiled to a &lt;code&gt;.h&lt;/code&gt; file and are mostly
  1341. interpreted by the C pre-processor using an elaborate set of macros.&lt;/p&gt;&lt;p&gt;It goes beyond simply abstracting the hardware using clever hacks.
  1342. Zephyr applications (and any zephyr module) can also introduce new
  1343. &amp;quot;kernel&amp;quot; code, configuration options, and even linker script fragments
  1344. at build time.
  1345. Essentially the Zephyr CMake build system acts like a reverse ld.
  1346. Instead of linking libraries after compilation, it discovers these
  1347. things before gcc is ever invoked and provides additional code
  1348. generation steps.&lt;/p&gt;&lt;p&gt;Zephyr does not have a stable &amp;quot;userland&amp;quot; interface for the same
  1349. reason Linux does not have a stable &amp;quot;kernel module&amp;quot; interface.
  1350. Because Zephyr applications are so tightly coupled to the hardware
  1351. they run on it is not uncommon to bypass Zephyr utilities and directly
  1352. touch hardware and memory.&lt;/p&gt;&lt;p&gt;In this way they are more related to kernel modules
  1353. than userspace applications such as GNU Hello.&lt;/p&gt;&lt;p&gt;Perhaps there is a lispy way to track several zephyr releases without reducing
  1354. the ability to freely modify components in the usual ways...I invite you dear
  1355. reader to developer code to explore that possibility.&lt;/p&gt;&lt;p&gt;It is use-able for Guix anyway.&lt;/p&gt;&lt;h1&gt;Why a Special Build System? Why not &lt;code&gt;--target=frdm_k64f&lt;/code&gt;?&lt;/h1&gt;&lt;p&gt;That is a fair question!
  1356. At first glance you might imagine the following incantation:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;guix build --target=arm-zephyr-eabi hello&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The problem with calling the toolchain directly is that the architecture
  1357. is specified by the board selection. It is not generally useful to
  1358. compile a board to a different architecture.&lt;/p&gt;&lt;p&gt;Perhaps maybe something like this then.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;guix build --target=frdm_k64f hello&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above command tells GNU hello to link against arm-zephyr-newlib and run on
  1359. a specific board. The problem is that while this &lt;em&gt;may&lt;/em&gt; work for GNU Hello, it
  1360. will not work for anything, which requires inputs that are discovered by normal
  1361. methods. Only packages which target zephyr explicitly could benefit from such an
  1362. interface, and at that point, you may as well record which board is being targeted
  1363. in the package definition.&lt;/p&gt;&lt;p&gt;In general not all zephyr applications can run on every board zephyr
  1364. can run on, so the usefulness of the above command is dubious.&lt;/p&gt;&lt;p&gt;I think if you have firmware which targets multiple boards it is
  1365. better to define a package for every board. It is likely every board
  1366. will require special configuration flags anyway.&lt;/p&gt;&lt;h1&gt;Conclusion&lt;/h1&gt;&lt;p&gt;Zephyr has a very complex build process which can be difficult to
  1367. understand and frustrating to set up.&lt;/p&gt;&lt;p&gt;Using Guix to define firmware packages makes these problems disappear.
  1368. It is trivial to create a channel which contains all of the quirks of
  1369. your platform and share it with a team or student.&lt;/p&gt;&lt;p&gt;Packages defined this way serve as a reproducible starting point for
  1370. future hardware revisions and variations.&lt;/p&gt;&lt;h1&gt;Footnotes&lt;/h1&gt;&lt;ol&gt;&lt;li&gt;I also made a &lt;code&gt;zephyr-module-build-system&lt;/code&gt; as well which is just the
  1371. &lt;code&gt;copy-build-system&lt;/code&gt; that mimics the default zephyr workspace layout as provided
  1372. by west. This way we do not need to provide the same install-plan for every
  1373. module we package. However as I use the &lt;code&gt;copy-build-system&lt;/code&gt; more often, it
  1374. doesn't really provide much over just using the copy-build system.&lt;/li&gt;&lt;/ol&gt;</content></entry><entry><title>Building Toolchains with Guix</title><id>https://gnucode.me/building-toolchains-with-guix.html</id><author><name>Mitchell Schmeisser &lt;mitchellschmeisser@librem.one&gt;</name><email>jbranso@dismail.de</email></author><updated>2023-02-23T23:00:00Z</updated><link href="https://gnucode.me/building-toolchains-with-guix.html" rel="alternate" /><content type="html">&lt;p&gt;Today's post is a guest post from my new internet friend Mitchell. We met on the
  1375. #guix irc channel, and I offered to post a few of his blog posts on this blog. Without further ado,
  1376. here is Michell's first blog post (it's pretty fantastic)!&lt;/p&gt;&lt;h1&gt;Overview&lt;/h1&gt;&lt;p&gt;In order to deploy embedded software using Guix we first need to teach Guix
  1377. how to build it. Since Guix bootstraps everything this means we must teach Guix
  1378. how to build our toolchain.&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://zephyrproject.org&quot;&gt;Zephyr Project&lt;/a&gt; uses its own fork of GCC with custom configs for
  1379. the architectures supported by the project.&lt;/p&gt;&lt;h1&gt;Anatomy of a toolchain&lt;/h1&gt;&lt;p&gt;Toolchains are responsible for taking high level descriptions of programs and
  1380. lowering them down to a series of equivalent machine instructions. This process
  1381. involves more than just a compiler. The compiler uses the &lt;code&gt;binutils&lt;/code&gt; to
  1382. manipulate it’s internal representation down to a given architecture. It
  1383. also needs the C standard library as well as a few other libraries needed for
  1384. some compiler optimizations.&lt;/p&gt;&lt;p&gt;The C library provides the interface to the underlying kernel. System calls like &lt;code&gt;write&lt;/code&gt;
  1385. and &lt;code&gt;read&lt;/code&gt; are provided by &lt;code&gt;Glibc&lt;/code&gt; on most Linux distributions.&lt;/p&gt;&lt;p&gt;In embedded systems smaller implementations like &lt;code&gt;newlib&lt;/code&gt; and &lt;code&gt;newlib-nano&lt;/code&gt; are used.&lt;/p&gt;&lt;h1&gt;Bootstrapping a Toolchain&lt;/h1&gt;&lt;p&gt;In order to compile GCC we need a C library that’s been compiled for
  1386. our target architecture. How can we cross compile our C library if we
  1387. need our C library to build a cross compiler? The solution is to build
  1388. a simpler compiler that doesn’t require the C library to function.
  1389. It will not be capable of as many optimizations and it will be very slow,
  1390. however it will be able to build the C libraries as well as the complete version
  1391. of GCC.&lt;/p&gt;&lt;p&gt;In order to build the simpler compiler we need to compile the &lt;code&gt;binutils&lt;/code&gt; to
  1392. work with our target architecture.
  1393. The &lt;code&gt;binutils&lt;/code&gt; can be bootstrapped with our host GCC and have no target dependencies.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://crosstool-ng.github.io/docs/toolchain-construction/&quot;&gt;For more information read this.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Doesn’t sound so bad right? It isn’t… in theory.
  1394. However internet forums since time immemorial have been
  1395. littered with the laments of those who came before.
  1396. From incorrect versions of &lt;code&gt;ISL&lt;/code&gt; to the wrong C library being linked
  1397. or the host linker being used, etc.
  1398. The one commonality between all of these issues is the environment.
  1399. Building GCC is difficult because isolating build environments is hard.&lt;/p&gt;&lt;p&gt;In fact as of &lt;code&gt;v0.14.2&lt;/code&gt; the zephyr SDK repository took down the build
  1400. instructions and posted a sign that read “Building this is too
  1401. complicated, don’t worry about it.” (I’m paraphrasing, but
  1402. &lt;a href=&quot;https://github.com/zephyrproject-rtos/sdk-ng/tree/v0.14.2#build-process&quot;&gt;not by
  1403. much&lt;/a&gt;.)&lt;/p&gt;&lt;p&gt;We will neatly side step all of these problems and not
  1404. risk destroying or polluting our host system with garbage
  1405. by using Guix to manage our environments for us.&lt;/p&gt;&lt;p&gt;Our toolchain only requires the first pass compiler because
  1406. newlib(-nano) is statically linked and introduced to the toolchain
  1407. by normal package composition.&lt;/p&gt;&lt;h1&gt;Defining the Packages&lt;/h1&gt;&lt;p&gt;All of the base packages are defined in &lt;code&gt;zephyr/packages/zephyr.scm&lt;/code&gt;.
  1408. Zephyr modules are defined in &lt;code&gt;zephyr/packages/zephyr-xyz.scm&lt;/code&gt;, following
  1409. the pattern of other module systems implemented by Guix.&lt;/p&gt;&lt;h2&gt;Binutils&lt;/h2&gt;&lt;p&gt;First thing we need to build is the &lt;code&gt;arm-zephyr-eabi&lt;/code&gt; binutils.
  1410. This is very easy in Guix.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(define-module (zephyr packages zephyr)
  1411. #:use-module (guix packages)
  1412. (define-public arm-zephyr-eabi-binutils
  1413. (let ((xbinutils (cross-binutils &amp;quot;arm-zephyr-eabi&amp;quot;)))
  1414. (package
  1415. (inherit xbinutils)
  1416. (name &amp;quot;arm-zephyr-eabi-binutils&amp;quot;)
  1417. (version &amp;quot;2.38&amp;quot;)
  1418. (source
  1419. (origin (method git-fetch)
  1420. (uri (git-reference
  1421. (url &amp;quot;https://github.com/zephyrproject-rtos/binutils-gdb&amp;quot;)
  1422. (commit &amp;quot;6a1be1a6a571957fea8b130e4ca2dcc65e753469&amp;quot;)))
  1423. (file-name (git-file-name name version))
  1424. (sha256 (base32 &amp;quot;0ylnl48jj5jk3jrmvfx5zf8byvwg7g7my7jwwyqw3a95qcyh0isr&amp;quot;))))
  1425. (arguments
  1426. `(#:tests? #f
  1427. ,@(substitute-keyword-arguments (package-arguments xbinutils)
  1428. ((#:configure-flags flags)
  1429. `(cons &amp;quot;--program-prefix=arm-zephyr-eabi-&amp;quot; ,flags)))))
  1430. (native-inputs
  1431. (append
  1432. (list texinfo
  1433. bison
  1434. flex
  1435. gmp
  1436. dejagnu)
  1437. (package-native-inputs xbinutils)))
  1438. (home-page &amp;quot;https://zephyrproject.org&amp;quot;)
  1439. (synopsis &amp;quot;binutils for zephyr RTOS&amp;quot;))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The function &lt;code&gt;cross-binutils&lt;/code&gt; returns a package which has been
  1440. configured for the given gnu triplet. We simply inherit that package
  1441. and replace the source.
  1442. The zephyr build system expects the binutils to be prefixed with
  1443. &lt;code&gt;arm-zephyr-eabi-&lt;/code&gt; which is accomplished by adding another flag to the
  1444. &lt;code&gt;#:configure-flags&lt;/code&gt; argument.&lt;/p&gt;&lt;p&gt;We can test our package definition using the &lt;code&gt;-L&lt;/code&gt; flag with &lt;code&gt;guix build&lt;/code&gt;
  1445. to add our packages.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix build -L guix-zephyr zephyr-binutils
  1446. /gnu/store/a947nb4rb2vymz2gaqnafgm1bsq4ipqp-zephyr-binutils-2.38&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This directory contains the results of &lt;code&gt;make install&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;GCC sans libc&lt;/h2&gt;&lt;p&gt;This one is a bit more involved. Don’t be afraid!
  1447. This version of GCC wants ISL version 0.15. It’s easy enough
  1448. to make that happen. Inherit the current version of ISL and swap
  1449. out the source and update the version. For most packages the build process doesn’t
  1450. change that much between versions.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(define-public isl-0.15
  1451. (package
  1452. (inherit isl)
  1453. (version &amp;quot;0.15&amp;quot;)
  1454. (source (origin
  1455. (method url-fetch)
  1456. (uri (list (string-append &amp;quot;mirror://sourceforge/libisl/isl-&amp;quot;
  1457. version &amp;quot;.tar.gz&amp;quot;)))
  1458. (sha256
  1459. (base32
  1460. &amp;quot;11vrpznpdh7w8jp4wm4i8zqhzq2h7nix71xfdddp8xnzhz26gyq2&amp;quot;))))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Like the binutils, there is a function for creating cross-gcc packages. This one
  1461. accepts keywords specifying which binutils and libc to use. If libc isn’t
  1462. given (like here), gcc is configured with many options disabled to facilitate
  1463. being built without libc. Therefore we need to add the extra options we want (I
  1464. got them from the SDK configuration scripts on the &lt;a href=&quot;https://github.com/zephyrproject-rtos/sdk-ng&quot;&gt;sdk
  1465. github&lt;/a&gt; as well as the commits to
  1466. use for each of the tools. ).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(define-public gcc-arm-zephyr-eabi-12
  1467. (let ((xgcc (cross-gcc &amp;quot;arm-zephyr-eabi&amp;quot;
  1468. #:xbinutils zephyr-binutils)))
  1469. (package
  1470. (inherit xgcc)
  1471. (version &amp;quot;12.1.0&amp;quot;)
  1472. (source (origin (method git-fetch)
  1473. (uri (git-reference
  1474. (url &amp;quot;https://github.com/zephyrproject-rtos/gcc&amp;quot;)
  1475. (commit &amp;quot;0218469df050c33479a1d5be3e5239ac0eb351bf&amp;quot;)))
  1476. (file-name (git-file-name (package-name xgcc) version))
  1477. (sha256
  1478. (base32 &amp;quot;1s409qmidlvzaw1ns6jaanigh3azcxisjplzwn7j2n3s33b76zjk&amp;quot;))
  1479. (patches
  1480. (search-patches &amp;quot;gcc-12-cross-environment-variables.patch&amp;quot;
  1481. &amp;quot;gcc-cross-gxx-include-dir.patch&amp;quot;))))
  1482. (native-inputs
  1483. (modify-inputs (package-native-inputs xgcc)
  1484. ;; Get rid of stock ISL
  1485. (delete &amp;quot;isl&amp;quot;)
  1486. ;; Add additional dependencies that xgcc doesn't have
  1487. ;; including our special ISL
  1488. (prepend flex
  1489. perl
  1490. python-3
  1491. gmp
  1492. isl-0.15
  1493. texinfo
  1494. python
  1495. mpc
  1496. mpfr
  1497. zlib)))
  1498. (arguments
  1499. (substitute-keyword-arguments (package-arguments xgcc)
  1500. ((#:phases phases)
  1501. `(modify-phases ,phases
  1502. (add-after 'unpack 'fix-genmultilib
  1503. (lambda _
  1504. (substitute* &amp;quot;gcc/genmultilib&amp;quot;
  1505. ((&amp;quot;#!/bin/sh&amp;quot;) (string-append &amp;quot;#!&amp;quot; (which &amp;quot;sh&amp;quot;))))
  1506. #t))
  1507. (add-after 'set-paths 'augment-CPLUS_INCLUDE_PATH
  1508. (lambda* (#:key inputs #:allow-other-keys)
  1509. (let ((gcc (assoc-ref inputs &amp;quot;gcc&amp;quot;)))
  1510. ;; Remove the default compiler from CPLUS_INCLUDE_PATH to
  1511. ;; prevent header conflict with the GCC from native-inputs.
  1512. (setenv &amp;quot;CPLUS_INCLUDE_PATH&amp;quot;
  1513. (string-join
  1514. (delete (string-append gcc &amp;quot;/include/c++&amp;quot;)
  1515. (string-split (getenv &amp;quot;CPLUS_INCLUDE_PATH&amp;quot;)
  1516. #\:))
  1517. &amp;quot;:&amp;quot;))
  1518. (format #t
  1519. &amp;quot;environment variable `CPLUS_INCLUDE_PATH' changed to ~a~%&amp;quot;
  1520. (getenv &amp;quot;CPLUS_INCLUDE_PATH&amp;quot;))
  1521. #t)))))
  1522. ((#:configure-flags flags)
  1523. ;; The configure flags are largely identical to the flags used by the
  1524. ;; &amp;quot;GCC ARM embedded&amp;quot; project.
  1525. `(append (list &amp;quot;--enable-multilib&amp;quot;
  1526. &amp;quot;--with-newlib&amp;quot;
  1527. &amp;quot;--with-multilib-list=rmprofile&amp;quot;
  1528. &amp;quot;--with-host-libstdcxx=-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm&amp;quot;
  1529. &amp;quot;--enable-plugins&amp;quot;
  1530. &amp;quot;--disable-decimal-float&amp;quot;
  1531. &amp;quot;--disable-libffi&amp;quot;
  1532. &amp;quot;--disable-libgomp&amp;quot;
  1533. &amp;quot;--disable-libmudflap&amp;quot;
  1534. &amp;quot;--disable-libquadmath&amp;quot;
  1535. &amp;quot;--disable-libssp&amp;quot;
  1536. &amp;quot;--disable-libstdcxx-pch&amp;quot;
  1537. &amp;quot;--disable-nls&amp;quot;
  1538. &amp;quot;--disable-shared&amp;quot;
  1539. &amp;quot;--disable-threads&amp;quot;
  1540. &amp;quot;--disable-tls&amp;quot;
  1541. &amp;quot;--with-gnu-ld&amp;quot;
  1542. &amp;quot;--with-gnu-as&amp;quot;
  1543. &amp;quot;--enable-initfini-array&amp;quot;)
  1544. (delete &amp;quot;--disable-multilib&amp;quot; ,flags)))))
  1545. (native-search-paths
  1546. (list (search-path-specification
  1547. (variable &amp;quot;CROSS_C_INCLUDE_PATH&amp;quot;)
  1548. (files '(&amp;quot;arm-zephyr-eabi/include&amp;quot;)))
  1549. (search-path-specification
  1550. (variable &amp;quot;CROSS_CPLUS_INCLUDE_PATH&amp;quot;)
  1551. (files '(&amp;quot;arm-zephyr-eabi/include&amp;quot;
  1552. &amp;quot;arm-zephyr-eabi/c++&amp;quot;
  1553. &amp;quot;arm-zephyr-eabi/c++/arm-zephyr-eabi&amp;quot;)))
  1554. (search-path-specification
  1555. (variable &amp;quot;CROSS_LIBRARY_PATH&amp;quot;)
  1556. (files '(&amp;quot;arm-zephyr-eabi/lib&amp;quot;)))))
  1557. (home-page &amp;quot;https://zephyrproject.org&amp;quot;)
  1558. (synopsis &amp;quot;GCC for zephyr RTOS&amp;quot;))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This GCC can be built like so.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix build -L guix-zephyr gcc-cross-sans-libc-arm-zephyr-eabi
  1559. /gnu/store/qmp8bzmwwimw0r6fh165hgfhkxkxilpj-gcc-cross-sans-libc-arm-zephyr-eabi-12.1.0-lib
  1560. /gnu/store/38rli0rbn7ksmym3wq99cr4p2cjdz4a7-gcc-cross-sans-libc-arm-zephyr-eabi-12.1.0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Great! We now have our stage-1 compiler.&lt;/p&gt;&lt;h2&gt;Newlib(-nano)&lt;/h2&gt;&lt;p&gt;The newlib package is quite straight forward (relatively).
  1561. It is mostly adding in the relevent configuration flags and patching
  1562. the files the &lt;code&gt;patch-shebangs&lt;/code&gt; phase missed.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; (define-public zephyr-newlib
  1563. (package
  1564. (name &amp;quot;zephyr-newlib&amp;quot;)
  1565. (version &amp;quot;3.3&amp;quot;)
  1566. (source (origin
  1567. (method git-fetch)
  1568. (uri (git-reference
  1569. (url &amp;quot;https://github.com/zephyrproject-rtos/newlib-cygwin&amp;quot;)
  1570. (commit &amp;quot;4e150303bcc1e44f4d90f3489a4417433980d5ff&amp;quot;)))
  1571. (sha256
  1572. (base32 &amp;quot;08qwjpj5jhpc3p7a5mbl7n6z7rav5yqlydqanm6nny42qpa8kxij&amp;quot;))))
  1573. (build-system gnu-build-system)
  1574. (arguments
  1575. `(#:out-of-source? #t
  1576. #:configure-flags '(&amp;quot;--target=arm-zephyr-eabi&amp;quot;
  1577. &amp;quot;--enable-newlib-io-long-long&amp;quot;
  1578. &amp;quot;--enable-newlib-io-float&amp;quot;
  1579. &amp;quot;--enable-newlib-io-c99-formats&amp;quot;
  1580. &amp;quot;--enable-newlib-retargetable-locking&amp;quot;
  1581. &amp;quot;--enable-newlib-lite-exit&amp;quot;
  1582. &amp;quot;--enable-newlib-multithread&amp;quot;
  1583. &amp;quot;--enable-newlib-register-fini&amp;quot;
  1584. &amp;quot;--enable-newlib-extra-sections&amp;quot;
  1585. &amp;quot;--disable-newlib-wide-orient&amp;quot;
  1586. &amp;quot;--disable-newlib-fseek-optimization&amp;quot;
  1587. &amp;quot;--disable-newlib-supplied-syscalls&amp;quot;
  1588. &amp;quot;--disable-newlib-target-optspace&amp;quot;
  1589. &amp;quot;--disable-nls&amp;quot;)
  1590. #:phases
  1591. (modify-phases %standard-phases
  1592. (add-after 'unpack 'fix-references-to-/bin/sh
  1593. (lambda _
  1594. (substitute* '(&amp;quot;libgloss/arm/cpu-init/Makefile.in&amp;quot;
  1595. &amp;quot;libgloss/arm/Makefile.in&amp;quot;
  1596. &amp;quot;libgloss/libnosys/Makefile.in&amp;quot;
  1597. &amp;quot;libgloss/Makefile.in&amp;quot;)
  1598. ((&amp;quot;/bin/sh&amp;quot;) (which &amp;quot;sh&amp;quot;)))
  1599. #t)))))
  1600. (native-inputs
  1601. `((&amp;quot;xbinutils&amp;quot; ,zephyr-binutils)
  1602. (&amp;quot;xgcc&amp;quot; ,gcc-arm-zephyr-eabi-12)
  1603. (&amp;quot;texinfo&amp;quot; ,texinfo)))
  1604. (home-page &amp;quot;https://www.sourceware.org/newlib/&amp;quot;)
  1605. (synopsis &amp;quot;C library for use on embedded systems&amp;quot;)
  1606. (description &amp;quot;Newlib is a C library intended for use on embedded
  1607. systems. It is a conglomeration of several library parts that are easily
  1608. usable on embedded products.&amp;quot;)
  1609. (license (license:non-copyleft
  1610. &amp;quot;https://www.sourceware.org/newlib/COPYING.NEWLIB&amp;quot;))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And the build.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix build -L guix-zephyr zephyr-newlib
  1611. /gnu/store/4lx37gga1jv3ckykrxsfgwy9slaamln4-zephyr-newlib-3.3&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Complete toolchain&lt;/h2&gt;&lt;p&gt;Note that the toolchain is &lt;em&gt;Mostly&lt;/em&gt; complete. libstdc++ does not build because
  1612. `arm-zephyr-eabi` is not `arm-none-eabi` so a dynamic link check is
  1613. performed/failed. I cannot figure out how crosstool-ng handles this.&lt;/p&gt;&lt;p&gt;Anyway, now that we’ve got the individual tools it’s time to create
  1614. our complete toolchain. For this we need to do some package transformations.
  1615. Because these transformations are must be done for every combination of
  1616. binutils/gcc/newlib, it is best to create a function which we can reuse for
  1617. every version of the SDK.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(define (arm-zephyr-eabi-toolchain xgcc newlib version)
  1618. &amp;quot;Produce a cross-compiler zephyr toolchain package with the compiler XGCC and the C
  1619. library variant NEWLIB.&amp;quot;
  1620. (let ((newlib-with-xgcc (package (inherit newlib)
  1621. (native-inputs
  1622. (alist-replace &amp;quot;xgcc&amp;quot; (list xgcc)
  1623. (package-native-inputs newlib))))))
  1624. (package
  1625. (name (string-append &amp;quot;arm-zephyr-eabi&amp;quot;
  1626. (if (string=? (package-name newlib-with-xgcc)
  1627. &amp;quot;newlib-nano&amp;quot;)
  1628. &amp;quot;-nano&amp;quot; &amp;quot;&amp;quot;)
  1629. &amp;quot;-toolchain&amp;quot;))
  1630. (version version)
  1631. (source #f)
  1632. (build-system trivial-build-system)
  1633. (arguments
  1634. '(#:modules ((guix build union)
  1635. (guix build utils))
  1636. #:builder
  1637. (begin
  1638. (use-modules (ice-9 match)
  1639. (guix build union)
  1640. (guix build utils))
  1641. (let ((out (assoc-ref %outputs &amp;quot;out&amp;quot;)))
  1642. (mkdir-p out)
  1643. (match %build-inputs
  1644. (((names . directories) ...)
  1645. (union-build (string-append out &amp;quot;/arm-zephyr-eabi&amp;quot;)
  1646. directories)
  1647. #t))))))
  1648. (inputs
  1649. `((&amp;quot;binutils&amp;quot; ,zephyr-binutils)
  1650. (&amp;quot;gcc&amp;quot; ,xgcc)
  1651. (&amp;quot;newlib&amp;quot; ,newlib-with-xgcc)))
  1652. (synopsis &amp;quot;Complete GCC tool chain for ARM zephyrRTOS development&amp;quot;)
  1653. (description &amp;quot;This package provides a complete GCC tool chain for ARM
  1654. bare metal development with zephyr rtos. This includes the GCC arm-zephyr-eabi cross compiler
  1655. and newlib (or newlib-nano) as the C library. The supported programming
  1656. language is C.&amp;quot;)
  1657. (home-page (package-home-page xgcc))
  1658. (license (package-license xgcc)))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This function creates a special package which consists of the toolchain in a special directory hierarchy, i.e &lt;code&gt;arm-zephyr-eabi/&lt;/code&gt;.
  1659. Our complete toolchain definition looks like this.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(define-public arm-zephyr-eabi-toolchain-0.15.0
  1660. (arm-zephyr-eabi-toolchain
  1661. gcc-arm-zephyr-eabi-12
  1662. zephyr-newlib
  1663. &amp;quot;0.15.0&amp;quot;))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To build:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix build -L guix-zephyr arm-zephyr-eabi-toolchain
  1664. /gnu/store/9jnanr27v6na5qq3dlgljraysn8r1sad-arm-zephyr-eabi-toolchain-0.15.0&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;Integrating with Zephyr Build System&lt;/h1&gt;&lt;p&gt;Zephyr uses CMake as it’s build system. It contains numerous CMake files in both the so-called &lt;code&gt;ZEPHYR_BASE&lt;/code&gt;,
  1665. the zephyr source code repository, as well as a handful in the SDK which help select the correct toolchain
  1666. for a given board.&lt;/p&gt;&lt;p&gt;There are standard locations the build system will look for the SDK. We are not
  1667. using any of them. Our SDK lives in the store, immutable forever. According to
  1668. &lt;a href=&quot;https://docs.zephyrproject.org/latest/develop/west/without-west.html&quot;&gt;this
  1669. webpage&lt;/a&gt;,
  1670. the variable &lt;code&gt;ZEPHYR_SDK_INSTALL_DIR&lt;/code&gt; needs to point to our custom spot.&lt;/p&gt;&lt;p&gt;We also need to grab the cmake files from the &lt;a href=&quot;https://github.com/zephyrproject-rtos/sdk-ng&quot;&gt;repository&lt;/a&gt; and create a file &lt;code&gt;sdk_version&lt;/code&gt; which
  1671. contains the version string &lt;code&gt;ZEPHYR_BASE&lt;/code&gt; uses to find a compatible SDK.&lt;/p&gt;&lt;p&gt;Along with the SDK proper we need to include a number of python packages required by the build system.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; (define-public zephyr-sdk
  1672. (package
  1673. (name &amp;quot;zephyr-sdk&amp;quot;)
  1674. (version &amp;quot;0.15.0&amp;quot;)
  1675. (home-page &amp;quot;https://zephyrproject.org&amp;quot;)
  1676. (source (origin (method git-fetch)
  1677. (uri (git-reference
  1678. (url &amp;quot;https://github.com/zephyrproject-rtos/sdk-ng&amp;quot;)
  1679. (commit &amp;quot;v0.15.0&amp;quot;)))
  1680. (file-name (git-file-name name version))
  1681. (sha256 (base32 &amp;quot;04gsvh20y820dkv5lrwppbj7w3wdqvd8hcanm8hl4wi907lwlmwi&amp;quot;))))
  1682. (build-system trivial-build-system)
  1683. (arguments
  1684. `(#:modules ((guix build union)
  1685. (guix build utils))
  1686. #:builder
  1687. (begin
  1688. (use-modules (guix build union)
  1689. (ice-9 match)
  1690. (guix build utils))
  1691. (let* ((out (assoc-ref %outputs &amp;quot;out&amp;quot;))
  1692. (cmake-scripts (string-append (assoc-ref %build-inputs &amp;quot;source&amp;quot;)
  1693. &amp;quot;/cmake&amp;quot;))
  1694. (sdk-out (string-append out &amp;quot;/zephyr-sdk-0.15.0&amp;quot;)))
  1695. (mkdir-p out)
  1696. (match (assoc-remove! %build-inputs &amp;quot;source&amp;quot;)
  1697. (((names . directories) ...)
  1698. (union-build sdk-out directories)))
  1699. (copy-recursively cmake-scripts
  1700. (string-append sdk-out &amp;quot;/cmake&amp;quot;))
  1701. (with-directory-excursion sdk-out
  1702. (call-with-output-file &amp;quot;sdk_version&amp;quot;
  1703. (lambda (p)
  1704. (format p &amp;quot;0.15.0&amp;quot;)))
  1705. #t)))))
  1706. (propagated-inputs
  1707. (list
  1708. arm-zephyr-eabi-toolchain-0.15.0
  1709. zephyr-binutils
  1710. dtc))
  1711. (native-search-paths
  1712. (list (search-path-specification
  1713. (variable &amp;quot;ZEPHYR_SDK_INSTALL_DIR&amp;quot;)
  1714. (files '(&amp;quot;&amp;quot;)))))
  1715. (synopsis &amp;quot;SDK for zephyrRTOS&amp;quot;)
  1716. (description &amp;quot;zephyr-sdk contains bundles a complete gcc toolchain as well
  1717. as host tools like dtc, openocd, qemu, and required python packages.&amp;quot;)
  1718. (license license:apsl2)))&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Testing&lt;/h2&gt;&lt;p&gt;In order to test we will need an environment with the SDK installed.
  1719. We can take advantage of &lt;code&gt;guix shell&lt;/code&gt; to avoid installing test packages into
  1720. our home environment. This way, if it causes problems, we can just exit the shell
  1721. and try again.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix shell -L guix-zephyr zephyr-sdk cmake ninja git&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;ZEPHYR_BASE&lt;/code&gt; can be cloned into a temporary workspace to test our toolchain
  1722. functionality (For now. Eventually we will need to create a package for
  1723. &lt;code&gt;zephyr-base&lt;/code&gt; that our guix zephyr-build-system can use).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mkdir /tmp/zephyr-project
  1724. cd /tmp/zephyr-project
  1725. git clone https://github.com/zephyrproject-rtos/zephyr
  1726. export ZEPHYR_BASE=/tmp/zephyr-project/zephyr&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to build for the test board (k64f in this case) we need to get a hold
  1727. of the vendor Hardware Abstraction Layers and CMSIS (These will also need to
  1728. become guix packages to allow the build system to compose modules).&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git clone https://github.com/zephyrproject-rtos/hal_nxp &amp;amp;&amp;amp;
  1729. git clone https://github.com/zephyrproject-rtos/cmsis&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To inform the build system about this module we pass it in with &lt;code&gt;-DZEPHYR_MODULES=&lt;/code&gt; which is
  1730. a semicolon separated list of paths containing a module.yml file.&lt;/p&gt;&lt;p&gt;To build the hello world sample we use the following incantation.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cmake -Bbuild $ZEPHYR_BASE/samples/hello_world \
  1731. -GNinja \
  1732. -DBOARD=frdm_k64f \
  1733. -DBUILD_VERSION=3.1.0 \
  1734. -DZEPHYR_MODULES=&amp;quot;/tmp/zephyr-project/hal_nxp;/tmp/zephyr-project/cmsis&amp;quot; \
  1735. &amp;amp;&amp;amp; ninja -Cbuild&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If everything is set up correctly we will end up with a &lt;code&gt;./build&lt;/code&gt;
  1736. directory with all our build artifacts. The SDK is installed correctly!&lt;/p&gt;</content></entry><entry><title>Nextcloud and Guix System Server</title><id>https://gnucode.me/nextcloud-and-guix-system-server.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-02-22T17:00:00Z</updated><link href="https://gnucode.me/nextcloud-and-guix-system-server.html" rel="alternate" /><content type="html">&lt;p&gt;So I have wanted to run &lt;a href=&quot;https://nextcloud.com/&quot;&gt;nextcloud&lt;/a&gt; for a while now. In my humble opinion, guix
  1737. system makes maintaining websites super easy, so I would prefer to run nextcloud
  1738. on guix system. Unfortunately, nextcloud will NOT be packaged in guix anytime
  1739. soon for two reasons:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Guix does not currently have a php build system or any php packages, though
  1740. there is a 80% completed &lt;a href=&quot;https://issues.guix.gnu.org/42338&quot;&gt;work-in-progress issue.&lt;/a&gt; So the php bits of nextcloud
  1741. cannot be packaged properly.&lt;/li&gt;&lt;li&gt;Nextcloud has a lot of javascript dependencies, and javascript is &lt;a href=&quot;https://dustycloud.org/blog/javascript-packaging-dystopia/&quot;&gt;notoriously
  1742. hard to package for guix.&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;It seems like the easiest way to currently run nextcloud on guix system is by
  1743. using the &lt;a href=&quot;https://github.com/nextcloud/all-in-one&quot;&gt;all in one docker image.&lt;/a&gt; Please consider this a guide to set up
  1744. running nextcloud on guix system via a linode, which currently costs me about $5
  1745. per month.&lt;/p&gt;&lt;p&gt;Note, that while this is the easiest method to run nextcloud, apparently this
  1746. all in one docker image has some security issues:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The AIO image mounts the Docker socket, which is a security risk since it allows
  1747. full access to other container as well as running any new container. It’s a bad
  1748. idea and should be avoided.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;tl;dr Here are the 6 simple steps that you need to do:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Set up a &lt;a href=&quot;https://guix.gnu.org/en/cookbook/en/html_node/Running-Guix-on-a-Linode-Server.html#Running-Guix-on-a-Linode-Server&quot;&gt;linode guix system server.&lt;/a&gt; &lt;code&gt;info &amp;quot;Guix Cookbook&amp;quot; RET i linode RET&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Buy a domain name. I use &lt;a href=&quot;https://hover.com&quot;&gt;hover.com&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Point your domain name at your linode IP address.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Set up a basic nginx static website without encryption. This means that you
  1749. don’t want to define &lt;code&gt;(service certbot-service-type)&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo mkdir -p /srv/www/html/yourdomainname.com
  1750. # the command I did was this:
  1751. sudo mkdir -p /srv/www/html/the-nx.com
  1752. sudo chgrp -R users /srv
  1753. sudo chmod -R g+rwx /srv&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Inside your newly created directory (&lt;em&gt;srv/www/html/yourdomainname.com&lt;/em&gt;), put
  1754. a simple HTML file and call it “index.html”. You could use this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
  1755. &amp;lt;html class=&amp;quot;no-js&amp;quot; lang=&amp;quot;&amp;quot;&amp;gt;
  1756. &amp;lt;head&amp;gt;
  1757. &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;
  1758. &amp;lt;meta http-equiv=&amp;quot;x-ua-compatible&amp;quot; content=&amp;quot;ie=edge&amp;quot;&amp;gt;
  1759. &amp;lt;title&amp;gt;the nx&amp;lt;/title&amp;gt;
  1760. &amp;lt;meta name=&amp;quot;description&amp;quot; content=&amp;quot;&amp;quot;&amp;gt;
  1761. &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1&amp;quot;&amp;gt;
  1762. &amp;lt;link rel=&amp;quot;apple-touch-icon&amp;quot; href=&amp;quot;/apple-touch-icon.png&amp;quot;&amp;gt;
  1763. &amp;lt;/head&amp;gt;
  1764. &amp;lt;body&amp;gt;
  1765. &amp;lt;!--[if lt IE 8]&amp;gt;
  1766. &amp;lt;p class=&amp;quot;browserupgrade&amp;quot;&amp;gt;
  1767. You are using an &amp;lt;strong&amp;gt;outdated&amp;lt;/strong&amp;gt; browser. Please
  1768. &amp;lt;a href=&amp;quot;http://browsehappy.com/&amp;quot;&amp;gt;upgrade your browser&amp;lt;/a&amp;gt; to improve
  1769. your experience.
  1770. &amp;lt;/p&amp;gt;
  1771. &amp;lt;![endif]--&amp;gt;
  1772. &amp;lt;p&amp;gt;Hello!&amp;lt;/p&amp;gt;
  1773. &amp;lt;/body&amp;gt;
  1774. &amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now set up a basic nginx configuration for a static website without
  1775. encryption. It will end up looking something like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(service nginx-service-type
  1776. (nginx-configuration
  1777. (server-blocks
  1778. (list
  1779. (nginx-server-configuration
  1780. (server-name '(&amp;quot;the-nx.com&amp;quot;))
  1781. (listen (list &amp;quot;80&amp;quot; &amp;quot;[::]:80&amp;quot;))
  1782. (root &amp;quot;/srv/www/html/the-nx.com&amp;quot;))))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you need to reconfigure so that the &lt;code&gt;nginx&lt;/code&gt; user is created:&lt;/p&gt;&lt;p&gt;&lt;code&gt;sudo guix system reconfigure config.scm&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Now, nginx is running, but you will probably need to give nginx access to
  1783. read the files in your /srv directory.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo chown -R nginx /srv
  1784. sudo chmod -R u-rwx /srv&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Open up a web browser and go to &lt;a href=&quot;http://yourdomainname.com&quot;&gt;http://yourdomainname.com&lt;/a&gt; and check to see
  1785. that you see a basic website.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now you need to turn your basic static website, into a site that has https
  1786. support. Now you need to edit your nginx config and add in a certbot config:&lt;/p&gt;&lt;p&gt;Before your &lt;code&gt;(operating-system ...)&lt;/code&gt; declartion, define this bit of code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(define %nginx-deploy-hook
  1787. (program-file
  1788. &amp;quot;nginx-deploy-hook&amp;quot;
  1789. #~(let ((pid (call-with-input-file &amp;quot;/var/run/nginx/pid&amp;quot; read)))
  1790. (kill pid SIGHUP))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Also make sure that you add in a &lt;code&gt;certbot&lt;/code&gt; service and a modified &lt;code&gt;nginx&lt;/code&gt;
  1791. service that look like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(service certbot-service-type
  1792. (certbot-configuration
  1793. (email &amp;quot;mysubscriptions@member.fsf.org&amp;quot;)
  1794. (webroot &amp;quot;/srv/www/&amp;quot;)
  1795. (certificates
  1796. (list
  1797. (certificate-configuration
  1798. (name &amp;quot;the-nx.com&amp;quot;)
  1799. (domains '(&amp;quot;the-nx.com&amp;quot; &amp;quot;www.the-nx.com&amp;quot;))
  1800. (deploy-hook %nginx-deploy-hook))))))
  1801. (service nginx-service-type
  1802. (nginx-configuration
  1803. (server-blocks
  1804. (list
  1805. (nginx-server-configuration
  1806. (server-name '(&amp;quot;the-nx.com&amp;quot;))
  1807. (listen (list &amp;quot;80&amp;quot;
  1808. &amp;quot;443 ssl http2&amp;quot;
  1809. &amp;quot;[::]:80&amp;quot;
  1810. &amp;quot;[::80]:443 ssl http2&amp;quot;))
  1811. (root &amp;quot;/srv/www/html/the-nx.com&amp;quot;)
  1812. (ssl-certificate &amp;quot;/etc/letsencrypt/live/the-nx.com/fullchain.pem&amp;quot;)
  1813. (ssl-certificate-key &amp;quot;/etc/letsencrypt/live/the-nx.com/privkey.pem&amp;quot;)
  1814. (locations
  1815. (list
  1816. (nginx-location-configuration ;; for certbot
  1817. (uri &amp;quot;/.well-known&amp;quot;)
  1818. (body (list &amp;quot;root /srv/www;&amp;quot;))))))))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we will have to reconfigure again to set up certbot:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo guix system reconfigure config.scm
  1819. # tell certbot to set up our certificates
  1820. sudo /var/lib/certbot/renew-certificates&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you should be able to go to &lt;a href=&quot;https://yourdomainname.com&quot;&gt;https://yourdomainname.com&lt;/a&gt; and see your site
  1821. in glorious encrypted mode!&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Modify your guix config based on my &lt;a href=&quot;https://notabug.org/jbranso/linode-guix-system-configuration/src/master/the-nx.com-current-config.scm&quot;&gt;the-nx.com-current-config.scm&lt;/a&gt;.
  1822. You will need to enable these services &lt;code&gt;(dbus-service)&lt;/code&gt;, &lt;code&gt;(service docker-service-type)&lt;/code&gt;, &lt;code&gt;(elogind service)&lt;/code&gt;, &lt;code&gt;(service certbot-service-type)&lt;/code&gt;,
  1823. and &lt;code&gt;(service nginx-service-type)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I just ran this command, and my local nextcloud just started working.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo docker run \
  1824. --sig-proxy=false \
  1825. --name nextcloud-aio-mastercontainer \
  1826. --restart always \
  1827. --publish 80:80 \
  1828. --publish 8080:8080 \
  1829. --publish 8443:8443 \
  1830. --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
  1831. --volume /var/run/docker.sock:/var/run/docker.sock:ro \
  1832. nextcloud/all-in-one:latest&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following is the same quick guide as above, but has more details:&lt;/p&gt;&lt;p&gt;I decided to create a new linode image following the linode cookbook guide, and
  1833. I noticed a tiny error in the guide:&lt;/p&gt;&lt;p&gt;&lt;code&gt;sudo apt-get install gpg&lt;/code&gt; failed. It worked after I ran &lt;code&gt;sudo apt-get update&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Also the basic config example needs to migrate to the new &amp;lt;swap-space&amp;gt; record.
  1834. It gave me this warning message:&lt;/p&gt;&lt;p&gt;/root/config.scm:11:0: warning: List elements of the field ’swap-devices’ should
  1835. now use the &amp;lt;swap-space&amp;gt; record, as the old method is deprecated. See “(guix)
  1836. operating-system Reference” for more details.&lt;/p&gt;&lt;p&gt;The cookbook guide also should probably mention that you may need to login to
  1837. the server for the first time using linode’s weblish, and set up the root passwd
  1838. with &lt;code&gt;passwd&lt;/code&gt;. Then set up your user password with &lt;code&gt;passwd &amp;lt;username&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Now that we have a basic site set up, let’s set up certbot and the nginx services:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(service certbot-service-type
  1839. (certbot-configuration
  1840. (email &amp;quot;mysubscriptions@member.fsf.org&amp;quot;)
  1841. (webroot &amp;quot;/srv/www/&amp;quot;)
  1842. (certificates
  1843. (list
  1844. (certificate-configuration
  1845. (name &amp;quot;the-nx.com&amp;quot;)
  1846. (domains '(&amp;quot;the-nx.com&amp;quot; &amp;quot;www.the-nx.com&amp;quot;))
  1847. (deploy-hook %nginx-deploy-hook))))))
  1848. (nginx-configuration
  1849. (server-blocks
  1850. (list
  1851. (nginx-server-configuration
  1852. (server-name '(&amp;quot;the-nx.com&amp;quot;))
  1853. (listen (list &amp;quot;80&amp;quot;
  1854. &amp;quot;443 ssl http2&amp;quot;
  1855. ;;&amp;quot;[::]:80&amp;quot;
  1856. ;;&amp;quot;[::80]:443 ssl http2&amp;quot;
  1857. ))
  1858. (root &amp;quot;/srv/www/html/the-nx.com&amp;quot;)
  1859. (ssl-certificate &amp;quot;/etc/letsencrypt/live/the-nx.com/fullchain.pem&amp;quot;)
  1860. (ssl-certificate-key &amp;quot;/etc/letsencrypt/live/the-nx.com/privkey.pem&amp;quot;)
  1861. (locations
  1862. (list
  1863. (nginx-location-configuration ;; for certbot
  1864. (uri &amp;quot;/.well-known&amp;quot;)
  1865. (body (list &amp;quot;root /srv/www;&amp;quot;)))))))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s reconfigure and get a certbot certificate. &lt;code&gt;ssh&lt;/code&gt; into the-nx.com and
  1866. run these commands:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo guix system reconfigure the-nx.com-current-config.scm
  1867. # tell certbot to set up our certificates
  1868. sudo /var/lib/certbot/renew-certificates&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So now my server has a valid certificate. It is time change the nginx
  1869. configuration to proxy incoming requests to the docker all in one image.&lt;/p&gt;&lt;p&gt;Ok, maybe I can use sexpressions to tell nginx to redirect all incoming traffic
  1870. to &lt;code&gt;the-nx.com&lt;/code&gt; to the docker nextcloud image:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(nginx-location-configuration
  1871. (uri &amp;quot;/&amp;quot;)
  1872. (body
  1873. (list
  1874. &amp;quot;proxy_pass http://127.0.0.1:9000;\n&amp;quot;
  1875. &amp;quot;proxy_set_header X-Real-IP $remote_addr;\n&amp;quot;
  1876. &amp;quot;proxy_set_header Host $host;\n&amp;quot;
  1877. &amp;quot;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n&amp;quot;
  1878. &amp;quot;client_max_body_size 0;\n&amp;quot;
  1879. &amp;quot;# Websocket\n&amp;quot;
  1880. &amp;quot;proxy_http_version 1.1;\n&amp;quot;
  1881. &amp;quot;proxy_set_header Upgrade $http_upgrade;\n&amp;quot;)))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I am going to deploy this image, and take a look at the generated nginx
  1882. configuration file. I ran this command on my T400 laptop:&lt;/p&gt;&lt;p&gt;&lt;code&gt;guix deploy the-nx.com-current-config.scm&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Well, that’s super annoying. I do not know which nginx.conf file is the right
  1883. one:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;find /gnu/store -name '*nginx.conf'
  1884. /gnu/store/7m1ygzqk6njn5mywqmhwbydbb2z4b9li-nginx.conf
  1885. /gnu/store/0gcfj61q4943h94jdqq7i9y0a0v9jr9q-nginx.conf
  1886. /gnu/store/4mzrp39w5i4v94kxf98gxc13ws79l88n-nginx.conf
  1887. /gnu/store/0nia2iqfw63ziasibbgq321wr9b3152n-nginx.conf
  1888. /gnu/store/pf8d0sj1yf9b2ndsbc61yj3h6rp4pck2-nginx.conf
  1889. /gnu/store/9nra62v41wsk08xf3msw5a1z35gji2gx-nginx-1.23.2/share/nginx/conf/nginx.conf
  1890. /gnu/store/4b1szfyn0snwzf3lm1snvaapk6diz3yq-nginx.conf
  1891. /gnu/store/fv5rg3nf5999vyg6qvp4sbgjysnkn1fc-nginx.conf
  1892. /gnu/store/vmjwj2zwblcz4wx2whsmxdfc7zxcgjh5-nginx.conf
  1893. /gnu/store/n3m2lihq9cjm6mxdln57q5nrbjgz53s6-nginx.conf
  1894. /gnu/store/jnl72hx0papzb42kbd1f19qx35w76lmg-nginx-1.23.2/share/nginx/conf/nginx.conf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I guess I will reboot, run &lt;code&gt;guix system delete-generations&lt;/code&gt; and &lt;code&gt;guix gc&lt;/code&gt;, and
  1895. run the above command again:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;find /gnu/store -name '*nginx.conf'
  1896. /gnu/store/7m1ygzqk6njn5mywqmhwbydbb2z4b9li-nginx.conf
  1897. /gnu/store/jnl72hx0papzb42kbd1f19qx35w76lmg-nginx-1.23.2/share/nginx/conf/nginx.conf&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well that looks promising. Let's check out my nginx.conf file.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /gnu/store/i2mzdhg8wlbxv7iza8y4qk5v0vmvp27q-nginx.conf
  1898. user nginx nginx;
  1899. pid /var/run/nginx/pid;
  1900. error_log /var/log/nginx/error.log info;
  1901. events { }
  1902. http {
  1903. client_body_temp_path /var/run/nginx/client_body_temp;
  1904. proxy_temp_path /var/run/nginx/proxy_temp;
  1905. fastcgi_temp_path /var/run/nginx/fastcgi_temp;
  1906. uwsgi_temp_path /var/run/nginx/uwsgi_temp;
  1907. scgi_temp_path /var/run/nginx/scgi_temp;
  1908. access_log /var/log/nginx/access.log;
  1909. include /gnu/store/jnl72hx0papzb42kbd1f19qx35w76lmg-nginx-1.23.2/share/nginx/conf/mime.types;
  1910. server {
  1911. listen 443 ssl http2;
  1912. server_name the-nx.com ;
  1913. ssl_certificate /etc/letsencrypt/live/the-nx.com/fullchain.pem;
  1914. ssl_certificate_key /etc/letsencrypt/live/the-nx.com/privkey.pem;
  1915. root /srv/www/html/the-nx.com;
  1916. index index.html ;
  1917. server_tokens off;
  1918. location /.well-known {
  1919. root /srv/www;
  1920. }
  1921. location / {
  1922. proxy_pass http://127.0.0.1:9000;
  1923. proxy_set_header X-Real-IP $remote_addr;
  1924. proxy_set_header Host $host;
  1925. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  1926. client_max_body_size 0;
  1927. # Websocket
  1928. proxy_http_version 1.1;
  1929. proxy_set_header Upgrade $http_upgrade;
  1930. }
  1931. }
  1932. server {
  1933. listen 80;
  1934. listen [::]:80;
  1935. server_name the-nx.com www.the-nx.com ;
  1936. root /srv/http;
  1937. index index.html ;
  1938. server_tokens off;
  1939. location /.well-known {
  1940. root /srv/www/;
  1941. }
  1942. location / {
  1943. return 301 https://$host$request_uri;
  1944. }
  1945. }
  1946. }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The generated configuration seems pretty wonky, and I am suprised that nginx is
  1947. still running, but it is still running. And I suppose that it should work.&lt;/p&gt;&lt;p&gt;I was able to get nextcloud to start with this command:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo docker run --sig-proxy=false --name nextcloud-aio-mastercontainer \
  1948. --restart always \
  1949. --publish 8080:8080 \
  1950. -e APACHE_PORT=9000 \
  1951. --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
  1952. --volume /var/run/docker.sock:/var/run/docker.sock:ro \
  1953. nextcloud/all-in-one:latest&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So now I can login at the-nx.com:8080 and configure various stuff. Also I really
  1954. need to set up a firewall. That’s probably a really good idea. Also what’s nice
  1955. about this docker image is that it will start itself if you update the guix
  1956. system server and reboot.&lt;/p&gt;&lt;p&gt;MORE BONUS CONTENT:&lt;/p&gt;&lt;p&gt;If you see this blog post, and you decide to set up your nextcloud on a guix
  1957. system server, and if your nginx config doesn’t seem to be proxying requests to
  1958. your docker container, then you may follow these steps to delete the docker
  1959. image and start over:&lt;/p&gt;&lt;p&gt;This &lt;a href=&quot;https://help.nextcloud.com/t/aio-this-site-can-t-provide-a-secure-connection/128478/5&quot;&gt;page&lt;/a&gt; has some good commands for deleting the docker image and starting
  1960. over:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo docker stop nextcloud-aio-mastercontainer &amp;amp;&amp;amp; \\
  1961. sudo docker rm nextcloud-aio-mastercontainer &amp;amp;&amp;amp; \\
  1962. sudo docker container prune -f &amp;amp;&amp;amp; \\
  1963. sudo docker volume prune -f &amp;amp;&amp;amp; \\
  1964. sudo docker pull nextcloud/all-in-one:latest&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok, so it looks like the nextcloud all in one documentation has a &lt;a href=&quot;https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md&quot;&gt;page&lt;/a&gt; for
  1965. understanding the reverse proxy.&lt;/p&gt;&lt;p&gt;It would also be nice to get my nextcloud image to sync my contacts. I probably just need to add in another nginx
  1966. location line for that. That will be a project for another day.&lt;/p&gt;</content></entry><entry><title>Upgrading the PinePhone</title><id>https://gnucode.me/upgrading-the-pinephone.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-02-04T18:00:00Z</updated><link href="https://gnucode.me/upgrading-the-pinephone.html" rel="alternate" /><content type="html">&lt;p&gt;So I have been running this to upgrade the pinephone for a while now:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# apk upgrade
  1967. # apk update
  1968. # apk upgrade
  1969. # apk update&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Today, when I rebooted I got a message that said that my pinephone’s version was
  1970. no longer supported. I should &lt;a href=&quot;https://postmarketos.org/upgrade&quot;&gt;upgrade&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;I figured that I will probably do this again, so I might as well write down the
  1971. steps for how to do the upgrade.&lt;/p&gt;&lt;p&gt;Before I really get started in this, I want to get set up in the &lt;a href=&quot;https://wiki.postmarketos.org/wiki/Matrix_and_IRC&quot;&gt;matrix chat
  1972. room.&lt;/a&gt; I used the web based interface for the matrix chat. It had me create an
  1973. online account, and verify my email address, then I could talk in the matrix
  1974. channel. That was easy, moving onto the next step.&lt;/p&gt;&lt;p&gt;First install &lt;code&gt;postmarketos-release-upgrade&lt;/code&gt; package:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# apk add postmarketos-release-upgrade&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next I want to create a &lt;a href=&quot;https://wiki.postmarketos.org/wiki/Backup_and_restore_your_data&quot;&gt;backup&lt;/a&gt;, of the pinephone incase the upgrade fails or
  1975. breaks the phone and I have to install postmarketOS.&lt;/p&gt;&lt;p&gt;Ok, in the pinephone’s terminal, start the sshd daemon:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo service sshd start&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So possibly the best way to upgrade your pinephone is to connect the phone to
  1976. your laptop/desktop via a usb cord and enable &lt;a href=&quot;https://wiki.postmarketos.org/wiki/USB_Internet#Linux&quot;&gt;usb internet.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Apparently after you connect the phone to your host machine, you should be able
  1977. to run:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ssh user@172.16.42.1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That didn’t work. And it is quickly looking to me like the usb internet upgrade
  1978. option is NOT going to work. Or rather, it will work, but it will take me a lot
  1979. of time to get it to work.&lt;/p&gt;&lt;p&gt;So instead of using the usb internet upgrade option, I will try connecting the
  1980. pinephone to the internet via an ethernet cord (I personally disabled the wifi
  1981. on the phone to try to save power). Then I will make a backup of the pinephone.&lt;/p&gt;&lt;p&gt;Ok, now that I have my phinephone connected to an ethernet port, I used my
  1982. laptop to ssh into the pinephone.&lt;/p&gt;&lt;p&gt;I found my pinephone’s ip address via running this on the pinephone’s terminal:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ip a&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok, so the looking at eth0: the pinephone’s ip address is:&lt;/p&gt;&lt;p&gt;SOME.IP.Address.04&lt;/p&gt;&lt;p&gt;So, I can now ssh into the phone via:&lt;/p&gt;&lt;p&gt;&lt;code&gt;ssh user@SOME.IP.Address.04&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Since I have ssh-agent set up, lets set up ssh key login:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ssh-copy-id user@SOME.IP.ADDRESS.04&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s create a backup on my host comptuter (laptop):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mkdir ~/postmarket-os-backup
  1983. rsync -avz --exclude=.cache user@SOME.IP.ADDRESS.04:/home/user/ .
  1984. fish: Unknown command: rsync
  1985. fish:
  1986. rsync --server --sender -vlogDtprze.iLsfxCIvu . /home/user/
  1987. ^
  1988. rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
  1989. rsync error: error in rsync protocol data stream (code 12) at io.c(231) [Receiver=3.2.7]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well that seems like a weird problem. Let’s go join the fish irc channel.&lt;/p&gt;&lt;p&gt;Well the channel is here:&lt;/p&gt;&lt;p&gt;&lt;code&gt;#fish&lt;/code&gt; at irc.oftc.net&lt;/p&gt;&lt;p&gt;I can find out how to connect via going to oftc.net. They ever have a &lt;a href=&quot;https://webchat.oftc.net/&quot;&gt;webchat&lt;/a&gt;.
  1990. That makes it easy. Just put in a goofy nickname and you are in the chat room!&lt;/p&gt;&lt;p&gt;It took the fish people a while to respond, so I also asked in the &lt;code&gt;#guix&lt;/code&gt;
  1991. channel, while I was waiting. A guix user said that I should try this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix shell --network -C coreutils rsync openssh-sans-x&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And then run my rsync command.&lt;/p&gt;&lt;p&gt;That didn’t work, but then the &lt;code&gt;#fish&lt;/code&gt; people just asked me if I have rsync
  1992. installed on my pinephone…I didn’t realize I needed it installed on both
  1993. devices.&lt;/p&gt;&lt;p&gt;So let’s do that on the pinephone: &lt;code&gt;sudo apk add rsync&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Let’s try this again. On my laptop I ran this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;rsync -avz --exclude=.cache user@SOME.IP.ADDRESS.04:/home/user/ ~/postmarket-os-backup&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok that worked!&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://wiki.postmarketos.org/wiki/Upgrade_to_a_newer_postmarketOS_release&quot;&gt;postmarketOS wiki&lt;/a&gt; recommends that I use tmux or screen to update the
  1994. pinephone, in case the ssh connection breaks. Well I believe that I have tried
  1995. updating the pinephone before using just an ssh connection, and the ssh
  1996. connection dropped. I did not know if they phone was done updating or if it had
  1997. just died. So I forcefully shut off the device, and it failed to boot. Fun
  1998. times.&lt;/p&gt;&lt;p&gt;Well let’s go ask in the postmarketOS irc channel or &lt;a href=&quot;https://wiki.postmarketos.org/wiki/Category:Community&quot;&gt;matrix&lt;/a&gt; and ask about using
  1999. tmux or screen. How does it make sure that the ssh connection does not break? I
  2000. can also check out the archlinux wiki. Also it seems as if tmux is more user
  2001. friendly, so I will check out the &lt;a href=&quot;https://wiki.archlinux.org/title/Tmux&quot;&gt;tmux&lt;/a&gt; page to learn more about it.&lt;/p&gt;&lt;p&gt;Well let’s go ahead and install tmux on my laptop: &lt;code&gt;guix install tmux&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Let’s try to run an ssh connection on the pinephone via tmux. I think this
  2002. is how you do it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;tmux
  2003. ssh user@&amp;lt;IP address of the pinephone&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well I asked in the postmarketOS irc channel why they reccommend using tmux in
  2004. case the ssh connection drops, and this is the answer that I got:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;if you use tmux, you can just restore your tmux session if the ssh connection drops
  2005. and the command will still be running in there&lt;/p&gt;&lt;p&gt;run tmux
  2006. then if the connection drops
  2007. tmux list-sessions
  2008. and then
  2009. tmux attach-session
  2010. I think&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Then if the ssh connection gets dropped, I can open up a new terminal and do
  2011. this &lt;code&gt;tmux attach&lt;/code&gt;, and I will be right back where I was. This &lt;a href=&quot;https://www.youtube.com/watch?v=JQ0yDCVu44E&quot;&gt;video&lt;/a&gt; explains
  2012. that. That is pretty awesome!&lt;/p&gt;&lt;p&gt;Here &lt;a href=&quot;https://mutelight.org/practical-tmux&quot;&gt;are&lt;/a&gt; &lt;a href=&quot;https://blog.hawkhost.com/2010/06/28/tmux-the-terminal-multiplexer/&quot;&gt;some&lt;/a&gt; &lt;a href=&quot;https://blog.hawkhost.com/2010/07/02/tmux-%E2%80%93-the-terminal-multiplexer-part-2&quot;&gt;tmux&lt;/a&gt; &lt;a href=&quot;https://man.archlinux.org/man/tmux.1&quot;&gt;resources.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Next, I ran the following to update the pinephone:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;tmux
  2013. ssh user@&amp;lt;my Pinephone IP address&amp;gt;
  2014. postmarketos-release-upgrade&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since, my phinephone had an ethernet connection, the upgrade process was over
  2015. inside 5 minutes, and the phone rebooted itself. Nice work postmarketos
  2016. developers!&lt;/p&gt;</content></entry><entry><title>Setting up a Firewall</title><id>https://gnucode.me/setting-up-a-firewall.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2023-01-23T13:00:00Z</updated><link href="https://gnucode.me/setting-up-a-firewall.html" rel="alternate" /><content type="html">&lt;p&gt;Edit: Feb 12: The below firewall does NOT work. I currently do NOT use a
  2017. firewall on my servers.&lt;/p&gt;&lt;p&gt;So my guix system servers have been running without a firewall. I have decided
  2018. to actually fix that. Unfortunately, OpenBSD’s pf does not work on linux. It
  2019. seems like the best packaged firewall for GNU Guix System is currently provided
  2020. by the netfilter service. Luckily Guix’s default server provides a good basic
  2021. configuration for enabling ssh access to the machine. That configuration looks
  2022. like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;table inet filter {
  2023. chain input {
  2024. type filter hook input priority 0; policy drop;
  2025. # early drop of invalid connections
  2026. ct state invalid drop
  2027. # allow established/related connections
  2028. ct state { established, related } accept
  2029. # allow from loopback
  2030. iifname lo accept
  2031. # allow icmp
  2032. ip protocol icmp accept
  2033. ip6 nexthdr icmpv6 accept
  2034. # allow ssh
  2035. tcp dport ssh accept
  2036. # reject everything else
  2037. reject with icmpx type port-unreachable
  2038. }
  2039. chain forward {
  2040. type filter hook forward priority 0; policy drop;
  2041. }
  2042. chain output {
  2043. type filter hook output priority 0; policy accept;
  2044. }
  2045. }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So it looks like I just need to add in policies just after the &lt;code&gt;#allow ssh&lt;/code&gt;
  2046. line.&lt;/p&gt;&lt;p&gt;It seems like the easiest way to test this service out, is to first, &lt;code&gt;guix install nft&lt;/code&gt;, then put your configuration into a file. Then load in those
  2047. firewall rules via &lt;code&gt;sudo nft -f nftables.conf&lt;/code&gt;. If those rules end up breaking
  2048. things, you can revert the firewall to allow everything via &lt;code&gt;sudo nft flush ruleset&lt;/code&gt;. You can also list the current ruleset via &lt;code&gt;sudo nft list ruleset&lt;/code&gt;.
  2049. You can also check the syntax in &lt;code&gt;nftables.conf&lt;/code&gt; via &lt;code&gt;sudo nft -cf nftable.conf&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Well I had a firewall working fairly well. I tested the firewall rules via
  2050. &lt;code&gt;sudo nft -f nftables-lamora.conf&lt;/code&gt;, and it worked really well. But this scheme
  2051. code seemed to break everything on the server. Now, I can’t login to lamora and
  2052. the websites it hosts are not working.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(service nftables-service-type
  2053. (nftables-configuration
  2054. (ruleset
  2055. (mixed-text-file &amp;quot;nftables.conf&amp;quot;
  2056. &amp;quot;./nftables-lamora.conf&amp;quot;))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I reached out to linode support, and I am able to boot the machine in a rescue
  2057. image, which is pretty awesome. From there I might be able to mount the
  2058. &lt;code&gt;/dev/sda&lt;/code&gt; drive such that &lt;code&gt;/gnu/store&lt;/code&gt; is set up properly. But I think that is
  2059. pretty much beyond me. Too much work to get correct. So instead, I shall start
  2060. from scratch I suppose. :(&lt;/p&gt;&lt;p&gt;What if I had just run,&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mount /dev/sda /mnt
  2061. chroot /mnt
  2062. sudo guix system roll-back&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That might have worked. But it also might not have and it might have just taken me
  2063. longer too.&lt;/p&gt;&lt;p&gt;Looks like I have a small basic guix image lying around that I can tell linode
  2064. to use. Let’s try that.&lt;/p&gt;&lt;p&gt;Well that caused a kernel panic. That didn’t work. Probably because I told
  2065. linode to set the root password, and linode doesn’t know how to mess with guix
  2066. system?&lt;/p&gt;&lt;p&gt;So I whiped my linode server, and started over. And it looks like
  2067. I need to modify the current cookbook entry about running guix system on linode via
  2068. adding in&lt;/p&gt;&lt;p&gt;&lt;code&gt;sudo apt-get update&lt;/code&gt;, then &lt;code&gt;sudo apt-get install gpg&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Here are some of the commands that I used to set up my new linode server. It's on the
  2069. same IP address. It's currently hosting gnucode.me.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;wget https://notabug.org/jbranso/linode-guix-system-configuration/raw/master/gnucode.me-initial-config.scm
  2070. mount /dev/sdc /mnt
  2071. sudo guix system reconfigure locke-lamora-initial-config.scm
  2072. guix install git
  2073. mkdir -p ~/prog/gnu/guix/guix-config/
  2074. cd ~/prog/gnu/guix/guix-config/
  2075. git clone https://notabug.org/jbranso/linode-guix-system-configuration
  2076. cd ../
  2077. git clone https://git.sr.ht/~whereiseveryone/guixrus
  2078. sudo mkdir -p /srv/www/html&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I need to git clone my various static websites on the server.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cd /srv/www/html
  2079. sudo git clone https://notabug.org/jbranso/gnucode.me.git
  2080. sudo git clone https://notabug.org/jbranso/propernaming.git
  2081. sudo git clone https://notabug.org/jbranso/gnu-hurd.com.git
  2082. sudo mv propernaming propernaming.org&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So I believe that I need to chmod the files in /srv/www/html, so that nginx can
  2083. actually serve them. Unfortunately, I cannot do a &lt;code&gt;sudo chown -R nginx /srv&lt;/code&gt;,
  2084. because my current guix system does not have an nginx user yet. But I believe
  2085. that I can still reconfigure the system, even if nginx will not be able to serve
  2086. the html files. After I have reconfigured, then I should be able chown the owner
  2087. of /srv to nginx. In the end I actually just did a &lt;code&gt;cd /srv; sudo chmod -R o+r *&lt;/code&gt; and just made every file readable by everyone. That sort of violates the
  2088. principle of least privledge, oh well.&lt;/p&gt;&lt;p&gt;Now that I have made some modifications to my gnucode.me-current-config.scm that
  2089. comments out various certificate files that are not there yet, I can attempt to
  2090. reconfigure on the server:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cd prog/gnu/guix/guix-config/linode-guix-system-configuration/
  2091. sudo guix system reconfigure gnucode.me-current-config.scm
  2092. guix system: error: aborting reconfiguration because commit
  2093. 9fe5b490df83ff32e2e0a604bf636eca48b9e240 of channel 'guix' is not a descendant
  2094. of 900d33527c9286a811f064d4bb8f4a9b18d1db0b&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well let’s try this updating everything. And I believe that you need to do a
  2095. guix pull as root at least once.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;su
  2096. guix pull;
  2097. exit;
  2098. guix pull;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Oh yeah, I also need to power down my linode, delete the debian partition, and
  2099. resize the guix partition to full size.&lt;/p&gt;&lt;p&gt;Now I believe that I cannot reconfigure my server with the current
  2100. &lt;code&gt;gnucode.me-current-config.scm&lt;/code&gt;, because nginx will fail to start because the
  2101. letsencrypt scripts are not there yet. So I need to modify the nginx bits before
  2102. I can start the service. I also decided to set up &lt;code&gt;guix deploy&lt;/code&gt; on my gnucode.me
  2103. machine, so that reconfiguring the remote server is faster.&lt;/p&gt;&lt;p&gt;Ok, so I have my current-config for gnucode.me deployed. Geez, guix deploy is
  2104. sooo super fast! And all you need to do is to set up ssh-agent and customize a
  2105. deployment list. I set up ssh-agent via my &lt;code&gt;.bash_profile&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat .bash_profile | grep eval -A 1
  2106. if [[ -z $DISPLAY ]] &amp;amp;&amp;amp; [[ $(tty) = /dev/tty6 ]]; then
  2107. eval `ssh-agent -s`
  2108. ssh-add
  2109. exec dbus-run-session sway
  2110. fi&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now all you need to do is customize this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(list (machine
  2111. (operating-system %system)
  2112. (environment managed-host-environment-type)
  2113. (configuration (machine-ssh-configuration
  2114. (host-name &amp;quot;45.56.66.20&amp;quot;)
  2115. (system &amp;quot;x86_64-linux&amp;quot;)
  2116. (user &amp;quot;joshua&amp;quot;)
  2117. (identity &amp;quot;~/.ssh/id_rsa&amp;quot;)
  2118. (host-key &amp;quot;ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJgL0hBTWmCVGGvNJYa+YS+fEXs89v0GbdkQ+M+LdZlf root@(none)&amp;quot;)
  2119. (port 63355)))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The port is the ssh port. And the ssh-ed25519 is found on your remote server’s
  2120. &lt;code&gt;etc/ssh/ssh_host_ed25519_key.pub&lt;/code&gt; file.&lt;/p&gt;&lt;p&gt;Now nginx serves my websites via http. Let’s get https working.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo /var/lib/certbot/renew-certificates&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alright, now I can set up my config.scm to allow nginx to serve web traffic via https.&lt;/p&gt;&lt;p&gt;Well, can I get a nftables service running now?&lt;/p&gt;&lt;p&gt;At first it seemed that &lt;code&gt;(service nftables-service-type)&lt;/code&gt; is apparently good
  2121. enough to be a decent firewall for my server. Then very quickly I realized that
  2122. it was a terrible firewall for a server, because it blocked all http and https
  2123. traffic.&lt;/p&gt;&lt;p&gt;It looks like the arch linux wiki has a decent configuration example for a server:&lt;/p&gt;&lt;p&gt;https://wiki.archlinux.org/title/Nftables#Examples&lt;/p&gt;&lt;p&gt;So I just took the example nftables configuration for a server and used that.
  2124. The configuration file is here:&lt;/p&gt;&lt;p&gt;https://notabug.org/jbranso/linode-guix-system-configuration/src/master/nftables.scm&lt;/p&gt;&lt;p&gt;Let me know if you see that I did something silly in it, because I probably did.&lt;/p&gt;&lt;p&gt;Bonus paragraph! It took me about 2-4 hours to re-set up my server just the way
  2125. it was before, except I haven't set up email yet. If you crashed your server
  2126. lost your backups, how long would it take you to set up you server, just as it
  2127. was? 2-4 hours is longer than I expected, but I think guix's declarative
  2128. approach certainly is pretty awesome!&lt;/p&gt;</content></entry><entry><title>Submitting Opensmtpd Service to Guixrus</title><id>https://gnucode.me/submitting-opensmtpd-service-to-guixrus.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2022-12-22T15:00:00Z</updated><link href="https://gnucode.me/submitting-opensmtpd-service-to-guixrus.html" rel="alternate" /><content type="html">&lt;p&gt;EDIT 02-24-2023: Through this whole process, I have used this guide to set up email.
  2129. If you are going to try to set up your own email service, do check it out:
  2130. &lt;a href=&quot;https://poolp.org/posts/2019-09-14/setting-up-a-mail-server-with-opensmtpd-dovecot-and-rspamd/&quot;&gt;https://poolp.org/posts/2019-09-14/setting-up-a-mail-server-with-opensmtpd-dovecot-and-rspamd/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I was recently encouraged by the delightfully friendly raghavgururajan to try to
  2131. merge my opensmtpd service project into guixrus, which is a small community
  2132. actively working to upstream packages and services into guix proper. I figured,
  2133. why not? Sounds like fun. The following post will describe my developmental
  2134. workflow, which is probably pretty poor…&lt;/p&gt;&lt;p&gt;tl;dr&lt;/p&gt;&lt;p&gt;Soonish, I will clean up the code for a proper ~opensmtpd-service-type~ with
  2135. ~opensmtpd-records~ for guix system. It may take 6 months to get it in a clean
  2136. state. Until it is merged, you may find it here:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://git.sr.ht/~whereiseveryone/guixrus/commit/255875f7d86e92bb64006a59be26c64430c0c046&quot;&gt;https://git.sr.ht/~whereiseveryone/guixrus/commit/255875f7d86e92bb64006a59be26c64430c0c046&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The current documentation is here:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://notabug.org/jbranso/linode-guix-system-configuration/src/master/opensmtpd-records-documentation.txt&quot;&gt;https://notabug.org/jbranso/linode-guix-system-configuration/src/master/opensmtpd-records-documentation.txt&lt;/a&gt;&lt;/p&gt;&lt;p&gt;My server's config is here:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://notabug.org/jbranso/linode-guix-system-configuration/src/master/linode-locke-lamora-current-config.scm&quot;&gt;https://notabug.org/jbranso/linode-guix-system-configuration/src/master/linode-locke-lamora-current-config.scm&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The current task list is here:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://notabug.org/jbranso/linode-guix-system-configuration/src/master/opensmtpd.org&quot;&gt;https://notabug.org/jbranso/linode-guix-system-configuration/src/master/opensmtpd.org&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Added, the guixrus channel to my ~/.config/guix/channels.scm&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat ~/.config/guix/channels.scm
  2137. (cons* (channel ;; for firefox-wayland
  2138. (name 'nonguix)
  2139. (url &amp;quot;https://gitlab.com/nonguix/nonguix&amp;quot;)
  2140. ;; Enable signature verification:
  2141. (introduction
  2142. (make-channel-introduction
  2143. &amp;quot;897c1a470da759236cc11798f4e0a5f7d4d59fbc&amp;quot;
  2144. (openpgp-fingerprint
  2145. &amp;quot;2A39 3FFF 68F4 EF7A 3D29 12AF 6F51 20A0 22FB B2D5&amp;quot;))))
  2146. (channel ;; for sway-latest
  2147. (name 'guixrus)
  2148. (url &amp;quot;https://git.sr.ht/~whereiseveryone/guixrus&amp;quot;)
  2149. (introduction
  2150. (make-channel-introduction
  2151. &amp;quot;7c67c3a9f299517bfc4ce8235628657898dd26b2&amp;quot;
  2152. (openpgp-fingerprint
  2153. &amp;quot;CD2D 5EAA A98C CB37 DA91 D6B0 5F58 1664 7F8B E551&amp;quot;))))
  2154. %default-channels)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Before I submit the patch, I should make sure that the code actually works. To
  2155. do that, I logged into my gnucode.me server tried to set up the opensmtpd
  2156. server.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix pull --url=https://notabug.org/jbranso/guix/src/newOpensmtpdBranch \
  2157. --branch=newOpensmtpdBranch
  2158. Updating channel 'guix' from Git repository at 'https://notabug.org/jbranso/guix'...
  2159. guix pull: error: Git error: cannot locate remote-tracking branch 'origin/keyring'
  2160. guix pull --url=https://notabug.org/jbranso/guix \
  2161. --commit=8abbb6c442d135ae8e7c1cb0e17525478fafe8f0
  2162. Updating channel 'guix' from Git repository at 'https://notabug.org/jbranso/guix'...
  2163. guix pull: error: Git error: cannot locate remote-tracking branch 'origin/keyring'&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hmm, well my opensmtpd service is NOT using signed commits. That’s probably the
  2164. problem. Hmmm… Well I guess I need to start signing my commits. Generate an
  2165. gpg key. grrr….&lt;/p&gt;&lt;p&gt;These three pages are seem promising:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://moser-isi.ethz.ch/gpg.html&quot;&gt;https://moser-isi.ethz.ch/gpg.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://wiki.debian.org/Keysigning&quot;&gt;https://wiki.debian.org/Keysigning&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://risanb.com/code/backup-restore-gpg-key/&quot;&gt;https://risanb.com/code/backup-restore-gpg-key/&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gpg --full-generate-key
  2166. gpg: directory '/home/joshua/.gnupg/openpgp-revocs.d' created
  2167. h.lgpg: revocation certificate stored as '/home/joshua/.gnupg/openpgp-revocs.d/LOTSOFNUMBERS.rev'&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I copied my Revocation-Certificate into my spare usb:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo cp .gnupg/openpgp-revocs.d/LOTSOFNUMBERS.rev /mnt/gnucode.gpg.rev&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s export my gpg key to the server.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gpg --auto-key-locate keyserver -a --send-keys 67A42A3CC23F979886F9686C750BCFEF3A579572
  2168. gpg -a --export gnucode
  2169. -----BEGIN PGP PUBLIC KEY BLOCK-----
  2170. mQINBGOSU7sBEAC/8renj2OgTHKJfbqz7CRplPQ0su8aasJXTkunx70IhVpTFBS+
  2171. 9Bwvjbo7HM2aBYD/NYa6n24J3OXla17uDxFt2i63ojhbl5AVntac3ZOeyn661Y2U
  2172. r9szIRM+edTieWZZvY5G49ZFTH5VJ+jZS2leRLpIqsYCst+Ru61MdUUggBNvPgBm
  2173. q97HAylBqQs0kf7XfctyqKbkChLsvkuD5cR1X8BQL8KAn/KDXrDSwj4hIO+tSdv5
  2174. VmaTC+6/xbdqfq6gpywJMEPkLNUjCArlF+Oz5UqQvLh1lRXWPejzFa0LmXsviqb3
  2175. RmQh+9cNvDVge+kYIRWHhCXY5dTau7ABnYsgxnW3zlBkFNbc+I5Sqiz6LDcuInlA
  2176. QznFw90GL3l0+1WGzeAD5DhNx6hgpOYvFZV7S3OgbOGeOHvF7bFBixB6Pa3oByMn
  2177. euKqol+rOZiUkjcaxo5XUKsglFLgOaxfmZujO7lwoipYXxiyD7jf1+ou1WZ5C3l+
  2178. YCOnia2qWE5DRpR/WDBRLQl3ZrCUtDQW7dKNAuweEgDT5T53k2m3Gqu1Z28SrzIS
  2179. is+SHZcZhv4dx9Cs6sX6me3WzQ3wgoI9DNW5v8XGitaGQFjIRI33Y8MeGjEBMip3
  2180. ZnT6Cl8WJgd0JBXsPQnKw1EO1sh2S5cU5drvHkuCPMA/PaBb8XrNpobSlwARAQAB
  2181. tDNKb3NodWEgQWxsZW4gQnJhbnNvbiAoZ251Y29kZSkgPGpicmFuc29AZGlzbWFp
  2182. bC5kZT6JAk4EEwEIADgWIQRnpCo8wj+XmIb5aGx1C8/vOleVcgUCY5JTuwIbAwUL
  2183. CQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRB1C8/vOleVcgwwEACp4ZwBIM/4Udc9
  2184. ndZvUJeegSP0W7o86v+9ELXfXdX99ZO0iErr6/XTWxov0mw7AaoDJRdETBTkYeU0
  2185. /CDrLcjklW8b7RZe98+Cr0+IB9XSozpqNVhiP7/TogL80lkbu2+Khtk29E/UYupt
  2186. 8rihR+2tkDKPaWOufGgi+6ftw8A9P9jlFsV1N1Oxo4rA+gbcXHtxbDiZ1dR2UOAS
  2187. Ge7TJPpIjgSiG+nm6b9BIoAxLpjf5JrwpNm5wvDXic1YP27GC2Il9Ny7TdGyKpn9
  2188. RCZXR1yEMQTVNn4iEiMK6XIcoAFUS1oWAP2JKQ4bCfcxM/VGx31rsGgNL36iW6yj
  2189. zLD9yJYhbvm536CiRb2cTco+lAmwS9/iM4Bdpp/H9fZFPp2CxeB02mOd/P0HkC+2
  2190. Po2KXpEj6Ettjp0xJcAQye75vRvjDMkHvTvugfY4FQg6V6a6N3jxSbfwuFUp426F
  2191. fgfki4Y7OWm47mYa7goI4oDOG2qUdN5YkbhpVA+j2tGGHbbXmUtvj4MES4fnaSkF
  2192. vc6+xMZpFTWcFRt8rVTqS1Vu1w8zfT/VUV+FC/J6hdSxIQJ4dg4WsaD2kzGflZzO
  2193. miTyxMYPvdQ6I7Nshp/bEyfd9F40sXm/kzL6r+qm9+ly2uR5V+bIo9gu6CfkM0ZJ
  2194. DDiIf9wkk+xSb/AGj1YVazQKpKS0wLkCDQRjklO7ARAAzrtyGaOFTtCHlItxxb51
  2195. s0Qt5LZwG3sNUjI9P7n3oZrzI35sbPrWxWCX2MMW0gUIx79dlMzQBt1RXQEKiipr
  2196. RdSrtuclTytxaMtLRP+VtmcRQkGgKb20ipCvFHX4oA7L+3Y8s2RQBsz+wo9h55Dt
  2197. iQRxoONm9biHXBUZ4EJnR4B8z0dp9j+fctTR4ds6OI3jIeKHcd4AALYIpyBnh5ue
  2198. 5Iictiv0evBjcogfCttHlg/NK3TVZpq8YYOG8x+8XVrvvJ5WKtmXduZuFIL3+Wmv
  2199. jBv807a4zGLPLpB6OcD7fj/12Eo9n7d9gHZOV200rPguzt9YMIoRGgtSEEpMsvrJ
  2200. 5upiFLPULj/14arXePdqZshlU01U0uE6glGJRUt7IVyU+1LbziQ8JqBlVTnRRYrb
  2201. uKDFqzmtd3zhLDPAPLkv7xLtEjYUPcFDmrf33dz22FHUGeOB0G5Ur+e9qTedfmj0
  2202. r5sHaoCspZzDcVR8sKyuUdAnRAGxJs9eIFUq2GkyxZGgfJoU2A9RMxg+YTfFfdQV
  2203. guvvPj6udOF4ugmIW1EnDXza08UyDqOITLIadNu4GqZL407JRIRtYfw48qQgL3Zo
  2204. 6lqxC/3n7orkuRU/cKvHArqQt1sP7ZYzAy5N/yoY0/m3o2RV9Li7SkF2m5By8EjH
  2205. RNvQMPsipdvjWf4I+jLaAM0AEQEAAYkCNgQYAQgAIBYhBGekKjzCP5eYhvlobHUL
  2206. z+86V5VyBQJjklO7AhsMAAoJEHULz+86V5Vy6U0QAJtjybCfDAqE5DIcKkiBDbIN
  2207. erk+MTU+uOROuVigDCyvqJUuxtGaJPIRWdBQuHcQxnf6Bv1xoAeDk/7hyL7i5+rz
  2208. 9vWZnSZRr4DB6pY8G5jz/HGdML4luEtuOrE5UMN8Bf5PM/9sj/c1QSuMhpAMw5TL
  2209. GoAu+MY/uDCHLb2nzwLIaCPFDTX0q5HgFQA7Do78fdxxPLqPlbg9xeTsAP5P6Egb
  2210. /8NUUa1SM4mfygriyL82nLH9SvwtnEbItovAWE+GH4XkE8xSjvWl6MpCk0+H0Xtr
  2211. WdbxtKqE7BPzs0lN3NOi+mOJABDt5ozPGfVcUsB/nqz00YiF33CQWu0ote1Q1TKn
  2212. NPOCLqFM3F1rG2z7Bf/LP9p6CpmfQGr54XmKpGinYNr8dqRtLEMVERCxGI+BuNhZ
  2213. ppQLuqOlHinKPaBO58LCwLA0uMScbmjgTQrJiXolCGHYXorCx3rcqitvMzbAcswr
  2214. wMeAXMREYKGM84Pf8fGxv+GZZwfQJHQNbOFrOTpnRITDAZvzKBD97yWkXcLGt6B7
  2215. A5iRXOI8sv9CGM3kI78b+MCcgbz8HNGF2RQipGNQZhEgL4ixbhpMaMVUuTo7BrKr
  2216. M3IeyVwUMpUBFbk5OqLsMqPbL2VvL6x1zgg4P0LmGQYoikKiwmPl/OyRQW6btWCG
  2217. 1f7+w1RrcKjUANLQNjXm
  2218. =Vl9S
  2219. -----END PGP PUBLIC KEY BLOCK-----
  2220. gpg -a --export gnucode &amp;gt; gnucode.pub
  2221. sudo cp gnucode.pub /mnt/&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let’s backup the gpg key.&lt;/p&gt;&lt;pre&gt;&lt;code&gt; gpg --export-secret-keys --armor gnucode &amp;gt; secret-key-backup.asc
  2222. sudo mv secret-key-backup.asc /mnt/&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If I ever need to move that gpg key to another computer, all I have to do is:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gpg --import /path/to/secret-key-backup.asc&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s try testing a signed commit.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git config --global commit.gpgsign true&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key&quot;&gt;https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key&lt;/a&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gpg --list-secret-keys --keyid-format=long
  2223. # git config --global user.signingkey MYSIGNINGKEY
  2224. git config --global alias.logs &amp;quot;log --show-signature&amp;quot;
  2225. git commit -m &amp;quot;mail.scm: minor sanitization improvements.&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok well let’s try this to see what the error was:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;GIT_TRACE=1 git commit -m &amp;quot;blah&amp;quot; -S
  2226. 23:07:37.656401 git.c:460 trace: built-in: git commit -m blah -S
  2227. 23:07:37.678825 run-command.c:655 trace: run_command: gpg --status-fd=2 -bsau 750BCFEF3A579572
  2228. error: gpg failed to sign the data
  2229. fatal: failed to write commit object
  2230. gpg --status-fd=2 -bsau 750BCFEF3A579572&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As I was running through the above command, I realized that, it is possible that
  2231. I did not have pinentry installed:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix install pinentry
  2232. git logs&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I think I will try rebooting and check to see if I can still sign git
  2233. commits.&lt;/p&gt;&lt;p&gt;And after I rebooted, I cannot sign commits with emacs…&lt;/p&gt;&lt;p&gt;Emacs says “hint: Waiting for your editor to close the file…”
  2234. “Waiting for Emacs”&lt;/p&gt;&lt;p&gt;Well online, I see this as a possible solution&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git config --global core.editor emacs&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well that didn’t quite work. I was able to squash two commits, via emacs, but
  2235. only after I had the gpg agent had cached my private key password. That makes
  2236. me think that magit is having a hard time querying my for my password.&lt;/p&gt;&lt;p&gt;Well let me try updating doom emacs. I doubt that will work, but I’ll try it.
  2237. That didn’t work. :(&lt;/p&gt;&lt;p&gt;Well I found a possible error here:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/magit/with-editor/issues/69&quot;&gt;https://github.com/magit/with-editor/issues/69&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://emacs.stackexchange.com/questions/74097/magit-cannot-commit-emacsclient-on-path-pop-os&quot;&gt;https://emacs.stackexchange.com/questions/74097/magit-cannot-commit-emacsclient-on-path-pop-os&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://magit.vc/manual/with-editor/Configuring-With_002dEditor.html&quot;&gt;https://magit.vc/manual/with-editor/Configuring-With_002dEditor.html&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Then I thought, how about I disable the with-editor elisp package that doom
  2238. emacs ships and instead &lt;code&gt;guix install emacs-with-editor&lt;/code&gt;. Let’s try that.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat .doom.d/packages.el | grep with-editor
  2239. (package! with-editor :disable t)
  2240. doom upgrade
  2241. doom sync
  2242. guix install emacs-with-editor&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nope. That didn’t work either. Hmmm. I can get emacs to commit the message,
  2243. after the gpg agent caches my key’s password.&lt;/p&gt;&lt;p&gt;Well let’s try running emacs without any configuration: &lt;code&gt;emacs -q&lt;/code&gt;. Nope. That
  2244. also didn’t work. :(&lt;/p&gt;&lt;p&gt;My current theory is that my wayland only session is prohibiting the pinentry
  2245. from displaying, which is NOT allowing me to enter in my gpg password. I shall
  2246. try temporarily enabling Xwayland and see if that fixed it.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat config | grep xwayland
  2247. # disable xwayland. Just trying it out
  2248. xwayland enable&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Yup! That fixed it. With the above, I can now sign my commits with emacs! But
  2249. I would rather keep my wayland only session. Let’s try pinetry-bemenu:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix package -i pinentry-bemenu -r pinentry
  2250. cat config | grep xwayland
  2251. # disable xwayland.
  2252. xwayland disable&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well that didn’t work. Let’s try pinetry-gnome3.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix package -r pinentry-bemenu -i pinentry-gnome3&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nope. It’s X only. Let’s try qt:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix package -r pinentry-gnome3 -i pinentry-qt&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nope. That also seems to be X only. grr. Maybe this bemenu thing works, but I
  2253. need to configure it properly.&lt;/p&gt;&lt;p&gt;Well let’s install pinentry, and temporarily enable xwayland.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix package -r pinentry-tty -i pinentry
  2254. cat config | grep xwayland
  2255. # enable xwayland.
  2256. xwayland enable&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Well I should probably try eventually to edit &lt;code&gt;.config/gpg.conf&lt;/code&gt; and tell it to
  2257. use pinentry-bemu as the pinentry program.&lt;/p&gt;&lt;p&gt;I think that spending all that time working on getting gpg key signing to work
  2258. was probably a big waste of time. :( I think instead of keeping my opensmtpd
  2259. code in guix-src/gnu/services/mail.scm, I will move it to
  2260. guixrus/services/opensmtpd.scm. Then I can just copy opensmtpd.scm file to my
  2261. linode server, and manually load in that code to start my opensmtpd service.&lt;/p&gt;&lt;p&gt;First I will delete the opensmtpd record stuff in gnu/services/mail.scm. I
  2262. don’t want myself getting confused where I am storing my developmental code.&lt;/p&gt;&lt;p&gt;Now I will cp my opensmtpd.scm code into my linode service git repo.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cp opensmtpd.scm ~/prog/gnu/guix/guix-config/linode-guix-system-configuration/guixrus/services/
  2263. ls ~/prog/gnu/guix/guix-config/linode-guix-system-configuration/guixrus/services/opensmtpd.scm
  2264. cat ~/prog/gnu/guix/guix-config/linode-guix-system-configuration/guixrus/services/opensmtpd.scm | tail
  2265. /home/joshua/prog/gnu/guix/guix-config/linode-guix-system-configuration/guixrus/services/opensmtpd.scm
  2266. (service-extension pam-root-service-type
  2267. (const %opensmtpd-pam-services))
  2268. (service-extension profile-service-type
  2269. (compose list opensmtpd-configuration-package))
  2270. (service-extension shepherd-root-service-type
  2271. opensmtpd-shepherd-service)
  2272. (service-extension setuid-program-service-type
  2273. opensmtpd-set-gids)))
  2274. (description &amp;quot;Run the OpenSMTPD, a lightweight @acronym{SMTP, Simple Mail
  2275. Transfer Protocol} server.&amp;quot;)))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now I will commit the changes to my linode git repo and push them.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git add opensmtpd.scm
  2276. git commit -m &amp;quot;copying opensmtpd.scm from guixrus.&amp;quot;
  2277. [master 7399550] copying opensmtpd.scm from guixrus.
  2278. 1 file changed, 7 insertions(+)
  2279. rename opensmtpd.scm =&amp;gt; guixrus/services/opensmtpd.scm (99%)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hmmm, was that commit signed? No idea.&lt;/p&gt;&lt;p&gt;Now let’s push that commit.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let's log into the gnucode service and pull that commit.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git pull
  2280. cat opensmtpd.scm | tail
  2281. Updating a8d88b9..7399550
  2282. Fast-forward
  2283. opensmtpd.scm =&amp;gt; guixrus/services/opensmtpd.scm | 7 +++++++
  2284. 1 file changed, 7 insertions(+)
  2285. rename opensmtpd.scm =&amp;gt; guixrus/services/opensmtpd.scm (99%)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I am realizing that it will probably be easiest to reconfigure my server with my
  2286. opensmtpd records, if my server has the same directory structure as my local
  2287. machine. Namely my git repos are in the same directories. So I did some changes
  2288. on my server to make sure that my server's directory structure matches my local
  2289. one. Now my server’s &lt;code&gt;config.scm&lt;/code&gt; is no longer at
  2290. ~/linode-guix-system-configuration/linode-locke-lamora-current-config.scm. Now
  2291. it is at:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;find . -name '*current-config.scm'
  2292. ./prog/gnu/guix/guix-config/linode-guix-system-configuration/linode-locke-lamora-current-config.scm&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I want to make sure that my remote server has a copy of the guixrus source code
  2293. with my newest commit committing &lt;code&gt;services/opensmtpd.scm&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;So, I made a guixrus repo on &lt;a href=&quot;https://notabug.org/jbranso/guixrus&quot;&gt;notabug.org&lt;/a&gt;, then I pulled that repo on my server:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git clone https://notabug.org/jbranso/guixrus
  2294. git show HEAD | head
  2295. commit 147a9ce316be2f9f7c9ed25b3e097fd84b8b01eb
  2296. Author: Joshua Branson &amp;lt;jbranso@dismail.de&amp;gt;
  2297. Date: Thu Dec 22 09:21:19 2022 -0500
  2298. services (opensmtpd): add opensmtpd records to enhance opensmtpd-configuration.
  2299. Openmstpd-configuration may only be configured by a config-file that
  2300. uses the smtpd.conf syntax. This patch, enables one to configure
  2301. opensmtpd by using record types.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It would be nice to test the configuration locally, to see if it will work
  2302. before I push it to the server.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix system vm linode-locke-lamora-current-config.scm
  2303. guix system: error: (cert &amp;quot;/etc/letsencrypt/live/gnucode.me/fullchain.pem&amp;quot;) is invalid.
  2304. hint: Try a file.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above is actually a good sign. I do not have that certificate locally, but
  2305. it is available on the server. If that is the only error, then let’s go ahead
  2306. and try to reconfigure the server.&lt;/p&gt;&lt;p&gt;The relevant opensmtpd-service looks like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(service opensmtpd-service-type
  2307. (let ([action-receive (opensmtpd-local-delivery
  2308. (name &amp;quot;receive&amp;quot;)
  2309. (method (opensmtpd-maildir
  2310. (pathname &amp;quot;/home/%{rcpt.user}/Maildir&amp;quot;)
  2311. (junk #t)))
  2312. (virtual (opensmtpd-table
  2313. (name &amp;quot;vusers&amp;quot;)
  2314. (data '((&amp;quot;joshua@gnucode.me&amp;quot; . &amp;quot;joshua&amp;quot;)
  2315. (&amp;quot;jbranso@gnucode.me&amp;quot; . &amp;quot;joshua&amp;quot;)
  2316. (&amp;quot;postmaster@gnucode.me&amp;quot; . &amp;quot;joshua&amp;quot;))))))]
  2317. [pki-gnucode (opensmtpd-pki
  2318. (domain &amp;quot;smtp.gnucode.me&amp;quot;)
  2319. (cert &amp;quot;/etc/letsencrypt/live/gnucode.me/fullchain.pem&amp;quot;)
  2320. (key &amp;quot;/etc/letsencrypt/live/gnucode.me/privkey.pem&amp;quot;))]
  2321. [filter-dkimsign (opensmtpd-filter
  2322. (name &amp;quot;dkimsign&amp;quot;)
  2323. (exec #t)
  2324. (proc (list (file-append opensmtpd-filter-dkimsign &amp;quot;/libexec/opensmtpd/filter-dkimsign&amp;quot;)
  2325. &amp;quot; -d gnucode.me -s 2021-09-22 -c relaxed/relaxed -k &amp;quot;
  2326. &amp;quot;/etc/dkim/private.key &amp;quot;
  2327. &amp;quot;user nobody group nogroup&amp;quot;)))]
  2328. [table-creds (opensmtpd-table
  2329. (name &amp;quot;creds&amp;quot;)
  2330. (data
  2331. (list
  2332. (cons &amp;quot;joshua&amp;quot;
  2333. &amp;quot;$6$Ec4m8FgKjT2F/03Y$k66ABdse9TzCX6qaALB3WBL9GC1rmAWJmaoSjFMpbhzat7DOpFqpnOwpbZ34wwsQYIK8RQlqwM1I/v6vsRq86.&amp;quot;))))])
  2334. (opensmtpd-configuration
  2335. (interfaces
  2336. (list
  2337. ;; this forum help suggests that I listen on 0.0.0.0 and NOT eth0
  2338. ;; https://serverfault.com/questions/726795/opensmtpd-wont-work-at-reboot
  2339. ;; this listens for email from the outside world
  2340. (opensmtpd-interface
  2341. (interface &amp;quot;eth0&amp;quot;)
  2342. (port 25)
  2343. (secure-connection &amp;quot;tls&amp;quot;)
  2344. (pki pki-gnucode))
  2345. ;; this lets local users logged into the system via ssh send email
  2346. (opensmtpd-interface
  2347. (interface &amp;quot;lo&amp;quot;)
  2348. (port 25)
  2349. (secure-connection &amp;quot;tls&amp;quot;)
  2350. (pki pki-gnucode))
  2351. (opensmtpd-interface
  2352. (interface &amp;quot;eth0&amp;quot;)
  2353. (port 465)
  2354. (secure-connection &amp;quot;smtps&amp;quot;)
  2355. (pki pki-gnucode)
  2356. (auth table-creds)
  2357. (filters (list filter-dkimsign)))
  2358. (opensmtpd-interface
  2359. (interface &amp;quot;eth0&amp;quot;)
  2360. (port 587)
  2361. (secure-connection &amp;quot;tls-require&amp;quot;)
  2362. (pki pki-gnucode)
  2363. (auth table-creds)
  2364. (filters (list filter-dkimsign)))))
  2365. (matches (list
  2366. (opensmtpd-match
  2367. (action (opensmtpd-relay
  2368. (name &amp;quot;relay&amp;quot;)))
  2369. (options
  2370. (list
  2371. (opensmtpd-option
  2372. (option &amp;quot;for any&amp;quot;))
  2373. (opensmtpd-option
  2374. (option &amp;quot;from any&amp;quot;))
  2375. (opensmtpd-option
  2376. (option &amp;quot;auth&amp;quot;)))))
  2377. (opensmtpd-match
  2378. (action action-receive)
  2379. (options
  2380. (list
  2381. (opensmtpd-option
  2382. (option &amp;quot;from any&amp;quot;))
  2383. (opensmtpd-option
  2384. (option &amp;quot;for domain&amp;quot;)
  2385. (data (opensmtpd-table
  2386. (name &amp;quot;vdoms&amp;quot;)
  2387. (data (list &amp;quot;gnucode.me&amp;quot;
  2388. &amp;quot;gnu-hurd.com&amp;quot;))))))))
  2389. (opensmtpd-match
  2390. (action action-receive)
  2391. (options
  2392. (list
  2393. (opensmtpd-option
  2394. (option &amp;quot;for local&amp;quot;))))))))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I was curious to see how outdated my server is. It’s dated apparently.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix system describe
  2395. Generation 118 Aug 14 2022 02:45:18 (current)
  2396. file name: /var/guix/profiles/system-118-link
  2397. canonical file name: /gnu/store/7jkrafkf61bw3fdxlrlzvkrl98ys1icj-system
  2398. label: GNU with Linux-Libre 5.18.16
  2399. bootloader: grub
  2400. root device: /dev/sda
  2401. kernel: /gnu/store/iz6xn1b1dyk6pwaf6dym3jm3vwnh4gz9-linux-libre-5.18.16/bzImage
  2402. channels:
  2403. guix:
  2404. repository URL: https://git.savannah.gnu.org/git/guix.git
  2405. branch: master
  2406. commit: 43decd1f7ea4ebd911199ad10c0ca555d0dffbd6
  2407. configuration file: /gnu/store/rv7rhwn5kd9yxv8kayqlsgxwyhcz55ca-configuration.scm&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let's try reconfiguring my server with the opensmtpd configuration.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix pull
  2408. sudo guix system reconfigure linode-locke-lamora-current-config.scm
  2409. In srfi/srfi-1.scm:
  2410. 586:29 19 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type mingetty 7f8…&amp;gt; …))
  2411. 586:29 18 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type mingetty 7f8…&amp;gt; …))
  2412. 586:29 17 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type mingetty 7f8…&amp;gt; …))
  2413. 586:29 16 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type mingetty 7f8…&amp;gt; …))
  2414. 586:29 15 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type mingetty 7f8…&amp;gt; …))
  2415. 586:29 14 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type agetty 7f8c1…&amp;gt; …))
  2416. 586:29 13 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type syslog 7f8c1…&amp;gt; …))
  2417. 586:29 12 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type console-font…&amp;gt; …))
  2418. 586:29 11 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type virtual-term…&amp;gt; …))
  2419. 586:17 10 (map1 (#&amp;lt;&amp;lt;service&amp;gt; type: #&amp;lt;service-type opensmtpd 7f…&amp;gt; …))
  2420. In guixrus/services/opensmtpd.scm:
  2421. 2567:27 9 (opensmtpd-shepherd-service #&amp;lt;&amp;lt;opensmtpd-configuration&amp;gt;…&amp;gt;)
  2422. 2541:19 8 (opensmtpd-configuration-&amp;gt;mixed-text-file #&amp;lt;&amp;lt;opensmtpd-…&amp;gt;)
  2423. 2496:3 7 (opensmtpd-configuration-&amp;gt;string #&amp;lt;&amp;lt;opensmtpd-configura…&amp;gt;)
  2424. 2421:9 6 (opensmtpd-configuration-fieldname-&amp;gt;string #&amp;lt;&amp;lt;opensmtp…&amp;gt; …)
  2425. 2430:10 5 (list-of-records-&amp;gt;string (#&amp;lt;&amp;lt;opensmtpd-interface&amp;gt; i…&amp;gt; …) …)
  2426. 2434:17 4 (loop (#&amp;lt;&amp;lt;opensmtpd-interface&amp;gt; interface: &amp;quot;eth0&amp;quot; fam…&amp;gt; …))
  2427. 1848:5 3 (opensmtpd-interface-&amp;gt;string #&amp;lt;&amp;lt;opensmtpd-interface&amp;gt; in…&amp;gt;)
  2428. In unknown file:
  2429. 2 (string-append &amp;quot;&amp;quot; &amp;quot;&amp;quot; &amp;quot;&amp;quot; &amp;quot;&amp;quot; &amp;quot;&amp;quot; &amp;quot;tls &amp;quot; #&amp;lt;unspecified&amp;gt; &amp;quot;p…&amp;quot; …)
  2430. In ice-9/boot-9.scm:
  2431. 1685:16 1 (raise-exception _ #:continuable? _)
  2432. 1685:16 0 (raise-exception _ #:continuable? _)
  2433. ice-9/boot-9.scm:1685:16: In procedure raise-exception:
  2434. In procedure string-append: Wrong type (expecting string): #&amp;lt;unspecified&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ahh, I know what that problem is! Let’s fix that. So now I have make a local
  2435. commit. Push it to my notabug.org/guixrus, ssh into lamora, run &lt;code&gt;git pull&lt;/code&gt; on
  2436. the guixrus repo, then try to reconfigure. This seems like a very odd/poor way
  2437. to test changes. By making a commit locally, pushing it, pulling it, and then
  2438. wondering if the reconfigure will work. I should really set up guix deploy.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo guix system reconfigure linode-locke-lamora-current-config.scm
  2439. module-import-compiled 1.0MiB 1.6MiB/s 00:01 [##################] 100.0%
  2440. building /gnu/store/mw8x4pbl11a5pdgxqcw2vvczdccpmicf-switch-to-system.scm.drv...
  2441. making '/gnu/store/0v5sbvlx9r151gjlc906lxyhps7xx1h8-system' the current system...
  2442. setting up setuid programs in '/run/setuid-programs'...
  2443. populating /etc from /gnu/store/1n0l349b03h7dclwai9l0kxglb8kwyv0-etc...
  2444. checking syntax of /gnu/store/51hahfmqlkj9jfxa2cqbm6dd05qrzxzd-smtpd.conf
  2445. /gnu/store/51hahfmqlkj9jfxa2cqbm6dd05qrzxzd-smtpd.conf:14: syntax error
  2446. /gnu/store/51hahfmqlkj9jfxa2cqbm6dd05qrzxzd-smtpd.conf:21: no such dispatcher: relay&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok, so I have a configuration error. Let’s take a look at the generated
  2447. configuration file:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;The first error is this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /gnu/store/51hahfmqlkj9jfxa2cqbm6dd05qrzxzd-smtpd.conf | grep '&amp;lt;&amp;quot;&amp;lt;&amp;quot;'
  2448. listen on eth0 filter &amp;quot;dkimsign&amp;quot; smtps port 465 pki smtp.gnucode.me auth &amp;lt;&amp;quot;&amp;lt;&amp;quot;creds&amp;quot;&amp;gt;&amp;quot;&amp;gt;
  2449. listen on eth0 filter &amp;quot;dkimsign&amp;quot; tls-require port 587 pki smtp.gnucode.me auth &amp;lt;&amp;quot;&amp;lt;&amp;quot;creds&amp;quot;&amp;gt;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It should be &amp;lt;“creds”&amp;gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Another error is this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /gnu/store/51hahfmqlkj9jfxa2cqbm6dd05qrzxzd-smtpd.conf | grep match
  2450. match !for any !from any !auth action &amp;quot;relay&amp;quot;
  2451. match !from any !for domain &amp;lt;&amp;quot;vdoms&amp;quot;&amp;gt; action &amp;quot;receive&amp;quot;
  2452. match !for local action &amp;quot;receive&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These match options should NOT be false. Let's quickly fix those issues
  2453. reconfigure again:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo guix system reconfigure linode-locke-lamora-current-config.scm
  2454. checking syntax of /gnu/store/a69a5vn2r94glh58wlfq41ygfl38ikgn-smtpd.conf
  2455. configuration OK&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That’s a good sign!&lt;/p&gt;&lt;p&gt;Let’s reboot and see what happens!&lt;/p&gt;&lt;p&gt;Well when I reboot, smtpd refused to start. Let’s look at the config file.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /gnu/store/a69a5vn2r94glh58wlfq41ygfl38ikgn-smtpd.conf
  2456. filter &amp;quot;dkimsign&amp;quot; proc-exec &amp;quot;/gnu/store/n2f5waxzdzcsdvh0xydhnc174n3kingw-opensmtpd-filter-dkimsign-0.6/libexec/opensmtpd/filter-dkimsign -d gnucode.me -s 2021-09-22 -c relaxed/relaxed -k /etc/dkim/private.key user nobody group nogroup&amp;quot;
  2457. mta max-deferred 100
  2458. table &amp;quot;creds&amp;quot; { &amp;quot;joshua&amp;quot; = &amp;quot;$6$Ec4m8FgKjT2F/03Y$k66ABdse9TzCX6qaALB3WBL9GC1rmAWJmaoSjFMpbhzat7DOpFqpnOwpbZ34wwsQYIK8RQlqwM1I/v6vsRq86.&amp;quot; }
  2459. table &amp;quot;vusers&amp;quot; { &amp;quot;joshua@gnucode.me&amp;quot; = &amp;quot;joshua&amp;quot;, &amp;quot;jbranso@gnucode.me&amp;quot; = &amp;quot;joshua&amp;quot;, &amp;quot;postmaster@gnucode.me&amp;quot; = &amp;quot;joshua&amp;quot; }
  2460. table &amp;quot;vdoms&amp;quot; { &amp;quot;gnucode.me&amp;quot;, &amp;quot;gnu-hurd.com&amp;quot; }
  2461. pki smtp.gnucode.me cert &amp;quot;/etc/letsencrypt/live/gnucode.me/fullchain.pem&amp;quot;
  2462. pki smtp.gnucode.me key &amp;quot;/etc/letsencrypt/live/gnucode.me/privkey.pem&amp;quot;
  2463. listen on eth0 tls port 25 pki smtp.gnucode.me
  2464. listen on lo tls port 25 pki smtp.gnucode.me
  2465. listen on eth0 filter &amp;quot;dkimsign&amp;quot; smtps port 465 pki smtp.gnucode.me auth &amp;lt;&amp;quot;creds&amp;quot;&amp;gt;
  2466. listen on eth0 filter &amp;quot;dkimsign&amp;quot; tls-require port 587 pki smtp.gnucode.me auth &amp;lt;&amp;quot;creds&amp;quot;&amp;gt;
  2467. action &amp;quot;relay&amp;quot; relay
  2468. action &amp;quot;receive&amp;quot; maildir &amp;quot;/home/%{rcpt.user}/Maildir&amp;quot; junk virtual &amp;lt;&amp;quot;vusers&amp;quot;&amp;gt;
  2469. match for any from any auth action &amp;quot;relay&amp;quot;
  2470. match from any for domain &amp;lt;&amp;quot;vdoms&amp;quot;&amp;gt; action &amp;quot;receive&amp;quot;
  2471. match for local action &amp;quot;receive&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It seems to be just fine...hmmm. What does the error log say?&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /var/log/maillog | tail
  2472. Dec 22 10:05:41 localhost smtpd[19325]: warn: lost processor: dkimsign exited abnormally
  2473. Dec 22 10:05:41 localhost smtpd[19328]: dkimsign: Can't open key file (/etc/dkim/private.key): No such file or directory
  2474. Dec 22 10:05:41 localhost smtpd[19330]: warn: invalid envelope a565cee5a763bf31: unknown dispatcher
  2475. Dec 22 10:05:41 localhost smtpd[19325]: Exiting
  2476. Dec 22 11:22:18 localhost smtpd[268]: info: OpenSMTPD 6.8.0p2 starting
  2477. Dec 22 11:22:18 localhost smtpd[269]: warn: lost processor: dkimsign exited abnormally
  2478. Dec 22 11:22:18 localhost smtpd[272]: dkimsign: Can't open key file (/etc/dkim/private.key): No such file or directory
  2479. Dec 22 11:22:18 localhost smtpd[274]: warn: invalid envelope a565cee5a763bf31: unknown dispatcher
  2480. Dec 22 11:22:18 localhost smtpd[269]: Exiting&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok, well I think I found the problem. haha. Let’s see, ah, looks like that key
  2481. is here:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;find . -name '*key'
  2482. /etc/opensmtpd/dkimsign/2021-09-22-rsa1024-gnucode.me.key&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s commit my current-config locally, push it upstream, pull it from my server
  2483. and reconfigure.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo guix system reconfigure linode-locke-lamora-current-config.scm
  2484. checking syntax of /gnu/store/42q90z8n03zi9rx29gwdnms4sdr2g2p9-smtpd.conf
  2485. configuration OK&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After I rebooted, smtpd still was not starting. Let’s try to find out why:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat /var/log/maillog | tail
  2486. Dec 22 11:38:03 localhost smtpd[498]: warn: invalid envelope a565cee5a763bf31: unknown dispatcher
  2487. Dec 22 11:38:03 localhost smtpd[493]: warn: lost processor: dkimsign exited abnormally
  2488. Dec 22 11:38:03 localhost smtpd[496]: dkimsign: Can't open key file (/etc/opensmtpd/dkimsign/2021-09-22-rsa1024-gnucode.me.key): Permission denied
  2489. Dec 22 11:38:03 localhost smtpd[493]: Exiting
  2490. Dec 22 11:40:02 localhost dovecot: master: Dovecot v2.3.19.1 (9b53102964) starting up for imap (core dumps disabled)
  2491. Dec 22 11:42:41 localhost smtpd[258]: info: OpenSMTPD 6.8.0p2 starting
  2492. Dec 22 11:42:41 localhost smtpd[259]: warn: lost processor: dkimsign exited abnormally
  2493. Dec 22 11:42:41 localhost smtpd[262]: dkimsign: Can't open key file (/etc/opensmtpd/dkimsign/2021-09-22-rsa1024-gnucode.me.key): Permission denied
  2494. Dec 22 11:42:41 localhost smtpd[264]: warn: invalid envelope a565cee5a763bf31: unknown dispatcher
  2495. Dec 22 11:42:41 localhost smtpd[259]: Exiting&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ok, this is just a permissions error. That’s an easy fix! I changed a
  2496. &lt;code&gt;sudo chown -R smtpd /etc/opensmtpd&lt;/code&gt;. Then I got this beauty:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo herd start smtpd
  2497. Service smtpd has been started.&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Woo hoo! Now let’s try to send an email and see if it works!&lt;/p&gt;&lt;p&gt;I sent an email to gmail, and if you select an email in gmail, you can click on
  2498. view original. It showed me that I did pass dkimsigning! That’s awesome! And
  2499. my email was in my gmail inbox. That’s a really good sign! Now I am off to
  2500. submit a patch to guixrus!&lt;/p&gt;&lt;p&gt;I did get a tip from someone on irc that mentioned that I should verify my
  2501. dkimsigning and SPF via https://dkimvalidator.com/ And when I used that tool, I
  2502. discovered that my SPF was failing, so I will need to fix that.&lt;/p&gt;</content></entry><entry><title>Simple Mispelling Problem</title><id>https://gnucode.me/simple-mispelling-problem.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2022-11-22T11:00:00Z</updated><link href="https://gnucode.me/simple-mispelling-problem.html" rel="alternate" /><content type="html">&lt;p&gt;Edit: Yes I am aware that I misspelled &amp;quot;mispelling&amp;quot;. I figure it's funny if I
  2503. leave it as it is. :)&lt;/p&gt;&lt;p&gt;I had this simple coding problem that I wanted to solve. Here's the problem:&lt;/p&gt;&lt;p&gt;Suppose you are writing an guix service &lt;a href=&quot;https://notabug.org/jbranso/guix/src/newOpensmtpdBranch/gnu/services/mail.scm&quot;&gt;(like I happen to be)&lt;/a&gt;, and you are
  2504. sanitizing user input for various records. Suppose your user mispells an
  2505. option. Wouldn't it be nice to include a nice helpful hint on what he probably
  2506. did wrong?&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(opensmtpd-option (option &amp;quot;forany&amp;quot;))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;error: (option &amp;quot;forany&amp;quot;) is invalid.
  2507. hint: Try &amp;quot;for rcpt-to&amp;quot;, &amp;quot;for domain&amp;quot;, &amp;quot;for local&amp;quot;, &amp;quot;for any&amp;quot;, or &amp;quot;for&amp;quot;.&lt;/p&gt;&lt;p&gt;Using &lt;code&gt;string-prefix-length-ci&lt;/code&gt;, I was able to construct a fairly naive
  2508. prococedure that tries to guess what the user meant to type. Here's what I came
  2509. up with:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;;; if strings is (list &amp;quot;auth&amp;quot; &amp;quot;for any&amp;quot; &amp;quot;from local&amp;quot;)
  2510. ;; Then this will return &amp;quot;Try \&amp;quot;auth\&amp;quot;, \&amp;quot;for any\&amp;quot;, or \&amp;quot;from local\&amp;quot;.&amp;quot;
  2511. (define (try-string strings)
  2512. (string-append &amp;quot;Try &amp;quot;
  2513. (let loop ((strings strings))
  2514. (cond ((= 1 (length strings))
  2515. (string-append
  2516. &amp;quot;or \&amp;quot;&amp;quot; (car strings) &amp;quot;\&amp;quot;.\n&amp;quot;))
  2517. (else
  2518. (string-append
  2519. &amp;quot;\&amp;quot;&amp;quot; (car strings) &amp;quot;\&amp;quot;, &amp;quot;
  2520. (loop (cdr strings))))))))
  2521. ;; suppose string is &amp;quot;for anys&amp;quot;
  2522. ;; and strings is (list &amp;quot;for any&amp;quot; &amp;quot;for local&amp;quot; &amp;quot;for domain&amp;quot;)
  2523. ;; then hint-string will return &amp;quot;Did you mean &amp;quot;for any&amp;quot;?&amp;quot;
  2524. (define* (hint-string string strings
  2525. #:key (fieldname #f))
  2526. (if (not (string? string))
  2527. (try-string strings)
  2528. (let loop ((current-max 1)
  2529. (loop-strings strings)
  2530. (hint-strings '()))
  2531. (if (null? loop-strings)
  2532. (cond ((= 1 (length hint-strings)) ;; only one worthwhile match
  2533. (if fieldname
  2534. (string-append &amp;quot;Did you mean (&amp;quot; fieldname &amp;quot; \&amp;quot;&amp;quot;
  2535. (car hint-strings) &amp;quot;\&amp;quot;) ?\n&amp;quot;)
  2536. (string-append &amp;quot;Did you mean \&amp;quot;&amp;quot; (car hint-strings)
  2537. &amp;quot;\&amp;quot;?\n&amp;quot;)))
  2538. (else (if (null? hint-strings)
  2539. (try-string strings)
  2540. (try-string hint-strings))))
  2541. (let* ((element-string (car loop-strings))
  2542. (element-max
  2543. (string-prefix-length-ci element-string string)))
  2544. (cond ((&amp;gt; element-max current-max)
  2545. (loop element-max (cdr loop-strings)
  2546. (list element-string)))
  2547. ((= element-max current-max)
  2548. (loop current-max (cdr loop-strings)
  2549. (cons element-string hint-strings)))
  2550. (else (loop current-max
  2551. (cdr loop-strings) hint-strings))))))))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It won't recognize that &amp;quot;or any&amp;quot; or &amp;quot;bor any&amp;quot; should match &amp;quot;for any&amp;quot;, but for
  2552. most mispellings, it should be half decent, provided the user got the first
  2553. character right.&lt;/p&gt;&lt;p&gt;What do you all think? How would you write such a procedure?&lt;/p&gt;&lt;p&gt;EDIT: Well it turns out that the guix developers actually have a
  2554. (string-closest) procedure. The relevant code can be found in
  2555. (guix utils) and (guix combinators):&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;(define fold2
  2556. (case-lambda
  2557. ((proc seed1 seed2 lst)
  2558. &amp;quot;Like `fold', but with a single list and two seeds.&amp;quot;
  2559. (let loop ((result1 seed1)
  2560. (result2 seed2)
  2561. (lst lst))
  2562. (if (null? lst)
  2563. (values result1 result2)
  2564. (call-with-values
  2565. (lambda () (proc (car lst) result1 result2))
  2566. (lambda (result1 result2)
  2567. (loop result1 result2 (cdr lst)))))))
  2568. ((proc seed1 seed2 lst1 lst2)
  2569. &amp;quot;Like `fold', but with two lists and two seeds.&amp;quot;
  2570. (let loop ((result1 seed1)
  2571. (result2 seed2)
  2572. (lst1 lst1)
  2573. (lst2 lst2))
  2574. (if (or (null? lst1) (null? lst2))
  2575. (values result1 result2)
  2576. (call-with-values
  2577. (lambda () (proc (car lst1) (car lst2) result1 result2))
  2578. (lambda (result1 result2)
  2579. (loop result1 result2 (cdr lst1) (cdr lst2)))))))))
  2580. (define (string-distance s1 s2)
  2581. &amp;quot;Compute the Levenshtein distance between two strings.&amp;quot;
  2582. ;; Naive implemenation
  2583. (define loop
  2584. (mlambda (as bt)
  2585. (match as
  2586. (() (length bt))
  2587. ((a s ...)
  2588. (match bt
  2589. (() (length as))
  2590. ((b t ...)
  2591. (if (char=? a b)
  2592. (loop s t)
  2593. (1+ (min
  2594. (loop as t)
  2595. (loop s bt)
  2596. (loop s t))))))))))
  2597. (let ((c1 (string-&amp;gt;list s1))
  2598. (c2 (string-&amp;gt;list s2)))
  2599. (loop c1 c2)))
  2600. (define* (string-closest trial tests #:key (threshold 3))
  2601. &amp;quot;Return the string from TESTS that is the closest from the TRIAL,
  2602. according to 'string-distance'. If the TESTS are too far from TRIAL,
  2603. according to THRESHOLD, then #f is returned.&amp;quot;
  2604. (identity ;discard second return value
  2605. (fold2 (lambda (test closest minimal)
  2606. (let ((dist (string-distance trial test)))
  2607. (if (and (&amp;lt; dist minimal) (&amp;lt; dist threshold))
  2608. (values test dist)
  2609. (values closest minimal))))
  2610. #f +inf.0
  2611. tests)))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A lot of the above code is a little bit above my head, but it sure looks cool.&lt;/p&gt;&lt;p&gt;And it actually works better than mine.:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-scheme&quot;&gt;;; old scheme code
  2612. (display (hint-string &amp;quot;bor any&amp;quot; (list &amp;quot;for any&amp;quot; &amp;quot;auth&amp;quot; &amp;quot;rdns&amp;quot;)))
  2613. Try &amp;quot;for any&amp;quot;, &amp;quot;auth&amp;quot;, or &amp;quot;rdns&amp;quot;.
  2614. ;; It didn't match any string. :(
  2615. ;; Let's try guix's (string-closest _) ...
  2616. (string-closest &amp;quot;bor any&amp;quot; (list &amp;quot;for any&amp;quot; &amp;quot;auth&amp;quot; &amp;quot;rdns&amp;quot;))
  2617. $1 = &amp;quot;for any&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Awesome!&lt;/p&gt;</content></entry><entry><title>Doom Emacs rocks!</title><id>https://gnucode.me/doom-emacs-rocks.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2022-11-15T13:00:00Z</updated><link href="https://gnucode.me/doom-emacs-rocks.html" rel="alternate" /><content type="html">&lt;p&gt;I have been using Doom emacs for about 6 months now, and I must say the
  2618. experience is truly wonderful! It is hands down the best Emacs distribution
  2619. that I have ever used. And it is &lt;em&gt;sooo fast&lt;/em&gt;!&lt;/p&gt;&lt;p&gt;I used to own my own emacs config, which is something that everyone should do at
  2620. some point to help you learn more about emacs, but maintaining your own emacs
  2621. config is really hard. You have to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Fix any bugs that you have. &lt;a href=&quot;https://elpa.gnu.org/packages/bug-hunter.html&quot;&gt;bug hunter is really helpful for this&lt;/a&gt;&lt;/li&gt;&lt;li&gt;examine any cool packages that you may want to add.&lt;/li&gt;&lt;li&gt;Keep up to date with new packages that are probably better than the packages
  2622. that you are using.&lt;/li&gt;&lt;li&gt;Update packages and deal with any new bugs they introduce.&lt;/li&gt;&lt;li&gt;Stay sane with all the complexity.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I did the above for some time, and it is doable. I maintained my own Emacs for
  2623. so long, because it was one of the few coding projects that I actively used and
  2624. worked on. The problem was that my config’s stability varied week to week, and
  2625. it made it harder to focus on actually helping &lt;a href=&quot;https://guix.gnu.org&quot;&gt;GNU Guix&lt;/a&gt;. At a certain point I
  2626. decided that I would rather let someone else maintain a config, so that I could
  2627. spend more time helping a free software project.&lt;/p&gt;&lt;p&gt;I also realized that since I use Doom emacs so often, and it is in need of
  2628. &lt;a href=&quot;https://liberapay.com/hlissner&quot;&gt;funding,&lt;/a&gt; that I should probably go ahead and chip in. I highly reccommend you
  2629. to check out Doom Emacs, and consider donating. Currently the maintainer of
  2630. Doom can only allocate 12 hours per week on the project, but hopefully the
  2631. community will be able to support his work full time.&lt;/p&gt;</content></entry><entry><title>PinePhone Update</title><id>https://gnucode.me/pinephone-update.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2022-11-02T12:40:00Z</updated><link href="https://gnucode.me/pinephone-update.html" rel="alternate" /><content type="html">&lt;p&gt;When I was using Mobian GNU/Linux, I had some issues with the PinePhone. Namely,
  2632. my phone no longer received SMS text messages. I switched to &lt;a href=&quot;https://postmarketos.org/&quot;&gt;PostMarketOS&lt;/a&gt;, and
  2633. my issues seemed to have gone away, at least if I keep using the phone as a dumb
  2634. phone. I have disabled wifi on the phone, because I really don’t use it.&lt;/p&gt;&lt;p&gt;It would be nice if I could get the PinePhone to work well with &lt;a href=&quot;https://jmp.chat&quot;&gt;JMP.chat&lt;/a&gt;, but
  2635. currently the texts from my desktop machine do NOT sync well with the phone. So
  2636. if I use two devices, I end up in a weird situation with out of sync text
  2637. messages, which is really confusing. Plus using the internet on the phone
  2638. drains the battery. So I have just disabled the internet on the phone via the
  2639. hardware kill switches.&lt;/p&gt;&lt;p&gt;Texting works flawlessly, but I cannot get SMS images. Also the phone volume
  2640. for calls is pretty poor. And sometimes when I make phone calls, I cannot hear
  2641. what the other person is saying. So that is a little odd.&lt;/p&gt;&lt;p&gt;I highly recommend installing the reversed engineered and nearly &lt;a href=&quot;https://github.com/the-modem-distro/pinephone_modem_sdk&quot;&gt;libre custom
  2642. firmware&lt;/a&gt; for the PinePhone’s modem. It was actually &lt;a href=&quot;https://www.youtube.com/watch?v=aokclNgnIbE&quot;&gt;super easy to do&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It might also not be a bad idea to edit the official PinePhone wiki and mention
  2643. that &lt;a href=&quot;https://tello.com/&quot;&gt;Tello&lt;/a&gt; is a fairly cheap provider. I pay them $8 per month and I have no
  2644. data and unlimited calling and texting texts. That’s pretty good.&lt;/p&gt;&lt;p&gt;That’s the main update for today!&lt;/p&gt;</content></entry><entry><title>Installing OpenBSD on a VM</title><id>https://gnucode.me/installing-openbsd-on-a-vm.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2022-08-05T07:00:00Z</updated><link href="https://gnucode.me/installing-openbsd-on-a-vm.html" rel="alternate" /><content type="html">&lt;p&gt;I am of the opinion, that in order to learn how to use an operating system, you
  2645. have to use it often. Since I am madly in love with Guix System, but have an
  2646. interest in the GNU/Hurd and OpenBSD, I might as well install those OSs on a
  2647. virtual machine! I have already done that with the GNU/Hurd, and today I also
  2648. did it for OpenBSD.&lt;/p&gt;&lt;p&gt;I was not that hard to do. I used this guide to &lt;a href=&quot;https://wiki.qemu.org/index.php/Hosts/BSD#OpenBSD&quot;&gt;install OpenBSD on a vm.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;First let’s create a qemu img for OpenBSD.&lt;/p&gt;&lt;p&gt;&lt;code&gt;qemu-img create -f qcow2 hd0.qcow2.img 100G&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Now, let's create an install script.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat install-bsd.sh
  2649. #!/bin/sh
  2650. qemu-system-x86_64 -m 2048 \
  2651. -no-reboot \
  2652. -cdrom cd71.iso \
  2653. -drive if=virtio,file=hd0.qcow2.img,format=qcow2 \
  2654. -enable-kvm \
  2655. -netdev user,id=mynet0,hostfwd=tcp:127.0.0.1:7922-:22 \
  2656. -device virtio-net,netdev=mynet0 \
  2657. -smp 2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As always installing OpenBSD is an absolute breeze. I do not know how to
  2658. manually partition things, so I just chose the auto install. Also OpenBSD
  2659. supports a &lt;code&gt;us.swapcaps.dvorak&lt;/code&gt; keyboard layout. That’s my layout! How cool is
  2660. that!? And it sets up that layout for the console and X by default. Guix
  2661. System does that, but not so well for wayland.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cat run-bsd.sh&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let's create a run script.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#!/bin/sh
  2662. qemu-system-x86_64 -m 4G \
  2663. -no-reboot \
  2664. -drive if=virtio,file=hd0.qcow2.img,format=qcow2 \
  2665. -enable-kvm \
  2666. -netdev user,id=mynet0,hostfwd=tcp:127.0.0.1:7922-:22 \
  2667. -device virtio-net,netdev=mynet0 \
  2668. -smp 2&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I find the &lt;code&gt;-no-reboot&lt;/code&gt; option helpful, because OpenBSD likes to try to autoreboot
  2669. itself, even when you give it the command: &lt;code&gt;halt&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;I have ran OpenBSD before for about a week before, and it is always a pleasure
  2670. to read man afterboot. With OpenBSD the man pages are absolutely excelent.&lt;/p&gt;&lt;p&gt;One of the first things I did was:&lt;/p&gt;&lt;p&gt;&lt;code&gt;# cp /etc/examples/doas.conf /etc/&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Now my user &lt;code&gt;berno&lt;/code&gt; can use &lt;code&gt;doas&lt;/code&gt; to install packages! Let’s install Emacs!&lt;/p&gt;&lt;p&gt;&lt;code&gt;doas pkg_add emacs&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Also OpenBSD has a habit of printing clues to the console after you type in a
  2671. command. For examle, after you install a package, OpenBSD tells you that it has
  2672. installed README files in &lt;code&gt;/usr/local/bsah/blah/README/emacs/&lt;/code&gt;. I find it really
  2673. cool that it reminds you of this. Also, when you run &lt;code&gt;doas syspatch&lt;/code&gt; it will
  2674. tell you that it updated syspatch. It will also say something like:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Please run syspatch again to apply the patches.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;That’s a handy tip! And indeed, &lt;code&gt;doas syspatch -c&lt;/code&gt; showed that the patches had
  2675. not yet been applied.&lt;/p&gt;&lt;p&gt;Also whilst searching for the internet for how to install OpenBSD on a vm image,
  2676. I came accross &lt;a href=&quot;https://www.skreutz.com/posts/autoinstall-openbsd-on-qemu/&quot;&gt;blog post&lt;/a&gt; that describes that you can automate OpenBSD installs.
  2677. That might be something to play with later!&lt;/p&gt;&lt;p&gt;I would like to also set up my local OpenBSD to set up ssh. That way I could do
  2678. something like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#+BEGIN_SRC shell :dir /ssh:berno@localhost:/home/berno :exports both
  2679. ls | wc -l
  2680. #+END_SRC
  2681. #+RESULTS:
  2682. : 9&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I also think it would be fabulous if the OpenBSD team started to make a
  2683. guix-like package manager/distro. I imagine that they could use perl to do it,
  2684. since it seems like OpenBSD has embraced perl as their scripting language, and I
  2685. think it their man pages show that perl can use some rather low lever operating
  2686. system interfaces.&lt;/p&gt;</content></entry><entry><title>Status Update July 2022</title><id>https://gnucode.me/status-update-july-2022.html</id><author><name>Joshua Branson</name><email>jbranso@dismail.de</email></author><updated>2022-08-02T13:00:00Z</updated><link href="https://gnucode.me/status-update-july-2022.html" rel="alternate" /><content type="html">&lt;p&gt;So I recently bought a guix system server! It cost me about $250. It’s got 16GB
  2687. of RAM (I can upgrade to 32GB) with a 4TB harddrive. I may play with RAID at
  2688. some point, but that’s a little down the line. If you want some help getting
  2689. something like this for yourself, please contact me. This blog post is my first
  2690. attempt at trying to figure out how to connect to &lt;code&gt;copertino&lt;/code&gt;, to the
  2691. internet. Now on with the blog post!&lt;/p&gt;&lt;p&gt;So when you are like me, and you start to wonder how the internets work, a good
  2692. thing to learn first is difference between &lt;strong&gt;WAN&lt;/strong&gt; and &lt;strong&gt;LAN&lt;/strong&gt;. LAN is your local area
  2693. network. When you are at home, on your computer, you are on your LAN. If your
  2694. computer talks to another computer in your house, then those machines are using
  2695. the LAN. When your computer talks to &lt;code&gt;www.gnu.org&lt;/code&gt;, your computer is accessing
  2696. the WAN, which is the wide area network, usually called the internet.&lt;/p&gt;&lt;p&gt;Computers talk to each other via IP addresses. An IP address is a numerical ID
  2697. that is unique to each computer. Computers use IP address as essentially phone
  2698. numbers to reach out and say, “Hey what time are we having this binary number
  2699. crunching date?” What’s interesting, is computers have more than just a phone
  2700. number, they have a phone number, plus several extensions.&lt;/p&gt;&lt;p&gt;When you call a business, and they say, “Thanks for calling Bank of Scotland.
  2701. Please press 5 to talk to a manager, 4 to talk to a sales person, and 3 to open
  2702. an account. Thanks!” 5, 4, and 3 are extensions. Computers have the same
  2703. thing, on steroids. They calls extensions ports, and there are like 50,000+
  2704. ports. Ports are usually set up to be used by specific applications. For
  2705. example, your web browser uses port 80 and 443 to visit websites.&lt;/p&gt;&lt;p&gt;Here’s a crazy example.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ping -c 1 gnu.org&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;PING gnu.org (209.51.188.116): 56 data bytes
  2706. 64 bytes from 209.51.188.116: icmp&amp;lt;sub&amp;gt;seq&amp;lt;/sub&amp;gt;=0 ttl=55 time=39.078 ms
  2707. — gnu.org ping statistics —
  2708. 1 packets transmitted, 1 packets received, 0% packet loss
  2709. round-trip min/avg/max/stddev = 39.078/39.078/39.078/0.000 ms&lt;/p&gt;&lt;p&gt;So, we now know that gnu.org is serving it’s website on 209.51.188.116. Try
  2710. posting this in a web browser url: 209.51.188.116. You’ll end up at
  2711. savannah.nongnu.org, which is a website that the fabulous people at GNU run.&lt;/p&gt;&lt;p&gt;Anyway, let’s take a look at your IP address:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ip address show&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;1: lo: &amp;lt;LOOPBACK,MULTICAST,UP,LOWER&amp;lt;sub&amp;gt;UP&amp;lt;/sub&amp;gt;&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  2712. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  2713. inet 127.0.0.1/8 scope global lo
  2714. valid&amp;lt;sub&amp;gt;lft&amp;lt;/sub&amp;gt; forever preferred&amp;lt;sub&amp;gt;lft&amp;lt;/sub&amp;gt; forever
  2715. 2: enp0s25: &amp;lt;BROADCAST,MULTICAST,UP,LOWER&amp;lt;sub&amp;gt;UP&amp;lt;/sub&amp;gt;&amp;gt; mtu 1500 qdisc pfifo&amp;lt;sub&amp;gt;fast&amp;lt;/sub&amp;gt; state UP group default qlen 1000
  2716. link/ether 00:1c:25:9a:37:ba brd ff:ff:ff:ff:ff:ff
  2717. inet 192.168.1.122/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s25
  2718. valid&amp;lt;sub&amp;gt;lft&amp;lt;/sub&amp;gt; 22986sec preferred&amp;lt;sub&amp;gt;lft&amp;lt;/sub&amp;gt; 22986sec
  2719. inet6 fe80::36a7:f91e:a1e0:16fe/64 scope link noprefixroute
  2720. valid&amp;lt;sub&amp;gt;lft&amp;lt;/sub&amp;gt; forever preferred&amp;lt;sub&amp;gt;lft&amp;lt;/sub&amp;gt; forever
  2721. 3: wlp2s0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue state DOWN group default qlen 1000
  2722. link/ether b6:cf:27:17:7c:fc brd ff:ff:ff:ff:ff:ff permaddr e4:ce:8f:59:d6:bf&lt;/p&gt;&lt;p&gt;Let’s take the above output line by line:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1: lo: &amp;lt;LOOPBACK,MULTICAST,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
  2723. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  2724. inet *127.0.0.1/8* scope global lo
  2725. valid_lft forever preferred_lft forever
  2726. lo is your loopback device, which is fancy talk for &amp;quot;ME&amp;quot;. The embolded
  2727. *127.0.0.1* is a universal alias for &amp;quot;ME&amp;quot;. If you have a web site running on
  2728. your computer, typing in 127.0.0.1:80 lets you access that website. 127.0.0.1:80
  2729. means, talk to the computer at address 127.0.0.1 (which is me), and request the
  2730. content on port 80.
  2731. 2: *enp0s25*: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
  2732. link/ether 00:1c:25:9a:37:ba brd ff:ff:ff:ff:ff:ff
  2733. *inet* *192.168.1.122/24* brd 192.168.1.255 scope global dynamic noprefixroute enp0s25
  2734. valid_lft 22986sec preferred_lft 22986sec
  2735. *inet6* *fe80::36a7:f91e:a1e0:16fe/64* scope link noprefixroute
  2736. valid_lft forever preferred_lft forever
  2737. *enp0s25* is your ethernet device. Anything that begins with an 'e' is usually
  2738. an ethernet device. Ethernet is usually the blue cable that you
  2739. plug into your laptop or server. Laptops increasingly do not have ethernet,
  2740. which is sad 'cause ethernet is faster than wifi.
  2741. *init* means IPv4. Remember when I said that computers have IP address? Well
  2742. than have one that looks like *192.168.1.122*. That is the IPv4 address. People
  2743. now adays have phones, tablets, gaming consoles, smart watches, etc. and each
  2744. need an IP address. As a result, the IPv4 address space is getting a little
  2745. crowded. So some smart people introduced IPv6, which has much more unique IDs.
  2746. (Keep reading to see an example IPv6 address).
  2747. Unfortunately for me, an IP address of 192.168.number.number is a LAN IP. That
  2748. means I have to be in my house to talk to view my personal website. I cannot
  2749. view that website at work. :(
  2750. *init6* is IPv6. And *fe80::36a7:f91e:a1e0:16fe* is this computer's IPv6
  2751. address. fe80 is also a LAN IPv6 address. The outside world cannot use that
  2752. address to talk to this local computer.
  2753. 3: *wlp2s0*: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc noqueue state DOWN group default qlen 1000
  2754. link/ether b6:cf:27:17:7c:fc brd ff:ff:ff:ff:ff:ff permaddr e4:ce:8f:59:d6:bf
  2755. This is my wifi device. Anything that begins with an 'w' is usually a wifi device.
  2756. ip route&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;default via 192.168.1.1 dev enp0s25 proto dhcp metric 100
  2757. 192.168.1.0/24 dev enp0s25 proto kernel scope link src 192.168.1.122 metric 100&lt;/p&gt;&lt;p&gt;The number after &lt;strong&gt;default&lt;/strong&gt; is the default gateway. That is my router’s LAN IP
  2758. address. If I type that into a web browser, when I am at home, then I can log
  2759. into my router. Usually your router’s username and password is on a stick on the
  2760. back of your router.&lt;/p&gt;&lt;p&gt;Also, it should be possible for me to log into the router and tell it to open up
  2761. ports 80 and 443 (http and https), so that anyone connecting to say
  2762. &lt;code&gt;www.copertino.me&lt;/code&gt; would be connecting to my computer only, AND NOT my
  2763. roommates’ laptop. However, an attacker could still potentially break into my
  2764. guix system computer, and attack my roommate’s computer.&lt;/p&gt;&lt;p&gt;Also, if you decide to play around with customizing your router, I would
  2765. recommend OpenBSD. OpenBSD potentially has some binary blobs for wifi, which is
  2766. why the &lt;a href=&quot;https://www.gnu.org/distros/free-distros.en.html&quot;&gt;FSF&lt;/a&gt; will not endorse it as a free distro. but if you don’t use wifi,
  2767. then there is no software freedom issues. Anyway, I have recently developed
  2768. quite the crush on OpenBSD, and I found this &lt;a href=&quot;https://openbsdrouterguide.net/&quot;&gt;guide&lt;/a&gt;, that helps you use OpenBSD
  2769. for your router. It’s actually quite comprehensive:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;In this guide we’re going to take a look at how we can use cheap and “low end”
  2770. hardware to build an amazing OpenBSD router with firewalling capabilities,
  2771. segmented local area networks, DNS with domain blocking, DHCP and more.&lt;/p&gt;&lt;p&gt;We will use a setup in which the router segments the local area network (LAN)
  2772. into three separate networks, one for the grown-ups in the house, one for the
  2773. children, and one for public facing servers (a DMZ), such as a private web
  2774. server or mail server. We will also look at how we can use DNS to block out ads,
  2775. porn, and other websites on the Internet. The OpenBSD router can also be used on
  2776. small to mid-size offices.&lt;/p&gt;&lt;/blockquote&gt;</content></entry></feed>