{"id":3661073,"date":"2024-04-30T08:00:25","date_gmt":"2024-04-30T12:00:25","guid":{"rendered":"https:\/\/spin.atomicobject.com\/?p=3661073"},"modified":"2024-04-29T14:34:26","modified_gmt":"2024-04-29T18:34:26","slug":"scripts-linux-installations","status":"publish","type":"post","link":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/","title":{"rendered":"Use Cheapie Scripts to Update a Batch of Linux Installations"},"content":{"rendered":"<p>My day job is authoring production-grade software. Often that has the side effect of creating abstract, reusable components. Creating components like this can take a lot of experience, skill, and brainpower. So by the end of the day, when I&#8217;m tired and want to automate some annoying task for my homelab, it <em>feels really good<\/em> to kick out some cheapie, ugly, barely maintainable, non-reusable, and possibly raunchy shell script.<\/p>\n<p>Here I&#8217;ll describe a small set of <code>zsh<\/code> scripts to <code>apt-get<\/code> update several Ubuntu installations I have throughout the homelab.<\/p>\n<h2>The chore<\/h2>\n<p>Right now, I have about a half dozen Ubuntu virtual machines or LXCs running across two Proxmox hosts. I also have two Raspberry Pis \u2014 with a third coming soon \u2014 running as independent hosts on the network. I use these VMs, LXCs, and Rasberry Pis for running various services and tinkering.<\/p>\n<p>On each system, I&#8217;ve given my user <code>fletcher<\/code> <code>sudo<\/code> permissions to run the <code>apt-get<\/code> upgrade suite of commands to upgrade packages. Each system also has an alias to run all the commands. But logging into each system and running the alias is annoying, so I used ChatGPT to help me make some zsh scripts to update all the systems in one go.<\/p>\n<h2>The scripts<\/h2>\n<p>There are three zsh scripts in total. Let&#8217;s start with the first two.<\/p>\n<p>First is <code>mass_upgradez.zsh<\/code> :<\/p>\n<pre><code>#!\/usr\/bin\/env zsh\n\nhere=$(dirname \"${${(%):-%x}:A}\")\n\ntypeset -A servers\nservers=(\n  fletcher \"trajan hadrian nero\"\n  root \"claudius\"\n)\n\nsource \"$here\/update_servers.zsh\"\n<\/code><\/pre>\n<p>This script, in turn, delegates to <code>update_servers.zsh<\/code> :<\/p>\n<pre><code>#!\/usr\/bin\/env zsh\n\nhere=$(dirname \"$0\")\n\nupgradez=\"export DEBIAN_FRONTEND=noninteractive; sudo -E apt-get update &amp;&amp; sudo -E apt-get upgrade -y &amp;&amp; sudo apt-get autoclean &amp;&amp; sudo apt-get autoremove -y\"\n\nfor user in ${(k)servers}; do\n  for server in ${(s: :)servers[$user]}; do\n    echo \"Updating [$server] with user [$user].\"\n    ssh \"$user\"@\"$server\" \"$upgradez\"\n    echo\n  done\ndone\n\necho \"Done.\"\n<\/code><\/pre>\n<p>The first script starts by defining <code>here<\/code> \u2014 which is an absolute path to the directory this script resides in. This is a much nicer way to say &#8220;here&#8221; than <code>dirname \"${${(%):-%x}:A}\"<\/code>. Arcane shell script syntax is something I rarely need, and therefore have no chance of remembering, and this is where ChatGPT comes in so handy. It gave me the <code>\"${${(%):-%x}:A}\"<\/code> funny business, and I am grateful ChatGPT can remember this so I don&#8217;t need to.<\/p>\n<p>Then, <code>mass_upgradez.zsh<\/code> defines an associative array using the <code>typeset<\/code> keyword and syntax. In this array, the keys are the name of the user account I need to use, and the value is a list of systems that have that username with <code>sudo<\/code> permissions. In this case, one system (the LXC) uses <code>root<\/code>, and the rest use <code>fletcher<\/code>.<\/p>\n<p>The script concludes by delegating control to the <code>update_servers.zsh<\/code> script, which is located alongside this one.<\/p>\n<h3>Running the updates<\/h3>\n<p>Believe it or not, <code>update_servers.zsh<\/code> is responsible for running the updates. First, it defines a variable to hold the chain of update and upgrade commands. This set of variables, commands, and flags should minimize the change that <code>apt-get<\/code> pops up any dialogs or prompts.<\/p>\n<p>Then the script loops over the users and servers. For each user-server pair, it uses <code>ssh<\/code> to run the upgrade commands. Lastly, this script uses <code>echo<\/code> to output some text and make the overall output a little more readable.<\/p>\n<h2>Reusing the delegate script<\/h2>\n<p>In case you&#8217;re wondering why we have two scripts here instead of one \u2014 it is because I want to reuse the <code>update_servers.zsh<\/code> script in another context.<\/p>\n<p>Here is another script I have for upgrading the Raspberry Pis: <code>pi_upgradez.zsh<\/code>:<\/p>\n<pre><code>#!\/usr\/bin\/env zsh\n\nhere=$(dirname \"${${(%):-%x}:A}\")\n\ntypeset -A servers\nservers=(\n  fletcher \"augustus paullus\"\n)\n\nsource \"$here\/update_servers.zsh\"\n<\/code><\/pre>\n<p>This one looks a lot like the first script, and that&#8217;s intentional \u2014 it is almost the same, aside from the list of servers. In this case, these are my Raspberry Pis. When I want to update my VMs and LXCs, I use the first script, when I want to update my Raspberry Pis, I use this one.<\/p>\n<h2>Ok, but why three scripts instead of one?<\/h2>\n<p>Yup, I could put all of this into one script. That would be trivial.<\/p>\n<p>The reason why I separate the VMs and LXCs from the Raspberry Pis is because of speed. The VMs and LXCs are running on high-powered, modern Intel platforms. They can all update pretty quickly. But in my case, at least one of the Raspberry Pis is a Raspberry Pi 2, which is slow. (The only thing it does is DNS, so it&#8217;s good at that at least.) Both Raspberry Pis, but especially the 2, are slow to run all the updates. I only run this script when I know I&#8217;ll have plenty of time to let it finish.<\/p>\n<p>Therefore I have three scripts: one for the fast computers, one for the slow computers, and common logic shared between the two.<\/p>\n<h2>Sometimes quick and dirty wins<\/h2>\n<p>As per usual, the shell scripts are appalling to look at and try to read. But they get the job done for my limited needs. And thanks to ChatGPT I don&#8217;t need to memorize the rain dance of obscure symbols to program the script. All-in-all I consider this set of scripts a big win.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My day job is authoring production-grade software. Often that has the side effect of creating abstract, reusable components. Creating components like this can take a lot of experience, skill, and brainpower. So by the end of the day, when I&#8217;m tired and want to automate some annoying task for my homelab, it feels really good [&hellip;]<\/p>\n","protected":false},"author":405,"featured_media":3661449,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1732],"tags":[606,1685,23482,23587],"series":[],"class_list":["post-3661073","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-extracurriculars","tag-linux","tag-automation","tag-shell","tag-zsh"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Use Cheapie Scripts to Update a Batch of Linux Installations<\/title>\n<meta name=\"description\" content=\"Sometimes some ugly, non-reusable shell scripts can really tie the room together. I consider this set of scripts a big win.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Use Cheapie Scripts to Update a Batch of Linux Installations\" \/>\n<meta property=\"og:description\" content=\"Sometimes some ugly, non-reusable shell scripts can really tie the room together. I consider this set of scripts a big win.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/\" \/>\n<meta property=\"og:site_name\" content=\"Atomic Spin\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/atomicobject\" \/>\n<meta property=\"article:published_time\" content=\"2024-04-30T12:00:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Matt Fletcher\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@atomicobject\" \/>\n<meta name=\"twitter:site\" content=\"@atomicobject\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Matt Fletcher\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/\"},\"author\":{\"name\":\"Matt Fletcher\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#\\\/schema\\\/person\\\/5a3fc1d22434c572f77b25fc9688e348\"},\"headline\":\"Use Cheapie Scripts to Update a Batch of Linux Installations\",\"datePublished\":\"2024-04-30T12:00:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/\"},\"wordCount\":758,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/atomicobject.com\\\/\"},\"image\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg\",\"keywords\":[\"Linux\",\"automation\",\"shell\",\"zsh\"],\"articleSection\":[\"Extracurricular Activities\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/\",\"name\":\"Use Cheapie Scripts to Update a Batch of Linux Installations\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg\",\"datePublished\":\"2024-04-30T12:00:25+00:00\",\"description\":\"Sometimes some ugly, non-reusable shell scripts can really tie the room together. I consider this set of scripts a big win.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/scripts-linux-installations\\\/#primaryimage\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg\",\"contentUrl\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg\",\"width\":2560,\"height\":1707,\"caption\":\"Use Cheapie Scripts to Update a Batch of Linux Installations\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#website\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/\",\"name\":\"Atomic Spin\",\"description\":\"Atomic Object\u2019s blog on everything we find fascinating.\",\"publisher\":{\"@id\":\"https:\\\/\\\/atomicobject.com\\\/\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/spin.atomicobject.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#organization\",\"name\":\"Atomic Object\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/AO-Logo-Emblem-Color.png\",\"contentUrl\":\"https:\\\/\\\/spin.atomicobject.com\\\/wp-content\\\/uploads\\\/AO-Logo-Emblem-Color.png\",\"width\":258,\"height\":244,\"caption\":\"Atomic Object\"},\"image\":{\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/atomicobject\",\"https:\\\/\\\/x.com\\\/atomicobject\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/spin.atomicobject.com\\\/#\\\/schema\\\/person\\\/5a3fc1d22434c572f77b25fc9688e348\",\"name\":\"Matt Fletcher\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9dc8ea01493f88a32d8436587c5f22f27d8b0ac07556e52a138ad72567d718ff?s=96&d=blank&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9dc8ea01493f88a32d8436587c5f22f27d8b0ac07556e52a138ad72567d718ff?s=96&d=blank&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/9dc8ea01493f88a32d8436587c5f22f27d8b0ac07556e52a138ad72567d718ff?s=96&d=blank&r=pg\",\"caption\":\"Matt Fletcher\"},\"description\":\"Long term Grand Rapids software development consultant.\",\"url\":\"https:\\\/\\\/spin.atomicobject.com\\\/author\\\/fletcher\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Use Cheapie Scripts to Update a Batch of Linux Installations","description":"Sometimes some ugly, non-reusable shell scripts can really tie the room together. I consider this set of scripts a big win.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/","og_locale":"en_US","og_type":"article","og_title":"Use Cheapie Scripts to Update a Batch of Linux Installations","og_description":"Sometimes some ugly, non-reusable shell scripts can really tie the room together. I consider this set of scripts a big win.","og_url":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/","og_site_name":"Atomic Spin","article_publisher":"https:\/\/www.facebook.com\/atomicobject","article_published_time":"2024-04-30T12:00:25+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg","type":"image\/jpeg"}],"author":"Matt Fletcher","twitter_card":"summary_large_image","twitter_creator":"@atomicobject","twitter_site":"@atomicobject","twitter_misc":{"Written by":"Matt Fletcher","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/#article","isPartOf":{"@id":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/"},"author":{"name":"Matt Fletcher","@id":"https:\/\/spin.atomicobject.com\/#\/schema\/person\/5a3fc1d22434c572f77b25fc9688e348"},"headline":"Use Cheapie Scripts to Update a Batch of Linux Installations","datePublished":"2024-04-30T12:00:25+00:00","mainEntityOfPage":{"@id":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/"},"wordCount":758,"commentCount":0,"publisher":{"@id":"https:\/\/atomicobject.com\/"},"image":{"@id":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/#primaryimage"},"thumbnailUrl":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg","keywords":["Linux","automation","shell","zsh"],"articleSection":["Extracurricular Activities"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/spin.atomicobject.com\/scripts-linux-installations\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/","url":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/","name":"Use Cheapie Scripts to Update a Batch of Linux Installations","isPartOf":{"@id":"https:\/\/spin.atomicobject.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/#primaryimage"},"image":{"@id":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/#primaryimage"},"thumbnailUrl":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg","datePublished":"2024-04-30T12:00:25+00:00","description":"Sometimes some ugly, non-reusable shell scripts can really tie the room together. I consider this set of scripts a big win.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/spin.atomicobject.com\/scripts-linux-installations\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/spin.atomicobject.com\/scripts-linux-installations\/#primaryimage","url":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg","contentUrl":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/JillDeVriesPhotography-AO2022-359-2-scaled.jpg","width":2560,"height":1707,"caption":"Use Cheapie Scripts to Update a Batch of Linux Installations"},{"@type":"WebSite","@id":"https:\/\/spin.atomicobject.com\/#website","url":"https:\/\/spin.atomicobject.com\/","name":"Atomic Spin","description":"Atomic Object\u2019s blog on everything we find fascinating.","publisher":{"@id":"https:\/\/atomicobject.com\/"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/spin.atomicobject.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/spin.atomicobject.com\/#organization","name":"Atomic Object","url":"https:\/\/spin.atomicobject.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/spin.atomicobject.com\/#\/schema\/logo\/image\/","url":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/AO-Logo-Emblem-Color.png","contentUrl":"https:\/\/spin.atomicobject.com\/wp-content\/uploads\/AO-Logo-Emblem-Color.png","width":258,"height":244,"caption":"Atomic Object"},"image":{"@id":"https:\/\/spin.atomicobject.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/atomicobject","https:\/\/x.com\/atomicobject"]},{"@type":"Person","@id":"https:\/\/spin.atomicobject.com\/#\/schema\/person\/5a3fc1d22434c572f77b25fc9688e348","name":"Matt Fletcher","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/9dc8ea01493f88a32d8436587c5f22f27d8b0ac07556e52a138ad72567d718ff?s=96&d=blank&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/9dc8ea01493f88a32d8436587c5f22f27d8b0ac07556e52a138ad72567d718ff?s=96&d=blank&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9dc8ea01493f88a32d8436587c5f22f27d8b0ac07556e52a138ad72567d718ff?s=96&d=blank&r=pg","caption":"Matt Fletcher"},"description":"Long term Grand Rapids software development consultant.","url":"https:\/\/spin.atomicobject.com\/author\/fletcher\/"}]}},"_links":{"self":[{"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/posts\/3661073","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/users\/405"}],"replies":[{"embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/comments?post=3661073"}],"version-history":[{"count":0,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/posts\/3661073\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/media\/3661449"}],"wp:attachment":[{"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/media?parent=3661073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/categories?post=3661073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/tags?post=3661073"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/spin.atomicobject.com\/wp-json\/wp\/v2\/series?post=3661073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}