Akom's Tech Ruminations
//tech.akom.net/
Various tech outbursts - code and solutions to practical problemsen//tech.akom.net/templates/2k11/img/s9y_banner_small.pngRSS: Akom's Tech Ruminations - Various tech outbursts - code and solutions to practical problems
//tech.akom.net/
10021Linux: Chrome Steals Focus on click despite mouse-focus mode
//tech.akom.net/archives/163-Linux-Chrome-Steals-Focus-on-click-despite-mouse-focus-mode.html
<p>I like to use mouse-focus mode in Linux (XFCE), which also means that I don't want windows to get raised on click.  This means, for example, that I can have a piece of a window visible but not raised and copy something to/from there:</p>
<p><img alt="The terminal is not raised on click" class="serendipity_image_center" height="513" loading="lazy" src="//tech.akom.net/uploads/screenshots/mouse-focus-example.png" width="604" /></p>
<p>However, Google Chrome does not honor this window manager setting.  Any click in a chrome window causes it to be raised.</p>
<p>It turns out that, with XFCE's xfwm, there is an additional setting to turn off in <strong>gconf</strong>:</p>
<figure class="serendipity_imageComment_center" style="width: 697px">
<div class="serendipity_imageComment_img"><!-- s9ymdb:263 --><img alt="XFCE Settings " class="serendipity_image_center" height="368" loading="lazy" src="//tech.akom.net/uploads/screenshots/mouse-focus-prevent-chrome.png" width="697" /></div>
<figcaption class="serendipity_imageComment_txt">Turning off raise_with_any_button stops Chrome from stealing focus</figcaption>
</figure>
Akom's Tech Ruminationsnospam@example.com (Admin)
Linux, 2024-02-29T16:52:00Z//tech.akom.net/wfwcomment.php?cid=1630//tech.akom.net/rss.php?version=1.0&type=comments&cid=163Automating minikube configuration to log in to a Docker Private Registy.
//tech.akom.net/archives/162-Automating-minikube-configuration-to-log-in-to-a-Docker-Private-Registy..html
<p>In CI, I am using <a onclick="_gaq.push(['_trackPageview', '/extlink/minikube.sigs.k8s.io/docs/']);" href="https://minikube.sigs.k8s.io/docs/">minikube</a> for local testing on my nodes.  In the name of repeatable builds, I completely rebuild minikube after each build (minikube delete, minikube start).   I am also using an internal Docker Private Registry (DPR or DTR).  Same methodology applies if you are using Google Container Registry or the Amazon equivalent.  In order to authenticate to DPR, I am using the <a onclick="_gaq.push(['_trackPageview', '/extlink/minikube.sigs.k8s.io/docs/handbook/registry/']);" href="https://minikube.sigs.k8s.io/docs/handbook/registry/">registry-creds</a> addon.  It is normally configured interactively:</p>
<p><code>$ minikube addons configure registry-creds</code></p>
<p><code>Do you want to <span class="builtin class-name token" style="box-sizing:border-box; color:rgb(223, 85, 113)">enable</span> Docker Registry? <span class="punctuation token" style="box-sizing:border-box; color:rgb(168, 160, 149)">[</span>y/n<span class="punctuation token" style="box-sizing:border-box; color:rgb(168, 160, 149)">]</span>: y</code></p>
<p>It then asks you some questions and expects user input.  </p>
<h2>Automating</h2>
<p>I want this automated, as it will be running several times an hour.  The addon config does not take any parameters, so I'm taking a different approach.  The configure step creates some credentials in k8s, and it is possible to transfer them from one cluster to another.  This is how I am doing it:</p>
<a class="block_level" href="//tech.akom.net/archives/162-Automating-minikube-configuration-to-log-in-to-a-Docker-Private-Registy..html#extended">Continue reading "Automating minikube configuration to log in to a Docker Private Registy."</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
DevOps, 2023-03-14T14:33:00Z//tech.akom.net/wfwcomment.php?cid=1620//tech.akom.net/rss.php?version=1.0&type=comments&cid=162Upgrading a non-LTS Ubuntu installation after EOL
//tech.akom.net/archives/155-Upgrading-a-non-LTS-Ubuntu-installation-after-EOL.html
<p>If you don't upgrade a non-LTS release (eg: 21.10) to a supported version before End-Of-Life, you will be dealing with a rather awkward user experience.  Here is what happens:</p>
<blockquote>
<p>$ do-release-upgrade</p>
<p>Please install all available updates for your release before upgrading.</p>
</blockquote>
<p>Yet if you atempt to install updates, that fails:</p>
<blockquote>
<p>$ apt dist-upgrade -y</p>
<p>Err:5 <a onclick="_gaq.push(['_trackPageview', '/extlink/archive.ubuntu.com/ubuntu']);" href="http://archive.ubuntu.com/ubuntu" rel="nofollow">http://archive.ubuntu.com/ubuntu</a> impish Release<br />
  404 Not Found [IP: 2001:67c:1562::18 80]</p>
<p>...</p>
</blockquote>
<p>Essentially, apt cache knows about some pending updates, but the actual packages are not longer available.  You can't update them, so you can't upgrade your OS.</p>
<a class="block_level" href="//tech.akom.net/archives/155-Upgrading-a-non-LTS-Ubuntu-installation-after-EOL.html#extended">Continue reading "Upgrading a non-LTS Ubuntu installation after EOL"</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
Linux, 2022-09-01T17:01:00Z//tech.akom.net/wfwcomment.php?cid=1550//tech.akom.net/rss.php?version=1.0&type=comments&cid=155Upgrading a non-LTS Ubuntu installation after EOL
//tech.akom.net/archives/156-Upgrading-a-non-LTS-Ubuntu-installation-after-EOL.html
<p>If you don't upgrade a non-LTS release (eg: 21.10) to a supported version before End-Of-Life, you will be dealing with a rather awkward user experience.  Here is what happens:</p>
<blockquote>
<p>$ do-release-upgrade</p>
<p>Please install all available updates for your release before upgrading.</p>
</blockquote>
<p>Yet if you atempt to install updates, that fails:</p>
<blockquote>
<p>$ apt dist-upgrade -y</p>
<p>Err:5 <a onclick="_gaq.push(['_trackPageview', '/extlink/archive.ubuntu.com/ubuntu']);" href="http://archive.ubuntu.com/ubuntu" rel="nofollow">http://archive.ubuntu.com/ubuntu</a> impish Release<br />
  404 Not Found [IP: 2001:67c:1562::18 80]</p>
<p>...</p>
</blockquote>
<p>Essentially, apt cache knows about some pending updates, but the actual packages are not longer available.  You can't update them, so you can't upgrade your OS.</p>
<a class="block_level" href="//tech.akom.net/archives/156-Upgrading-a-non-LTS-Ubuntu-installation-after-EOL.html#extended">Continue reading "Upgrading a non-LTS Ubuntu installation after EOL"</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
Linux, 2022-09-01T17:01:00Z//tech.akom.net/wfwcomment.php?cid=1560//tech.akom.net/rss.php?version=1.0&type=comments&cid=156Preserving a Static Copy of Atlassian Jira (and Confluence) as a Jekyll Site
//tech.akom.net/archives/154-Preserving-a-Static-Copy-of-Atlassian-Jira-and-Confluence-as-a-Jekyll-Site.html
<p>Last month an old Jira installation I own was compromised via a recent vulnerability. This is bound to happen. Keeping a public product like that secure would require very frequent patching, which is a lot of maintenance. Fortunately, this installation is only a historical record of a popular open-source project (current development uses github issues). In other words, I can get away with a static, read-only copy.</p>
<h3>Going Static</h3>
<p>Of course, I can use</p>
<blockquote>wget --mirror</blockquote>
<p>to save the whole site exactly as-is. This is a simple option, but it will also need a lot of massaging (for example, to remove confusing links to login, javascript that may break, etc).</p>
<p>Instead, I'm going to convert the content to <b>markdown</b> so that I can then regenerate the site using Jekyll, changing the look and feel, headers and footers as needed. This will also preserve all existing URLs (including attachments).</p>
<h3>Making this Happen</h3>
<p>I wrote a project to help automate this process fully via the Jira API: <a onclick="_gaq.push(['_trackPageview', '/extlink/github.com/akomakom/jira-to-jekyll/']);" href="https://github.com/akomakom/jira-to-jekyll/">https://github.com/akomakom/jira-to-jekyll/</a>.</p>
<p>The basic goal is to do what I outlined above. There is a comprehensive README that explains the process.</p>
<a class="block_level" href="//tech.akom.net/archives/154-Preserving-a-Static-Copy-of-Atlassian-Jira-and-Confluence-as-a-Jekyll-Site.html#extended">Continue reading "Preserving a Static Copy of Atlassian Jira (and Confluence) as a Jekyll Site"</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
Linux, 2021-10-25T13:34:00Z//tech.akom.net/wfwcomment.php?cid=1540//tech.akom.net/rss.php?version=1.0&type=comments&cid=154Bootstrapping S3/CloudFront with LetsEncrypt
//tech.akom.net/archives/152-Bootstrapping-S3CloudFront-with-LetsEncrypt.html
<p>Let's assume that you want to do the following:</p>
<ol>
<li>Host the contents of your S3 bucket via YOUR.DOMAIN.COM</li>
<li>Use CloudFront</li>
<li>Use a LetsEncrypt cert</li>
</ol>
<p>
<em>"What's the problem?"</em>, you may ask. There are plenty of tutorials for this stuff. Not exactly. A CloudFront Distribution <strong>will not let you add a CNAME</strong> until you have an SSL cert, but you can't use certbot to auto-provision an SSL cert until you are hosting from your domain.
</p>
<h3>Solution</h3>
<p>
The easiest solution is to <b>initially</b> generate your SSL cert manually. You can then use something like <a onclick="_gaq.push(['_trackPageview', '/extlink/github.com/akomakom/certbot-s3front']);" href="https://github.com/akomakom/certbot-s3front">certbot-s3front</a> to auto-renew.
</p>
<h3>Details</h3>
<a class="block_level" href="//tech.akom.net/archives/152-Bootstrapping-S3CloudFront-with-LetsEncrypt.html#extended">Continue reading "Bootstrapping S3/CloudFront with LetsEncrypt"</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
DevOps, Linux, 2021-08-05T15:30:00Z//tech.akom.net/wfwcomment.php?cid=1520//tech.akom.net/rss.php?version=1.0&type=comments&cid=152Adventures in Modifying a UPS for external DC power and LiFePO4 batteries
//tech.akom.net/archives/151-Adventures-in-Modifying-a-UPS-for-external-DC-power-and-LiFePO4-batteries.html
<p>I have an ancient APC Smart-UPS 1400 RMNET. It's a very nice UPS, but I have frequent multi-hour power outages and battery life becomes a problem. I have these issues:</p>
<ol>
<li>Short battery <strong>runtime</strong>, especially as batteries age</li>
<li>Lead-acid <strong>batteries</strong> require frequent replacement and quickly lose capacity (and there are 4 of them)</li>
<li>UPS will not accept 110v from a <strong>cheap generator</strong> (mine is a 700w). This means that I can't do a live power transfer from mains to this generator, and I have to reboot everything to switch</li>
</ol>
<h3>So, I had a few ideas</h3>
<ul>
<li>What if I could feed externally-generated DC battery voltage <strong>directly to the batteries</strong>? For example, via a generator powering a AC-DC power supply</li>
<li>What if I could substitute <strong>Lithium batteries</strong> for Lead-Acid? LiFePO4 would be ideal in this application because weight doesn't matter but the long cycle life does. A 4S pack would have a similar voltage to a 12v lead-acid battery</li>
</ul>
<a class="block_level" href="//tech.akom.net/archives/151-Adventures-in-Modifying-a-UPS-for-external-DC-power-and-LiFePO4-batteries.html#extended">Continue reading "Adventures in Modifying a UPS for external DC power and LiFePO4 batteries"</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
Hardware Hacks, 2021-06-26T21:09:00Z//tech.akom.net/wfwcomment.php?cid=1510//tech.akom.net/rss.php?version=1.0&type=comments&cid=151PowerShell on Linux doesn't find modules when run through Puppet
//tech.akom.net/archives/149-PowerShell-on-Linux-doesnt-find-modules-when-run-through-Puppet.html
<p>I'm running <b>PowerShell</b> on Linux for the sake of using <b><a onclick="_gaq.push(['_trackPageview', '/extlink/developer.vmware.com/powercli']);" href="https://developer.vmware.com/powercli">PowerCLI</a></b>. An interesting thing happens: when <b>pwsh</b> is run interactively, in a terminal, the following works fine when PowerCLI is already installed:</p>
<blockquote><pre>pwsh -c 'Get-InstalledModule VMware.PowerCLI'</pre></blockquote>
<p>When puppet runs it - it doesn't find the module:</p>
<blockquote><pre>
Get-Package: /opt/microsoft/powershell/7/Modules/PowerShellGet/PSModule.psm1:9445
Line |
9445 | PackageManagement\Get-Package @PSBoundParameters | Microsoft. …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| No match was found for the specified search criteria and
| module names 'VMware.PowerCLI'.
Error: 'pwsh -c "if (-not(Get-InstalledModule VMware.PowerCLI)) { Exit 1 }"' returned 1 instead of one of [0]
</pre></blockquote>
<p>After some experimentation, I narrowed it down to a single environment variable missing when puppet executes the command: <b>HOME</b>. Set HOME, and powershell will find modules. That gets us the following recipe:</p>
<blockquote><pre>
$my_user = 'some_user'
exec { 'Install PowerCLI':
path => ['/bin', '/usr/bin'],
command => 'pwsh -c \'Install-Module -Force:$true -Name VMware.PowerCLI\'',
unless => 'pwsh -c \'if (-not(Get-InstalledModule VMware.PowerCLI -ErrorAction silentlycontinue)) { Exit 1 }\'',
user => $my_user,
environment => [ "HOME=/home/${my_user}"]
}
</pre></blockquote>
Akom's Tech Ruminationsnospam@example.com (Admin)
DevOps, Linux, 2021-03-11T16:56:00Z//tech.akom.net/wfwcomment.php?cid=1490//tech.akom.net/rss.php?version=1.0&type=comments&cid=149Gradle Toolchains Support - different JVMs for compile and test
//tech.akom.net/archives/148-Gradle-Toolchains-Support-different-JVMs-for-compile-and-test.html
<p>I'm testing a product that needs to be compiled with JDK 8 but tested (sometimes) on JDK 11. This is now <a onclick="_gaq.push(['_trackPageview', '/extlink/github.com/apache/maven-surefire/pull/285/commits']);" href="https://github.com/apache/maven-surefire/pull/285/commits">possible to do with maven surefire</a> (although that took some effort). With gradle, I was doing it as follows, which is terrible, even if the path comes from configuration:</p>
<pre>
<div class="groovy geshi" style="text-align: left"><br /><span style="color: #808080; font-style: italic;">// The old way:</span><br />test <span style="color: #66cc66;">{</span><br />    executable <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'/some/hardcoded/path/to/java'</span><br /><span style="color: #66cc66;">}</span><br /> </div>
</pre>
<p>Now that Gradle 6.7+ has <a onclick="_gaq.push(['_trackPageview', '/extlink/docs.gradle.org/current/userguide/toolchains.html']);" href="https://docs.gradle.org/current/userguide/toolchains.html">built-in toolchains support</a>, it's trivial to configure the <strong>compile</strong> toolchain:</p>
<pre>
<div class="groovy geshi" style="text-align: left"><br />java <span style="color: #66cc66;">{</span><br />    toolchain <span style="color: #66cc66;">{</span><br />        languageVersion <span style="color: #66cc66;">=</span> JavaLanguageVersion.<span style="color: #006600;">of</span><span style="color: #66cc66;">(</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">)</span><br />    <span style="color: #66cc66;">}</span><br /><span style="color: #66cc66;">}</span><br /> </div>
</pre>
<p>But what about tests? What if I want to <strong>test</strong> with a different JVM? It's a little more verbose:</p>
<pre>
<div class="groovy geshi" style="text-align: left"><br />test <span style="color: #66cc66;">{</span><br />    JavaToolchainService javaToolchainService <span style="color: #66cc66;">=</span> project.<span style="color: #006600;">getExtensions</span><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>.<span style="color: #006600;">getByType</span><span style="color: #66cc66;">(</span>JavaToolchainService.<a onclick="_gaq.push(['_trackPageview', '/extlink/www.google.de/search?q=site%3Agroovy.codehaus.org/%20class']);" href="http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20class"><span style="color: #000000; font-weight: bold;">class</span></a><span style="color: #66cc66;">)</span><br />    <a onclick="_gaq.push(['_trackPageview', '/extlink/www.google.de/search?q=site%3Agroovy.codehaus.org/%20def']);" href="http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20def"><span style="color: #000000; font-weight: bold;">def</span></a> launcher <span style="color: #66cc66;">=</span> javaToolchainService.<span style="color: #006600;">launcherFor</span><span style="color: #66cc66;">{</span><br />        languageVersion <span style="color: #66cc66;">=</span> JavaLanguageVersion.<span style="color: #006600;">of</span><span style="color: #66cc66;">(</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">)</span><br />    <span style="color: #66cc66;">}</span><br />    javaLauncher <span style="color: #66cc66;">=</span> launcher<br />    environment <span style="color: #ff0000;">'JAVA_HOME'</span>, launcher.<a onclick="_gaq.push(['_trackPageview', '/extlink/www.google.de/search?q=site%3Agroovy.codehaus.org/%20get']);" href="http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20get"><span style="color: #663399;">get</span></a><span style="color: #66cc66;">(</span><span style="color: #66cc66;">)</span>.<span style="color: #006600;">metadata</span>.<span style="color: #006600;">installationPath</span> <span style="color: #808080; font-style: italic;">//if your tests care about JAVA_HOME</span><br /><span style="color: #66cc66;">}</span><br /> </div>
</pre>
Akom's Tech Ruminationsnospam@example.com (Admin)
DevOps, Java, 2021-02-04T18:51:00Z//tech.akom.net/wfwcomment.php?cid=1480//tech.akom.net/rss.php?version=1.0&type=comments&cid=148Puppet recipe for setting up autossh via systemd
//tech.akom.net/archives/144-Puppet-recipe-for-setting-up-autossh-via-systemd.html
<p>I've always set up <strong><a onclick="_gaq.push(['_trackPageview', '/extlink/linux.die.net/man/1/autossh']);" href="https://linux.die.net/man/1/autossh">autossh</a></strong> in <strong>/etc/rc.local</strong>, but with CentOS 8 that doesn't work well (things start too early, etc). Luckily, there is a nicer way using systemd templates. Essentially, all you have to do is create one symlink and one config file per instance of autossh.</p>
<h2>Example:</h2>
<h3>Make a config file</h3>
<p><br/></p>
<p><strong>/etc/autossh/mything.conf:</strong></p>
<blockquote><pre>
OPTIONS=-N -M 20000 -R8888:1.2.3.4:8888 5.6.7.8
</pre></blockquote>
<p><br/></p>
<h3>Make a symlink</h3>
<blockquote><pre>
ln -s /usr/lib/systemd/system/autossh@.service /etc/systemd/system/autossh@mything.service
</pre></blockquote>
<p><br/></p>
<h3>Test</h3>
<blockquote><pre>
systemctl start autossh@mything.service
journalctl -xe
</pre></blockquote>
<p><br/></p>
<p>But it's better to automate:</p>
<h2>Puppet Recipe</h2>
<blockquote>
<div class="ruby geshi" style="text-align: left"><br /><br />define autossh<span style="color:#006600; font-weight:bold;">(</span><br />    <span style="color:#ff6633; font-weight:bold;">$service</span>=$name,<br />    <span style="color:#ff6633; font-weight:bold;">$args</span>,<br />  <span style="color:#006600; font-weight:bold;">)</span> <span style="color:#006600; font-weight:bold;">{</span><br /><br />    file <span style="color:#006600; font-weight:bold;">{</span><span style="color:#996600;">"/etc/systemd/system/autossh@${service}.service"</span>:<br />      <span style="color:#9966CC; font-weight:bold;">ensure</span> <span style="color:#006600; font-weight:bold;">=></span> link,<br />      target <span style="color:#006600; font-weight:bold;">=></span> <span style="color:#996600;">'/usr/lib/systemd/system/autossh@.service'</span><br />    <span style="color:#006600; font-weight:bold;">}</span> <span style="color:#006600; font-weight:bold;">-></span><br />    file <span style="color:#006600; font-weight:bold;">{</span><span style="color:#996600;">"/etc/autossh/${service}.conf"</span>:<br />      content <span style="color:#006600; font-weight:bold;">=></span> <span style="color:#996600;">"OPTIONS=${args}"</span><br />    <span style="color:#006600; font-weight:bold;">}</span> <span style="color:#006600; font-weight:bold;">-></span><br />    service <span style="color:#006600; font-weight:bold;">{</span><span style="color:#996600;">"autossh@${service}"</span>:<br />      <span style="color:#9966CC; font-weight:bold;">ensure</span> <span style="color:#006600; font-weight:bold;">=></span> running,<br />      enable <span style="color:#006600; font-weight:bold;">=></span> <span style="color:#0000FF; font-weight:bold;">true</span>,<br />    <span style="color:#006600; font-weight:bold;">}</span><br /><br /><span style="color:#006600; font-weight:bold;">}</span><br /><br /><span style="color:#008000; font-style:italic;"># and example usage - random port forwarding</span><br />autossh<span style="color:#006600; font-weight:bold;">{</span><span style="color:#996600;">'mything'</span>: args <span style="color:#006600; font-weight:bold;">=></span> <span style="color:#996600;">'-N  -M 20000 -R8888:1.2.3.4:8888 host1'</span><span style="color:#006600; font-weight:bold;">}</span><br />autossh<span style="color:#006600; font-weight:bold;">{</span><span style="color:#996600;">'mything2'</span>: args <span style="color:#006600; font-weight:bold;">=></span> <span style="color:#996600;">'-N  -M 20000 -R8888:1.2.3.4:8888 host2'</span><span style="color:#006600; font-weight:bold;">}</span><br /> </div>
</blockquote>
Akom's Tech Ruminationsnospam@example.com (Admin)
DevOps, Linux, 2020-11-19T21:33:00Z//tech.akom.net/wfwcomment.php?cid=1440//tech.akom.net/rss.php?version=1.0&type=comments&cid=144Using puppet to set Windows Computer Description
//tech.akom.net/archives/133-Using-puppet-to-set-Windows-Computer-Description.html
<p>My company's security department decided to assign Antivirus exclusion policies based on the value of the windows computer description. That means that I need to set computer descriptions ( <i>net config server /srvcomment:"new description"</i> ) to the same value on a whole bunch of windows machines. Doing that by hand is unappealing, and I already have puppet, so here is a simple solution:</p>
<p><br/></p>
<p><b>MY_CLASS/lib/facter/win_computer_description.rb</b></p>
<div class="ruby geshi" style="text-align: left"><br /><span style="color:#008000; font-style:italic;"># Gets computer decscription from 'net config server'</span><br />Facter.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">(</span><span style="color:#996600;">"win_computer_description"</span><span style="color:#006600; font-weight:bold;">)</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />  setcode <span style="color:#9966CC; font-weight:bold;">do</span><br />    output = <span style="color:#996600;">`net config server`</span><br />    output.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">(</span><span style="color:#006600; font-weight:bold;">/</span>\n<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">)</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">{</span><span style="color:#006600; font-weight:bold;">|</span>it<span style="color:#006600; font-weight:bold;">|</span> it.<span style="color:#9900CC;">start_with</span>?<span style="color:#006600; font-weight:bold;">(</span><span style="color:#996600;">'Server Comment'</span><span style="color:#006600; font-weight:bold;">)</span> <span style="color:#006600; font-weight:bold;">}</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">(</span><span style="color:#006600; font-weight:bold;">/</span>Server Comment<span style="color:#006600; font-weight:bold;">[</span>\s<span style="color:#006600; font-weight:bold;">]</span><span style="color:#006600; font-weight:bold;">*/</span>,<span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">)</span><br />  <span style="color:#9966CC; font-weight:bold;">end</span><br /><span style="color:#9966CC; font-weight:bold;">end</span><br /> </div>
<p><b>MY_CLASS/manifests/init.pp</b></p>
<div class="ruby geshi" style="text-align: left"><br /><span style="color:#9966CC; font-weight:bold;">class</span> MY_CLASS<span style="color:#006600; font-weight:bold;">(</span><br />  <span style="color:#ff6633; font-weight:bold;">$computer_description</span> = <span style="color:#996600;">'Some-new-description'</span>,<br /><span style="color:#006600; font-weight:bold;">)</span> <span style="color:#006600; font-weight:bold;">{</span><br />  <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">(</span>$win_computer_description != <span style="color:#ff6633; font-weight:bold;">$computer_description</span><span style="color:#006600; font-weight:bold;">)</span> <span style="color:#006600; font-weight:bold;">{</span><br />    <span style="color:#CC0066; font-weight:bold;">exec</span> <span style="color:#006600; font-weight:bold;">{</span> <span style="color:#996600;">'Set computer description'</span>:<br />      path <span style="color:#006600; font-weight:bold;">=></span> <span style="color:#006600; font-weight:bold;">[</span><span style="color:#996600;">"C:<span style="color:#000099;">\\</span>windows<span style="color:#000099;">\\</span>system32"</span><span style="color:#006600; font-weight:bold;">]</span>,<br />      command <span style="color:#006600; font-weight:bold;">=></span> <span style="color:#996600;">"net config server /SRVCOMMENT:<span style="color:#000099;">\"</span>${computer_description}<span style="color:#000099;">\"</span>"</span>,<br />    <span style="color:#006600; font-weight:bold;">}</span><br />  <span style="color:#006600; font-weight:bold;">}</span><br /><span style="color:#006600; font-weight:bold;">}</span><br /> </div>
Akom's Tech Ruminationsnospam@example.com (Admin)
DevOps, 2020-05-18T14:22:00Z//tech.akom.net/wfwcomment.php?cid=1330//tech.akom.net/rss.php?version=1.0&type=comments&cid=133Replacing Dishwasher Circulation Pump Bearings without buying a whole new unit
//tech.akom.net/archives/132-Replacing-Dishwasher-Circulation-Pump-Bearings-without-buying-a-whole-new-unit.html
<p>I have a DW80j3020us/AA Samsung dishwasher. It has been producing a loud noise for some time, and the noise kept getting worse. It was a matter of time before it either seized or melted the motor. The reason I know that the problem is with the <strong>circulation pump</strong> is that the noise is only audible while it's washing (circulating), not while draining or filling. Clearly the problem could be the motor (bearings) or some part of the impeller/grinder (less likely).</p>
<div class="serendipity_imageComment_right" style="width: 110px">
<div class="serendipity_imageComment_img"><a class="serendipity_image_link" href="//tech.akom.net/uploads/photos/gadgets/hacks/dishwasher-samsung-DW80j3020us.png"><!-- s9ymdb:252 --><img alt="" class="serendipity_image_right" src="//tech.akom.net/uploads/photos/gadgets/hacks/dishwasher-samsung-DW80j3020us.serendipityThumb.png" style="width:110px" /></a></div>
<div class="serendipity_imageComment_txt">Samsung Dishwasher</div>
</div>
<p>My options were:</p>
<ol>
<li>New dishwasher</li>
<li>New Circulation Pump motor DD31-00008A ($150)</li>
<li>Try to change the bearings (I've found nothing online about anyone doing this)</li>
</ol>
<p> </p>
<p>You can find lots of videos online on how to properly replace the circulation pump motor/assembly. I followed the guides for removing the internal components down to the food chopper, since the chopper is on the motor shaft. This takes about 20 minutes. After that, it was easy - all I had to do was pull the bottom cover off and remove 4 screws to get the motor out. Then a magical thing happened.</p>
<a class="block_level" href="//tech.akom.net/archives/132-Replacing-Dishwasher-Circulation-Pump-Bearings-without-buying-a-whole-new-unit.html#extended">Continue reading "Replacing Dishwasher Circulation Pump Bearings without buying a whole new unit"</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
Low Tech Hacks, 2019-04-26T12:21:00Z//tech.akom.net/wfwcomment.php?cid=1326//tech.akom.net/rss.php?version=1.0&type=comments&cid=132Android doing Optimizing app 1 of 1 on every boot
//tech.akom.net/archives/131-Android-doing-Optimizing-app-1-of-1-on-every-boot.html
<p>The message appears for a good 15 minutes every time my phone boots up. I followed the usual suggestions (wipe cache partition), and that didn't help</p>
<p><br/><br/></p>
<p>Figuring out what app is causing this issue is the hard part. I did it with logcat (I happened to have the Android Studio installed, so logcat is a tab, and it displays the log automatically as the plugged-in phone is booting). You don't need the whole thing, just the adb tools so you can run "adb logcat"</p>
<p><br/><br/>
At the moment when the message appears, I saw this in the log:</p>
<blockquote>05-04 14:48:10.388 1230-1230/? I/PackageManager.DexOptimizer: Running dexopt (dex2oat) on: /data/app/com.alltrails.alltrails-2/base.apk pkg=com.alltrails.alltrails isa=arm64 vmSafeMode=false debuggable=false oatDir = /data/app/com.alltrails.alltrails-2/oat
</blockquote>
<p>Well, now I know what to uninstall. I didn't need Alltrails anyway.</p>
Akom's Tech Ruminationsnospam@example.com (Admin)
Android, 2018-05-04T21:48:00Z//tech.akom.net/wfwcomment.php?cid=1310//tech.akom.net/rss.php?version=1.0&type=comments&cid=131Disabling Windows Recycle Bin with Puppet on all versions of Windows
//tech.akom.net/archives/130-Disabling-Windows-Recycle-Bin-with-Puppet-on-all-versions-of-Windows.html
<p>And when I say "All versions of Windows" I mean that I tested it on Server 2008, 2012 and 2016.</p>
<p><br/><br/></p>
<p>This was oddly hard to figure out, and most tutorials either apply to only one version of windows or to outdated tools. The best way to do this that I found was using Local Group Policy. Now, how to automate this? The puppet local_group_policy module didn't work at all when I tried it (and has not been updated since 2014). The proper way to do this is of course with a Domain-based Group Policy, but my machines are not members of a domain.</p>
<p><br/><br/>
Fortunately, there is a new Microsoft tool called LGPO that allows for some degree of command-line control of the Local Group Policy. Download "LGPO.exe" <a onclick="_gaq.push(['_trackPageview', '/extlink/www.microsoft.com/en-us/download/details.aspx?id=55319']);" href="https://www.microsoft.com/en-us/download/details.aspx?id=55319">here</a>.
<br/><br/></p>
<h3>First, let's make a reusable policy text file that we can import on all machines:</h3>
<ol>
<li>take a vanilla Windows machine that hasn't had any Group Policy customization, and use lgpo.exe to export the policy: "<strong>lgpo.exe /v /parse /u c:\windows\system32\GroupPolicy\User\Registry.pol</strong>" (at least that was appropriate in my case). You should get more or less empty output. </li>
<li>Then use the Local Group Policy Editor to change "Do not move deleted files to the Recycle bin" (under User Configuration -> Administrative Tools -> All Settings) to "Enabled"</li>
<li>Repeat step 1. You should see this one setting that you changed in the output. Redirect output to a file, this will be our text file</li>
<li>You can test that importing this file will change the setting: "<strong>lgpo /r myfile.txt</strong>". (Change the setting back first, run this, then re-open the Local Group Policy Editor to see the change)
</ol>
<h3>Now, we can set up puppet:</h3>
<a class="block_level" href="//tech.akom.net/archives/130-Disabling-Windows-Recycle-Bin-with-Puppet-on-all-versions-of-Windows.html#extended">Continue reading "Disabling Windows Recycle Bin with Puppet on all versions of Windows"</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
DevOps, 2018-03-22T18:19:00Z//tech.akom.net/wfwcomment.php?cid=1300//tech.akom.net/rss.php?version=1.0&type=comments&cid=130Jenkins Pipeline: parallel and waitUntil, waiting until the other branch finishes
//tech.akom.net/archives/128-Jenkins-Pipeline-parallel-and-waitUntil,-waiting-until-the-other-branch-finishes.html
<p>Let's say that for the sake of speed, you are running two slow things in parallel, but you want one to wait for the other.</p>
<blockquote>
<div class="groovy geshi" style="text-align: left"><br />parallel one: <span style="color: #66cc66;">{</span><br />    node <span style="color: #66cc66;">{</span><br />        sh <span style="color: #ff0000;">"sleep 15"</span><br />    <span style="color: #66cc66;">}</span><br /><span style="color: #66cc66;">}</span>, two: <span style="color: #66cc66;">{</span><br />    node <span style="color: #66cc66;">{</span><br />        <span style="color: #808080; font-style: italic;">//slow part:</span><br />        sh <span style="color: #ff0000;">"sleep 10"</span>  <br /><br />        <span style="color: #808080; font-style: italic;">// now do something that needs "one" to finish.  There is a good chance that this will run too soon...</span><br />        sh <span style="color: #ff0000;">'wget http://something'</span> <span style="color: #808080; font-style: italic;">//for example</span><br />    <span style="color: #66cc66;">}</span><br /><span style="color: #66cc66;">}</span><br /> </div>
</blockquote>
<p>
The problem, obviously, is that you can't be sure that the wget will run after part one finishes. (Let's assume that part one creates the file).
</p>
<a class="block_level" href="//tech.akom.net/archives/128-Jenkins-Pipeline-parallel-and-waitUntil,-waiting-until-the-other-branch-finishes.html#extended">Continue reading "Jenkins Pipeline: parallel and waitUntil, waiting until the other branch finishes"</a>
Akom's Tech Ruminationsnospam@example.com (Admin)
DevOps, 2018-01-22T19:21:00Z//tech.akom.net/wfwcomment.php?cid=1281//tech.akom.net/rss.php?version=1.0&type=comments&cid=128