https://systemreboot.net/systemreboot -- blog2024-02-11T00:00:00ZEmacs 29.1 Org-mode 9.6.19 ennum 0.1.0All content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.https://systemreboot.net/post/using-guix-despite-uncooperative-hpc-admins-the-ultimate-solution.htmlUsing Guix despite uncooperative HPC admins—the ultimate solution2024-02-11T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">Using Guix despite uncooperative HPC admins—the ultimate solution</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2024-02-11 12:00:00">February 11, 2024</time></p><p>In other languages: <a hreflang="ta" href="/post/%E0%AE%92%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B4%E0%AF%88%E0%AE%AF%E0%AE%BE-hpc-%E0%AE%AE%E0%AF%87%E0%AE%B2%E0%AE%BE%E0%AE%A3%E0%AF%8D%E0%AE%AE%E0%AF%88%E0%AE%AF%E0%AF%81%E0%AE%9F%E0%AE%A9%E0%AF%81%E0%AE%AE%E0%AF%8D-guix-%E0%AE%AA%E0%AE%AF%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AF%81%E0%AE%B5%E0%AE%A4%E0%AF%81-%E0%AE%87%E0%AE%B1%E0%AF%81%E0%AE%A4%E0%AE%BF%E0%AE%A4%E0%AF%8D-%E0%AE%A4%E0%AF%80%E0%AE%B0%E0%AF%8D%E0%AE%B5%E0%AF%81">தமிழ்</a></p><p>Tags: <a class="p-category" href="/tag/guix">guix</a>, <a class="p-category" href="/tag/software">software</a></p><div class="p-summary">How do you use Guix on HPC when your friendly HPC admins are uncooperative? This is the ultimate solution.</div><div class="e-content"><p>
Guix is extremely useful on HPC. But often, your friendly HPC admins are uncooperative. guix packs are an idea, but they only work from /gnu/store. There are ways to make relocatable packs using -R, -RR, etc. But, when these hacks do not work, there is an ultimate solution—rebuild all packages from scratch to work from your HPC home folder. Here's how.
</p>
<div id="outline-container-org28ce604" class="outline-2">
<h2 id="org28ce604">A guix-daemon with a different store and state directory</h2>
<div class="outline-text-2" id="text-org28ce604">
<p>
First, create the path you want on your HPC (say, /home/hpcuser) on your own machine.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ sudo mkdir /home/hpcuser
</pre>
</div>
<p>
Then, build a guix-daemon that puts its store and state directories in that path. To do so, use the following guix-daemon.scm. Put your path of choice in the %relocate-path variable.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages package-management)
(guix gexp)
(guix packages)
(guix utils))
(<span class="org-keyword">define</span> <span class="org-function-name">%relocate-path</span>
<span class="org-string">"/home/hpcuser"</span>)
(package
(inherit guix)
(arguments
(substitute-keyword-arguments (package-arguments guix)
<span class="org-comment-delimiter">;; </span><span class="org-comment">Skip tests to save time.</span>
((<span class="org-builtin">#:tests?</span> tests? #f)
#f)
<span class="org-comment-delimiter">;; </span><span class="org-comment">Set store and state directories to be inside %relocate-path.</span>
((<span class="org-builtin">#:configure-flags</span> flags '())
#~(cons #$(string-append <span class="org-string">"--with-store-dir="</span> %relocate-path <span class="org-string">"/store"</span>)
(<span class="org-keyword">map</span> (<span class="org-keyword">lambda</span> (flag)
(<span class="org-keyword">if</span> (string=? flag <span class="org-string">"--localstatedir=/var"</span>)
#$(string-append <span class="org-string">"--localstatedir="</span> %relocate-path <span class="org-string">"/var"</span>)
flag))
#$flags))))))
</pre>
</div>
<p>
Build and run the guix-daemon.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ sudo $(guix build -f guix-daemon.scm)/bin/guix-daemon --build-users-group=guixbuild --listen=/tmp/guix-daemon-socket --no-substitutes
</pre>
</div>
</div>
</div>
<div id="outline-container-org15d6ddf" class="outline-2">
<h2 id="org15d6ddf">Use the new guix-daemon to build yourself a guix pack</h2>
<div class="outline-text-2" id="text-org15d6ddf">
<p>
Use the new guix-daemon to build yourself a guix pack; no need to use -R, -RR, etc.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules ((gnu packages base) <span class="org-builtin">#:select</span> (hello))
(guix build-system)
(guix packages)
(guix utils))
<span class="org-comment-delimiter">;; </span><span class="org-comment">Skip tests to save time.</span>
(<span class="org-keyword">define</span> (<span class="org-function-name">package-without-tests</span> p)
<span class="org-comment-delimiter">;; </span><span class="org-comment">Some build systems (raw and trivial) do not support a #:tests?</span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">argument. So, don't modify the package.</span>
(<span class="org-keyword">if</span> (memq (build-system-name (package-build-system p))
(list 'raw 'trivial))
p
<span class="org-comment-delimiter">;; </span><span class="org-comment">For all other packages, disable tests.</span>
(package/inherit p
(arguments
(substitute-keyword-arguments (package-arguments p)
((<span class="org-builtin">#:tests?</span> _ #f) #f))))))
(packages->manifest
(<span class="org-keyword">map</span> (package-mapping package-without-tests)
(list hello)))
</pre>
</div>
<p>
With the above manifest.scm, run guix pack like so.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ <span class="org-variable-name">NIX_STORE_DIR</span>=/home/hpcuser/store <span class="org-variable-name">GUIX_DAEMON_SOCKET</span>=/tmp/guix-daemon-socket guix pack -S /home/hpcuser/bin=bin -m manifest.scm
</pre>
</div>
<p>
Now, this guix pack will work on our HPC, specifically from the one path that we chose. This will work no matter what!
</p>
<div class="org-src-container">
<pre class="src src-shell">$ scp /home/hpcuser/store/…-guix-pack.tar.gz hpc:~
$ ssh hpc
[hpc]~$ tar --strip-components=3 xf …-guix-pack.tar.gz
[hpc]~$ ./bin/hello
Hello, world!
</pre>
</div>
</div>
</div>
<div id="outline-container-org5d1c5ca" class="outline-2">
<h2 id="org5d1c5ca">Bonus: Save more build time!</h2>
<div class="outline-text-2" id="text-org5d1c5ca">
<p>
Even though the above manifest.scm will work, we can save a little more build time with the following.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules ((gnu compression) <span class="org-builtin">#:select</span> (compressor))
((gnu packages base) <span class="org-builtin">#:select</span> (hello tar))
((gnu packages compression) <span class="org-builtin">#:select</span> (gzip))
(guix build-system)
(guix gexp)
(guix monads)
(guix packages)
(guix profiles)
(guix scripts pack)
(guix store)
(guix utils))
(<span class="org-keyword">define</span> <span class="org-function-name">%relocate-path</span>
<span class="org-string">"/home/hpcuser"</span>)
<span class="org-comment-delimiter">;; </span><span class="org-comment">Skip tests to save time.</span>
(<span class="org-keyword">define</span> (<span class="org-function-name">package-without-tests</span> p)
<span class="org-comment-delimiter">;; </span><span class="org-comment">Some build systems (raw and trivial) do not support a #:tests?</span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">argument. So, don't modify the package.</span>
(<span class="org-keyword">if</span> (memq (build-system-name (package-build-system p))
(list 'raw 'trivial))
p
<span class="org-comment-delimiter">;; </span><span class="org-comment">For all other packages, disable tests.</span>
(package/inherit p
(arguments
(substitute-keyword-arguments (package-arguments p)
((<span class="org-builtin">#:tests?</span> _ #f) #f))))))
(<span class="org-keyword">define</span> <span class="org-function-name">hpc-profile</span>
(profile
(content (packages->manifest
(<span class="org-keyword">map</span> (package-mapping package-without-tests)
(list hello))))
<span class="org-comment-delimiter">;; </span><span class="org-comment">Disable hooks and locales? to save on package building. Hope</span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">that these are irrelevant to us.</span>
(hooks '())
(locales? #f)
(allow-collisions? #t)))
(with-store store
(run-with-store store
(with-monad %store-monad
(>>= (self-contained-tarball <span class="org-string">"hpc-pack"</span>
hpc-profile
<span class="org-builtin">#:compressor</span> (compressor <span class="org-string">"gzip"</span> <span class="org-string">".gz"</span>
#~(list #+(file-append (package-without-tests gzip)
<span class="org-string">"/bin/gzip"</span>)
<span class="org-string">"-9n"</span>))
<span class="org-builtin">#:symlinks</span> `((,(string-append %relocate-path <span class="org-string">"/bin"</span>)
->
<span class="org-string">"/bin"</span>))
<span class="org-builtin">#:archiver</span> (package-without-tests tar))
(<span class="org-keyword">lambda</span> (drv)
(return drv))))))
</pre>
</div>
<p>
Put this in hpc-pack.scm and build like so.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ <span class="org-variable-name">NIX_STORE_DIR</span>=/home/hpcuser/store <span class="org-variable-name">GUIX_DAEMON_SOCKET</span>=/tmp/guix-daemon-socket guix build -f hpc-pack.scm
</pre>
</div>
</div>
</div>
<div id="outline-container-org61244be" class="outline-2">
<h2 id="org61244be">A different approach to avoid rebuilding the world</h2>
<div class="outline-text-2" id="text-org61244be">
<p>
Rebuilding all packages is a waste of time and energy. There is a way to avoid this however—download Guix substitutes and patch them replacing the /gnu/store path with a path of our choice. Patching binaries this way is not bullet-proof. It is hard to support all kinds of binary files. But, it is another worthy choice. <a href="https://gitlab.com/pjotrp/guix-relocate">Pjotr describes this</a> further.
</p>
</div>
</div>
<div id="outline-container-org977e879" class="outline-2">
<h2 id="org977e879">Acknowledgment</h2>
<div class="outline-text-2" id="text-org977e879">
<p>
Thanks to Christopher Baines for suggesting this technique in a Guix London meetup!
</p>
</div>
</div>
</div></article>https://systemreboot.net/post/ஒத்துழையா-hpc-மேலாண்மையுடனும்-guix-பயன்படுத்துவது-இறுதித்-தீர்வு.htmlஒத்துழையா HPC மேலாண்மையுடனும் Guix பயன்படுத்துவது—இறுதித் தீர்வு2024-02-11T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">ஒத்துழையா HPC மேலாண்மையுடனும் Guix பயன்படுத்துவது—இறுதித் தீர்வு</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2024-02-11 12:00:00">பிப்ரவரி 11, 2024</time></p><p>In other languages: <a hreflang="en" href="/post/using-guix-despite-uncooperative-hpc-admins-the-ultimate-solution">English</a></p><p>Tags: <a class="p-category" href="/tag/guix.ta">guix</a>, <a class="p-category" href="/tag/%E0%AE%AE%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%8A%E0%AE%B0%E0%AF%81%E0%AE%B3%E0%AF%8D.ta">மென்பொருள்</a></p><div class="p-summary">சற்றும் ஒத்துழையா HPC மேலாண்மையுடனும் Guix பயன்படுத்த இறுதிக் கட்டத் தீர்வு.</div><div class="e-content"><p>
HPC கொத்துக்கணினிகளில் Guix பெரும் பயனுடையது. ஆயினும் பல வேளை அவற்றில் Guix நிறுவ HPC மேலாண்மை ஒத்துழைப்பதில்லை. guix pack பெட்டகங்கள் /gnu/store தவிர்த்து வேறு பாதைகளில் செயல்படா. அதற்கே -R, -RR மூலம் அவற்றை வேலை செய்விக்க வெவ்வேறு நுட்பங்கள் இருக்கின்றன. அன்னுட்பங்கள் வேலை செய்யாவிடின் இறுதித் தீர்வொன்றிருக்கிறது—/gnu/store அல்லாது நமக்கு வேண்டிய பாதையில் செயல்படும் இரும நிரல்களை நாமே முதற்கண் உருவாக்கலாம்.
</p>
<div id="outline-container-org05e0f0b" class="outline-2">
<h2 id="org05e0f0b">புதிய கிடங்கடைவும் நிலையடைவும் (store and state directories) உடைய guix-daemon</h2>
<div class="outline-text-2" id="text-org05e0f0b">
<p>
முதலில் HPC கொத்துக்கணினியில் நமக்கு வேண்டிய பாதையை (எடுத்துக்காட்டிற்கு /home/hpcuser) நமது சொந்த கணனியில் அமைக்க.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ sudo mkdir /home/hpcuser
</pre>
</div>
<p>
பின்னர் அப்பாதையை கிடங்காகப் பயன்படுத்தும் guix-daemon ஒன்றை உருவாக்குக. இதற்குக் கீழ்க்காணும் guix-daemon.scm கோப்பைப் பயன்படுத்துக. இதில் உங்களுக்கு வேண்டிய பாதையை %relocate-path மாறியில் இடுக.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages package-management)
(guix gexp)
(guix packages)
(guix utils))
(<span class="org-keyword">define</span> <span class="org-function-name">%relocate-path</span>
<span class="org-string">"/home/hpcuser"</span>)
(package
(inherit guix)
(arguments
(substitute-keyword-arguments (package-arguments guix)
<span class="org-comment-delimiter">;; </span><span class="org-comment">நேரத்தைச் சேமிக்க சோதனை தவிர்.</span>
((<span class="org-builtin">#:tests?</span> tests? #f)
#f)
<span class="org-comment-delimiter">;; </span><span class="org-comment">கிடங்கு அடைவும் (store directory) நிலை அடைவும் (state directory)</span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">%relocate-path அகத்தே இருக்கும்படி அமை.</span>
((<span class="org-builtin">#:configure-flags</span> flags '())
#~(cons #$(string-append <span class="org-string">"--with-store-dir="</span> %relocate-path <span class="org-string">"/store"</span>)
(<span class="org-keyword">map</span> (<span class="org-keyword">lambda</span> (flag)
(<span class="org-keyword">if</span> (string=? flag <span class="org-string">"--localstatedir=/var"</span>)
#$(string-append <span class="org-string">"--localstatedir="</span> %relocate-path <span class="org-string">"/var"</span>)
flag))
#$flags))))))
</pre>
</div>
<p>
guix-daemon அமைத்து இயக்குக.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ sudo $(guix build -f guix-daemon.scm)/bin/guix-daemon --build-users-group=guixbuild --listen=/tmp/guix-daemon-socket --no-substitutes
</pre>
</div>
</div>
</div>
<div id="outline-container-orgd8c236b" class="outline-2">
<h2 id="orgd8c236b">புதிய guix-daemon மூலம் வேண்டிய பெட்டகத்தை அமைக்க</h2>
<div class="outline-text-2" id="text-orgd8c236b">
<p>
அதன் பின் அந்த guix-daemon மூலம் நமக்கு வேண்டிய நிரல்தொகுப்புகளை உருவாக்கி அவற்றை guix pack (-R, -RR எதுவும் இன்றி) செய்க.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules ((gnu packages base) <span class="org-builtin">#:select</span> (hello))
(guix build-system)
(guix packages)
(guix utils))
<span class="org-comment-delimiter">;; </span><span class="org-comment">நேரத்தைச் சேமிக்க சோதனை தவிர்.</span>
(<span class="org-keyword">define</span> (<span class="org-function-name">package-without-tests</span> p)
<span class="org-comment-delimiter">;; </span><span class="org-comment">#:tests? செயலுருபு இல்லா பெயர்ப்பு முறைகளை உடைய நிரல்தொகுப்புகளை</span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">மாற்றாதே.</span>
(<span class="org-keyword">if</span> (memq (build-system-name (package-build-system p))
(list 'raw 'trivial))
p
<span class="org-comment-delimiter">;; </span><span class="org-comment">பிற நிரல்தொகுப்புகளுக்குச் சோதனை தவிர்.</span>
(package/inherit p
(arguments
(substitute-keyword-arguments (package-arguments p)
((<span class="org-builtin">#:tests?</span> _ #f) #f))))))
(packages->manifest
(<span class="org-keyword">map</span> (package-mapping package-without-tests)
(list hello)))
</pre>
</div>
<p>
இதை manifest.scm என்னும் கோப்பிலிட்டு guix pack பெட்டகம் அமைத்து மகிழ்க.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ <span class="org-variable-name">NIX_STORE_DIR</span>=/home/hpcuser/store <span class="org-variable-name">GUIX_DAEMON_SOCKET</span>=/tmp/guix-daemon-socket guix pack -S /home/hpcuser/bin=bin -m manifest.scm
</pre>
</div>
<p>
இப்பெட்டகம் நமது HPC கொத்துக்கணினியில் நாம் குறிப்பிட்ட பாதையில் மட்டும் செயல்படும்; இதுத் தவறவே தவறாது—எப்போதும் வேலை செய்யும்!
</p>
<div class="org-src-container">
<pre class="src src-shell">$ scp /home/hpcuser/store/…-guix-pack.tar.gz hpc:~
$ ssh hpc
[hpc]~$ tar --strip-components=3 xf …-guix-pack.tar.gz
[hpc]~$ ./bin/hello
Hello, world!
</pre>
</div>
</div>
</div>
<div id="outline-container-org81112ee" class="outline-2">
<h2 id="org81112ee">இன்னும் கொஞ்சம் நேரம் சேமிக்க!</h2>
<div class="outline-text-2" id="text-org81112ee">
<p>
மேற்கண்ட manifest.scm போதுமேயாயினும் இறுதி guix pack பெட்டகமைப்பில் இன்னும் நேரம் சேமிக்க கீழ்க்காணும்வாறு guix pack பெட்டகத்தை நாமே scheme நிரலில் அமைக்கலாம்.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules ((gnu compression) <span class="org-builtin">#:select</span> (compressor))
((gnu packages base) <span class="org-builtin">#:select</span> (hello tar))
((gnu packages compression) <span class="org-builtin">#:select</span> (gzip))
(guix build-system)
(guix gexp)
(guix monads)
(guix packages)
(guix profiles)
(guix scripts pack)
(guix store)
(guix utils))
(<span class="org-keyword">define</span> <span class="org-function-name">%relocate-path</span>
<span class="org-string">"/home/hpcuser"</span>)
<span class="org-comment-delimiter">;; </span><span class="org-comment">நேரத்தைச் சேமிக்க சோதனை தவிர்.</span>
(<span class="org-keyword">define</span> (<span class="org-function-name">package-without-tests</span> p)
<span class="org-comment-delimiter">;; </span><span class="org-comment">#:tests? செயலுருபு இல்லா பெயர்ப்பு முறைகளை உடைய நிரல்தொகுப்புகளை</span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">மாற்றாதே.</span>
(<span class="org-keyword">if</span> (memq (build-system-name (package-build-system p))
(list 'raw 'trivial))
p
<span class="org-comment-delimiter">;; </span><span class="org-comment">பிற நிரல்தொகுப்புகளுக்குச் சோதனை தவிர்.</span>
(package/inherit p
(arguments
(substitute-keyword-arguments (package-arguments p)
((<span class="org-builtin">#:tests?</span> _ #f) #f))))))
(<span class="org-keyword">define</span> <span class="org-function-name">hpc-profile</span>
(profile
(content (packages->manifest
(<span class="org-keyword">map</span> (package-mapping package-without-tests)
(list hello))))
<span class="org-comment-delimiter">;; </span><span class="org-comment">நேரத்தைச் சேமிக்க hooks, locales? தவிர். இவை நமக்குத் தேவையில்லையென</span>
<span class="org-comment-delimiter">;; </span><span class="org-comment">நம்புவோம்.</span>
(hooks '())
(locales? #f)
(allow-collisions? #t)))
(with-store store
(run-with-store store
(with-monad %store-monad
(>>= (self-contained-tarball <span class="org-string">"hpc-pack"</span>
hpc-profile
<span class="org-builtin">#:compressor</span> (compressor <span class="org-string">"gzip"</span> <span class="org-string">".gz"</span>
#~(list #+(file-append (package-without-tests gzip)
<span class="org-string">"/bin/gzip"</span>)
<span class="org-string">"-9n"</span>))
<span class="org-builtin">#:symlinks</span> `((,(string-append %relocate-path <span class="org-string">"/bin"</span>)
->
<span class="org-string">"/bin"</span>))
<span class="org-builtin">#:archiver</span> (package-without-tests tar))
(<span class="org-keyword">lambda</span> (drv)
(return drv))))))
</pre>
</div>
<p>
இதை hpc-pack.scm என்னும் கோப்பிலிட்டு கீழ்க்காணும்வாறு பெட்டகம் அமைக்க.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ <span class="org-variable-name">NIX_STORE_DIR</span>=/home/hpcuser/store <span class="org-variable-name">GUIX_DAEMON_SOCKET</span>=/tmp/guix-daemon-socket guix build -f hpc-pack.scm
</pre>
</div>
</div>
</div>
<div id="outline-container-org0142dbb" class="outline-2">
<h2 id="org0142dbb">உலகத்தையே முதற்கண் படைக்காமல் இன்னொரு வழி</h2>
<div class="outline-text-2" id="text-org0142dbb">
<p>
அனைத்து நிரல்தொகுப்புகளையும் முதற்கண் படைப்பது ஆக்கமும் நேரமும் வீண். இதிலிருந்துத் தப்ப இன்னொரு வழி உள்ளது—Guix மாற்றீடுகளைப் (substitutes) பதவிறக்கி அவற்றில் /gnu/store பாதையை மட்டும் நமக்கு வேண்டிய பாதையாக திருத்தியமைப்பது. இவ்வாறு இருமக்கோப்புகளைத் திருத்தல் எளிதல்ல, எல்லா வித இருமக்கோப்புகளிலும் உறுதியாக வேலைச் செய்யுமென்றும் கூற இயலாது. ஆனால் இதுவும் ஒரு வழி. இதைப் பற்றி <a href="https://gitlab.com/pjotrp/guix-relocate">பியோட்டர் விவரித்துள்ளார்</a>.
</p>
</div>
</div>
<div id="outline-container-org8a8247e" class="outline-2">
<h2 id="org8a8247e">நன்றி</h2>
<div class="outline-text-2" id="text-org8a8247e">
<p>
இம்முறை Guix இலண்டன் சந்திப்பில் கிறிஷ்டோஃபர் பெயின்ஸ் அறிவுறுத்தியது. அவருக்கு நன்றி!
</p>
</div>
</div>
</div></article>https://systemreboot.net/post/nagercoil-dump.htmlNagercoil dump site2023-12-27T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">Nagercoil dump site</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2023-12-27 12:00:00">December 27, 2023</time></p><p>In other languages: <a hreflang="ta" href="/post/%E0%AE%A8%E0%AE%BE%E0%AE%95%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AF%8B%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AE%BF%E0%AE%B2%E0%AF%8D-%E0%AE%95%E0%AF%81%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AF%88-%E0%AE%AE%E0%AF%87%E0%AE%9F%E0%AF%81">தமிழ்</a></p><p>Tags: <a class="p-category" href="/tag/nagercoil">nagercoil</a>, <a class="p-category" href="/tag/waste">waste</a>, <a class="p-category" href="/tag/environment">environment</a></p><div class="p-summary">A dump site in Nagercoil that is a manifestation of the growing solid waste management problem</div><div class="e-content">
<div id="orgba1f299" class="figure">
<p><a href="/images/nagercoil-dump-site-1024px.jpg"><img src="/images/nagercoil-dump-site-640px.jpg" alt="A giant dump site at a "Nagercoil Corporation Solid Waste Management Centre". Workers are seen processing the waste using earth movers and trucks." /></a>
</p>
<p><span class="figure-number">Figure 1: </span>A dump site on Nagercoil beach road</p>
</div>
<p>
I am in my hometown of Nagercoil on vacation. Each time I am here, I see increased material welfare with more and more multinational brands setting up shop. This time, I also found this giant dump site on Nagercoil Beach Road—a manifestation of India's growing solid waste management crisis.
</p>
</div></article>https://systemreboot.net/post/நாகர்கோயிலில்-குப்பை-மேடு.htmlநாகர்கோயிலில் குப்பை மேடு2023-12-27T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">நாகர்கோயிலில் குப்பை மேடு</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2023-12-27 12:00:00">டிசம்பர் 27, 2023</time></p><p>In other languages: <a hreflang="en" href="/post/nagercoil-dump">English</a></p><p>Tags: <a class="p-category" href="/tag/%E0%AE%A8%E0%AE%BE%E0%AE%95%E0%AE%B0%E0%AF%8D%E0%AE%95%E0%AF%8B%E0%AE%AF%E0%AE%BF%E0%AE%B2%E0%AF%8D.ta">நாகர்கோயில்</a>, <a class="p-category" href="/tag/%E0%AE%95%E0%AF%81%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AF%88.ta">குப்பை</a>, <a class="p-category" href="/tag/%E0%AE%9A%E0%AF%81%E0%AE%B1%E0%AF%8D%E0%AE%B1%E0%AF%81%E0%AE%9A%E0%AF%8D%E0%AE%9A%E0%AF%82%E0%AE%B4%E0%AE%B2%E0%AF%8D.ta">சுற்றுச்சூழல்</a></p><div class="p-summary">நாகர்கோயிலில் வளர்ந்து வரும் திடக்கழிவு சிக்கலின் வெளிப்பாடாக குப்பை மேடொன்று</div><div class="e-content">
<div id="orgc41b88e" class="figure">
<p><a href="/images/nagercoil-dump-site-1024px.jpg"><img src="/images/nagercoil-dump-site-640px.jpg" alt=""நாகர்கோவில் மாநகராட்சி திடக்கழிவு மேலாண்மை திட்ட மையம்" என்னும் பலகை பின் வளர்ந்துக் குவிந்துக் கிடக்கும் பெரும் குப்பை மேடு. சரக்கு வண்டிகளுடனும் மண்வாரியுடனும் குப்பையைத் திரட்டும் துப்புறவுப் பணியாளர்." /></a>
</p>
<p><span class="figure-number">Figure 1: </span>நாகர்கோயில்க் கடற்கரைச் சாலையில் குப்பை மேடு</p>
</div>
<p>
விடுமுறைக்காக சொந்த ஊரான நாகர்கோயில் வந்தேன். ஒவ்வொரு முறை வரும் போதும் நாகர்கோயிலின் பொருளாதார வளர்ச்சியையும் வெவ்வேறு பன்னாட்டு நிறுவனங்கள் இங்குக் கடை போட்டிருப்பதையும் காண்கிறேன். அதனுடன் சேர்ந்து இப்போது நாகர்கோயில்க் கடற்கரைச் சாலையில் (Beach Road) குப்பை மேடொன்றும் தோன்றியுள்ளது. இந்தியா முழுவதும் வளர்ந்து வரும் திடக்கழிவு சிக்கலின் வெளிப்பாடு இது.
</p>
</div></article>https://systemreboot.net/post/guile-வலை-வழங்கியை-இயங்கிக்கொண்டிருக்கும்போதே-REPL-மூலம்-மாற்றியமைப்பது.htmlguile வலை வழங்கியை இயங்கிக்கொண்டிருக்கும்போதே REPL மூலம் மாற்றியமைப்பது2023-02-27T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">guile வலை வழங்கியை இயங்கிக்கொண்டிருக்கும்போதே REPL மூலம் மாற்றியமைப்பது</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2023-02-27 12:00:00">பிப்ரவரி 27, 2023</time></p><p>In other languages: <a hreflang="en" href="/post/live-hacking-a-guile-web-server">English</a></p><p>Tags: <a class="p-category" href="/tag/lisp.ta">lisp</a>, <a class="p-category" href="/tag/scheme.ta">scheme</a>, <a class="p-category" href="/tag/%E0%AE%AE%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%8A%E0%AE%B0%E0%AF%81%E0%AE%B3%E0%AF%8D.ta">மென்பொருள்</a></p><div class="p-summary">guile வலை வழங்கியை இயங்கிக்கொண்டிருக்கும்போதே REPL மூலம் மாற்றியமைப்பது எப்படி?</div><div class="e-content"><p>
இயங்கிக்கொண்டிருக்கும் வழங்கிகளை முடக்காமலேயே அவற்றின் நிரலை REPL மூலம் மாற்றியமைப்பது lisp மொழிகளின் தனிச் சிறப்பு. ஆனால் இதை scheme மொழியில், குறிப்பாக guile மொழியில், செய்வது சற்று சிக்கலானது. இதை நான் எவ்வாறு செய்கிறேன் என விளக்குகிறேன். இது நல்ல வழியாவென அறியேன். வேறு நல்ல வழியறிந்தால் கண்டிப்பாக மின்மடல் அனுப்புக.
</p>
<p>
முதலில் guile மொழியில் localhost:8080 பொருந்துவாயில் காத்திருக்கும் எளிய வலை வழங்கியொன்று.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (web server))
(<span class="org-keyword">define</span> (<span class="org-function-name">handler</span> request request-body)
(values '((content-type . (text/plain)))
<span class="org-string">"Hello World!\n"</span>))
(run-server handler)
</pre>
</div>
<div class="org-src-container">
<pre class="src src-shell">$ curl http://localhost:8080
Hello World!
</pre>
</div>
<p>
இதனுடன் /tmp/guile Unix பொருந்துவாயில் (Unix socket) REPL வழங்கியொன்றை இன்னொரு இணை இழையாக (parallel thread) அமைப்போம்.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (system repl server)
(web server))
(<span class="org-keyword">define</span> (<span class="org-function-name">handler</span> request request-body)
(values '((content-type . (text/plain)))
<span class="org-string">"Hello World!"</span>))
(spawn-server (make-unix-domain-server-socket
<span class="org-builtin">#:path</span> <span class="org-string">"/tmp/guile"</span>))
(run-server handler)
</pre>
</div>
<p>
Emacs பயன்படுத்தினால் இதனுடன் M-x geiser-connect-local /tmp/guile கொண்டு இணையலாம். இப்போது handler செயலாற்றியை மாற்றி geiser REPL மூலம் நிறுவினாலும் வலை வழங்கியின் வெளியீடு மாறாது. ஏன்? ஏனென்றால் run-server செயலாற்றி handler செயலாற்றியின் மதிப்பை (value) மட்டுமே பெறுகிறது. handler செயலாற்றி மாறினாலும் run-server பழைய handler செயலாற்றியையே கவ்வியிருக்கிறது.
</p>
<p>
இதைத் தவிர்க்க என் செய்யலாம்? நிரல்கூறு அகங்காணல் (module introspection) பொறியைப் பயன்படுத்தி ஒவ்வொரு முறையும் 'handler என்னும் பெயர் சுட்டும் செயலாற்றியைக் கண்டறியுமாறு ஒருப் பெயரற்ற lambda செயலாற்றியை run-server கண் அளிக்கலாம். இப்போது handler செயலாற்றியை மாற்றினால் வலை வழங்கியின் வெளியீடும் சரியாக மாறும்.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(run-server (<span class="org-keyword">lambda</span> (request body)
((module-ref (current-module)
'handler)
request body)))
</pre>
</div>
<p>
handler செயலாற்றி வேறு நிரல்கூறில் இருப்பின் அதைப் பின்வருமாறு பெறலாம்.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(run-server (<span class="org-keyword">lambda</span> (request body)
((module-ref (resolve-module '(my-project web-server-module))
'handler)
request body)))
</pre>
</div>
</div></article>https://systemreboot.net/post/live-hacking-a-guile-web-server.htmlLive hacking a guile web server2023-02-27T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">Live hacking a guile web server</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2023-02-27 12:00:00">February 27, 2023</time></p><p>In other languages: <a hreflang="ta" href="/post/guile-%E0%AE%B5%E0%AE%B2%E0%AF%88-%E0%AE%B5%E0%AE%B4%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%AF%E0%AF%88-%E0%AE%87%E0%AE%AF%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%BF%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%8A%E0%AE%A3%E0%AF%8D%E0%AE%9F%E0%AE%BF%E0%AE%B0%E0%AF%81%E0%AE%95%E0%AF%8D%E0%AE%95%E0%AF%81%E0%AE%AE%E0%AF%8D%E0%AE%AA%E0%AF%8B%E0%AE%A4%E0%AF%87-REPL-%E0%AE%AE%E0%AF%82%E0%AE%B2%E0%AE%AE%E0%AF%8D-%E0%AE%AE%E0%AE%BE%E0%AE%B1%E0%AF%8D%E0%AE%B1%E0%AE%BF%E0%AE%AF%E0%AE%AE%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%A4%E0%AF%81">தமிழ்</a></p><p>Tags: <a class="p-category" href="/tag/lisp">lisp</a>, <a class="p-category" href="/tag/scheme">scheme</a>, <a class="p-category" href="/tag/software">software</a></p><div class="p-summary">How to live hack a guile web server on the REPL</div><div class="e-content"><p>
Live hacking running servers on the REPL is one of the many specialities of a lisp. But doing this in scheme, or at least in guile, is quite tricky. In this post, I will explain how I do it. This may not be the best solution. If you have a better idea, I'm eager to hear about it. Shoot me an email.
</p>
<p>
First, a simple guile web server that listens on localhost:8080.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (web server))
(<span class="org-keyword">define</span> (<span class="org-function-name">handler</span> request request-body)
(values '((content-type . (text/plain)))
<span class="org-string">"Hello World!\n"</span>))
(run-server handler)
</pre>
</div>
<div class="org-src-container">
<pre class="src src-shell">$ curl http://localhost:8080
Hello World!
</pre>
</div>
<p>
Now, let's add a REPL server that runs on a different thread and listens on a Unix socket at /tmp/guile.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (system repl server)
(web server))
(<span class="org-keyword">define</span> (<span class="org-function-name">handler</span> request request-body)
(values '((content-type . (text/plain)))
<span class="org-string">"Hello World!"</span>))
(spawn-server (make-unix-domain-server-socket
<span class="org-builtin">#:path</span> <span class="org-string">"/tmp/guile"</span>))
(run-server handler)
</pre>
</div>
<p>
You can connect to this in Emacs using <i>M-x geiser-connect-local /tmp/guile</i>. Now, modifying the definition of handler using the REPL does not reflect in the output of the web server. Why? The <i>run-server</i> function only obtains the "value" of <i>handler</i>. Even though you may have modified <i>handler</i>, <i>run-server</i> still holds on to the old value of <i>handler</i>.
</p>
<p>
How do we mitigate this? We could use the module introspection machinery to dereference the <i>'handler</i> symbol on every request. We wrap this in a lambda function and pass that to <i>run-server</i>. Like so:
</p>
<div class="org-src-container">
<pre class="src src-scheme">(run-server (<span class="org-keyword">lambda</span> (request body)
((module-ref (current-module)
'handler)
request body)))
</pre>
</div>
<p>
Now, changes to <i>handler</i> should reflect correctly in the output of the web server.
</p>
<p>
If your <i>handler</i> is defined in a different module, say <i>(my-project web-server-module)</i>, you could use the following.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(run-server (<span class="org-keyword">lambda</span> (request body)
((module-ref (resolve-module '(my-project web-server-module))
'handler)
request body)))
</pre>
</div>
</div></article>https://systemreboot.net/post/spqr-behind-simran.htmlSimran and SPQR2023-02-23T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">Simran and SPQR</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2023-02-23 12:00:00">February 23, 2023</time></p><p>In other languages: <a hreflang="ta" href="/post/%E0%AE%9A%E0%AE%BF%E0%AE%AE%E0%AF%8D%E0%AE%B0%E0%AE%A9%E0%AF%8D-%E0%AE%AA%E0%AE%BF%E0%AE%A9%E0%AF%8D-SPQR">தமிழ்</a></p><p>Tags: <a class="p-category" href="/tag/cinema">cinema</a>, <a class="p-category" href="/tag/tamilcinema">tamilcinema</a></p><div class="p-summary">In the 1999 Thulladha Manamum Thullum Tamil movie, Simran appears in front of SPQR and the Roman eagle.</div><div class="e-content">
<div id="org04f7f66" class="figure">
<p><a href="/images/simran-spqr-1024px.jpg"><img src="/images/simran-spqr-640px.jpg" alt="Horse ridings bearing SPQR and the Roman eagle are in the background. Simran rides a horse-drawn carriage in the foreground." /></a>
</p>
<p><span class="figure-number">Figure 1: </span>Simran appears before SPQR in Thulladha Manamum Thullum</p>
</div>
<p>
In the first scene of the <i>Thodu Thodu Enavae Vanavil</i> song in the 1999 <a href="https://en.wikipedia.org/wiki/Thulladha_Manamum_Thullum">Thulladha Manamum Thullum</a> Tamil movie, Simran appears in front of horse riders bearing SPQR and the Roman eagle. SPQR stands for <a href="https://en.wikipedia.org/wiki/SPQR">Senatus Populusque Romanus</a>. In Latin, this means <i>The Senate and People of Rome</i>. Did the film makers know what they were doing when they included this in the movie? Or, did they just include it as a prop without understanding its meaning?! 😝 Not in their wildest dreams could the Romans have anticipated that their symbols would occur in such a bizarre context in the future! Christian churches using textiles embroidered with Arabic Islamic text comes to mind<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>
</div><div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">
<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara"><a href="https://www.laphamsquarterly.org/fashion/crusader-chic">https://www.laphamsquarterly.org/fashion/crusader-chic</a> quote: Inscriptions with Allah’s blessing abound in Christian churches, transformed into orphreys, elaborately embroidered ornamental stripes or bands on ecclesiastical vestments. A textile with embroidered and woven Arabic inscriptions, quoting the Qur’an at length, might proclaim Muhammad the messenger of God and announce the name of the reigning caliph and royal manufacture in which the textile was produced, all while serving as a burial shroud for a Christian saint.</p></div></div>
</div>
</div></article>https://systemreboot.net/post/சிம்ரன்-பின்-SPQR.htmlசிம்ரன் பின் SPQR2023-02-23T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">சிம்ரன் பின் SPQR</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2023-02-23 12:00:00">பிப்ரவரி 23, 2023</time></p><p>In other languages: <a hreflang="en" href="/post/spqr-behind-simran">English</a></p><p>Tags: <a class="p-category" href="/tag/%E0%AE%A4%E0%AE%BF%E0%AE%B0%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AE%AE%E0%AF%8D.ta">திரைப்படம்</a>, <a class="p-category" href="/tag/%E0%AE%A4%E0%AE%AE%E0%AE%BF%E0%AE%B4%E0%AF%8D%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AE%BF%E0%AE%B0%E0%AF%88%E0%AE%AA%E0%AF%8D%E0%AE%AA%E0%AE%9F%E0%AE%AE%E0%AF%8D.ta">தமிழ்த்திரைப்படம்</a></p><div class="p-summary">துள்ளாத மனமும் துள்ளும் திரைப்படத்தில் ரோமாபுரியின் SPQR சின்னமும் கழுகும் முன் சிம்ரன் தோன்றுவார்.</div><div class="e-content">
<div id="orga3b49fe" class="figure">
<p><a href="/images/simran-spqr-1024px.jpg"><img src="/images/simran-spqr-640px.jpg" alt="முன்னணியில் சிம்ரன் குதிரை வண்டியில் வருகிறார். பின்னணியில் குதிரை வீரர் SPQR சின்னத்தையும் ரோம கழுகையும் ஏந்தி வருகின்றனர்." /></a>
</p>
<p><span class="figure-number">Figure 1: </span>துள்ளாத மனமும் துள்ளும் படத்தில் சிம்ரன் SPQR முன் தோன்றும் காட்சி</p>
</div>
<p>
<a href="https://ta.wikipedia.org/wiki/%E0%AE%A4%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AE%BE%E0%AE%A4_%E0%AE%AE%E0%AE%A9%E0%AE%AE%E0%AF%81%E0%AE%AE%E0%AF%8D_%E0%AE%A4%E0%AF%81%E0%AE%B3%E0%AF%8D%E0%AE%B3%E0%AF%81%E0%AE%AE%E0%AF%8D">துள்ளாத மனமும் துள்ளும்</a> திரைப்படத்தில் <i>தொடுதொடுவெனவே வானவில்</i> பாட்டின் முதல் காட்சியில் ரோமாபுரியின் SPQR சின்னத்தையும் கழுகையும் ஏந்தி வரும் குதிரை வீரர் முன் சிம்ரன் தோன்றுவார். SPQR என்றால் <a href="https://en.wikipedia.org/wiki/SPQR">Senatus Populusque Romanus</a> என்பதன் சுருக்கும். இது இலத்தீன் மொழியில் The Senate and People of Rome, அதாவது ரோமாபுரி ஆளவையும் மக்களும், எனப் பொருள்படும். இது என்னவென்று அறிந்து தான் படத்தில் அமைத்தனரா அல்லது ஏதோ அழகுப் பொருளென்றெண்ணி இக்காட்சியில் இட்டனரா? வேடிக்கை! 😝 ரோமர் அவரது சின்னம் எதிர்காலத்தில் இப்படி ஓர் இடம்பெறுமென்று கனவிலும் நினைத்திருக்கமாட்டார்! கிறிஸ்தவ கோயில் துணிகளில் அரபு இஸ்லாமிய எழுத்து அமைவது நினைவுக்கு வருகிறது<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>.
</p>
</div><div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">
<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara"><a href="https://www.laphamsquarterly.org/fashion/crusader-chic">https://www.laphamsquarterly.org/fashion/crusader-chic</a> மேற்கோள்: Inscriptions with Allah’s blessing abound in Christian churches, transformed into orphreys, elaborately embroidered ornamental stripes or bands on ecclesiastical vestments. A textile with embroidered and woven Arabic inscriptions, quoting the Qur’an at length, might proclaim Muhammad the messenger of God and announce the name of the reigning caliph and royal manufacture in which the textile was produced, all while serving as a burial shroud for a Christian saint.</p></div></div>
</div>
</div></article>https://systemreboot.net/post/G-கோவையால்-உரைநிரல்-அமர்த்து.htmlG-கோவையால் உரைநிரல் அமர்த்து2023-01-02T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">G-கோவையால் உரைநிரல் அமர்த்து</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2023-01-02 12:00:00">ஜனவரி 02, 2023</time></p><p>In other languages: <a hreflang="en" href="/post/deploy-scripts-using-g-expressions">English</a></p><p>Tags: <a class="p-category" href="/tag/lisp.ta">lisp</a>, <a class="p-category" href="/tag/scheme.ta">scheme</a>, <a class="p-category" href="/tag/guix.ta">guix</a>, <a class="p-category" href="/tag/%E0%AE%AE%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%8A%E0%AE%B0%E0%AF%81%E0%AE%B3%E0%AF%8D.ta">மென்பொருள்</a></p><div class="p-summary">உரைநிரல்களை Guix G-கோவையால் அமர்த்துக. ஏன்? எப்படி?</div><div class="e-content"><p>
உரைநிரல்களை வழங்கிகளில் அமர்த்த அவற்றிற்குத் தேவையான நிரல்களையும் சேர்த்து நிறுவ வேண்டும். அன்னிரல்கள் சரியான பதிப்புடையதென உறுதிப்படுத்த வேண்டும். அவ்வப்போது அவற்றைத் திறமுயர்த்தவும் வேண்டும். இன்றுத் தேவைப்படும் நிரல்கள் நாளை தேவைப்படாதாகின் அவற்றை நிறுவகற்ற வேண்டும். இதைத் தொடர்ந்துச் சரியாகச் செய்வது எளிதல்ல. தொலை வழங்கிக்கும் நம் நிலையத்திற்குமிடையே பதிப்பு வேறுபாடு ஏற்படுவது இயல்பு. இதைத் தவிர்ப்பதெப்படி? Guix G-கோவைகளைப் பயன்படுத்தலாம். எப்படியென்றுப் பார்ப்போம்.
</p>
<div id="outline-container-org00bbfd2" class="outline-2">
<h2 id="org00bbfd2">G-கோவையால் Guile உரைநிரல் அமர்த்து</h2>
<div class="outline-text-2" id="text-org00bbfd2">
<p>
வலைவழங்கிகள் உட்பட பல்லிடங்களில் பயனரையும் கடவுச்சொற்களையும் பதிவு செய்ய <a href="https://en.wikipedia.org/wiki/.htpasswd">htpasswd கோப்புகள்</a> பயன்படுத்தப்படுகின்றன. அத்தகைய htpasswd கோப்பில் பயனரைச் சேர்க்கவும் நீக்கவும் பின்வரும் bash உரைநிரலைப் பயன்படுத்தலாம்.
</p>
<div class="org-src-container">
<pre class="src src-shell"><span class="org-variable-name">passwd_file</span>=/etc/web/passwd
<span class="org-keyword">case</span> $<span class="org-variable-name">1</span><span class="org-keyword"> in</span>
add) htpasswd $<span class="org-variable-name">passwd_file</span> $<span class="org-variable-name">2</span>
;;
delete) htpasswd -D $<span class="org-variable-name">passwd_file</span> $<span class="org-variable-name">2</span>
;;
<span class="org-keyword">esac</span>
</pre>
</div>
<p>
இதை bash இன்றி Guile மொழியில் பின்வரும் Guix G-கோவையாக எழுதலாம். இதில் குறிப்பிடத்தக்கது <a href="https://guix.gnu.org/manual/en/html_node/G_002dExpressions.html#index-file_002dappend">file-append</a> மற்றும் <a href="https://guix.gnu.org/manual/en/html_node/G_002dExpressions.html#index-program_002dfile">program-file</a> என்பவையே. file-append httpd நிரல்தொகுப்பில் <code>/bin/htpasswd</code> நிரலைச் சுட்டப் பயன்படுகிறது. program-file நம் G-கோவையை Guix கிடங்கில் புகுக்கப் பயன்படுகிறது.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages web)
(guix gexp))
(<span class="org-keyword">define</span> <span class="org-function-name">webuser-gexp</span>
(with-imported-modules '((guix build utils))
#~(<span class="org-keyword">begin</span>
(use-modules (guix build utils)
(ice-9 match))
(<span class="org-keyword">define</span> <span class="org-function-name">passwd-file</span> <span class="org-string">"/etc/web/passwd"</span>)
(match (program-arguments)
((_ <span class="org-string">"add"</span> user)
(invoke #$(file-append httpd <span class="org-string">"/bin/htpasswd"</span>)
passwd-file user))
((_ <span class="org-string">"delete"</span> user)
(invoke #$(file-append httpd <span class="org-string">"/bin/htpasswd"</span>)
<span class="org-string">"-D"</span> passwd-file user))))))
(program-file <span class="org-string">"webuser"</span> webuser-gexp)
</pre>
</div>
<p>
இது webuser.scm என்னும் கோப்பில் இட்டால், தொகுத்து உரைநிரலாக்க
</p>
<div class="org-src-container">
<pre class="src src-shell">$ guix build -f webuser.scm
/gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser
</pre>
</div>
<p>
இக்கோப்பைத் திறந்து என்னவிருக்கிறதெனப் பார்ப்போம்.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ cat /gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser
</pre>
</div>
<div class="org-src-container">
<pre class="src src-scheme">#!/gnu/store/cnfsv9ywaacyafkqdqsv2ry8f01yr7a9-guile-3.0.7/bin/guile --no-auto-compile
!#
(eval-when (expand load eval)
(<span class="org-keyword">let</span> ((extensions (quote ()))
(prepend (<span class="org-keyword">lambda</span> (items lst)
(<span class="org-keyword">let</span> <span class="org-function-name">loop</span> ((items items)
(lst lst))
(<span class="org-keyword">if</span> (null? items)
lst
(loop (cdr items)
(cons (car items)
(delete (car items) lst))))))))
(set! %load-path
(prepend (cons <span class="org-string">"/gnu/store/pgj8653w17hsapbd1srlvd44rlnhbx8n-module-import"</span>
(<span class="org-keyword">map</span> (<span class="org-keyword">lambda</span> (extension)
(string-append extension
<span class="org-string">"/share/guile/site/"</span>
(effective-version)))
extensions))
%load-path))
(set! %load-compiled-path
(prepend (cons <span class="org-string">"/gnu/store/fwzac0aal1y24rx2vn8yhw6hf45kk46j-module-import-compiled"</span>
(<span class="org-keyword">map</span> (<span class="org-keyword">lambda</span> (extension)
(string-append extension
<span class="org-string">"/lib/guile/"</span>
(effective-version)
<span class="org-string">"/site-ccache"</span>))
extensions))
%load-compiled-path))))
(<span class="org-keyword">begin</span>
(use-modules (guix build utils)
(ice-9 match))
(<span class="org-keyword">define</span> <span class="org-function-name">passwd-file</span> <span class="org-string">"/etc/web/passwd"</span>)
(match (program-arguments)
((_ <span class="org-string">"add"</span> user)
(invoke <span class="org-string">"/gnu/store/xkmpq6vwhml48bwfn2fxjdvqfmzf9ccb-httpd-2.4.52/bin/htpasswd"</span>
passwd-file user))
((_ <span class="org-string">"delete"</span> user)
(invoke <span class="org-string">"/gnu/store/xkmpq6vwhml48bwfn2fxjdvqfmzf9ccb-httpd-2.4.52/bin/htpasswd"</span>
<span class="org-string">"-D"</span> passwd-file user))))
</pre>
</div>
<p>
முதல் பத்தி வெவ்வேறு Guile நிரல்கூறுகளை உள்ளிழுக்க பாதைகளை அமைக்கிறது. இரண்டாம் பத்தியில் நாம் எழுதிய G-கோவை உள்ளது. அதில் file-append கூற்றுகளுக்கு மாறாக htpasswd நிரலுக்கான முழுப் பாதையைக் காணலாம்.
</p>
<p>
இவ்வுரைநிரலை வழங்கியில் அமர்த்தி அதை /usr/local/bin/webuser என்னும் பாதையில் நிறுவி அதை Guix குப்பைத்திரட்டியிடமிருந்து காக்க அதைக் குப்பைத்திரட்டி வேராக பதிவு செய்ய
</p>
<div class="org-src-container">
<pre class="src src-shell">$ guix copy --to=remote /gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser
$ ssh remote ln --symbolic --force /gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser /usr/local/bin/webuser
$ ssh remote ln --symbolic --force /usr/local/bin/webuser /var/guix/gcroots
</pre>
</div>
<p>
இங்கு remote என்பது ஏற்கனவே அமைக்கப்பட்ட ஒரு நிலையமாகயிருக்க வேண்டும். இதைப் பற்றி <a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-copy.html">guix copy</a> ஆவணத்தில் காண்க.
</p>
<p>
இதையெல்லாம் செய்து என்ன பயன்? நாம் வழங்கியில் அமர்த்திய உரைநிரல் வெறும் உரைநிரலுடன் மட்டும் செல்லவில்லை. அவ்வுரைநிரல் அதற்குத் தேவையான htpasswd நிரலையும் அன்னிரலுக்குத் தேவையான அத்தனை மென்பொருளையும் அழைத்து பெருந்திரளாகச் சென்றது. அத்திரளில் எவையெவை இருக்கின்றனவெனப் பார்த்தால் மொத்தம் 407.9 MiB அளவிற்கு மென்பொருள் உள்ளது.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ guix size /gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser
கிடங்குருப்படி மொத்தம் தனது
/gnu/store/hy6abswwv4d89zp464fw52z65fkzr7h5-perl-5.34.0 147.7 58.6 14.4%
/gnu/store/rc781v4k0drhaqn90xfwwpspki5x0bvf-binutils-2.37 92.7 54.4 13.3%
/gnu/store/cnfsv9ywaacyafkqdqsv2ry8f01yr7a9-guile-3.0.7 129.1 52.0 12.8%
/gnu/store/1kws5vkl0glvpxg7arabsv6q9vazp0hx-guile-3.0.7 129.1 52.0 12.8%
/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33 38.3 36.6 9.0%
/gnu/store/094bbaq6glba86h1d4cj16xhdi6fk2jl-gcc-10.3.0-lib 71.7 33.4 8.2%
/gnu/store/xkmpq6vwhml48bwfn2fxjdvqfmzf9ccb-httpd-2.4.52 350.1 29.7 7.3%
/gnu/store/vqdsrvs9jbn0ix2a58s99jwkh74124y5-coreutils-minimal-8.32 88.0 16.4 4.0%
/gnu/store/d251rfgc9nm2clzffzhgiipdvfvzkvwi-coreutils-8.32 88.0 16.4 4.0%
/gnu/store/fnr1z6xsan0437r0yg48d0y8k32kqxby-glibc-utf8-locales-2.33 13.9 13.9 3.4%
/gnu/store/4jdghmc65q7i7ib89zmvq66l0ghf7jc4-glibc-2.33-static 46.9 8.6 2.1%
/gnu/store/4ic6244i3ca4b4rxc2wnrgllsidyishv-file-5.39 78.2 6.6 1.6%
/gnu/store/lk3ywzavgz30xrlfcmx2x9rfz3cs7xq6-openssl-1.1.1s 77.2 5.5 1.4%
/gnu/store/690qz3fg334dpwn3pn6k59n4wc943p2b-gawk-5.1.0 76.0 3.3 0.8%
/gnu/store/hkhbq2q1gfs970gsp2nhsmcqb4vmv2xr-libunistring-0.9.10 74.0 2.3 0.6%
/gnu/store/ckh3gy7gpvd4b65s6jsm6f1y9bp460ji-libunistring-0.9.10 74.0 2.3 0.6%
/gnu/store/720rj90bch716isd8z7lcwrnvz28ap4y-bash-static-5.1.8 1.7 1.7 0.4%
/gnu/store/di5bqb45hi5lvp2q08hlxqjdcl9phjb1-pcre-8.45 73.4 1.7 0.4%
/gnu/store/rbb9h501zyf8mg1hz47plql80gsl99za-apr-1.7.0 312.1 1.5 0.4%
/gnu/store/2b3blhwbag1ial0dhxw7wh4zjxl0cqpk-pkg-config-0.29.2 72.8 1.1 0.3%
/gnu/store/lk24spr6hbkzh68s79nzqp9z36nx0m1f-pkg-config-0.29.2 72.8 1.1 0.3%
/gnu/store/c8isj4jq6knv0icfgr43di6q3nvdzkx7-xz-5.2.5 73.7 1.1 0.3%
/gnu/store/chfwin3a4qp1znnpsjbmydr2jbzk0d6y-bash-minimal-5.1.8 72.7 1.0 0.2%
/gnu/store/4y5m9lb8k3qkb1y9m02sw9w9a6hacd16-bash-minimal-5.1.8 39.3 1.0 0.2%
/gnu/store/xjwp2hsd9256icjjybfrmznppjicywf6-grep-3.6 73.5 0.8 0.2%
/gnu/store/wxgv6i8g0p24q5gcyzd0yr07s8kn9680-sed-4.8 72.5 0.8 0.2%
/gnu/store/r3lv5k4mxaz53f4sr4wf9dqkqadcpms6-apr-util-1.6.1 313.2 0.8 0.2%
/gnu/store/2lczkxbdbzh4gk7wh91bzrqrk7h5g1dl-libgc-8.0.4 72.4 0.7 0.2%
/gnu/store/3pylba5sjy3r7b8fjm9yxz24751721ff-libgc-8.0.4 72.4 0.7 0.2%
/gnu/store/s3hl12jxz9ybs7nsy7kq7ybzz7qnzmsg-bzip2-1.0.8 73.1 0.4 0.1%
/gnu/store/52zhpralb3iimrm7xbc1vf3qsy4gy1vl-expat-2.4.9 72.0 0.4 0.1%
/gnu/store/fwzac0aal1y24rx2vn8yhw6hf45kk46j-module-import-compiled 0.3 0.3 0.1%
/gnu/store/wgqhlc12qvlwiklam7hz2r311fdcqfim-libffi-3.3 71.8 0.2 0.0%
/gnu/store/g000a71kc336795axa3hh1xhd3mfq083-libffi-3.3 71.8 0.2 0.0%
/gnu/store/2i5alw7qcp35x0rn0yqxmvxv3pd6ln3w-libltdl-2.4.6 71.8 0.1 0.0%
/gnu/store/s2pg5k98fl2g2szg9dykxyd9zl3xihv9-ld-wrapper-0 183.5 0.1 0.0%
/gnu/store/k04pcgdvdipdc37cc6xvm33pcglbb8rz-libsigsegv-2.13 71.7 0.1 0.0%
/gnu/store/pgj8653w17hsapbd1srlvd44rlnhbx8n-module-import 0.1 0.1 0.0%
/gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser 407.9 0.0 0.0%
மொத்தம்: 407.9 MiB
</pre>
</div>
<p>
இவ்வாறு நம் உரைநிரலை மட்டும் நிறுவினால் போதும். நம் உரைநிரலுக்குத் தேவையான மென்பொருள் தானே நிறுவப்படும். நேற்று தேவைப்பட்டு இன்று தேவைப்படா மென்பொருள் பற்றியும் ஏங்கேல். அடுத்த guix gc இயக்கத்தில் அவைத் தானாக அழிக்கப்படும்.
</p>
</div>
</div>
<div id="outline-container-orgce0beb3" class="outline-2">
<h2 id="orgce0beb3">பிற மொழி உரைநிரல்களை அமர்த்தல்</h2>
<div class="outline-text-2" id="text-orgce0beb3">
</div>
<div id="outline-container-orge65ffe5" class="outline-3">
<h3 id="orge65ffe5">G-கோவையால் bash உரைநிரல் அமர்த்து</h3>
<div class="outline-text-3" id="text-orge65ffe5">
<p>
Guile மொழி உங்களுக்குப் பிடிக்காதா? உரைநிரல்களை bash மொழியிலேயே எழுத விரும்புகிறீரா? G-கோவையால் bash உரைநிரலையும் அமர்த்த இயலும். அதற்கு உம் bash உரைநிரல்ப் பொதிந்த G-கோவையொன்றை அமைக்க வேண்டும். webuser.sh என்னும் bash உரைநிரலைப் பொதியும் G-கோவையைக் கீழ்க் காண்க. இதில் குறிப்பிடத்தக்கது <a href="https://guix.gnu.org/manual/en/html_node/G_002dExpressions.html#index-local_002dfile">local-file</a> webuser.sh கோப்பை Guix கிடங்குக்குள் புகுத்துவது. மேலும் htpasswd நிரலைக் கண்டறிய set-path-environment-variable PATH சூழல்மாறியை அமைப்பது.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages bash)
(gnu packages web)
(guix gexp))
(<span class="org-keyword">define</span> <span class="org-function-name">webuser-gexp</span>
(with-imported-modules '((guix build utils))
#~(<span class="org-keyword">begin</span>
(use-modules (guix build utils)
(ice-9 match))
(set-path-environment-variable
<span class="org-string">"PATH"</span> (list <span class="org-string">"bin"</span>) (list #$httpd))
(apply invoke
#$(file-append bash <span class="org-string">"/bin/bash"</span>)
#$(local-file <span class="org-string">"webuser.sh"</span>)
(match (program-arguments)
((arg0 . rest-args)
rest-args))))))
(program-file <span class="org-string">"webuser"</span> webuser-gexp)
</pre>
</div>
</div>
</div>
<div id="outline-container-org15b5d74" class="outline-3">
<h3 id="org15b5d74">G-கோவையால் python உரைநிரல் அமர்த்து</h3>
<div class="outline-text-3" id="text-org15b5d74">
<p>
bash என்ன பெரிய bash, python போன்று பிற மொழி உரைநிரலையும் G-கோவையில் பொதிந்து அமர்த்தலாம். ஓர் எடுத்துக்காட்டைக் கீழ்க்காண்க.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages python)
(guix gexp))
(<span class="org-keyword">define</span> <span class="org-function-name">foo-gexp</span>
(with-imported-modules '((guix build utils))
#~(<span class="org-keyword">begin</span>
(use-modules (guix build utils))
(invoke #$(file-append python <span class="org-string">"/bin/python3"</span>)
#$(local-file <span class="org-string">"foo.py"</span>)))))
(program-file <span class="org-string">"foo"</span> foo-gexp)
</pre>
</div>
</div>
</div>
<div id="outline-container-orga57ae8d" class="outline-3">
<h3 id="orga57ae8d">G-கோவையால் பிற நிரல்கூறுகள் தேவைப்படும் python உரைநிரலை அமர்த்து</h3>
<div class="outline-text-3" id="text-orga57ae8d">
<p>
Python உரைநிரலுக்குப் பிற நிரல்கூறுகள் தேவைப்படின் அவற்றையும் எளிமையாகச் சேர்க்கலாம். எடுத்துக்காட்டாக, python-colorama நிரல்கூறுடை G-கோவையைக் கீழ்க்காண்க.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages python)
(gnu packages python-xyz)
(guix packages)
(guix gexp)
(guix utils))
(<span class="org-keyword">define</span> <span class="org-function-name">foo-gexp</span>
(with-imported-modules '((guix build utils))
#~(<span class="org-keyword">begin</span>
(use-modules (guix build utils))
(set-path-environment-variable
<span class="org-string">"GUIX_PYTHONPATH"</span>
(list #$(string-append <span class="org-string">"lib/python"</span>
(version-major+minor (package-version python))
<span class="org-string">"/site-packages"</span>))
(list #$python-colorama))
(invoke #$(file-append python <span class="org-string">"/bin/python3"</span>)
#$(local-file <span class="org-string">"foo-color.py"</span>)))))
(program-file <span class="org-string">"foo"</span> foo-gexp)
</pre>
</div>
<p>
இவ்வாறு Emacs Lisp, Rust, Ruby என விருப்பத்திற்கேற்ப பன்மொழிகளை ஒருமைப்படுத்தும் பெருந்திறன் படைத்தவை Guix நிரல்நிறுவியும் அதன் G-கோவைகளும்.
</p>
<p>
வணக்கம்!
</p>
</div>
</div>
</div>
</div></article>https://systemreboot.net/post/deploy-scripts-using-g-expressions.htmlDeploy scripts using G-expressions2023-01-02T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">Deploy scripts using G-expressions</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2023-01-02 12:00:00">January 02, 2023</time></p><p>In other languages: <a hreflang="ta" href="/post/G-%E0%AE%95%E0%AF%8B%E0%AE%B5%E0%AF%88%E0%AE%AF%E0%AE%BE%E0%AE%B2%E0%AF%8D-%E0%AE%89%E0%AE%B0%E0%AF%88%E0%AE%A8%E0%AE%BF%E0%AE%B0%E0%AE%B2%E0%AF%8D-%E0%AE%85%E0%AE%AE%E0%AE%B0%E0%AF%8D%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AF%81">தமிழ்</a></p><p>Tags: <a class="p-category" href="/tag/lisp">lisp</a>, <a class="p-category" href="/tag/scheme">scheme</a>, <a class="p-category" href="/tag/guix">guix</a>, <a class="p-category" href="/tag/software">software</a></p><div class="p-summary">Deploy scripts using Guix G-expressions. Why? How?</div><div class="e-content"><p>
When deploying scripts to remote machines, one also needs to install all the necessary dependencies. These dependencies need to keep up-to-date and of the right version. When some dependencies are no longer needed, they need to be uninstalled. This is a pain and getting things wrong is a common problem. Guix G-expressions can be used to alleviate the problem. Let's see how.
</p>
<div id="outline-container-org3c64cca" class="outline-3">
<h3 id="org3c64cca">Deploy a pure Guile script using a G-expression</h3>
<div class="outline-text-3" id="text-org3c64cca">
<p>
Web users and other software often use <a href="https://en.wikipedia.org/wiki/.htpasswd">htpasswd files</a> to store usernames and passwords. We may use the following bash script to add and delete users from such a htpasswd file.
</p>
<div class="org-src-container">
<pre class="src src-shell"><span class="org-variable-name">passwd_file</span>=/etc/web/passwd
<span class="org-keyword">case</span> $<span class="org-variable-name">1</span><span class="org-keyword"> in</span>
add) htpasswd $<span class="org-variable-name">passwd_file</span> $<span class="org-variable-name">2</span>
;;
delete) htpasswd -D $<span class="org-variable-name">passwd_file</span> $<span class="org-variable-name">2</span>
;;
<span class="org-keyword">esac</span>
</pre>
</div>
<p>
We may rewrite this bash script in Guile as a Guix G-expression. Noteworthy below are the use of <a href="https://guix.gnu.org/manual/en/html_node/G_002dExpressions.html#index-file_002dappend">file-append</a> and <a href="https://guix.gnu.org/manual/en/html_node/G_002dExpressions.html#index-program_002dfile">program-file</a>. <i>file-append</i> is used to refer to the <code>/bin/htpasswd</code> file of the httpd package. <i>program-file</i> is used to intern our G-expression into the Guix store.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages web)
(guix gexp))
(<span class="org-keyword">define</span> <span class="org-function-name">webuser-gexp</span>
(with-imported-modules '((guix build utils))
#~(<span class="org-keyword">begin</span>
(use-modules (guix build utils)
(ice-9 match))
(<span class="org-keyword">define</span> <span class="org-function-name">passwd-file</span> <span class="org-string">"/etc/web/passwd"</span>)
(match (program-arguments)
((_ <span class="org-string">"add"</span> user)
(invoke #$(file-append httpd <span class="org-string">"/bin/htpasswd"</span>)
passwd-file user))
((_ <span class="org-string">"delete"</span> user)
(invoke #$(file-append httpd <span class="org-string">"/bin/htpasswd"</span>)
<span class="org-string">"-D"</span> passwd-file user))))))
(program-file <span class="org-string">"webuser"</span> webuser-gexp)
</pre>
</div>
<p>
Say this is written into a file <i>webuser.scm</i>, we may build it using
</p>
<div class="org-src-container">
<pre class="src src-shell">$ guix build -f webuser.scm
/gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser
</pre>
</div>
<p>
Let's see what is in the built store item.
</p>
<div class="org-src-container">
<pre class="src src-shell">$ cat /gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser
</pre>
</div>
<div class="org-src-container">
<pre class="src src-scheme">#!/gnu/store/cnfsv9ywaacyafkqdqsv2ry8f01yr7a9-guile-3.0.7/bin/guile --no-auto-compile
!#
(eval-when (expand load eval)
(<span class="org-keyword">let</span> ((extensions (quote ()))
(prepend (<span class="org-keyword">lambda</span> (items lst)
(<span class="org-keyword">let</span> <span class="org-function-name">loop</span> ((items items)
(lst lst))
(<span class="org-keyword">if</span> (null? items)
lst
(loop (cdr items)
(cons (car items)
(delete (car items) lst))))))))
(set! %load-path
(prepend (cons <span class="org-string">"/gnu/store/pgj8653w17hsapbd1srlvd44rlnhbx8n-module-import"</span>
(<span class="org-keyword">map</span> (<span class="org-keyword">lambda</span> (extension)
(string-append extension
<span class="org-string">"/share/guile/site/"</span>
(effective-version)))
extensions))
%load-path))
(set! %load-compiled-path
(prepend (cons <span class="org-string">"/gnu/store/fwzac0aal1y24rx2vn8yhw6hf45kk46j-module-import-compiled"</span>
(<span class="org-keyword">map</span> (<span class="org-keyword">lambda</span> (extension)
(string-append extension
<span class="org-string">"/lib/guile/"</span>
(effective-version)
<span class="org-string">"/site-ccache"</span>))
extensions))
%load-compiled-path))))
(<span class="org-keyword">begin</span>
(use-modules (guix build utils)
(ice-9 match))
(<span class="org-keyword">define</span> <span class="org-function-name">passwd-file</span> <span class="org-string">"/etc/web/passwd"</span>)
(match (program-arguments)
((_ <span class="org-string">"add"</span> user)
(invoke <span class="org-string">"/gnu/store/xkmpq6vwhml48bwfn2fxjdvqfmzf9ccb-httpd-2.4.52/bin/htpasswd"</span>
passwd-file user))
((_ <span class="org-string">"delete"</span> user)
(invoke <span class="org-string">"/gnu/store/xkmpq6vwhml48bwfn2fxjdvqfmzf9ccb-httpd-2.4.52/bin/htpasswd"</span>
<span class="org-string">"-D"</span> passwd-file user))))
</pre>
</div>
<p>
The first paragraph sets up paths to import various Guile modules. The second paragraph is our G-expression only that the <i>file-append</i> calls are replaced with absolute paths to <i>htpasswd</i>.
</p>
<p>
To deploy this to a remote machine, install it at /usr/local/bin/webuser and protect it from garbage collection by registering it as a garbage collector root, we run
</p>
<div class="org-src-container">
<pre class="src src-shell">$ guix copy --to=remote /gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser
$ ssh remote ln --symbolic --force /gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser /usr/local/bin/webuser
$ ssh remote ln --symbolic --force /usr/local/bin/webuser /var/guix/gcroots
</pre>
</div>
<p>
Here, <i>remote</i> is a machine that has been configured to accept guix copy requests. See <a href="https://guix.gnu.org/manual/en/html_node/Invoking-guix-copy.html">guix copy</a> documentation for more.
</p>
<p>
So, what is the use of doing all this? The G-expression we installed on the remote machine didn't go alone. It went carrying along the <i>htpasswd</i> utility and all the other required dependencies. In total, this amounted to 407.9 MiB!
</p>
<div class="org-src-container">
<pre class="src src-shell">$ guix size /gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser
store item total self
/gnu/store/hy6abswwv4d89zp464fw52z65fkzr7h5-perl-5.34.0 147.7 58.6 14.4%
/gnu/store/rc781v4k0drhaqn90xfwwpspki5x0bvf-binutils-2.37 92.7 54.4 13.3%
/gnu/store/cnfsv9ywaacyafkqdqsv2ry8f01yr7a9-guile-3.0.7 129.1 52.0 12.8%
/gnu/store/1kws5vkl0glvpxg7arabsv6q9vazp0hx-guile-3.0.7 129.1 52.0 12.8%
/gnu/store/5h2w4qi9hk1qzzgi1w83220ydslinr4s-glibc-2.33 38.3 36.6 9.0%
/gnu/store/094bbaq6glba86h1d4cj16xhdi6fk2jl-gcc-10.3.0-lib 71.7 33.4 8.2%
/gnu/store/xkmpq6vwhml48bwfn2fxjdvqfmzf9ccb-httpd-2.4.52 350.1 29.7 7.3%
/gnu/store/vqdsrvs9jbn0ix2a58s99jwkh74124y5-coreutils-minimal-8.32 88.0 16.4 4.0%
/gnu/store/d251rfgc9nm2clzffzhgiipdvfvzkvwi-coreutils-8.32 88.0 16.4 4.0%
/gnu/store/fnr1z6xsan0437r0yg48d0y8k32kqxby-glibc-utf8-locales-2.33 13.9 13.9 3.4%
/gnu/store/4jdghmc65q7i7ib89zmvq66l0ghf7jc4-glibc-2.33-static 46.9 8.6 2.1%
/gnu/store/4ic6244i3ca4b4rxc2wnrgllsidyishv-file-5.39 78.2 6.6 1.6%
/gnu/store/lk3ywzavgz30xrlfcmx2x9rfz3cs7xq6-openssl-1.1.1s 77.2 5.5 1.4%
/gnu/store/690qz3fg334dpwn3pn6k59n4wc943p2b-gawk-5.1.0 76.0 3.3 0.8%
/gnu/store/hkhbq2q1gfs970gsp2nhsmcqb4vmv2xr-libunistring-0.9.10 74.0 2.3 0.6%
/gnu/store/ckh3gy7gpvd4b65s6jsm6f1y9bp460ji-libunistring-0.9.10 74.0 2.3 0.6%
/gnu/store/720rj90bch716isd8z7lcwrnvz28ap4y-bash-static-5.1.8 1.7 1.7 0.4%
/gnu/store/di5bqb45hi5lvp2q08hlxqjdcl9phjb1-pcre-8.45 73.4 1.7 0.4%
/gnu/store/rbb9h501zyf8mg1hz47plql80gsl99za-apr-1.7.0 312.1 1.5 0.4%
/gnu/store/2b3blhwbag1ial0dhxw7wh4zjxl0cqpk-pkg-config-0.29.2 72.8 1.1 0.3%
/gnu/store/lk24spr6hbkzh68s79nzqp9z36nx0m1f-pkg-config-0.29.2 72.8 1.1 0.3%
/gnu/store/c8isj4jq6knv0icfgr43di6q3nvdzkx7-xz-5.2.5 73.7 1.1 0.3%
/gnu/store/chfwin3a4qp1znnpsjbmydr2jbzk0d6y-bash-minimal-5.1.8 72.7 1.0 0.2%
/gnu/store/4y5m9lb8k3qkb1y9m02sw9w9a6hacd16-bash-minimal-5.1.8 39.3 1.0 0.2%
/gnu/store/xjwp2hsd9256icjjybfrmznppjicywf6-grep-3.6 73.5 0.8 0.2%
/gnu/store/wxgv6i8g0p24q5gcyzd0yr07s8kn9680-sed-4.8 72.5 0.8 0.2%
/gnu/store/r3lv5k4mxaz53f4sr4wf9dqkqadcpms6-apr-util-1.6.1 313.2 0.8 0.2%
/gnu/store/2lczkxbdbzh4gk7wh91bzrqrk7h5g1dl-libgc-8.0.4 72.4 0.7 0.2%
/gnu/store/3pylba5sjy3r7b8fjm9yxz24751721ff-libgc-8.0.4 72.4 0.7 0.2%
/gnu/store/s3hl12jxz9ybs7nsy7kq7ybzz7qnzmsg-bzip2-1.0.8 73.1 0.4 0.1%
/gnu/store/52zhpralb3iimrm7xbc1vf3qsy4gy1vl-expat-2.4.9 72.0 0.4 0.1%
/gnu/store/fwzac0aal1y24rx2vn8yhw6hf45kk46j-module-import-compiled 0.3 0.3 0.1%
/gnu/store/wgqhlc12qvlwiklam7hz2r311fdcqfim-libffi-3.3 71.8 0.2 0.0%
/gnu/store/g000a71kc336795axa3hh1xhd3mfq083-libffi-3.3 71.8 0.2 0.0%
/gnu/store/2i5alw7qcp35x0rn0yqxmvxv3pd6ln3w-libltdl-2.4.6 71.8 0.1 0.0%
/gnu/store/s2pg5k98fl2g2szg9dykxyd9zl3xihv9-ld-wrapper-0 183.5 0.1 0.0%
/gnu/store/k04pcgdvdipdc37cc6xvm33pcglbb8rz-libsigsegv-2.13 71.7 0.1 0.0%
/gnu/store/pgj8653w17hsapbd1srlvd44rlnhbx8n-module-import 0.1 0.1 0.0%
/gnu/store/1d8qs814gi1vgf52n7x0s43ix6rc5qzc-webuser 407.9 0.0 0.0%
total: 407.9 MiB
</pre>
</div>
<p>
So, using G-expressions, we need only concern ourselves with installing the G-expression alone. Guix automatically takes care of the required dependencies. If any dependencies that are required today are no longer required in the future, no sweat—they will automatically be erased in the next <i>guix gc</i> run.
</p>
</div>
</div>
<div id="outline-container-org60e1e83" class="outline-2">
<h2 id="org60e1e83">Deploy scripts written in other languages</h2>
<div class="outline-text-2" id="text-org60e1e83">
</div>
<div id="outline-container-org413b92e" class="outline-3">
<h3 id="org413b92e">Deploy a bash script using a G-expression</h3>
<div class="outline-text-3" id="text-org413b92e">
<p>
Don't like Guile and would prefer to write your scripts in bash? No problem! G-expressions can deploy bash scripts too. To do that, we must wrap our bash script in a G-expression. Here, we show a G-expression wrapping a bash script <i>webuser.sh</i>. Noteworthy here is <a href="https://guix.gnu.org/manual/en/html_node/G_002dExpressions.html#index-local_002dfile">local-file</a> used to intern <i>webuser.sh</i> into the Guix store, and <i>set-path-environment-variable</i> used to make <i>htpasswd</i> visible on <i>PATH</i>.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages bash)
(gnu packages web)
(guix gexp))
(<span class="org-keyword">define</span> <span class="org-function-name">webuser-gexp</span>
(with-imported-modules '((guix build utils))
#~(<span class="org-keyword">begin</span>
(use-modules (guix build utils)
(ice-9 match))
(set-path-environment-variable
<span class="org-string">"PATH"</span> (list <span class="org-string">"bin"</span>) (list #$httpd))
(apply invoke
#$(file-append bash <span class="org-string">"/bin/bash"</span>)
#$(local-file <span class="org-string">"webuser.sh"</span>)
(match (program-arguments)
((arg0 . rest-args)
rest-args))))))
(program-file <span class="org-string">"webuser"</span> webuser-gexp)
</pre>
</div>
</div>
</div>
<div id="outline-container-org426ceae" class="outline-3">
<h3 id="org426ceae">Deploy a python script using a G-expression</h3>
<div class="outline-text-3" id="text-org426ceae">
<p>
bash is not special, and we can indeed deploy scripts written in other language such as python too! Here is an example.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages python)
(guix gexp))
(<span class="org-keyword">define</span> <span class="org-function-name">foo-gexp</span>
(with-imported-modules '((guix build utils))
#~(<span class="org-keyword">begin</span>
(use-modules (guix build utils))
(invoke #$(file-append python <span class="org-string">"/bin/python3"</span>)
#$(local-file <span class="org-string">"foo.py"</span>)))))
(program-file <span class="org-string">"foo"</span> foo-gexp)
</pre>
</div>
</div>
</div>
<div id="outline-container-org8747c4a" class="outline-3">
<h3 id="org8747c4a">Deploy a python script with dependencies using a G-expression</h3>
<div class="outline-text-3" id="text-org8747c4a">
<p>
If our python script depends on other python packages, that can be handled with ease too. Here is an example that pulls in <i>python-colorama</i>.
</p>
<div class="org-src-container">
<pre class="src src-scheme">(use-modules (gnu packages python)
(gnu packages python-xyz)
(guix packages)
(guix gexp)
(guix utils))
(<span class="org-keyword">define</span> <span class="org-function-name">foo-gexp</span>
(with-imported-modules '((guix build utils))
#~(<span class="org-keyword">begin</span>
(use-modules (guix build utils))
(set-path-environment-variable
<span class="org-string">"GUIX_PYTHONPATH"</span>
(list #$(string-append <span class="org-string">"lib/python"</span>
(version-major+minor (package-version python))
<span class="org-string">"/site-packages"</span>))
(list #$python-colorama))
(invoke #$(file-append python <span class="org-string">"/bin/python3"</span>)
#$(local-file <span class="org-string">"foo-color.py"</span>)))))
(program-file <span class="org-string">"foo"</span> foo-gexp)
</pre>
</div>
<p>
Likewise, it is possible to deploy scripts written in Emacs Lisp, Rust, Ruby or indeed any other language of your heart's desire. This is the great unifying power of Guix and G-expressions that cuts across traditional language boundaries.
</p>
<p>
Have a nice day!
</p>
</div>
</div>
</div>
</div></article>https://systemreboot.net/post/guile-உடன்-இலண்டனில்-வீடுத்-தேடல்.htmlGuile உடன் இலண்டனில் வீடுத் தேடல்2022-12-18T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">Guile உடன் இலண்டனில் வீடுத் தேடல்</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2022-12-18 12:00:00">டிசம்பர் 18, 2022</time></p><p>In other languages: <a hreflang="en" href="/post/renting-in-london-with-guile">English</a></p><p>Tags: <a class="p-category" href="/tag/%E0%AE%87%E0%AE%B2%E0%AE%A3%E0%AF%8D%E0%AE%9F%E0%AE%A9%E0%AF%8D.ta">இலண்டன்</a>, <a class="p-category" href="/tag/lisp.ta">lisp</a>, <a class="p-category" href="/tag/scheme.ta">scheme</a>, <a class="p-category" href="/tag/%E0%AE%AE%E0%AF%86%E0%AE%A9%E0%AF%8D%E0%AE%AA%E0%AF%8A%E0%AE%B0%E0%AF%81%E0%AE%B3%E0%AF%8D.ta">மென்பொருள்</a></p><div class="p-summary">இலண்டனில் வாடகைக்குச் சரியான வீட்டைக் கண்டறிய ஒரு Guile உரைநிரல். Guile நடைமுறைக்கு ஒவ்வாத மொழி என்றுச் சொன்னதெவர்!</div><div class="e-content">
<div id="org52f2dde" class="figure">
<p><a href="/images/big-ben-with-guile-1024px.svg"><img src="/images/big-ben-with-guile-640px.svg" alt="பிக் பென் மணிக்கூடு அருகே lambda என்னும் கிரேக்க எழுத்தும் GNU Guile சின்னமும்" class="org-svg" /></a>
</p>
<p><span class="figure-number">Figure 1: </span>பிக் பென் மணிக்கூடுடன் GNU Guile</p>
</div>
<p>
அண்மையில் வேலைக்காக இலண்டன் வந்தேன். இலண்டனில் நெடுநாள் வாழ வேண்டியிருப்பதால் நல்லதோர் வீடு வேண்டுமென்றெண்ணினேன். ஆனால் இலண்டனில் வீடு தேடல் எளிதன்று. என்னால் கொடுக்க இயன்ற வாடகைக்குச் சில வீடுகளே இருந்தன. அவற்றைக் கண்டறிந்துப் பார்த்து முடிவெடுப்பதற்குள் இன்னொருவர் அதைக் கவ்விச் செல்கிறார். மேலும், நான் வீடு விளம்பரங்களைத் தேடும் <a href="https://www.openrent.co.uk/">OpenRent</a> வலைத்தளத்தில் என் தேவைகளைச் சரியாகக் குறிப்பிட வசதியில்லை. அதனால் OpenRent தரவை இறக்கி என் கணினியிலேயே பகுத்தாய Guile உரைநிரலொன்றை எழுதினேன். முதலில் OpenRent குறைகள் பற்றிக் காண்போம்.
</p>
<div id="outline-container-orgeaebe39" class="outline-2">
<h2 id="orgeaebe39">OpenRent குறைகள்</h2>
<div class="outline-text-2" id="text-orgeaebe39">
</div>
<div id="outline-container-orgfb58f97" class="outline-3">
<h3 id="orgfb58f97">வாடகையில் பிறக் கட்டணங்கள் சேரா வீடு</h3>
<div class="outline-text-3" id="text-orgfb58f97">
<p>
நான் மின், நீர், வளி, ஊர்மன்ற வரி (council tax) போன்ற கட்டணங்கள் வாடகையில் சேரா வீட்டையே விரும்பினேன். அக்கட்டணங்கள் வாடகையில் சேர்ந்த வீடுகளை மட்டும் காட்ட OpenRent தளத்தில் வசதியுள்ளது. ஆனால் அக்கட்டணங்கள் வாடகையில் சேரா வீடுகளை மட்டும் காட்ட வசதியில்லை.
</p>
</div>
</div>
<div id="outline-container-org840db39" class="outline-3">
<h3 id="org840db39">சாலை வழித் தொலைவும் நேர்க்கோட்டுத் தொலைவும்</h3>
<div class="outline-text-3" id="text-org840db39">
<p>
OpenRent தளத்தில் ஒரு மையப்புள்ளியிலிருந்து குறிப்பிட்ட சுற்றளவிலுள்ள வீடுகளை மட்டும் பட்டியலிடலாம். ஆனால் இது நேர்க்கோட்டளவிலுள்ள தொலைவையே பயன்படுத்துவது. நேர்க்கோட்டுத் தொலைவு சரியானதன்று. நாம் பறவையெனின் சேரிடம் நோக்கி நேராக பறந்துச் செல்லலாம். ஆனால் நாம் தரையிலே நடந்துச் செல்லும் உயிர்களாவதால் சாலை வழியே சுற்றிச் சுற்றித் தான் செல்ல இயலும். நேர்க்கோட்டளவில் வீடு எவ்வளவு தொலைவில் இருக்கிறதென்பது பற்றி நமக்குக் கவலையில்லை. நேர்க்கோட்டளவில் தொலைவாக இருப்பினும் சரியான தொடருந்து பாதை அருகே இருந்தால் சென்று வருவது எளிதே.
</p>
</div>
</div>
<div id="outline-container-orgf20e4f8" class="outline-3">
<h3 id="orgf20e4f8">புதிய விளம்பரங்களே வேண்டும்</h3>
<div class="outline-text-3" id="text-orgf20e4f8">
<p>
மிக அண்மையில் வெளிவந்த புதிய வீட்டு விளம்பரங்களை நாடுவதே நன்று. பழைய விளம்பரங்கள் அநேகமாக யாராவது ஏற்கனவே அணுகி பேச்சுவார்த்தையில் இருப்பார்; அவை கிடைப்பதரிது. விளம்பரங்களின் புதுமை கொண்டு வரிசைப்படுத்த OpenRent தளத்தில் வசதியில்லை.
</p>
</div>
</div>
<div id="outline-container-org169b067" class="outline-3">
<h3 id="org169b067">குடியிருப்போர் எண்ணிக்கை</h3>
<div class="outline-text-3" id="text-org169b067">
<p>
சிறு வீடுகள் பல ஒருவரை மட்டுமே குடியிருக்க அனுமதியளிக்கின்றனர். எனக்கு என் மனைவியுடன் தங்க இருவரையாவது அனுமதிக்கும் வீடு தேவைப்பட்டது. குடியிருப்போர் எண்ணிக்கை வைத்து வீடுகளைக் காண OpenRent தளத்தில் வசதியில்லை.
</p>
</div>
</div>
<div id="outline-container-org385d309" class="outline-3">
<h3 id="org385d309">Bedsit தவிர்</h3>
<div class="outline-text-3" id="text-org385d309">
<p>
பல வீடுகள் <a href="https://en.wikipedia.org/wiki/Bedsit">Bedsit</a> வகையைச் சார்ந்தவை. அத்தகைய வீடுகளில் சரியான அடுக்களை இருப்பதில்லை. அவற்றைக் காட்டாமைக்கு OpenRent தளத்தில் வசதியில்லை.
</p>
</div>
</div>
</div>
<div id="outline-container-org721906e" class="outline-2">
<h2 id="org721906e">குறைகளை நிறையாக்கும் Guile உரைநிரல்</h2>
<div class="outline-text-2" id="text-org721906e">
<p>
இக்குறைகளை நிறையாக்கும் வகையில் OpenRent தரவை எனது கணினிக்கே இறக்கி என் விருப்பம் போல் பகுத்தாயலாம் என நினைத்தேன். இதைச் செய்ய OpenRent எளிதான API எதுவும் வழங்கவில்லை. அதனால் OpenRent வலைப்பக்கங்களின்று தேவையான தரவை நானே சுரண்ட வேண்டியிருந்தது. இதற்கு <a href="https://github.com/aconchillo/guile-json">guile-json</a> மற்றும் <a href="https://www.nongnu.org/guile-lib/doc/ref/htmlprag/">guile-lib (htmlprag) HTML கூறாக்கியும்</a> மிகவும் பயன்பட்டன. வீட்டிலிருந்து வேலைக்கு மிதிவண்டியிலேயே சென்றால் எவ்வளவு தொலைவென்றறிய <a href="https://www.openstreetmap.org">OpenStreetMap</a> தரவைப் பயன்படுத்தும் <a href="https://project-osrm.org/">Open Source Routing Machine (OSRM)</a> API யை அணுகினேன். வீட்டருகேயுள்ள தொடருந்து நிலையங்கள் வழியாக எந்தெந்த தொடருந்துப் பாதைகள் செல்கின்றன என்றறிய <a href="https://tfl.gov.uk/">Transport for London (TfL)</a> API யை அணுகினேன். இவற்றையெல்லாம் அடிக்கடி அணுகி தொல்லை செய்ய வேண்டாமென அவற்றின் மறுமொழிகளைப் பதுக்ககமைத்துப் பதுக்கினேன்.
</p>
<p>
எனது Guile உரைநிரல் <a href="https://git.systemreboot.net/rent-in-london/">https://git.systemreboot.net/rent-in-london/</a> git களஞ்சியத்தில் வாழ்கின்றது. அது உங்களுக்கும் பயன்பட்டால் மகிழ்ச்சி. அவ்வுரைநிரலை இயக்கினால் அதுக் கீழ்க்காணும்வாரு விடையளிக்கும். நான் அறிய விரும்பும் வீட்டுப் பண்புகளை மட்டும் அழகாகத் தொகுத்துக் காட்டுகிறது. அதுமட்டுமன்றி என் தேவைகளுக்குப் பொருந்தும் வீடொன்று புதிதாக விளம்பரப்படுத்தப்பட்டால் மிக எளிதாக உடனே கண்டறியவும் பயன்பட்டது.
</p>
<pre class="example">
1 Bed Flat, Lyonsdown Rd, EN5 (posted 58 hours ago)
https://www.openrent.co.uk/1566437
£1350 pcm
Cycling distance: 16.4 km
Tube: High Barnet (northern), Totteridge & Whetstone (northern)
1 Bed Flat, Page Green Terrace, N15 (posted 56 hours ago)
https://www.openrent.co.uk/1571987
£1400 pcm
Cycling distance: 9.1 km
Tube: Seven Sisters (victoria)
1 Bed Flat, Neasden Lane, NW10 (posted 56 hours ago)
https://www.openrent.co.uk/1571965
£1280 pcm
Cycling distance: 13.2 km
Tube: Neasden (jubilee), Dollis Hill (jubilee), Wembley Park (jubilee metropolitan)
1 Bed Maisonette, Albert Road, E18 (posted 6 hours ago)
https://www.openrent.co.uk/1573365
£1200 pcm
Cycling distance: 17.0 km
Tube: South Woodford (central), Snaresbrook (central), Redbridge (central), Wanstead (central)
</pre>
</div>
</div>
<div id="outline-container-org44a3f3d" class="outline-2">
<h2 id="org44a3f3d">பதிப்புரிமை</h2>
<div class="outline-text-2" id="text-org44a3f3d">
<p>
பிக் பென் தலைப்புப் படம் <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA 3.0</a> உரிமத்தின் கீழ் வெளியடப்படுகிறது. அது பின்வரும் படங்களின்று உருவாக்கப்பட்டது.
</p>
<ul class="org-ul">
<li>David Iliff படைத்து <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA 3.0</a> உரிமத்தின் கீழ் வெளியிட்ட <a href="https://commons.wikimedia.org/wiki/File:Clock_Tower_-_Palace_of_Westminster,_London_-_May_2007.jpg">Clock Tower - Palace of Westminster, London - May 2007</a></li>
<li>Luis Felipe López Acevedo படைத்து <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">CC BY-SA 4.0</a> உரிமத்தின் கீழ் வெளியிட்ட <a href="https://git.savannah.gnu.org/cgit/guile/guile-web.git/tree/designs/logo.svg">GNU Guile logo</a></li>
</ul>
</div>
</div>
</div></article>https://systemreboot.net/post/renting-in-london-with-guile.htmlRenting in London with Guile2022-12-18T00:00:00ZArun Isaacarunisaac@systemreboot.net<article class="h-entry"><h1 class="p-name">Renting in London with Guile</h1>
<p>Published by <a class="p-author h-card" href="https://systemreboot.net/">Arun Isaac</a> on <time class="dt-published" datetime="2022-12-18 12:00:00">December 18, 2022</time></p><p>In other languages: <a hreflang="ta" href="/post/guile-%E0%AE%89%E0%AE%9F%E0%AE%A9%E0%AF%8D-%E0%AE%87%E0%AE%B2%E0%AE%A3%E0%AF%8D%E0%AE%9F%E0%AE%A9%E0%AE%BF%E0%AE%B2%E0%AF%8D-%E0%AE%B5%E0%AF%80%E0%AE%9F%E0%AF%81%E0%AE%A4%E0%AF%8D-%E0%AE%A4%E0%AF%87%E0%AE%9F%E0%AE%B2%E0%AF%8D">தமிழ்</a></p><p>Tags: <a class="p-category" href="/tag/London">London</a>, <a class="p-category" href="/tag/lisp">lisp</a>, <a class="p-category" href="/tag/scheme">scheme</a>, <a class="p-category" href="/tag/software">software</a></p><div class="p-summary">Finding the right place to rent in London using a Guile script. Who said Guile is not useful for practical stuff!</div><div class="e-content">
<div id="org634eaba" class="figure">
<p><a href="/images/big-ben-with-guile-1024px.svg"><img src="/images/big-ben-with-guile-640px.svg" alt="The Big Ben with the letter lambda and the GNU Guile logo next to it." class="org-svg" /></a>
</p>
<p><span class="figure-number">Figure 1: </span>The Big Ben with GNU Guile</p>
</div>
<p>
I recently moved to London for work. I will be working in London for at least a few years and wanted to find a good house. House hunting in London was not easy. There weren't that many houses within my budget. Besides, the rental market was so fast and competitive that suitable houses were taken by the time I could identify and enquire about them. I was using <a href="https://www.openrent.co.uk/">OpenRent</a> to search for houses, and found that the built-in filters in the web interface were not sophisticated enough to allow expression of the criteria I was looking for. So, I decided to scrape OpenRent data and process them on my own machine with a Guile script.
</p>
<div id="outline-container-org47f6eb4" class="outline-2">
<h2 id="org47f6eb4">Insufficiency of OpenRent filters</h2>
<div class="outline-text-2" id="text-org47f6eb4">
</div>
<div id="outline-container-org8e610e9" class="outline-3">
<h3 id="org8e610e9">Filtering houses that do not include bills in the rent</h3>
<div class="outline-text-3" id="text-org8e610e9">
<p>
I was looking for houses that did not include utilities (electricity, water, gas) and council tax in the rent. OpenRent allows you to filter houses that have bills included, but it does not allow you to filter houses that do not have bills included.
</p>
</div>
</div>
<div id="outline-container-org1ce5308" class="outline-3">
<h3 id="org1ce5308">Straight line distance (as the crow flies) between points</h3>
<div class="outline-text-3" id="text-org1ce5308">
<p>
In OpenRent, you select a point and list all houses at a certain radius from that house. Unfortunately, this radius is a straight line distance as the crow flies. Since we are denizens of the ground and cannot fly straight from point to point, this is not very useful to us. Even if a house is farther from work as the crow flies, it may be close to a tube line and thus may offer a good commute.
</p>
</div>
</div>
<div id="outline-container-orgaa7e648" class="outline-3">
<h3 id="orgaa7e648">Old advertisements are duds</h3>
<div class="outline-text-3" id="text-orgaa7e648">
<p>
Older advertisements tend to have already been taken or be under negotiation. Enquiring about them is mostly a waste of time and energy. Unfortunately, OpenRent does not let you filter or sort by the age of the advertisement.
</p>
</div>
</div>
<div id="outline-container-org567862b" class="outline-3">
<h3 id="org567862b">Maximum tenants</h3>
<div class="outline-text-3" id="text-org567862b">
<p>
Many smaller houses only allow a maximum of one tenant. Since I needed a house for me and my partner, I needed a house that allows at least two tenants. OpenRent does not let you filter for such houses.
</p>
</div>
</div>
<div id="outline-container-org207430c" class="outline-3">
<h3 id="org207430c">Avoid bedsits</h3>
<div class="outline-text-3" id="text-org207430c">
<p>
Many smaller houses are <a href="https://en.wikipedia.org/wiki/Bedsit">bedsits</a>. Bedsits don't have kitchens at all or have shared kitchens. I wanted to avoid them, but OpenRent does not let you filter them away.
</p>
</div>
</div>
</div>
<div id="outline-container-orgab23d32" class="outline-2">
<h2 id="orgab23d32">A Guile script to fix these issues</h2>
<div class="outline-text-2" id="text-orgab23d32">
<p>
To address these issues, I decided to scrape OpenRent data and process them on my own machine. OpenRent offers no easy API. So, scraping was necessary. <a href="https://github.com/aconchillo/guile-json">guile-json</a> and <a href="https://www.nongnu.org/guile-lib/doc/ref/htmlprag/">guile-lib's (htmlprag) HTML parser</a> were very useful for this. To find the distance from a house to work by bicycle, I queried the <a href="https://www.openstreetmap.org">OpenStreetMap</a> data-wielding <a href="https://project-osrm.org/">Open Source Routing Machine (OSRM)</a> API. To find the tube lines incident on stations near a house, I queried the <a href="https://tfl.gov.uk/">Transport for London (TfL)</a> API. And, to avoid bothering these API endpoints too much and getting banned from them, I cached their responses.
</p>
<p>
My Guile script lives in the <a href="https://git.systemreboot.net/rent-in-london/">https://git.systemreboot.net/rent-in-london/</a> git repository. I hope it is of some use to others, or serves as an inspiration. If you run the script it will produce output as shown below. The output succinctly lists all the properties of a house that I care about. It was of great use in finding suitable houses as soon as they were listed on OpenRent.
</p>
<pre class="example">
1 Bed Flat, Lyonsdown Rd, EN5 (posted 58 hours ago)
https://www.openrent.co.uk/1566437
£1350 pcm
Cycling distance: 16.4 km
Tube: High Barnet (northern), Totteridge & Whetstone (northern)
1 Bed Flat, Page Green Terrace, N15 (posted 56 hours ago)
https://www.openrent.co.uk/1571987
£1400 pcm
Cycling distance: 9.1 km
Tube: Seven Sisters (victoria)
1 Bed Flat, Neasden Lane, NW10 (posted 56 hours ago)
https://www.openrent.co.uk/1571965
£1280 pcm
Cycling distance: 13.2 km
Tube: Neasden (jubilee), Dollis Hill (jubilee), Wembley Park (jubilee metropolitan)
1 Bed Maisonette, Albert Road, E18 (posted 6 hours ago)
https://www.openrent.co.uk/1573365
£1200 pcm
Cycling distance: 17.0 km
Tube: South Woodford (central), Snaresbrook (central), Redbridge (central), Wanstead (central)
</pre>
</div>
</div>
<div id="outline-container-orgac332d2" class="outline-2">
<h2 id="orgac332d2">Copyright</h2>
<div class="outline-text-2" id="text-orgac332d2">
<p>
The Big Ben title image is released under the <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA 3.0</a> license, and is assembled from
</p>
<ul class="org-ul">
<li><a href="https://commons.wikimedia.org/wiki/File:Clock_Tower_-_Palace_of_Westminster,_London_-_May_2007.jpg">Clock Tower - Palace of Westminster, London - May 2007</a>, a photo by David Iliff and released under the <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">CC BY-SA 3.0</a> license</li>
<li><a href="https://git.savannah.gnu.org/cgit/guile/guile-web.git/tree/designs/logo.svg">GNU Guile logo</a> by Luis Felipe López Acevedo released under the <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">CC BY-SA 4.0</a> license</li>
</ul>
</div>
</div>
</div></article>