Akom's Tech Ruminations

Various tech outbursts - code and solutions to practical problems

Linux Linux: Chrome Steals Focus on click despite mouse-focus mode

Posted by Admin • Thursday, February 29. 2024 • Category: Linux

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:

The terminal is not raised on click

However, Google Chrome does not honor this window manager setting.  Any click in a chrome window causes it to be raised.

It turns out that, with XFCE's xfwm, there is an additional setting to turn off in gconf:

XFCE Settings
Turning off raise_with_any_button stops Chrome from stealing focus

Linux Upgrading a non-LTS Ubuntu installation after EOL

Posted by Admin • Thursday, September 1. 2022 • Category: Linux

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:

$ do-release-upgrade

Please install all available updates for your release before upgrading.

Yet if you atempt to install updates, that fails:

$ apt dist-upgrade -y

Err:5 http://archive.ubuntu.com/ubuntu impish Release
  404 Not Found [IP: 2001:67c:1562::18 80]

...

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.

Continue reading "Upgrading a non-LTS Ubuntu installation after EOL"

Linux Upgrading a non-LTS Ubuntu installation after EOL

Posted by Admin • Thursday, September 1. 2022 • Category: Linux

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:

$ do-release-upgrade

Please install all available updates for your release before upgrading.

Yet if you atempt to install updates, that fails:

$ apt dist-upgrade -y

Err:5 http://archive.ubuntu.com/ubuntu impish Release
  404 Not Found [IP: 2001:67c:1562::18 80]

...

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.

Continue reading "Upgrading a non-LTS Ubuntu installation after EOL"

Linux Preserving a Static Copy of Atlassian Jira (and Confluence) as a Jekyll Site

Posted by Admin • Monday, October 25. 2021 • Category: Linux

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.

Going Static

Of course, I can use

wget --mirror

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).

Instead, I'm going to convert the content to markdown 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).

Making this Happen

I wrote a project to help automate this process fully via the Jira API: https://github.com/akomakom/jira-to-jekyll/.

The basic goal is to do what I outlined above. There is a comprehensive README that explains the process.

Continue reading "Preserving a Static Copy of Atlassian Jira (and Confluence) as a Jekyll Site"

Linux Bootstrapping S3/CloudFront with LetsEncrypt

Posted by Admin • Thursday, August 5. 2021 • Category: DevOps, Linux

Let's assume that you want to do the following:

  1. Host the contents of your S3 bucket via YOUR.DOMAIN.COM
  2. Use CloudFront
  3. Use a LetsEncrypt cert

"What's the problem?", you may ask. There are plenty of tutorials for this stuff. Not exactly. A CloudFront Distribution will not let you add a CNAME 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.

Solution

The easiest solution is to initially generate your SSL cert manually. You can then use something like certbot-s3front to auto-renew.

Details

Continue reading "Bootstrapping S3/CloudFront with LetsEncrypt"

Linux PowerShell on Linux doesn't find modules when run through Puppet

Posted by Admin • Thursday, March 11. 2021 • Category: DevOps, Linux

I'm running PowerShell on Linux for the sake of using PowerCLI. An interesting thing happens: when pwsh is run interactively, in a terminal, the following works fine when PowerCLI is already installed:

pwsh -c 'Get-InstalledModule VMware.PowerCLI'

When puppet runs it - it doesn't find the module:

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]

After some experimentation, I narrowed it down to a single environment variable missing when puppet executes the command: HOME. Set HOME, and powershell will find modules. That gets us the following recipe:

  $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}"]
  }

Linux Puppet recipe for setting up autossh via systemd

Posted by Admin • Thursday, November 19. 2020 • Category: DevOps, Linux

I've always set up autossh in /etc/rc.local, 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.

Example:

Make a config file


/etc/autossh/mything.conf:

OPTIONS=-N  -M 20000 -R8888:1.2.3.4:8888 5.6.7.8


Make a symlink

ln -s /usr/lib/systemd/system/[email protected] /etc/systemd/system/[email protected]


Test

systemctl start [email protected]
journalctl -xe


But it's better to automate:

Puppet Recipe



define autossh(
    $service=$name,
    $args,
  ) {

    file {"/etc/systemd/system/autossh@${service}.service":
      ensure => link,
      target => '/usr/lib/systemd/system/[email protected]'
    } ->
    file {"/etc/autossh/${service}.conf":
      content => "OPTIONS=${args}"
    } ->
    service {"autossh@${service}":
      ensure => running,
      enable => true,
    }

}

# and example usage - random port forwarding
autossh{'mything': args => '-N  -M 20000 -R8888:1.2.3.4:8888 host1'}
autossh{'mything2': args => '-N  -M 20000 -R8888:1.2.3.4:8888 host2'}
 

Linux OCR on a large PDF using tesseract and pdftk

Posted by Admin • Thursday, January 19. 2017 • Category: Linux

This turned out to be harder than I thought. I found a large (50MB) PDF with about 50 pages, and none of the tesseract GUI's seemed to be able to handle it without crashing. The solution is to convert the PDF to TIFF so that command-line tesseract could handle it directly, but now ImageMagick couldn't handle that conversion as it was running out of memory (even with the limit settings). So the only option was to reduce the load on all the moving parts by splitting the PDF into pages.



Even after splitting the PDF and running each page through the PDF->TIFF->Tesseract->PDF chain I was still having issues:

Error in pixReadFromTiffStream: spp not in set {1,3,4}

Huh? So it turns out that sometimes you may wind up with an alpha channel in your TIFF and tesseract can't handle this. There is a solution, fortunately. So finally, I put all of these steps together into a script:

Continue reading "OCR on a large PDF using tesseract and pdftk"

Java Linux Running Jenkins Swarm client as a service via Upstart

Posted by Admin • Wednesday, December 21. 2016 • Category: DevOps, Java, Linux

This turned out to be fairly simple, with only one gotcha: do not follow the how-to's out there that tell you to use expect fork. The process doesn't technically fork. When I had that setting enabled, upstart commands would hang under very specific but repeatable conditions (if the process was killed externally).



So, here is my upstart conf file:

Continue reading "Running Jenkins Swarm client as a service via Upstart"

Linux Docker: Automatically remove containers that have been running too long

Posted by Admin • Thursday, October 20. 2016 • Category: DevOps, Linux

Why Because my Jenkins setup sometimes starts containers and forgets about them. Either it thinks it failed to start one, or the container itself has trouble starting. Either way, I'm left with containers that are running, trying to connect to Jenkins in vain, forever. The proper way to fix this is probably to have the containers timeout at some point, but that mechanism is broken.



Anyway, the fix I have is a true hack: find containers that have been up more than 2 days and kill them. None of our jobs should run for more than about a day, so this is a safe limit. Here is a bash script to do this:

Continue reading "Docker: Automatically remove containers that have been running too long"

Linux Jenkins command line ssh: Host key verification failed despite ssh-agent

Posted by Admin • Thursday, August 4. 2016 • Category: DevOps, Linux

After hours of "Why does it work locally but not in Jenkins", this error boils down to StrictHostKeyChecking... In other words, since the job runs as a user on a random slave, and this user most likely doesn't have a known hosts file with an entry for the target system, this fails rather cryptically. You think that the user's keys don't work, but that's not the problem.



The whole setup boils down to :

  1. Install ssh-agent plugin
  2. Configure credentials with a valid ssh key for your target
  3. Enable ssh-agent with that credential entry in your job config
  4. Add StrictHostKeyChecking=no to whatever ssh command you are using. Some examples:
    • GIT:
      export GIT_SSH_COMMAND="ssh -oStrictHostKeyChecking=no"
    • SSH:
      ssh -oStrictHostKeyChecking=no ....

Linux Ubuntu 18.04: Handling Dell Latitude laptop dock events to reconfigure displays

Posted by Admin • Tuesday, April 12. 2016 • Category: Linux

Couldn't find any good solutions out there. I have a Dell Latitutde E6410 running Ubuntu 15.10 (Update: these instructions worked fine on a Precision 7510 running Ubuntu 18.04) with XFCE (no Gnome or KDE). I use a physical docking station that allows me to use two external monitors. Ubuntu doesn't seem to understand that if these external monitors vanish, it should switch to the monitor that remains (built-in LCD), and vice versa, so I have to automate it myself. (Ubuntu 18.04 does in fact notice monitor changes, but insists on arranging the monitors in the wrong order, so this solution is still necessary)



The trick to doing this reliably is finding a udev device you can monitor using udev rules and perform actions when it appears or disappears. This would be a device that is 100% absent when undocked and is 100% present when docked. There is no kernel built-in dock device on these laptops. In order to watch what devices are coming and going, I used the following command (as root):

udevadm -p -u
udevadm monitor # in Ubuntu 18.x

Run that in a terminal, undock/dock and see what it says. You may want to save the output to a file, it's a lot. In my case, there was nothing definitive. There is "drm" device which sounds promising, but there is no good way to tell a "remove" apart from an "add" event. Ultimately, I settled on the numlock event. Why? Because it is specific to my external USB keyboard (Microsoft 4000) that is always plugged into the docking station. The internal laptop keyboard is unlikely to generate that event, and the full-size keyboard always produces one. Here is the relevant remove event:

Continue reading "Ubuntu 18.04: Handling Dell Latitude laptop dock events to reconfigure displays"

Linux Migrating Maven Jenkins jobs to FreeStyleJobs due to JDK 1.6 incompatibility

Posted by Admin • Tuesday, March 15. 2016 • Category: DevOps, Linux
Soon after Jenkins 1.609.1 support for JDK 1.6 was dropped altogether. This means that you can run jobs with whatever JDK you want as long as you are not using the Maven job type. Maven jobs require JDK 1.7 or higher (actually they run on whatever version the master is using, ignoring the JDK setting in the job configuration). This is a big deal for a shop that does extensive cross-platform testing. There are two solutions:
  1. Convert hundreds (in our case) of Maven jobs to regular (freestyle) jobs. There appears to be no simple script to do this, so I wrote one here
  2. Use maven toolchains to compile and test with a different JDK. Although converting jobs is a viable option that requires no additional setup, using toolchains may be preferred in some cases. For one thing, Jenkins offers the "Perform Release" button on maven jobs, something that is difficult to emulate in freestyle jobs.
Regarding option 1:

Initially I tried doing this using JobDSL, but that is way too time-consuming and hard to maintain. The simplest approach is to take the job XML, make minimal changes and push it back. Except that it's not that simple - you can't change the job type. You need to create new jobs, which is why I wrote a script to do all of the above. It will move the pre/post builders to the main builder list, and create a new maven job step in between. The rest is left unchanged and most of the XML is naturally valid for this version of jenkins/plugins since it's pulled from the live Jenkins.

Java Linux Jenkins: Bulk editing jobs to remove a trigger

Posted by Admin • Thursday, December 17. 2015 • Category: DevOps, Java, Linux
I have about 200 jobs that have the HudsonStartupTrigger (this is a plugin) turned on. This makes all of them run every time the master is restarted, causing the build queue to go crazy. I don't know why people turned this on in so many jobs (probably blindly copying jobs) over the years, but I'd like it gone. I don't want to restart the master or uninstall the plugin.

Here is a script console snippet to do this (can be adapted to remove other triggers easily). This does not do folders, if you're using that plugin.


import hudson.triggers.*
 
for (item in Hudson.instance.items) {
    name = item.name
       
  if (item instanceof AbstractProject) {
    triggers = ((AbstractProject)item).getTriggers()
   
    triggers.each{descriptor, trigger ->
      if (descriptor instanceof org.jvnet.hudson.plugins.triggers.startup.HudsonStartupTrigger$HudsonStartupDescriptor) {
            out.println("Removing startup trigger from job " + name)
        ((AbstractProject)item).removeTrigger(descriptor)
      }
    }
  }
}
 

Linux Suse11 cannot mount NFS share

Posted by Admin • Wednesday, December 9. 2015 • Category: DevOps, Linux
This is a recent issue on Suse 11.3. I have hundreds of machines mounting the same share fine - Centos, RedHat, even AIX.
mount -v /mountpoint                                                                                                               
mount.nfs: timeout set for Wed Dec  9 11:09:27 2015
mount.nfs: trying text-based options 'rsize=8192,wsize=8192,intr,hard,addr=X.X.X.X'
mount.nfs: prog 100003, trying vers=3, prot=6
mount.nfs: portmap query retrying: RPC: Program not registered
mount.nfs: prog 100003, trying vers=3, prot=17
mount.nfs: portmap query failed: RPC: Program not registered
mount.nfs: prog 100003, trying vers=2, prot=6
mount.nfs: portmap query retrying: RPC: Program not registered
mount.nfs: prog 100003, trying vers=2, prot=17
mount.nfs: portmap query failed: RPC: Program not registered
mount.nfs: prog 100003, trying vers=2, prot=6
mount.nfs: portmap query retrying: RPC: Program not registered
mount.nfs: prog 100003, trying vers=2, prot=17
mount.nfs: portmap query failed: RPC: Program not registered
mount.nfs: requested NFS version or transport protocol is not supported


Suprisingly, the problem is exactly what it says it is. Adding ",vers=4" to the options takes care of the problem. Hope this saves you time.