Jimmie Lightner

    • About
    • Privacy Policy
    • Shady Merchants
Illustration of a bird flying.
  • Writing systemd User Timers

    Why am I writing this? I omitted installing the cron package on my Linux box since systemd provides a timers function. Who needs two packages to do one thing? Heh… for a moment I thought maybe I do because some of the documentation out there is a little confusing. Or I’m just dumb. Or both. 😛 So here’s a quick and dirty mash up of the Arch Linux wiki for User units and systemd Timers (because I want this to run when my user is logged in!).

    Timers require two files – the service file and the timer file. I’m pretty sure you can call them whatever you want, including different names since the timer config references the service by its name. For simplicity, I named mine the same thing. User unit files live in the .config directory for systemd within your home dir. Here’s mine:

    ls -l /home/jimmie/.config/systemd/user
    
    drwxr-xr-x 2 jimmie jimmie 4.0K Jan 16 16:51 default.target.wants
    drwxr-xr-x 2 jimmie jimmie 4.0K Jan  4 09:03 sockets.target.wants
    drwxr-xr-x 2 jimmie jimmie 4.0K Jan 17 08:53 timers.target.wants
    -rw-r--r-- 1 jimmie jimmie  179 Jan 16 16:43 update-blocklists.service
    -rw-r--r-- 1 jimmie jimmie  142 Jan 16 16:45 update-blocklists.timer
    

    The timer unit file (update-blocklists.timer) just tells systemd when to do a thing. This unit executes every 180 minutes.

    [Unit]
    Description=Run "Update Blocklists" every 180 minutes
    
    [Timer]
    OnBootSec=3min
    OnUnitActiveSec=180min
    
    [Install]
    WantedBy=timers.target
    

    The service unit file (update-blocklists.service) tells systemd what to do.

    [Unit]
    Description=Update Blocklists
    After=network.target
    
    [Service]
    Type=oneshot
    WorkingDirectory=%h
    ExecStart=%h/Scripts/update-blocklists.sh
    
    [Install]
    WantedBy=default.target
    

    The main parts here give some basic dependencies – execute only after the network is up, do the work in my homedir, and the location of the script to execute. I’m not going to post the contents of the script because you can go find it yourself here.

    Once you have the unit files in place (and the script you want to execute, too) you can enable this thing. Trigger a daemon-reload first, then make sure you enter BOTH the service and the timer units on the line or your timer will not work. I know because I tried with one and then the other before using both. When I came back to the machine this morning nothing had updated since I manually triggered the service.

    systemctl --user daemon-reload
    
    systemctl --user enable --now update-blocklists.service update-blocklists.timer

    Now you can list your user timers:

    systemctl --user list-timers --all
    NEXT                            LEFT LAST                         PASSED UNIT                    ACTIVATES                
    Wed 2024-01-17 11:53:51 EST 2h 59min Wed 2024-01-17 08:53:51 EST 25s ago update-blocklists.timer update-blocklists.service
    
    1 timers listed.
    

    Tada. Easy, right? Lastly, if you need to peep at the logs for your timer, journalctl can filter those! Check it out:

    journalctl --user-unit update-blocklists

    Happy Hump Day!

    January 17, 2024
  • Parallels Desktop VM Isolation

    I’m fascinated by the logic here. Why is this experience not inverted? Why is the user only prompted for confirmation when ENABLING isolation (because: why would I want said VM to be able to read the contents of my clipboard?) but not when disabling it? Isn’t the isolation the entire point of the VM? 🤔

    January 10, 2024
  • Holiday Time Off Shenanigans

    What do you do for time off? Home improvement? Technical skilling? Visiting family? Hang out with friends? I’m off work until January 3rd! I need some things to keep myself busy:

    • Finish the trim in our kitchen
    • Set up a live-stream of the office reef tank
    • Figure out mail delivery for the lab
    • Look at server colocation options
    • Hang out with friends and family
    • Renew my certifications (yuck)

    Seems like enough for a while. It’s a rough work in progress, but check out https://www.communityreeftank.com

    December 15, 2023
  • A&M Landscaping and Lawncare

    While hopping off a work call just now I happened to notice the sound of a mower outside. Odd. When I peered out the window, the neighbor’s yard was being mowed. VERY ODD. Especially today, on the 28th of November. It’s currently 29° Fahrenheit (that’s -1.67° Celsius for you metric weirdos) and the ground felt pretty well frozen just a bit ago when I took the dog out to potty.

    What the hell? If I was paying a REPUTABLE service to care for my lawn, I’d hope they wouldn’t rip me off with “final mow” on a day when they’d actually do more harm to grass than good. Then again, A&M are the same folks who damaged and put ruts in my yard while trying to park their truck to mow next door – and argued with me about “rights of way” and easements when I confronted them about it. 🤣 (See: passive aggressive red reflectors)

    Another local company doing shady, weird shit! 🤷🏼‍♂️

    November 28, 2023
  • Ozotech Poseidon Racket

    It’s been a long time since I’ve given any thought to the ozone setup I run on the office tank. I was contemplating updating my 15+ year old (but still very much working!) AquaMedic 200 mg Ozone Generator with one of the Ozotech Poseidon units until I read on the Ozotech website they suggest replacing their corona discharge cells YEARLY?

    This seems like a HUGE racket to me – I’ve never had to do any maintenance beyond a simple flush of my AquaMedic unit. Do these Ozotech cells really go bad so quickly, or is this just an abundance of caution type thing? If this is true, not only will you pay nearly $300 for the unit, but another $100 / year for the privilege of changing out the CD cell! LOL NO THANKS!

    I asked this very question to BRS weeks ago, but they’ve yet to acknowledge or publish it. (gee, I wonder why?) I think I’ll be staying away from these! 😉

    I need a fellow fish friend in the EU to buy one of the new AquaMedic units and ship it to me! I’ll happily send you trashy American goodies and junk food in exchange!

    November 11, 2023
  • The Purge

    I’m done being idly complacent while shitty companies harvest or sell my data for their own benefit and profit. Let’s start with the largest offender: Google, I’m looking squarely at you. I’ve been a long-time gmail user – since the old days when an invitation was required to join. The service used to be the best there was. Their spam filter used to be top notch. The user experience was great. However, today, these things are no longer true. The one reason I stuck with Google all this time is now gone.

    For the past several months I’ve been migrating all of my online accounts that were linked to my gmail to other platforms or to self-hosted mail. It’s been tedious, but today, that transition is done! I’ve been waiting for this moment for what seems like oh so long. 🎉

    This is such a good feeling! One more click after ticking the box to acknowledge and…

    Good riddance, scourge of the net! I can finally enable the Little Snitch rules to block all Google IP space registered to their ASNs! The web is now a slightly better place. 🥳

    October 13, 2023
  • Cleaning Azure File Shares with Azure Functions

    One of the complaints I have about using FSLogix to store AVD User Profiles on Azure File Shares is that there’s no native way to clean up the stale / unneeded VHDs once users move on. If you search the web, you’ll come across some curiously misleading examples that discuss setting up an Azure Function to do this. I’ll share what actually worked for me, as the others did not!

    Requirements: I’d like to delete all VHDs that haven’t been modified in the last 90 days.

    Solution: I created a consumption (serverless) Azure Function App with a PowerShell core runtime.

    The official Microsoft documentation states that newly created Functions App projects have the necessary Az PowerShell modules by default, but that was not my experience. To enable the Functions Service to install / maintain the required modules, edit the requirements.psd1 file to look like so:

    @{
        'Az' = '10.*'
        'Az.Storage' = '5.*'
    }

    Once that’s done, you can create your Function. I created a basic timer function that runs daily at 30 minutes past midnight. To do that, my function.json file looks like:

    {
      "bindings": [
        {
          "name": "Timer",
          "type": "timerTrigger",
          "direction": "in",
          "schedule": "0 30 0 * * *"
        }
      ]
    }

    The last piece of this is the run.ps1 file that actually gets executed:

    $fileShare = "share"
    $storageAccountName = "simplefilesharestorage"
    $storageAccountKey = "YqoRK/En6bMJl+xWi7PVyDyTToOt/bwoGjaSZ/4adgyRRBvUW9K+HQBicyt2rVHRFUlrsSr4F/gg+AStOiapWg=="
    
    $filelist = Get-AzStorageFile -ShareName $fileShare -Context (New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey)
    
    foreach ($file in $filelist | Where-Object {$_.lastModified -lt ((Get-Date).AddDays(-90))})
        {
            $removefile = $file.name
            if ($removefile -ne $null)
            {
                Write-Host "Removing file $removefile"
                Remove-AzStorageFile -ShareName $fileShare -Path $removefile -Context (New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey)
    
            }
        }

    Obviously you’ll need to update the variables above with values relevant to your deployment. A quick way to test that things are working is to modify the Get-Date to AddSeconds instead of Days, upload a random file to your share, then kick off a Test Run.

    The first run will take a while as the Functions service installs the required dependencies. You may have to fiddle with a stop / start to coax this along, but it will eventually work!

    October 6, 2023
  • Credit Card “Convenience” Fees

    You ever have those nights where you just don’t feel like cooking even though you have plenty of food in the fridge? Yeah, that was us last night. We ended up heading out to Gallo’s Tap Room for dinner.

    The place wasn’t crowded despite it being 6pm. The patio had plenty of spots, so we sat with our backs to the sun and enjoyed some beer, wings, and a sandwich. When it was time to settle up, we even sprang for dessert to go. (Avoid it. For $8, that slice of cheesecake should be at least twice the size!)

    It was all good until the check came. That’s when I noticed a “convenience fee” was added to our bill with no warning. This is the second restaurant we’ve been to that has started doing this. It’s an ugly practice that will drive me to stop going to restaurants who do so. They’d be better off to bake that nonsense into the cost of the food – I can’t be the only one who thinks “guess that’s coming off the tip.” It’s not fair to the wait staff. Guarantee the management doesn’t care, though.

    When this happens from now on I’m using the card that will be most expensive for the establishment to accept, and then avoiding that merchant in the future! 😽 GFC!

    Now that I think about it, I’mma start a page to publish all of the places who practice this shit. Posted here

    If you want to contribute, drop me an email!

    October 2, 2023
  • Meet Koda

    We adopted a baby pupper! He’s something akin to a murder floof, or so the scary things you’d read about on the interwebz or hear about on TikTok would have you believe. Maligator, vicious, bitey demon, fur missile, etc. Some of those may be partly true. 😅 He’s got a little mouth full of razor sharp puppy teeth, but he knows it. He’s incredibly gentle with us (except when it comes to my toes … weirdo. ) but not so much with toys or sticks. I’ve never watched a puppy shred a stick in a sitting before.

    He’s still very young – 7 weeks and 5 days, but he’s learning fast! We’ve started crate training and aside from a mistake that was entirely my fault, he’s gone potty outside every single time!

    I’m excited for everyone to meet him! 🐕

    September 4, 2023
  • New Keyboard

    Earlier this week we had to get my partner a new keyboard and mouse setup – so we hopped across the road to Microcenter together. I should have known better. I can’t step foot in that store without getting something… and of course it’s something I don’t really need. I ended up with an ROG Strix Scope II keyboard and woah, this thing is badass! I was merely poking at the keyboards as I passed, but I fell in love with the sound and feel of the keys on this one. Enough to buy it.

    Having had it several days I swear I can type faster with it than on any other keyboard I’ve had. The only thing I’d wish to be different is to have a bit of an ergonomic curve, but otherwise I’d say it’s perfect.

    I’m fascinated by the fact that it can be paired with up to 3 different computers / bluetooth devices and flip between them. That’s just overboard crazy… or is it? There’s also a 2.4ghz USB wireless dongle or a USB C wired connection.

    I remember when my coworker was looking for a keyboard with backlighting… I thought it was a gimmick. It’s actually pretty neat and kind of useful (especially on a black keyboard used in a room with barely any ambient light besides the glow of the fish tank behind me). I ended up setting the lighting pretty dim – just enough to be able to make out the letters if needed but with a quick color change that responds to keypresses. It’s over the top, but it’s fun and makes me smile.

    I think it’s a far better experience than something like the Apple Magic Keyboard or Microsoft Comfort Keyboard which are both just flat and boring. There’s something to the tactile feedback and feel of mechanical switches – if nothing more than just nostalgia of keyboards past.

    Now I just have to get used to this 96% layout…

    July 30, 2023
←Previous Page
1 2 3 4 5 6
Next Page→

Jimmie Lightner