Something went wrong on our end
-
Hugo Builder Automation authoredd84807a9
index.html 50.21 KiB
<!doctype html><html lang=en dir=auto><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name=robots content="index, follow"><title>Test: Using a Docker image to Build This Blog | On My Mind...</title><meta name=keywords content="blog,geek"><meta name=description content="I use Docker to run several microservices across my websites. Generally, they are standalone tools and demonstrations, mostly made to teach myself how to get these things done in microservices.
I recently came across the concept of utility containers. Up to now, all the containers I run are meant to run all the time, and be easily replaced by spinning up a replacement container. Utility containers, on the other hand, are literally containers that hold the bits needed to process input data into output data, do that process, then exit."><meta name=author content="Gary Allen Vollink"><link rel=canonical href=https://blog.vollink.nyc/post/2022/05/test-using-a-docker-image-to-build-this-blog/><link crossorigin=anonymous href=/assets/css/stylesheet.min.ec8da366ca2fb647537ccb7a8f6fa5b4e9cd3c7a0d3171dd2d3baad1e49c8bfc.css integrity="sha256-7I2jZsovtkdTfMt6j2+ltOnNPHoNMXHdLTuq0eSci/w=" rel="preload stylesheet" as=style><script defer crossorigin=anonymous src=/assets/js/highlight.min.2840b7fccd34145847db71a290569594bdbdb00047097f75d6495d162f5d7dff.js integrity="sha256-KEC3/M00FFhH23GikFaVlL29sABHCX911kldFi9dff8=" onload=hljs.initHighlightingOnLoad()></script>
<link rel=icon href=https://blog.vollink.nyc/favicon.ico><link rel=icon type=image/png sizes=16x16 href=https://blog.vollink.nyc/favicon-16x16.png><link rel=icon type=image/png sizes=32x32 href=https://blog.vollink.nyc/favicon-32x32.png><link rel=apple-touch-icon href=https://blog.vollink.nyc/apple-touch-icon.png><link rel=mask-icon href=https://blog.vollink.nyc/safari-pinned-tab.svg><meta name=theme-color content="#2e2e33"><meta name=msapplication-TileColor content="#2e2e33"><noscript><style>#theme-toggle,.top-link{display:none}</style><style>@media(prefers-color-scheme:dark){:root{--theme:rgb(29, 30, 32);--entry:rgb(46, 46, 51);--primary:rgb(218, 218, 219);--secondary:rgb(155, 156, 157);--tertiary:rgb(65, 66, 68);--content:rgb(196, 196, 197);--hljs-bg:rgb(46, 46, 51);--code-bg:rgb(55, 56, 62);--border:rgb(51, 51, 51)}.list{background:var(--theme)}.list:not(.dark)::-webkit-scrollbar-track{background:0 0}.list:not(.dark)::-webkit-scrollbar-thumb{border-color:var(--theme)}}</style></noscript><meta property="og:title" content="Test: Using a Docker image to Build This Blog"><meta property="og:description" content="I use Docker to run several microservices across my websites. Generally, they are standalone tools and demonstrations, mostly made to teach myself how to get these things done in microservices.
I recently came across the concept of utility containers. Up to now, all the containers I run are meant to run all the time, and be easily replaced by spinning up a replacement container. Utility containers, on the other hand, are literally containers that hold the bits needed to process input data into output data, do that process, then exit."><meta property="og:type" content="article"><meta property="og:url" content="https://blog.vollink.nyc/post/2022/05/test-using-a-docker-image-to-build-this-blog/"><meta property="article:section" content="post"><meta property="article:published_time" content="2022-05-21T15:34:49-04:00"><meta property="article:modified_time" content="2022-05-21T21:43:00-04:00"><meta property="og:site_name" content="On My Mind..."><meta name=twitter:card content="summary"><meta name=twitter:title content="Test: Using a Docker image to Build This Blog"><meta name=twitter:description content="I use Docker to run several microservices across my websites. Generally, they are standalone tools and demonstrations, mostly made to teach myself how to get these things done in microservices.
I recently came across the concept of utility containers. Up to now, all the containers I run are meant to run all the time, and be easily replaced by spinning up a replacement container. Utility containers, on the other hand, are literally containers that hold the bits needed to process input data into output data, do that process, then exit."><script type=application/ld+json>{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Posts","item":"https://blog.vollink.nyc/post/"},{"@type":"ListItem","position":2,"name":"Test: Using a Docker image to Build This Blog","item":"https://blog.vollink.nyc/post/2022/05/test-using-a-docker-image-to-build-this-blog/"}]}</script><script type=application/ld+json>{"@context":"https://schema.org","@type":"BlogPosting","headline":"Test: Using a Docker image to Build This Blog","name":"Test: Using a Docker image to Build This Blog","description":"I use Docker to run several microservices across my websites. Generally, they are standalone tools and demonstrations, mostly made to teach myself how to get these things done in microservices.\nI recently came across the concept of utility containers. Up to now, all the containers I run are meant to run all the time, and be easily replaced by spinning up a replacement container. Utility containers, on the other hand, are literally containers that hold the bits needed to process input data into output data, do that process, then exit.","keywords":["blog","geek"],"articleBody":"I use Docker to run several microservices across my websites. Generally, they are standalone tools and demonstrations, mostly made to teach myself how to get these things done in microservices.\nI recently came across the concept of utility containers. Up to now, all the containers I run are meant to run all the time, and be easily replaced by spinning up a replacement container. Utility containers, on the other hand, are literally containers that hold the bits needed to process input data into output data, do that process, then exit.\nAt the same time, I’ve been transitioning from Google’s blogger platform onto my in-home hardware, using Hugo. I’ve written my own little Docker utility container to hold the go language and the Hugo executable, specifically made to process data checked out from my hugo-content and hugo-static (private) repositories and automatically check the outputs back into my blog-htdocs repository.\nI’m writing this post directly on my gitlab website, and it will be the first post that I’m writing directly into source control, to be processed by my hugo-builder container, and posted publicly.\nDetail: Dockerfile NOTE: As this is a test-post, the below is VERY likely to change (possibly, in many ways).\n# Docker 20.10.16FROMalpine:latestMAINTAINERGary Allen Vollink g.hugo@vollink.comRUN apk update \\ \u0026\u0026 apk upgrade \\ \u0026\u0026 apk add coreutils shadow bash openssh curl go git \\ \u0026\u0026 mkdir /root/.ssh \\ \u0026\u0026 ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 \\ -N '' -C 'git@hugobuilder' -q \\ \u0026\u0026 chmod 700 /root/.ssh \\ \u0026\u0026 chmod 600 /root/.ssh/id_ed25519 \\ \u0026\u0026 chmod 644 /root/.ssh/id_ed25519.pub \\ \u0026\u0026 curl -LOs https://github.com/gohugoio/hugo/releases/download/v0.99.1/hugo_0.99.1_Linux-64bit.tar.gz \\ \u0026\u0026 cd /usr/local/bin \\ \u0026\u0026 tar xfz /hugo_0.99.1_Linux-64bit.tar.gz \\ \u0026\u0026 rm LICENSE README.md \\ \u0026\u0026 /bin/echo \"#######################\" \\ \u0026\u0026 /bin/echo \"## Add key to gitlab.\" \\ \u0026\u0026 /bin/echo \"#######################\" \\ \u0026\u0026 cat /root/.ssh/id_ed25519.pub \\ \u0026\u0026 /bin/echo \"#######################\"COPY src/* /run/CMD /run/entry.shDetail: entry.sh For now, I’m not sharing the whole thing. Key points:\n Does /work exist (it came from -v on the command line): Store the owner’s UID SAVED_USERID Store the owner’s GID SAVID_GROUPID If There’s no user for SAVED_USERID Create the user (and group if needed) If there is a user for SAVED_USERID Modify the user to make sure it can be used for work Get or add a home directory Make sure the shell is set to bash If /work doesn’t exist, use UID/GID 33 (Ubuntu’s www-data userid) Create /work Back up any .ssh and .gitconfig that are “in the way” Copy the /root/.ssh to the user folder. Execute the go_hugo.sh script (see below). Cleanup/revert any .ssh changes Cleanup/revert any .gitconfig changes Details go_hugo.sh #!/bin/bash ############################################################################# VAR_ERROR=\"\" cd /work # Read the environment package that entry.sh left us. if [ -r \"$1\" ] then echo \"Reading $1\" eval $(cat \"$1\") else echo \"Unable to read $1\" ls -ld \"$1\" fi # Read any environment package that a user put in /work if [ -r \"/work/hugobuilder.env\" ] then eval $(cat \"/work/hugobuilder.env\") fi # Check for expected variables # These should all have something, even if left unused. if [ -z \"$GROUP_NAME\" ] then VAR_ERROR=\"${VAR_ERROR}GROUP_NAME:\" fi if [ -z \"$WORK_GID\" ] then VAR_ERROR=\"${VAR_ERROR}WORK_GID:\" fi if [ -z \"$WORK_NAME\" ] then VAR_ERROR=\"${VAR_ERROR}WORK_NAME:\" fi if [ -z \"$WORK_HOME\" ] then VAR_ERROR=\"${VAR_ERROR}WORK_HOME:\" fi if [ -z \"$WORK_UID\" ] then VAR_ERROR=\"${VAR_ERROR}WORK_UID:\" fi if [ -z \"$HAS_CONFIG\" ] then VAR_ERROR=\"${VAR_ERROR}HAS_CONFIG:\" fi if [ ! -z \"$VAR_ERROR\" ] then echo \"ERR: Expected variables missing: ${VAR_ERROR}\" echo \"HAS_CONFIG=$HAS_CONFIG\" exit 2 fi if [ -z \"$GIT_SSH_COMMAND\" ] then # ONLY if the user has not given us a better one. GIT_SSH_COMMAND=\"ssh -o UserKnownHostsFile=/dev/null\" GIT_SSH_COMMAND=\"${GIT_SSH_COMMAND}-o StrictHostKeyChecking=no\" fi export GIT_SSH_COMMAND if [ -r \"/work/.gitconfig\" ] then # If it exists, this was already backed up by entry.sh cp \"/work/.gitconfig\" \"${WORK_HOME}/.gitconfig\" fi # See if we have the two settings needed for `git commit` # Assume we don't _NEED_GCFG_E=1 _NEED_GCFG_N=1 if [ -r \"${WORK_HOME}/.gitconfig\" ] then grep 'user.email' \"${WORK_HOME}/.gitconfig\" 2\u00261 /dev/null if [ \"0\" = \"$?\" ] then # Unless we find it _NEED_GCFG_E=0 fi grep 'user.name' \"${WORK_HOME}/.gitconfig\" 2\u00261 /dev/null if [ \"0\" = \"$?\" ] then _NEED_GCFG_N=0 fi fi # Add needed git settings. if [ \"1\" = \"${_NEED_GCFG_E}\" ] then git config --global user.email \"hugobuilder-auto@vollink.com\" fi if [ \"1\" = \"${_NEED_GCFG_N}\" ] then git config --global user.name \"Hugo Builder Automation\" fi if [ ! -d \"/work/blog/.git\" ] then git clone --recursive \\ ssh://git@gitlab.home.vollink.com:30022/external/blog-htdocs.git \\ \"/work/blog\" if [ \"0\" -ne \"$?\" ] then echo \"ERROR: git failed.\" echo \"Was key added to gitlab?\" echo \"===\" cat ${WORK_HOME}/.ssh/id_ed25519.pub echo \" exit 1 fi if [ ! -d \"/work/blog/htdocs\" ] then echo \"ERROR: git claims success, but blog/htdocs was not created.\" exit 1 fi fi cd /work if [ ! -d \"/work/hugo-blog/.git\" ] then git clone --recursive \\ ssh://git@gitlab.home.vollink.com:30022/home/web/hugo-blog.git \\ \"/work/hugo-blog\" if [ \"0\" -ne \"$?\" ] then echo \"ERROR: git failed.\" echo \"Was key added to gitlab?\" echo \"===\" cat ${WORK_HOME}/.ssh/id_ed25519.pub echo \" exit 1 fi if [ ! -d \"/work/hugo-blog\" ] then echo \"ERROR: git claims success, but hugo-blog/ was not created.\" exit 1 fi fi cd /work/hugo-blog git fetch --all git pull git submodule foreach git pull origin master ## # before running hugo: do I have a config? if [ -r \"${HAS_CONFIG}\" ] then cp \"${HAS_CONFIG}\" \"/work/hugo-blog/.\" fi /usr/local/bin/hugo --destination \"/work/blog/htdocs\" # This is bullshit, by the way... if there is a git FOLDER in the # destination, hugo will delete it entirely before replacing everything, # so I've set this up so the destination is one layer deep. rm /work/blog/htdocs/.git cd /work/blog git add . if [ \"0\" = \"$?\" ] then git commit -m 'docker hugobuilder automated check-in.' if [ \"0\" = \"$?\" ] then git push origin master if [ \"0\" -ne \"$?\" ] then exit 1 fi fi fi Update The page above was run through the hugobuilder container and deployed using a git pull from my web server. With this edit, I’m going to attempt to let the hugobuilder and my various crontabs deploy this automatically (checks are done on a 10 minute schedule). There won’t need to be a further update if this just works.\n","wordCount":"1002","inLanguage":"en","datePublished":"2022-05-21T15:34:49-04:00","dateModified":"2022-05-21T21:43:00-04:00","author":{"@type":"Person","name":"Gary Allen Vollink"},"mainEntityOfPage":{"@type":"WebPage","@id":"https://blog.vollink.nyc/post/2022/05/test-using-a-docker-image-to-build-this-blog/"},"publisher":{"@type":"Organization","name":"On My Mind...","logo":{"@type":"ImageObject","url":"https://blog.vollink.nyc/favicon.ico"}}}</script></head><body id=top><script>localStorage.getItem("pref-theme")==="dark"?document.body.classList.add("dark"):localStorage.getItem("pref-theme")==="light"?document.body.classList.remove("dark"):window.matchMedia("(prefers-color-scheme: dark)").matches&&document.body.classList.add("dark")</script><header class=header><nav class=nav><div class=logo><a href=https://blog.vollink.nyc/ accesskey=h title="Home (Alt + H)"><img src=https://blog.vollink.nyc/AllenWrench.gif alt=logo aria-label=logo height=35>Home</a>
<span class=logo-switches><button id=theme-toggle accesskey=t title="(Alt + T)"><svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentcolor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg><svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentcolor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg></button></span></div><ul id=menu><li><a href=https://blog.vollink.nyc/post/ title=Posts><span>Posts</span></a></li><li><a href=https://blog.vollink.nyc/tags/ title=Tags><span>Tags</span></a></li><li><a href=https://home.vollink.com/ title=home.vollink.com><span>home.vollink.com</span></a></li></ul></nav></header><main class=main><article class=post-single><header class=post-header><div class=breadcrumbs><a href=https://blog.vollink.nyc/>Home</a> » <a href=https://blog.vollink.nyc/post/>Posts</a></div><h1 class=post-title>Test: Using a Docker image to Build This Blog</h1><div class=post-meta><span title="2022-05-21 15:34:49 -0400 -0400">21 May 2022</span> · 5 min · Gary Allen Vollink</div></header><div class=post-content><p>I use <code>Docker</code> to run several microservices across my websites. Generally, they are standalone tools
and demonstrations, mostly made to teach myself how to get these things done in microservices.</p><p>I recently came across the concept of utility containers. Up to now, all the containers I run are meant
to run all the time, and be easily replaced by spinning up a replacement container. Utility
containers, on the other hand, are literally containers that hold the bits
needed to process input data into output data, do that process, then exit.</p><p>At the same time, I’ve been transitioning from Google’s blogger platform onto my in-home hardware,
using <a href=https://gohugo.io/>Hugo</a>. I’ve written my own little Docker utility container to hold
the <code>go</code> language and the <code>Hugo</code> executable, specifically made to process data checked out from
my <code>hugo-content</code> and <code>hugo-static</code> (private) repositories and automatically check the outputs back
into my <a href=https://gitlab.home.vollink.com/external/blog-htdocs>blog-htdocs</a> repository.</p><p>I’m writing this post directly on my gitlab website, and it will be the first post that I’m writing
directly into source control, to be processed by my <code>hugo-builder</code> container, and posted publicly.</p><h2 id=detail-dockerfile>Detail: Dockerfile<a hidden class=anchor aria-hidden=true href=#detail-dockerfile>#</a></h2><p>NOTE: As this is a test-post, the below is VERY likely to change (possibly, in many ways).</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-Dockerfile data-lang=Dockerfile><span class=line><span class=cl><span class=c># Docker 20.10.16</span><span class=err>
</span></span></span><span class=line><span class=cl><span class=err></span><span class=k>FROM</span><span class=s> alpine:latest</span><span class=err>
</span></span></span><span class=line><span class=cl><span class=err></span><span class=k>MAINTAINER</span><span class=s> Gary Allen Vollink g.hugo@vollink.com</span><span class=err>
</span></span></span><span class=line><span class=cl><span class=err>
</span></span></span><span class=line><span class=cl><span class=err></span><span class=k>RUN</span> apk update <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> apk upgrade <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> apk add coreutils shadow bash openssh curl go git <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> mkdir /root/.ssh <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> -N <span class=s1>''</span> -C <span class=s1>'git@hugobuilder'</span> -q <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> chmod <span class=m>700</span> /root/.ssh <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> chmod <span class=m>600</span> /root/.ssh/id_ed25519 <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> chmod <span class=m>644</span> /root/.ssh/id_ed25519.pub <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> curl -LOs https://github.com/gohugoio/hugo/releases/download/v0.99.1/hugo_0.99.1_Linux-64bit.tar.gz <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> <span class=nb>cd</span> /usr/local/bin <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> tar xfz /hugo_0.99.1_Linux-64bit.tar.gz <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> rm LICENSE README.md <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> /bin/echo <span class=s2>"#######################"</span> <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> /bin/echo <span class=s2>"## Add key to gitlab."</span> <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> /bin/echo <span class=s2>"#######################"</span> <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> cat /root/.ssh/id_ed25519.pub <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=o>&&</span> /bin/echo <span class=s2>"#######################"</span><span class=err>
</span></span></span><span class=line><span class=cl><span class=err>
</span></span></span><span class=line><span class=cl><span class=err></span><span class=k>COPY</span> src/* /run/<span class=err>
</span></span></span><span class=line><span class=cl><span class=err></span><span class=k>CMD</span> /run/entry.sh<span class=err>
</span></span></span></code></pre></div><h2 id=detail-entrysh>Detail: entry.sh<a hidden class=anchor aria-hidden=true href=#detail-entrysh>#</a></h2><p>For now, I’m not sharing the whole thing. Key points:</p><ul><li>Does <code>/work</code> exist (it came from <code>-v</code> on the command line):<ul><li>Store the owner’s UID <code>SAVED_USERID</code></li><li>Store the owner’s GID <code>SAVID_GROUPID</code></li></ul></li><li>If There’s no user for SAVED_USERID<ul><li>Create the user (and group if needed)</li></ul></li><li>If there is a user for SAVED_USERID<ul><li>Modify the user to make sure it can be used for work</li><li>Get or add a home directory</li><li>Make sure the shell is set to bash</li></ul></li><li>If /work doesn’t exist, use UID/GID 33 (Ubuntu’s www-data userid)<ul><li>Create <code>/work</code></li></ul></li><li>Back up any .ssh and .gitconfig that are “in the way”</li><li>Copy the /root/.ssh to the user folder.</li><li>Execute the <code>go_hugo.sh</code> script (see below).</li><li>Cleanup/revert any .ssh changes</li><li>Cleanup/revert any .gitconfig changes</li></ul><h2 id=details-go_hugosh>Details go_hugo.sh<a hidden class=anchor aria-hidden=true href=#details-go_hugosh>#</a></h2><div class=highlight><pre tabindex=0 class=chroma><code class=language-bash data-lang=bash><span class=line><span class=cl><span class=cp>#!/bin/bash
</span></span></span><span class=line><span class=cl><span class=cp></span><span class=c1>#############################################################################</span>
</span></span><span class=line><span class=cl><span class=nv>VAR_ERROR</span><span class=o>=</span><span class=s2>""</span>
</span></span><span class=line><span class=cl><span class=nb>cd</span> /work
</span></span><span class=line><span class=cl><span class=c1># Read the environment package that entry.sh left us.</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -r <span class=s2>"</span><span class=nv>$1</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"Reading </span><span class=nv>$1</span><span class=s2>"</span>
</span></span><span class=line><span class=cl> <span class=nb>eval</span> <span class=k>$(</span>cat <span class=s2>"</span><span class=nv>$1</span><span class=s2>"</span><span class=k>)</span>
</span></span><span class=line><span class=cl><span class=k>else</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"Unable to read </span><span class=nv>$1</span><span class=s2>"</span>
</span></span><span class=line><span class=cl> ls -ld <span class=s2>"</span><span class=nv>$1</span><span class=s2>"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=c1># Read any environment package that a user put in /work</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -r <span class=s2>"/work/hugobuilder.env"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nb>eval</span> <span class=k>$(</span>cat <span class=s2>"/work/hugobuilder.env"</span><span class=k>)</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=c1># Check for expected variables</span>
</span></span><span class=line><span class=cl><span class=c1># These should all have something, even if left unused.</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -z <span class=s2>"</span><span class=nv>$GROUP_NAME</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nv>VAR_ERROR</span><span class=o>=</span><span class=s2>"</span><span class=si>${</span><span class=nv>VAR_ERROR</span><span class=si>}</span><span class=s2>GROUP_NAME:"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -z <span class=s2>"</span><span class=nv>$WORK_GID</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nv>VAR_ERROR</span><span class=o>=</span><span class=s2>"</span><span class=si>${</span><span class=nv>VAR_ERROR</span><span class=si>}</span><span class=s2>WORK_GID:"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -z <span class=s2>"</span><span class=nv>$WORK_NAME</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nv>VAR_ERROR</span><span class=o>=</span><span class=s2>"</span><span class=si>${</span><span class=nv>VAR_ERROR</span><span class=si>}</span><span class=s2>WORK_NAME:"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -z <span class=s2>"</span><span class=nv>$WORK_HOME</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nv>VAR_ERROR</span><span class=o>=</span><span class=s2>"</span><span class=si>${</span><span class=nv>VAR_ERROR</span><span class=si>}</span><span class=s2>WORK_HOME:"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -z <span class=s2>"</span><span class=nv>$WORK_UID</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nv>VAR_ERROR</span><span class=o>=</span><span class=s2>"</span><span class=si>${</span><span class=nv>VAR_ERROR</span><span class=si>}</span><span class=s2>WORK_UID:"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -z <span class=s2>"</span><span class=nv>$HAS_CONFIG</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nv>VAR_ERROR</span><span class=o>=</span><span class=s2>"</span><span class=si>${</span><span class=nv>VAR_ERROR</span><span class=si>}</span><span class=s2>HAS_CONFIG:"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> ! -z <span class=s2>"</span><span class=nv>$VAR_ERROR</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"ERR: Expected variables missing: </span><span class=si>${</span><span class=nv>VAR_ERROR</span><span class=si>}</span><span class=s2>"</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"HAS_CONFIG=</span><span class=nv>$HAS_CONFIG</span><span class=s2>"</span>
</span></span><span class=line><span class=cl> <span class=nb>exit</span> <span class=m>2</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -z <span class=s2>"</span><span class=nv>$GIT_SSH_COMMAND</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=c1># ONLY if the user has not given us a better one.</span>
</span></span><span class=line><span class=cl> <span class=nv>GIT_SSH_COMMAND</span><span class=o>=</span><span class=s2>"ssh -o UserKnownHostsFile=/dev/null"</span>
</span></span><span class=line><span class=cl> <span class=nv>GIT_SSH_COMMAND</span><span class=o>=</span><span class=s2>"</span><span class=si>${</span><span class=nv>GIT_SSH_COMMAND</span><span class=si>}</span><span class=s2> -o StrictHostKeyChecking=no"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=nb>export</span> GIT_SSH_COMMAND
</span></span><span class=line><span class=cl>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -r <span class=s2>"/work/.gitconfig"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=c1># If it exists, this was already backed up by entry.sh</span>
</span></span><span class=line><span class=cl> cp <span class=s2>"/work/.gitconfig"</span> <span class=s2>"</span><span class=si>${</span><span class=nv>WORK_HOME</span><span class=si>}</span><span class=s2>/.gitconfig"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl>
</span></span><span class=line><span class=cl><span class=c1># See if we have the two settings needed for `git commit`</span>
</span></span><span class=line><span class=cl><span class=c1># Assume we don't</span>
</span></span><span class=line><span class=cl><span class=nv>_NEED_GCFG_E</span><span class=o>=</span><span class=m>1</span>
</span></span><span class=line><span class=cl><span class=nv>_NEED_GCFG_N</span><span class=o>=</span><span class=m>1</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -r <span class=s2>"</span><span class=si>${</span><span class=nv>WORK_HOME</span><span class=si>}</span><span class=s2>/.gitconfig"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> grep <span class=s1>'user.email'</span> <span class=s2>"</span><span class=si>${</span><span class=nv>WORK_HOME</span><span class=si>}</span><span class=s2>/.gitconfig"</span> 2><span class=p>&</span><span class=m>1</span> >/dev/null
</span></span><span class=line><span class=cl> <span class=k>if</span> <span class=o>[</span> <span class=s2>"0"</span> <span class=o>=</span> <span class=s2>"</span><span class=nv>$?</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl> <span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=c1># Unless we find it</span>
</span></span><span class=line><span class=cl> <span class=nv>_NEED_GCFG_E</span><span class=o>=</span><span class=m>0</span>
</span></span><span class=line><span class=cl> <span class=k>fi</span>
</span></span><span class=line><span class=cl> grep <span class=s1>'user.name'</span> <span class=s2>"</span><span class=si>${</span><span class=nv>WORK_HOME</span><span class=si>}</span><span class=s2>/.gitconfig"</span> 2><span class=p>&</span><span class=m>1</span> >/dev/null
</span></span><span class=line><span class=cl> <span class=k>if</span> <span class=o>[</span> <span class=s2>"0"</span> <span class=o>=</span> <span class=s2>"</span><span class=nv>$?</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl> <span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nv>_NEED_GCFG_N</span><span class=o>=</span><span class=m>0</span>
</span></span><span class=line><span class=cl> <span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl>
</span></span><span class=line><span class=cl><span class=c1># Add needed git settings.</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> <span class=s2>"1"</span> <span class=o>=</span> <span class=s2>"</span><span class=si>${</span><span class=nv>_NEED_GCFG_E</span><span class=si>}</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> git config --global user.email <span class=s2>"hugobuilder-auto@vollink.com"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> <span class=s2>"1"</span> <span class=o>=</span> <span class=s2>"</span><span class=si>${</span><span class=nv>_NEED_GCFG_N</span><span class=si>}</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> git config --global user.name <span class=s2>"Hugo Builder Automation"</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> ! -d <span class=s2>"/work/blog/.git"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> git clone --recursive <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> ssh://git@gitlab.home.vollink.com:30022/external/blog-htdocs.git <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=s2>"/work/blog"</span>
</span></span><span class=line><span class=cl> <span class=k>if</span> <span class=o>[</span> <span class=s2>"0"</span> -ne <span class=s2>"</span><span class=nv>$?</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl> <span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"ERROR: git failed."</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"Was key added to gitlab?"</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"===>"</span>
</span></span><span class=line><span class=cl> cat <span class=si>${</span><span class=nv>WORK_HOME</span><span class=si>}</span>/.ssh/id_ed25519.pub
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"<==="</span>
</span></span><span class=line><span class=cl> <span class=nb>exit</span> <span class=m>1</span>
</span></span><span class=line><span class=cl> <span class=k>fi</span>
</span></span><span class=line><span class=cl> <span class=k>if</span> <span class=o>[</span> ! -d <span class=s2>"/work/blog/htdocs"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl> <span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"ERROR: git claims success, but blog/htdocs was not created."</span>
</span></span><span class=line><span class=cl> <span class=nb>exit</span> <span class=m>1</span>
</span></span><span class=line><span class=cl> <span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=nb>cd</span> /work
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> ! -d <span class=s2>"/work/hugo-blog/.git"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> git clone --recursive <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> ssh://git@gitlab.home.vollink.com:30022/home/web/hugo-blog.git <span class=se>\
</span></span></span><span class=line><span class=cl><span class=se></span> <span class=s2>"/work/hugo-blog"</span>
</span></span><span class=line><span class=cl> <span class=k>if</span> <span class=o>[</span> <span class=s2>"0"</span> -ne <span class=s2>"</span><span class=nv>$?</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl> <span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"ERROR: git failed."</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"Was key added to gitlab?"</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"===>"</span>
</span></span><span class=line><span class=cl> cat <span class=si>${</span><span class=nv>WORK_HOME</span><span class=si>}</span>/.ssh/id_ed25519.pub
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"<==="</span>
</span></span><span class=line><span class=cl> <span class=nb>exit</span> <span class=m>1</span>
</span></span><span class=line><span class=cl> <span class=k>fi</span>
</span></span><span class=line><span class=cl> <span class=k>if</span> <span class=o>[</span> ! -d <span class=s2>"/work/hugo-blog"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl> <span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nb>echo</span> <span class=s2>"ERROR: git claims success, but hugo-blog/ was not created."</span>
</span></span><span class=line><span class=cl> <span class=nb>exit</span> <span class=m>1</span>
</span></span><span class=line><span class=cl> <span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl>
</span></span><span class=line><span class=cl><span class=nb>cd</span> /work/hugo-blog
</span></span><span class=line><span class=cl>git fetch --all
</span></span><span class=line><span class=cl>git pull
</span></span><span class=line><span class=cl>git submodule foreach git pull origin master
</span></span><span class=line><span class=cl>
</span></span><span class=line><span class=cl><span class=c1>##</span>
</span></span><span class=line><span class=cl><span class=c1># before running hugo: do I have a config?</span>
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> -r <span class=s2>"</span><span class=si>${</span><span class=nv>HAS_CONFIG</span><span class=si>}</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> cp <span class=s2>"</span><span class=si>${</span><span class=nv>HAS_CONFIG</span><span class=si>}</span><span class=s2>"</span> <span class=s2>"/work/hugo-blog/."</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span><span class=line><span class=cl>/usr/local/bin/hugo --destination <span class=s2>"/work/blog/htdocs"</span>
</span></span><span class=line><span class=cl><span class=c1># This is bullshit, by the way... if there is a git FOLDER in the</span>
</span></span><span class=line><span class=cl><span class=c1># destination, hugo will delete it entirely before replacing everything,</span>
</span></span><span class=line><span class=cl><span class=c1># so I've set this up so the destination is one layer deep.</span>
</span></span><span class=line><span class=cl>rm /work/blog/htdocs/.git
</span></span><span class=line><span class=cl><span class=nb>cd</span> /work/blog
</span></span><span class=line><span class=cl>git add .
</span></span><span class=line><span class=cl><span class=k>if</span> <span class=o>[</span> <span class=s2>"0"</span> <span class=o>=</span> <span class=s2>"</span><span class=nv>$?</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl><span class=k>then</span>
</span></span><span class=line><span class=cl> git commit -m <span class=s1>'docker hugobuilder automated check-in.'</span>
</span></span><span class=line><span class=cl> <span class=k>if</span> <span class=o>[</span> <span class=s2>"0"</span> <span class=o>=</span> <span class=s2>"</span><span class=nv>$?</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl> <span class=k>then</span>
</span></span><span class=line><span class=cl> git push origin master
</span></span><span class=line><span class=cl> <span class=k>if</span> <span class=o>[</span> <span class=s2>"0"</span> -ne <span class=s2>"</span><span class=nv>$?</span><span class=s2>"</span> <span class=o>]</span>
</span></span><span class=line><span class=cl> <span class=k>then</span>
</span></span><span class=line><span class=cl> <span class=nb>exit</span> <span class=m>1</span>
</span></span><span class=line><span class=cl> <span class=k>fi</span>
</span></span><span class=line><span class=cl> <span class=k>fi</span>
</span></span><span class=line><span class=cl><span class=k>fi</span>
</span></span></code></pre></div><h2 id=update>Update<a hidden class=anchor aria-hidden=true href=#update>#</a></h2><p>The page above was run through the <code>hugobuilder</code> container and deployed using a <code>git pull</code> from my web server.
With this edit, I’m going to attempt to let the <code>hugobuilder</code> and my various crontabs deploy this automatically
(checks are done on a 10 minute schedule). There won’t need to be a further update if this just works.</p></div><footer class=post-footer><ul class=post-tags><li><a href=https://blog.vollink.nyc/tags/blog/>blog</a></li><li><a href=https://blog.vollink.nyc/tags/geek/>geek</a></li></ul><nav class=paginav><a class=next href=https://blog.vollink.nyc/post/2022/05/trying-hugo/><span class=title>Next »</span><br><span>Trying Hugo</span></a></nav><div class=share-buttons><a target=_blank rel="noopener noreferrer" aria-label="share Test: Using a Docker image to Build This Blog on twitter" href="https://twitter.com/intent/tweet/?text=Test%3a%20Using%20a%20Docker%20image%20to%20Build%20This%20Blog&url=https%3a%2f%2fblog.vollink.nyc%2fpost%2f2022%2f05%2ftest-using-a-docker-image-to-build-this-blog%2f&hashtags=blog%2cgeek"><svg viewBox="0 0 512 512"><path d="M449.446.0C483.971.0 512 28.03 512 62.554v386.892C512 483.97 483.97 512 449.446 512H62.554c-34.524.0-62.554-28.03-62.554-62.554V62.554c0-34.524 28.029-62.554 62.554-62.554h386.892zM195.519 424.544c135.939.0 210.268-112.643 210.268-210.268.0-3.218.0-6.437-.153-9.502 14.406-10.421 26.973-23.448 36.935-38.314-13.18 5.824-27.433 9.809-42.452 11.648 15.326-9.196 26.973-23.602 32.49-40.92-14.252 8.429-30.038 14.56-46.896 17.931-13.487-14.406-32.644-23.295-53.946-23.295-40.767.0-73.87 33.104-73.87 73.87.0 5.824.613 11.494 1.992 16.858-61.456-3.065-115.862-32.49-152.337-77.241-6.284 10.881-9.962 23.601-9.962 37.088.0 25.594 13.027 48.276 32.95 61.456-12.107-.307-23.448-3.678-33.41-9.196v.92c0 35.862 25.441 65.594 59.311 72.49-6.13 1.686-12.72 2.606-19.464 2.606-4.751.0-9.348-.46-13.946-1.38 9.349 29.426 36.628 50.728 68.965 51.341-25.287 19.771-57.164 31.571-91.8 31.571-5.977.0-11.801-.306-17.625-1.073 32.337 21.15 71.264 33.41 112.95 33.41z"/></svg></a><a target=_blank rel="noopener noreferrer" aria-label="share Test: Using a Docker image to Build This Blog on linkedin" href="https://www.linkedin.com/shareArticle?mini=true&url=https%3a%2f%2fblog.vollink.nyc%2fpost%2f2022%2f05%2ftest-using-a-docker-image-to-build-this-blog%2f&title=Test%3a%20Using%20a%20Docker%20image%20to%20Build%20This%20Blog&summary=Test%3a%20Using%20a%20Docker%20image%20to%20Build%20This%20Blog&source=https%3a%2f%2fblog.vollink.nyc%2fpost%2f2022%2f05%2ftest-using-a-docker-image-to-build-this-blog%2f"><svg viewBox="0 0 512 512"><path d="M449.446.0C483.971.0 512 28.03 512 62.554v386.892C512 483.97 483.97 512 449.446 512H62.554c-34.524.0-62.554-28.03-62.554-62.554V62.554c0-34.524 28.029-62.554 62.554-62.554h386.892zM160.461 423.278V197.561h-75.04v225.717h75.04zm270.539.0V293.839c0-69.333-37.018-101.586-86.381-101.586-39.804.0-57.634 21.891-67.617 37.266v-31.958h-75.021c.995 21.181.0 225.717.0 225.717h75.02V297.222c0-6.748.486-13.492 2.474-18.315 5.414-13.475 17.767-27.434 38.494-27.434 27.135.0 38.007 20.707 38.007 51.037v120.768H431zM123.448 88.722C97.774 88.722 81 105.601 81 127.724c0 21.658 16.264 39.002 41.455 39.002h.484c26.165.0 42.452-17.344 42.452-39.002-.485-22.092-16.241-38.954-41.943-39.002z"/></svg></a><a target=_blank rel="noopener noreferrer" aria-label="share Test: Using a Docker image to Build This Blog on reddit" href="https://reddit.com/submit?url=https%3a%2f%2fblog.vollink.nyc%2fpost%2f2022%2f05%2ftest-using-a-docker-image-to-build-this-blog%2f&title=Test%3a%20Using%20a%20Docker%20image%20to%20Build%20This%20Blog"><svg viewBox="0 0 512 512"><path d="M449.446.0C483.971.0 512 28.03 512 62.554v386.892C512 483.97 483.97 512 449.446 512H62.554c-34.524.0-62.554-28.03-62.554-62.554V62.554c0-34.524 28.029-62.554 62.554-62.554h386.892zM446 265.638c0-22.964-18.616-41.58-41.58-41.58-11.211.0-21.361 4.457-28.841 11.666-28.424-20.508-67.586-33.757-111.204-35.278l18.941-89.121 61.884 13.157c.756 15.734 13.642 28.29 29.56 28.29 16.407.0 29.706-13.299 29.706-29.701.0-16.403-13.299-29.702-29.706-29.702-11.666.0-21.657 6.792-26.515 16.578l-69.105-14.69c-1.922-.418-3.939-.042-5.585 1.036-1.658 1.073-2.811 2.761-3.224 4.686l-21.152 99.438c-44.258 1.228-84.046 14.494-112.837 35.232-7.468-7.164-17.589-11.591-28.757-11.591-22.965.0-41.585 18.616-41.585 41.58.0 16.896 10.095 31.41 24.568 37.918-.639 4.135-.99 8.328-.99 12.576.0 63.977 74.469 115.836 166.33 115.836s166.334-51.859 166.334-115.836c0-4.218-.347-8.387-.977-12.493 14.564-6.47 24.735-21.034 24.735-38.001zM326.526 373.831c-20.27 20.241-59.115 21.816-70.534 21.816-11.428.0-50.277-1.575-70.522-21.82-3.007-3.008-3.007-7.882.0-10.889 3.003-2.999 7.882-3.003 10.885.0 12.777 12.781 40.11 17.317 59.637 17.317 19.522.0 46.86-4.536 59.657-17.321 3.016-2.999 7.886-2.995 10.885.008 3.008 3.011 3.003 7.882-.008 10.889zm-5.23-48.781c-16.373.0-29.701-13.324-29.701-29.698.0-16.381 13.328-29.714 29.701-29.714 16.378.0 29.706 13.333 29.706 29.714.0 16.374-13.328 29.698-29.706 29.698zM160.91 295.348c0-16.381 13.328-29.71 29.714-29.71 16.369.0 29.689 13.329 29.689 29.71.0 16.373-13.32 29.693-29.689 29.693-16.386.0-29.714-13.32-29.714-29.693z"/></svg></a></div></footer></article></main><footer class=footer><span>© 2022 <a href=https://blog.vollink.nyc/>On My Mind...</a></span>
<span>Powered by
<a href=https://gohugo.io/ rel="noopener noreferrer" target=_blank>Hugo</a> &
<a href=https://git.io/hugopapermod rel=noopener target=_blank>PaperMod</a></span></footer><a href=#top aria-label="go to top" title="Go to Top (Alt + G)" class=top-link id=top-link accesskey=g><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 6" fill="currentcolor"><path d="M12 6H0l6-6z"/></svg></a><script>let menu=document.getElementById("menu");menu&&(menu.scrollLeft=localStorage.getItem("menu-scroll-position"),menu.onscroll=function(){localStorage.setItem("menu-scroll-position",menu.scrollLeft)}),document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(t){t.preventDefault();var e=this.getAttribute("href").substr(1);window.matchMedia("(prefers-reduced-motion: reduce)").matches?document.querySelector(`[id='${decodeURIComponent(e)}']`).scrollIntoView():document.querySelector(`[id='${decodeURIComponent(e)}']`).scrollIntoView({behavior:"smooth"}),e==="top"?history.replaceState(null,null," "):history.pushState(null,null,`#${e}`)})})</script><script>var mybutton=document.getElementById("top-link");window.onscroll=function(){document.body.scrollTop>800||document.documentElement.scrollTop>800?(mybutton.style.visibility="visible",mybutton.style.opacity="1"):(mybutton.style.visibility="hidden",mybutton.style.opacity="0")}</script><script>document.getElementById("theme-toggle").addEventListener("click",()=>{document.body.className.includes("dark")?(document.body.classList.remove("dark"),localStorage.setItem("pref-theme","light")):(document.body.classList.add("dark"),localStorage.setItem("pref-theme","dark"))})</script><script>document.querySelectorAll("pre > code").forEach(t=>{const n=t.parentNode.parentNode,e=document.createElement("button");e.classList.add("copy-code"),e.innerHTML="copy";function s(){e.innerHTML="copied!",setTimeout(()=>{e.innerHTML="copy"},2e3)}e.addEventListener("click",o=>{if("clipboard"in navigator){navigator.clipboard.writeText(t.textContent),s();return}const e=document.createRange();e.selectNodeContents(t);const n=window.getSelection();n.removeAllRanges(),n.addRange(e);try{document.execCommand("copy"),s()}catch(e){}n.removeRange(e)}),n.classList.contains("highlight")?n.appendChild(e):n.parentNode.firstChild==n||(t.parentNode.parentNode.parentNode.parentNode.parentNode.nodeName=="TABLE"?t.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(e):t.parentNode.appendChild(e))})</script></body></html>