<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>gocallag &#8211; Made For Cloud</title>
	<atom:link href="https://madeforcloud.com/author/gocallag/feed/" rel="self" type="application/rss+xml" />
	<link>https://madeforcloud.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Sat, 06 Jun 2026 01:40:20 +0000</lastBuildDate>
	<language>en-AU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>
	<item>
		<title>Ansible Data Manipulation with Modules</title>
		<link>https://madeforcloud.com/2026/06/06/ansible-data-manipulation-with-a-module/</link>
					<comments>https://madeforcloud.com/2026/06/06/ansible-data-manipulation-with-a-module/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Sat, 06 Jun 2026 01:45:00 +0000</pubDate>
				<category><![CDATA[Ansible]]></category>
		<category><![CDATA[Proxmox]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=294</guid>

					<description><![CDATA[Ansible loves to pretend that YAML is a programming language. It isn’t. And every engineer who has ever tried to munge data inside a playbook knows the pain. You have filters everywhere, Jinja spaghetti, and tasks that look like they were written during a period of sleep deprivation. How do I know, guilty as charged.&#8230;<p><a class="more-link" href="https://madeforcloud.com/2026/06/06/ansible-data-manipulation-with-a-module/" title="Continue reading &#8216;Ansible Data Manipulation with Modules&#8217;">Continue reading <span class="meta-nav">&#8594;</span></a></p>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Ansible loves to pretend that YAML is a programming language. It isn’t. And every engineer who has ever tried to munge data inside a playbook knows the pain. You have filters everywhere, Jinja spaghetti, and tasks that look like they were written during a period of sleep deprivation. How do I know, guilty as charged.</p>



<h3 class="wp-block-heading"><strong>Just to be clear, what i&#8217;m saying is YAML and Jinja are not intended to be a Data‑Processing stack</strong></h3>



<p class="wp-block-paragraph">The usual Ansible talking point is that “Ansible is declarative, not imperative”. Sure. But then I immediately need to write imperative logic in Jinja because the playbook layer simply isn’t built for data transformation. I do it, you do it, we&#8217;ve all done it.  It&#8217;s usually quick, and depending on the use case, relatively painless, but at some point, you&#8217;ve taken it too far. I know I have, so I&#8217;m talking about it now. Automation should be declarative, but you need imperative to achieve declarative &#8211; stuff needs to be queried and computed to achieve a desired state. Ansible provides all the batteries needed to achieve this.</p>



<p class="wp-block-paragraph">The pain points you run into are real, you end up with:</p>



<ul class="wp-block-list">
<li>Complex list/dict transformations</li>



<li>Conditional logic that becomes unreadable in YAML</li>



<li>Repeated filter chains that break the moment your data shape changes</li>



<li>Playbooks that become untestable because the logic is embedded in templates</li>
</ul>



<p class="wp-block-paragraph"><strong>Fundamentally</strong>, <strong>if you’re doing anything non‑trivial with data, YAML based tasks and Jinja are the wrong tool.</strong></p>



<h3 class="wp-block-heading">Ansible does have a s<strong>olution: Move the logic into a module</strong></h3>



<p class="wp-block-paragraph"><strong>Stop abusing filters, YAML, Jinja. Write a module.</strong> <strong>If your playbook contains more than two chained filters, or chains of set_facts, or complex jinja, you probably should have written a module.</strong></p>



<p class="wp-block-paragraph">I&#8217;ve written my fair share of modules, they aren&#8217;t that difficult, but my mindset has always gone to the convoluted set_fact, conditional, filter, jinja fiasco &#8211; because somehow it seems easier at the time. Perhaps it is when you&#8217;re trying to capture that initial thought process. But at some point, you need to give yourself a reality check, and maybe it&#8217;s just simpler to start with modules than convert later. That&#8217;s the thought experiment i&#8217;d like you to consider. A module gives you:</p>



<ul class="wp-block-list">
<li>Real programming constructs</li>



<li>Real error handling</li>



<li>Real testability</li>



<li>Real maintainability</li>



<li>Real version control and reuse</li>
</ul>



<h3 class="wp-block-heading"><strong>Why is this a better Pattern</strong>?</h3>



<p class="wp-block-paragraph"><strong>Input validation &#8211; YAML doesn’t. Playbooks don&#8217;t, (don&#8217;t say assert to me as i&#8217;ve abused that as well).  Jinja definitely doesn’t.</strong></p>



<p class="wp-block-paragraph">Modules let you validate input before you do your thing with it.</p>



<p class="wp-block-paragraph"><strong>Modules are testable</strong></p>



<p class="wp-block-paragraph">You can unit test a module. You cannot unit test a Jinja filter chain inside a task, and when your processing is a sequence of knitted tasks full of set_facts and recursive playbook calls, you&#8217;ve crossed the line into prayer-based testing.</p>



<p class="wp-block-paragraph"><strong>Modules are reusable across roles and playbooks</strong></p>



<p class="wp-block-paragraph">Copy‑pasting filter chains, or jinja compute, or those wonderful blocks of set_facts and conditionals is how outages happen.</p>



<p class="wp-block-paragraph"><strong>Modules reduce cognitive load</strong></p>



<p class="wp-block-paragraph">A 20‑line Python function is easier to understand than a 20‑line set_fact, conditional, jinja monstrosity.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">The summary is <strong>Playbooks orchestrate.</strong> <strong>Modules compute.</strong> This is how Ansible should always have been used.</p>



<h3 class="wp-block-heading">So, what is my example problem and how do I fix it with modules. </h3>



<p class="wp-block-paragraph">My ansible role was running Proxmox backups in my home lab. I was only backing up systems in my lab that had been powered on since the last backup, either daily or weekly. My pve_backup role was doing all of the following in YAML:</p>



<ul class="wp-block-list">
<li>Multi‑node API discovery</li>



<li>Cross‑node VM enumeration</li>



<li>Tag parsing and normalization</li>



<li>Per‑VM filtering</li>



<li>Per‑VM state evaluation</li>



<li>Time‑window logic</li>



<li>Task‑history correlation</li>



<li>Backup triggering</li>



<li>UPID polling</li>



<li>Error handling</li>
</ul>



<p class="wp-block-paragraph">This is <strong>imperative logic</strong>. YAML + Jinja is <strong>not</strong> an imperative language. I had effectively built a Python program using a markup language.  Yay me!</p>



<p class="wp-block-paragraph">Based on my thought process that I describe above, I could identify many &#8216;code smells&#8217;:</p>



<p class="wp-block-paragraph"><strong>Excessive </strong><code>set_fact</code></p>



<p class="wp-block-paragraph">This is always a sign the playbook is doing computation, not orchestration.</p>



<p class="wp-block-paragraph"><strong>Nested loops + sub elements</strong></p>



<p class="wp-block-paragraph">This is a red flag that the data model is too complex for YAML.</p>



<p class="wp-block-paragraph"><strong>Repeated REST calls with identical headers</strong></p>



<p class="wp-block-paragraph">Modules handle this cleanly; playbooks do not.</p>



<p class="wp-block-paragraph"><strong>Per‑VM include files</strong></p>



<p class="wp-block-paragraph">This is a workaround for the fact that YAML cannot express real logic.</p>



<p class="wp-block-paragraph"><strong>State accumulation (</strong><code>vms_powered_on_last_week</code><strong>)</strong></p>



<p class="wp-block-paragraph">This is business logic, not orchestration.</p>



<p class="wp-block-paragraph"><strong>UPID polling in YAML</strong></p>



<p class="wp-block-paragraph">This is the worst possible place to do it.</p>



<p class="wp-block-paragraph"><strong>Debug statements everywhere</strong></p>



<p class="wp-block-paragraph">Because debugging YAML logic is hell.</p>



<p class="wp-block-paragraph">My role wasn&#8217;t bad in the terms that it did &#8216;work&#8217;. It’s simply doing something <strong>Ansible playbooks were never designed to do</strong>.</p>



<h3 class="wp-block-heading">How did I refactor this mess?</h3>



<p class="wp-block-paragraph">A good module model I use is:</p>



<p class="wp-block-paragraph"><strong>One module = one conceptual operation</strong></p>



<p class="wp-block-paragraph">My conceptual operations are:</p>



<p class="wp-block-paragraph"><strong>“Given a Proxmox cluster, return the list of VMIDs that should be backed up.”</strong></p>



<p class="wp-block-paragraph"><strong>“Given a VMID, run vzdump and wait for completion.”</strong></p>



<p class="wp-block-paragraph">That’s it. Two modules replace ~300 lines of gnarly YAML.</p>



<h3 class="wp-block-heading">Why this is objectively better (oh and I simply feel better about it)</h3>



<p class="wp-block-paragraph"><strong>Testable</strong></p>



<p class="wp-block-paragraph">You can unit‑test the module logic without running Ansible.</p>



<p class="wp-block-paragraph"><strong>Faster</strong></p>



<p class="wp-block-paragraph">Fewer tasks, leading to fewer forks, leading to fewer HTTP sessions.</p>



<p class="wp-block-paragraph"><strong>Maintainable</strong></p>



<p class="wp-block-paragraph">No more Jinja filter soup.</p>



<p class="wp-block-paragraph"><strong>Debuggable</strong></p>



<p class="wp-block-paragraph">You can print structured Python objects, not YAML hacks.</p>



<p class="wp-block-paragraph"><strong>Reusable</strong></p>



<p class="wp-block-paragraph">Other roles can use the same modules.</p>



<p class="wp-block-paragraph"><strong>Correct abstraction</strong></p>



<p class="wp-block-paragraph">Playbooks orchestrate. Modules compute.</p>



<h2 class="wp-block-heading">In summary</h2>



<p class="wp-block-paragraph">Think of your future self now <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Train yourself to spot the above code smells sooner rather than later.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2026/06/06/ansible-data-manipulation-with-a-module/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>N-4 support for Windows Server Upgrades &#8211; Wow?</title>
		<link>https://madeforcloud.com/2026/06/05/n-4-support-for-windows-server-upgrades-wow/</link>
					<comments>https://madeforcloud.com/2026/06/05/n-4-support-for-windows-server-upgrades-wow/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Fri, 05 Jun 2026 07:08:00 +0000</pubDate>
				<category><![CDATA[Windows]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=286</guid>

					<description><![CDATA[Windows Server 2025 is well and truly here, and Microsoft is pushing hard to convince you that this is the smoothest upgrade cycle in years. They’re not wrong but is it the whole story. If you’re running 2012 R2, 2016, 2019, or 2022, the new N‑4 in‑place upgrade support means you can jump straight to&#8230;<p><a class="more-link" href="https://madeforcloud.com/2026/06/05/n-4-support-for-windows-server-upgrades-wow/" title="Continue reading &#8216;N-4 support for Windows Server Upgrades &#8211; Wow?&#8217;">Continue reading <span class="meta-nav">&#8594;</span></a></p>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Windows Server 2025 is well and truly here, and Microsoft is pushing hard to convince you that this is the smoothest upgrade cycle in years. They’re not wrong but is it the whole story. If you’re running 2012 R2, 2016, 2019, or 2022, the new <strong>N‑4 in‑place upgrade support</strong> means you <em>can</em> jump straight to 2025 in one hop. That’s a big deal. But whether you really can do this is a different question.</p>



<p class="wp-block-paragraph">If you’re still on 2012 R2, this is your last lifeline.</p>



<h2 class="wp-block-heading"><strong>Media‑Based Upgrade: The Official Story vs Reality</strong></h2>



<p class="wp-block-paragraph">Microsoft claims the ISO‑based upgrade takes “under an hour per server.” Sure, in a lab. With clean images. And no vendor agents. And no ancient NIC drivers. And no weird backup software from 2014. I was able to easily do it under these ideal conditions.</p>



<p class="wp-block-paragraph">In the real world, which is often quite messy (today&#8217;s understatement), expect:</p>



<ul class="wp-block-list">
<li><strong>Several hours</strong> for typical servers &#8211; some of these old physical servers take 15 minutes to boot.</li>



<li><strong>Longer</strong> for anything with third‑party agents, monitoring hooks, or legacy storage drivers</li>



<li><strong>Rollback time</strong> if something breaks (and something always breaks). Do you have a rollback plan for your in-place upgrade?  Does your backup actually work?</li>
</ul>



<p class="wp-block-paragraph">Still, the process is quite straightforward: mount ISO &#8212;&gt; run setup &#8212;&gt; choose “Keep files, settings, and apps” &#8212;&gt; Ok, some form of conversation with a deity may help here.</p>



<h2 class="wp-block-heading"><strong>Virtual Machines: The Easy Path (Mostly)</strong></h2>



<p class="wp-block-paragraph">If you’re on <strong>Hyper‑V</strong>, Microsoft is right: upgrades are usually painless. Hyper‑V integration components update automatically during setup.</p>



<p class="wp-block-paragraph">If you’re on VMware, Nutanix, Proxmox, or anything else, Microsoft’s advice is blunt but correct:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Update your guest drivers first. Outdated virtualization drivers are the #1 cause of upgrade failures.</strong> </p>
</blockquote>



<p class="wp-block-paragraph">Ignore this and you’ll be staring at a recovery console and re-considering your life choices.</p>



<h2 class="wp-block-heading"><strong>Physical Servers: Where Things Get Messy</strong></h2>



<p class="wp-block-paragraph">Microsoft politely hints that your 2012 R2 hardware is “about 15 years old.” Translation: <strong>Your server is a fossil. Don’t expect miracles.</strong></p>



<p class="wp-block-paragraph">You must validate:</p>



<ul class="wp-block-list">
<li>NIC drivers</li>



<li>HBAs</li>



<li>RAID/storage controllers</li>



<li>PCIe cards</li>



<li>Out‑of‑band management firmware</li>
</ul>



<p class="wp-block-paragraph">If any of these lack 2025‑compatible drivers, you’re choosing between:</p>



<ul class="wp-block-list">
<li>Buying new hardware</li>



<li>Virtualizing the workload</li>



<li>Moving it to the cloud</li>



<li>Or hoping</li>
</ul>



<h2 class="wp-block-heading"><strong>Planning: The Part Everyone Skips Until It’s Too Late</strong></h2>



<p class="wp-block-paragraph">Microsoft’s checklist is great, but incomplete. But really put some thought into these as well &#8230;</p>



<ul class="wp-block-list">
<li><strong>Uninstall old antivirus/EDR agents</strong> as they break upgrades constantly</li>



<li><strong>Disable third‑party disk encryption</strong></li>



<li><strong>Remove legacy monitoring agents</strong> (SolarWinds, SCOM, etc.)</li>



<li><strong>Disconnect from SANs you don’t need during upgrade</strong></li>



<li><strong>Expect to reboot multiple times</strong> even after the upgrade completes</li>
</ul>



<p class="wp-block-paragraph">The main missing step: <strong>Fix whatever broke. Something always breaks.</strong></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>You cannot in‑place upgrade domain controllers.</strong> Don&#8217;t even bother trying, let me help you here &#8211; no, stop, don&#8217;t, you can thank me later</p>
</blockquote>



<p class="wp-block-paragraph">The process for Active Directory upgrades remains the same as it has been for 20 years: Deploy new DC, Replicate, Demote / Promote, Raise Functional Levels.</p>



<h2 class="wp-block-heading"><strong>Licensing: The Part Everyone Forgets</strong> &#8211; I say everyone, but it was me &#8211; I forgot.</h2>



<p class="wp-block-paragraph">If you have <strong>Software Assurance</strong>, you’re fine. If you rely on <strong>KMS</strong>, make sure it’s updated — 2025 requires new keys.</p>



<p class="wp-block-paragraph"></p>



<h2 class="wp-block-heading"><strong>If the Upgrade Fails</strong></h2>



<p class="wp-block-paragraph">Microsoft recommends:</p>



<ul class="wp-block-list">
<li>Checking logs in <code>C:\Windows\Panther</code></li>



<li>Running <strong>SetupDiag</strong></li>



<li>Restoring from backup</li>
</ul>



<h2 class="wp-block-heading"><strong>Final Thoughts</strong></h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>If you didn’t test the upgrade on a clone first, you’re already headed for disaster &#8211; think of your future self.</strong></p>
</blockquote>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">You can find more details at <a href="https://techcommunity.microsoft.com/blog/windowsservernewsandbestpractices/upgrading-to-windows-server-2025-from-windows-server-2012-r2-2016-2019-or-2022-u/4456406">Upgrading to Windows Server 2025 from Windows Server 2012 R2, 2016, 2019, or 2022 using Media (ISO) | Microsoft Community Hub</a></p>



<p class="wp-block-paragraph"><img decoding="async" alt="" src="blob:https://madeforcloud.com/9aaba871-001a-48b2-97be-83883710a38c"></p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2026/06/05/n-4-support-for-windows-server-upgrades-wow/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Looking at the Microsoft Agent Framework 1.0</title>
		<link>https://madeforcloud.com/2026/05/23/looking-at-the-microsoft-agent-framework-1-0/</link>
					<comments>https://madeforcloud.com/2026/05/23/looking-at-the-microsoft-agent-framework-1-0/#comments</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Fri, 22 May 2026 22:15:00 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=280</guid>

					<description><![CDATA[Microsoft Agent Framework 1.0 is the Microsoft’s first production‑level, open‑source platform for building long‑running, autonomous, multi‑agent systems in .NET and Python. It formalises what developers have been improvising for the past year: structured reasoning loops, tool calling, multi‑agent orchestration, and governance. Basically, Microsoft thinks we need to move from &#8216;research toys&#8217; to &#8216;cloud‑native automation components&#8217;&#8230;<p><a class="more-link" href="https://madeforcloud.com/2026/05/23/looking-at-the-microsoft-agent-framework-1-0/" title="Continue reading &#8216;Looking at the Microsoft Agent Framework 1.0&#8217;">Continue reading <span class="meta-nav">&#8594;</span></a></p>]]></description>
										<content:encoded><![CDATA[
<h1 class="wp-block-heading"></h1>



<p class="wp-block-paragraph">Microsoft Agent Framework 1.0 is the Microsoft’s first production‑level, open‑source platform for building long‑running, autonomous, multi‑agent systems in .NET and Python. It formalises what developers have been improvising for the past year: structured reasoning loops, tool calling, multi‑agent orchestration, and governance. Basically, Microsoft thinks we need to move from &#8216;research toys&#8217; to &#8216;cloud‑native automation components&#8217; with deterministic workflows and enterprise boundaries<strong>.</strong></p>



<h2 class="wp-block-heading">What is it?</h2>



<p class="wp-block-paragraph">The framework is not a simple code library!  it’s a runtime, SDK and, orchestration fabric:</p>



<h2 class="wp-block-heading">Why care?</h2>



<p class="wp-block-paragraph">Agents are no longer simplistic &#8216;chatbots&#8217;. Agentic AI is shifting toward long‑running, autonomous systems that collaborate, reason, and operate reliably in production, aligning with the broader industry trend where LLMs are becoming cloud automation components, not fancy UI features.</p>



<h2 class="wp-block-heading">How? or what&#8217;s inside an agentic application</h2>



<h3 class="wp-block-heading">Agents</h3>



<p class="wp-block-paragraph">In the start, Agents were basically just wrappers around various prompts. Now they are stateful runtime components that use LLMs to interpret inputs, call tools and MCP servers, maintain session state, and generate responses. This creates a clean abstraction that aligns well with cloud-native micro-automation.</p>



<h3 class="wp-block-heading">Workflows</h3>



<p class="wp-block-paragraph">Workflows are deterministic graphs that enforce execution order, coordinate multiple agents, and support both checkpointing and human-in-the-loop interactions. They&#8217;re important because LLM&#8217;s are non-deterministic, they don&#8217;t respond the same way to the same inputs. In a business process determinism can be a key concern.</p>



<p class="wp-block-paragraph">This separation of concerns is the most important architectural decision which relates &#8216;Reasoning / Interpretation&#8217; to the Agent, and the overall execution policy and control to the Workflow giving us the best of both worlds.</p>



<h3 class="wp-block-heading">Middleware</h3>



<p class="wp-block-paragraph">The middleware pipeline allows overall addition of logging, telemetry, filters and compliance logic to our application. Without this, governance typically fails.</p>



<h3 class="wp-block-heading">Agent to Agent (A2A) communication</h3>



<p class="wp-block-paragraph">Agents can now communicate across runtimes (e.g. From Python to .NET) using a structured protocol.This opens up the multi-language development world for agents.</p>



<h3 class="wp-block-heading">MCP Integration</h3>



<p class="wp-block-paragraph">Agents can dynamically discover and invoke tools without custom integration code. This defacto industry standard is a must-have for tool usage.</p>



<p class="wp-block-paragraph">If you’re already in Azure, this will likely become your default agentic automation layer over the next year, or until the next announcements change the playing-field again.</p>



<p class="wp-block-paragraph">If you’re multi‑cloud, it’s still worth having a look, because this is the direction the entire industry is moving. Frameworks help keep the gun-bearing monkey&#8217;s known as LLM&#8217;s under control.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2026/05/23/looking-at-the-microsoft-agent-framework-1-0/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>AlmaLinux 10 &#8211; Install docker-ce</title>
		<link>https://madeforcloud.com/2025/10/19/almalinux-10-install-docker-ce/</link>
					<comments>https://madeforcloud.com/2025/10/19/almalinux-10-install-docker-ce/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Sat, 18 Oct 2025 23:13:25 +0000</pubDate>
				<category><![CDATA[AlmaLinux]]></category>
		<category><![CDATA[Docker]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=272</guid>

					<description><![CDATA[You can read lots of blogs about this. This is the simple minimal version 🙂 Assuming you&#8217;re doing everything as root, but if you aren&#8217;t then prefix these commands with sudo as appropriate for your environment. That&#8217;s it. Done. Now if you want to allow non-root users to use docker.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">You can read lots of blogs about this. This is the simple minimal version <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Assuming you&#8217;re doing everything as root, but if you aren&#8217;t then prefix these commands with sudo as appropriate for your environment.</p>



<p class="wp-block-paragraph"></p>



<pre class="wp-block-code"><code>dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker</code></pre>



<p class="wp-block-paragraph">That&#8217;s it. Done.  Now if you want to allow non-root users to use docker.</p>



<pre class="wp-block-code"><code> usermod -aG docker user   # user is the non-root user you want to be able to use docker</code></pre>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2025/10/19/almalinux-10-install-docker-ce/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Proxmox &#8211; No device with valid iso found</title>
		<link>https://madeforcloud.com/2025/08/20/proxmox-no-device-with-valid-iso-found/</link>
					<comments>https://madeforcloud.com/2025/08/20/proxmox-no-device-with-valid-iso-found/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Wed, 20 Aug 2025 05:35:16 +0000</pubDate>
				<category><![CDATA[Proxmox]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=267</guid>

					<description><![CDATA[You&#8217;ve probably tried to build a bootable USB drive and it hasn&#8217;t copied the image correctly. I highly recommend using rufus in DD mode. This has always worked for me.]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">You&#8217;ve probably tried to build a bootable USB drive and it hasn&#8217;t copied the image correctly.</p>



<p class="wp-block-paragraph">I highly recommend using rufus in <strong>DD</strong> mode.  This has always worked for me.</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2025/08/20/proxmox-no-device-with-valid-iso-found/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Permanently mount a CIFS share on Linux</title>
		<link>https://madeforcloud.com/2025/03/27/permanently-mount-a-cifs-share-on-linux/</link>
					<comments>https://madeforcloud.com/2025/03/27/permanently-mount-a-cifs-share-on-linux/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Thu, 27 Mar 2025 00:28:52 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=259</guid>

					<description><![CDATA[Install the required packages You will need to install the cifs-utils package to mount a network drive on an Ubuntu Linux system. For a Red Hat based system you will also need the cifs-utils package, installed by dnf Create a mount point Create a mount point for the CIFS share. eg. Create a credentials file&#8230;<p><a class="more-link" href="https://madeforcloud.com/2025/03/27/permanently-mount-a-cifs-share-on-linux/" title="Continue reading &#8216;Permanently mount a CIFS share on Linux&#8217;">Continue reading <span class="meta-nav">&#8594;</span></a></p>]]></description>
										<content:encoded><![CDATA[
<h4 class="wp-block-heading"></h4>



<p class="wp-block-paragraph"><span style="text-decoration: underline;">Install the required packages</span></p>



<p class="wp-block-paragraph">You will need to install the cifs-utils package to mount a network drive on an Ubuntu Linux system. </p>



<pre class="wp-block-code"><code>sudo apt-get install -y cifs-utils</code></pre>



<p class="wp-block-paragraph">For a Red Hat based system you will also need the cifs-utils package, installed by <strong>dnf</strong></p>



<pre class="wp-block-code"><code>sudo dnf install -y cifs-utils</code></pre>



<p class="wp-block-paragraph"><span style="text-decoration: underline;">Create a mount point</span></p>



<p class="wp-block-paragraph">Create a mount point for the CIFS share.  eg.</p>



<pre class="wp-block-code"><code>sudo mkdir /srv/cifs/&lt;share>      # where '&lt;share>' is the name of the share you want mounted</code></pre>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"><span style="text-decoration: underline;">Create a credentials file</span></p>



<pre class="wp-block-code"><code>sudo vim /etc/credentials.&lt;share>   # where '&lt;share>' is the name of the share you want mounted</code></pre>



<p class="wp-block-paragraph">Add the following contents to the credentials file, updating with your userid/password details to access your share.</p>



<pre class="wp-block-code"><code>username=&lt;shareuser>
password=&lt;sharepassword></code></pre>



<p class="wp-block-paragraph">Make sure the credentials file is only visible to root</p>



<pre class="wp-block-code"><code>sudo chown root:root /etc/credentials.&lt;share>      # where '&lt;share>' is the name of the share you want mounted
sudo chmod 600 /etc/credentials.&lt;share></code></pre>



<p class="wp-block-paragraph"><span style="text-decoration: underline;">Add the mount to /etc/fstab</span></p>



<p class="wp-block-paragraph">To mount the network drive permanently, you need to add an entry to the /etc/fstab file to ensure the share is mounted automatically when the system boots.</p>



<p class="wp-block-paragraph">Open the /etc/fstab file in a text editor and add the following line:</p>



<pre class="wp-block-code"><code>//&lt;ip address of your cifs server>/&lt;share> /srv/cifs/&lt;share> cifs credentials=/etc/credentials.&lt;share> 0 0</code></pre>



<p class="wp-block-paragraph"><span style="text-decoration: underline;">Testing the mount</span></p>



<pre class="wp-block-code"><code>sudo mount -a
df -h
</code></pre>



<p class="wp-block-paragraph"><br>This should show the CIFS share mounted at the specified mount point.</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2025/03/27/permanently-mount-a-cifs-share-on-linux/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AlmaLinux 9 &#038; Centos 9 Stream builds can now be created for oVirt Nodes</title>
		<link>https://madeforcloud.com/2025/02/23/almalinux-9-centos-9-stream-builds-can-now-be-created-for-ovirt-nodes/</link>
					<comments>https://madeforcloud.com/2025/02/23/almalinux-9-centos-9-stream-builds-can-now-be-created-for-ovirt-nodes/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Sun, 23 Feb 2025 02:50:24 +0000</pubDate>
				<category><![CDATA[AlmaLinux]]></category>
		<category><![CDATA[oVirt]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=253</guid>

					<description><![CDATA[When PR https://github.com/oVirt/ovirt-node-ng-image/pull/146 lands you will be able to build oVirt nodes using AlmaLinux 9 (new) and Centos 9 Stream (fixed). There are still a few issues with AlmaLinux 9, not because of AlmaLinux, but because the oVirt engine force enables a bunch of Centos 9 Stream repositories breaking the system. You can get around&#8230;<p><a class="more-link" href="https://madeforcloud.com/2025/02/23/almalinux-9-centos-9-stream-builds-can-now-be-created-for-ovirt-nodes/" title="Continue reading &#8216;AlmaLinux 9 &#038; Centos 9 Stream builds can now be created for oVirt Nodes&#8217;">Continue reading <span class="meta-nav">&#8594;</span></a></p>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">When PR <a href="https://github.com/oVirt/ovirt-node-ng-image/pull/146" data-type="link" data-id="https://github.com/oVirt/ovirt-node-ng-image/pull/146">https://github.com/oVirt/ovirt-node-ng-image/pull/146</a> lands you will be able to build oVirt nodes using AlmaLinux 9 (new) and Centos 9 Stream (fixed).</p>



<p class="wp-block-paragraph">There are still a few issues with AlmaLinux 9, not because of AlmaLinux, but because the oVirt engine force enables a bunch of Centos 9 Stream repositories breaking the system.  You can get around this by basically disabling those repositories in /etc/yum.repos.d/  as they appear &#8211; bugs will be filed with the engine.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2025/02/23/almalinux-9-centos-9-stream-builds-can-now-be-created-for-ovirt-nodes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VS Code on Almalinux 9</title>
		<link>https://madeforcloud.com/2025/02/14/vs-code-on-almalinux-9/</link>
					<comments>https://madeforcloud.com/2025/02/14/vs-code-on-almalinux-9/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Fri, 14 Feb 2025 03:23:46 +0000</pubDate>
				<category><![CDATA[AlmaLinux]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=251</guid>

					<description><![CDATA[Step 1. Add the signing key Step 2. Add the repository Step 3. Refresh the yum meta data Step 4. Install vscode]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Step 1. Add the signing key</p>



<pre class="wp-block-code"><code>
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
</code></pre>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Step 2. Add the repository</p>



<pre class="wp-block-code"><code>
echo -e  "&#91;vscode]\nname=packages.microsoft.com\nbaseurl=https://packages.microsoft.com/yumrepos/vscode/\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc\nmetadata_expire=1h" | sudo tee -a /etc/yum.repos.d/vscode.repo
</code></pre>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Step 3. Refresh the yum meta data</p>



<pre class="wp-block-code"><code>
sudo dnf update -y
</code></pre>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Step 4. Install vscode</p>



<pre class="wp-block-code"><code>
sudo dnf install code -y
</code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2025/02/14/vs-code-on-almalinux-9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Microsoft Edge on Almalinux 9</title>
		<link>https://madeforcloud.com/2025/02/14/microsoft-edge-on-almalinux-9/</link>
					<comments>https://madeforcloud.com/2025/02/14/microsoft-edge-on-almalinux-9/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Fri, 14 Feb 2025 03:18:15 +0000</pubDate>
				<category><![CDATA[AlmaLinux]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=249</guid>

					<description><![CDATA[Step 1. Import the key Step 2. Add the repos Step 3. Refresh the yum meta data Step 4. Install Edge Microsoft Edge should now be available for you to use either via the CLI or the Gnome Deskop]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Step 1. Import the key</p>



<pre class="wp-block-code"><code>
sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc
</code></pre>



<p class="wp-block-paragraph">Step 2. Add the repos</p>



<pre class="wp-block-code"><code>
sudo dnf config-manager --add-repo https://packages.microsoft.com/yumrepos/edge
</code></pre>



<p class="wp-block-paragraph">Step 3. Refresh the yum meta data</p>



<pre class="wp-block-code"><code>
sudo dnf update --refresh
</code></pre>



<p class="wp-block-paragraph">Step 4. Install Edge</p>



<pre class="wp-block-code"><code>
sudo dnf install microsoft-edge-stable
</code></pre>



<p class="wp-block-paragraph">Microsoft Edge should now be available for you to use either via the CLI or the Gnome Deskop</p>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2025/02/14/microsoft-edge-on-almalinux-9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Compacting WSL hard disk</title>
		<link>https://madeforcloud.com/2024/12/24/compacting-wsl-hard-disk/</link>
					<comments>https://madeforcloud.com/2024/12/24/compacting-wsl-hard-disk/#respond</comments>
		
		<dc:creator><![CDATA[gocallag]]></dc:creator>
		<pubDate>Tue, 24 Dec 2024 06:03:54 +0000</pubDate>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[WSL]]></category>
		<guid isPermaLink="false">https://madeforcloud.com/?p=233</guid>

					<description><![CDATA[Like many people I am an extensive user of WSL and Linux under Windows in general. It&#8217;s the only real option I have at work and it&#8217;s quite a reasonable proposition. That being said though, the WSL vhdx files can grow as you&#8217;re doing Linux work and while you can (and should) clean up side&#8230;<p><a class="more-link" href="https://madeforcloud.com/2024/12/24/compacting-wsl-hard-disk/" title="Continue reading &#8216;Compacting WSL hard disk&#8217;">Continue reading <span class="meta-nav">&#8594;</span></a></p>]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Like many people I am an extensive user of WSL and Linux under Windows in general. It&#8217;s the only real option I have at work and it&#8217;s quite a reasonable proposition.</p>



<p class="wp-block-paragraph">That being said though, the WSL vhdx files can grow as you&#8217;re doing Linux work and while you can (and should) clean up side the Linux environment it&#8217;s not reflected back to windows as free space.</p>



<p class="wp-block-paragraph">So how do you compact your WSL file?</p>



<ol class="wp-block-list">
<li>Shutdown your WSL system.<br><br><code>wsl.exe --list --verbose   # note the verbose is required to get the state</code> <br><img fetchpriority="high" decoding="async" width="600" height="93" class="wp-image-235" style="width: 600px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-163339.png" alt="Output from wsl.exe to show running WSL environment" srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-163339.png 757w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-163339-300x46.png 300w" sizes="(max-width: 600px) 100vw, 600px" /><br><br><code>wsl.exe --terminate Ubuntu-24.04</code><br><img decoding="async" width="600" height="137" class="wp-image-238" style="width: 600px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-163855.png" alt="This shows the output of the wsl command with the instance being terminated" srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-163855.png 750w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-163855-300x68.png 300w" sizes="(max-width: 600px) 100vw, 600px" /><br></li>



<li>Shrink the disk using <strong>diskpart</strong><br><br><code>diskpart</code><br><br><img decoding="async" width="600" height="226" class="wp-image-239" style="width: 600px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164232.png" alt="The diskpart dialogue is displayed" srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164232.png 617w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164232-300x113.png 300w" sizes="(max-width: 600px) 100vw, 600px" /><br><br>You need to <strong>select</strong> the vhdx file for your WSL instance.  The VHDX file is typically found in your <strong>AppData</strong> folder. In my case it was this.<br><br><img loading="lazy" decoding="async" width="800" height="158" class="wp-image-240" style="width: 800px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716.png" alt="Windows explorer show the location of my VHDX file" srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716.png 1500w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716-300x59.png 300w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716-1024x202.png 1024w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716-768x152.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><br><br>I copy the VHDX file location as a path.<br><br><img loading="lazy" decoding="async" width="800" height="407" class="wp-image-241" style="width: 800px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164903.png" alt="The easiest way to get the full filename + path is to use explorer to copy as path" srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164903.png 1045w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164903-300x153.png 300w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164903-1024x521.png 1024w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164903-768x391.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><br><br>DISKPART> <code>select vdisk file="C:\Users\geoff\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx"</code><br><br><img loading="lazy" decoding="async" width="800" height="66" class="wp-image-242" style="width: 800px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165237.png" alt="Output from selecting the vdisk in diskpart
" srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165237.png 1662w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165237-300x25.png 300w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165237-1024x84.png 1024w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165237-768x63.png 768w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165237-1536x127.png 1536w" sizes="auto, (max-width: 800px) 100vw, 800px" /><br></li>



<li>Compact the vdisk<br><br>DISKPART> <code>compact vdisk</code><br><br><img loading="lazy" decoding="async" width="800" height="168" class="wp-image-243" style="width: 800px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165742.png" alt="output of diskpart compact " srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165742.png 600w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165742-300x63.png 300w" sizes="auto, (max-width: 800px) 100vw, 800px" /><br></li>



<li>The results.<br><br>BEFORE<br><br><img loading="lazy" decoding="async" width="800" height="158" class="wp-image-240" style="width: 800px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716.png" alt="Explorer vhdx filesize before compact" srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716.png 1500w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716-300x59.png 300w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716-1024x202.png 1024w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-164716-768x152.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><br><br>AFTER<br><br><img loading="lazy" decoding="async" width="800" height="175" class="wp-image-244" style="width: 800px;" src="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165909.png" alt="Explorer vhdx file size after compact" srcset="https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165909.png 1078w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165909-300x66.png 300w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165909-1024x224.png 1024w, https://madeforcloud.com/wp-content/uploads/2024/12/Screenshot-2024-12-24-165909-768x168.png 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><br><br>As you can see, i&#8217;ve freed up nearly 6Gb.<br></li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://madeforcloud.com/2024/12/24/compacting-wsl-hard-disk/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
