Persistent Windows SMB mount in Raspbian via CIFS

I’m using Navidrome in CasaOS on a Pi for music right now and I like it quite a bit. The one thing irking me was that the network storage mounts you can define within CasaOS (Files > Location > Connect network storage) don’t persist. At least they don’t for me – every reboot or update and they’re gone.

I’ve gotten around this by creating a persistent mount within Raspbian utilizing CIFS.

SSH into your Pi, and go ahead and

to avoid having to sudo every line you input. First, make sure cifs-utils are installed (they should be, but still):

Now create a credentials file for your mount to access using nano:

Populate the credfile with the credentials necessary to access your Windows share:

Save it, then set the appropriate permissions to keep it safe from prying eyes:

Create a mount directory on your Pi to link the share to:

Now open fstab:

Add your mount to the bottom of the file, changing the first path to the Windows share and the second to the mount path you created previously:

Finally, reload the daemon:

And mount the share using the details you defined in fstab:

To confirm, cd to the share and confirm you can see the contents.

Leaving YouTube, or What’s Happening to The Intertoobs

Watching the MatPat leaving YouTube video is an interesting thing. The constant repositioning from “I’m going to miss how personal this is and my connection with all of you” to “we’ve achieved penetration in four verticals on YouTube” creates a dissonance that I can’t unsee.

The internet, in its infancy, was supposed to set us free. It was supposed to put information at our fingertips, make life easier, make us more efficient, more capable, happier. People started websites, created and joined listservs, got involved in usenet, and eventually posted to YouTube and streamed on various platforms because they had an interest, a passion, and they wanted to share. Personally, I created my own sites on various topics and inherited and hosted a listserv dedicated to an obscure band for many years just because I wanted to engage with other people who shared my interests, and I wanted to contribute something.

But once capitalism got over its initial trepidation of the internet and began to get its arms around it, everything changed. We moved rapidly into the web being one giant shopping mall. From there it evolved into us, the users, being the product, our data collected in a million ways. And I thought that was bad – the digital us being bought and sold and harvested – but the worst was yet to come, because its next evolution was to convince us to cut out the middlemen and become our own pimps. And so we do – hustling ourselves. Hustling for money. Hustling for clout. Hustling for virtue. Hustling for imaginary internet points.

We were no longer posting because we wanted to share or contribute – We were posting strictly for some kind of digital or material gain. Now platforms are filled with fakers. Skaters who fake skating. Singers who fake singing. Mechanics who don’t really repair. Craftsmen who can’t really build anything. Rugged outdoorsfolks who lie about the comfortable home they go to once the cameras are off. Musclebound fitness gurus slap full of tren and lying about it, hawking pills and powders filled with sawdust and broken dreams.

We’re all doing it on some scale. Social media is awash with people constantly signaling goodness and virtue they don’t exhibit with their actions in meatspace. We’ve replaced judging people for their actions with judging them for their proclamations. When someone posts a profound position, no one asks them what they’re actually doing in real life to support that position – they just celebrate the words and reply “Oh, me too! I’m a good person too!” In the meantime everything in Actual Reality gets worse, and no one seems to understand why. They’re all saying the right things, after all. They’re posting the black squares. They’re encircling their profile pictures with the correct slogans. They’re shit-talking all the right people. Perhaps if we all just post a little bit harder…

And The Hustle has now bled into reality. What are YOU doing that can be monetized? Why are you wasting your time doing things you like for free? Have you considered dropshipping, or trying to create viral videos? Don’t write a whole song – you only need about 40 seconds for a TikTok. Why would you spend any time painting a picture you can’t sell, or playing a video game you’re not streaming and providing color commentary over? You know if you don’t hustle you’re going to get left behind right? I can’t believe you haven’t started a SubStack yet. What are you waiting for?

I’m reminded of the time before the last housing crash, when capitalism was all-in on convincing us that the path to happiness was accumulation. Sad? You don’t have enough stuff! You need a McMansion, a couple of gigantic SUVs, a television the size of a mini-theater in every room! Not only will gross accumulation make you happy, it’ll signal to everyone else just how successful you are! Except we know now, in hindsight, after millions of people had to walk away from mortgages and car notes and into bankruptcy, just how big a lie that was. No matter – the folks who pushed it profited, and that’s what mattered.

Those of us who were early adopters of and involved in the development of the internet thought it would help free the world, and though it sounds naive now you can’t blame us for thinking so. For awhile there it was a wild, untamed, magical place. Those days are long gone and now, rather than free us, the internet has introduced new, even heavier chains.

I’m not in MatPat’s head, so I wonder what it’s like. He’s an internet success story. His net worth is currently estimated at $30 million, and he’s not even 40 years old. So why leave YouTube? And why cry about it? Per the parameters of the rest of the folks hustling online, MatPat is a indisputable Winner. He achieved all they desperately strive for and more. But I’m reminded of musicians of old who would make it big and subsequently become miserable. The music made them rich. It made them famous. But they didn’t become musicians to be rich and famous – they became musicians because they had something they wanted to share. Once that passion became a job it was no longer about sharing. It was about numbers, bottom lines, “verticals.” The joy of making music replaced with the drudgery of making product. And this is what the internet is now doing to our lives, all of us. We all spend all of our online time marketing ourselves in one way or another. Empty, shallow, ultimately meaningless marketing. But humans aren’t mere products, and forcing ourselves to be so makes us miserable, even when it’s working.

I don’t have an answer. I wish I did. My joke about this, as about so many things, is that I really, really need to get to work on that time machine.

Navidrome, Clients and the Compilation MP3 Tag

As I outlined in a previous post, I switched from Jellyfin to Navidrome for my music. While on the whole I’m happy with the change, I discovered that Navidrome handles Various Artists albums such that if the Compilation tag isn’t set, it indexes the album from one into as many as there are artists. And, as outlined in the aforementioned post, this is not a bug, but by design. The intent is to account for different artists with the same album name, and that makes sense.

So I set out to attempt to automate the modification of the Compilation tag – a quest that turned out to be more complicated than I anticipated. The Compilation tag is apparently not a ‘standard’ tag. If you load up an mp3 in taglibsharp and have it vomit out all the tags, the Compilation tag won’t be among them. Here, try it yourself in PowerShell. You’ll have to update the path to your taglibsharp.dll and your test mp3 file.

Here’s an example output:

As you can see, no Compilation tag there. Compilation is technically an iTunes Flag Text Frame, and is set with a Boolean value (1 for Yup, 0 for Nope). It’s defined as TCMP. As of this writing id3.org is down, but here’s the archived page on this tag.

Given all this, I threw together the below. As per usual it’s unrefined, has almost zero error handling, and will be something I improve upon over time. This thing assumes your compilation albums are in directories formatted as “Various – Name of Album.”

Bonus: If you, like me, discovered you have a whole mess of compilation albums in directories with the format “VA – Album Title” instead of “Various – Album Title,” This one liner will help correct that.

Navidrome, Clients and Albums With Varying Artist Tags

I’m using Navidrome as my music server now, having switched from shoehorning Jellyfin into that role, and I quite like it. One thing I discovered, however, is that it – and quite a few clients that support it – rely on the Album Artist tag to help index files. Initially I found this problematic because many of my files didn’t have Album Artist populated. I solved this by writing a PowerShell script to copy the Perfomers tag data (Performers = Artist) to the Album Artist tag. I’ll share that in another post.

But then I discovered a different problem. If an album is a compilation or has variance in the artists from file to file (for example: This Guy feat. That Other Guy), it’d index files into separate albums of the same title. Navidrome’s developers confirmed that this is a feature, not a bug, and it makes sense. The solution for compilation albums is to set the Compilation tag to 1, which I haven’t automated yet but will shortly. The solution for non-comp albums is to make sure the Album Artists tag is consistent.

To accomplish this, I threw together the below script. It’s not optimized, it doesn’t have error handling or confirmation, and it’s apt to be destructive if you’re not careful. Still, it’s something you can build on, just as I inevitably will. As with all my music file related scripts, it requires taglib-sharp.dll. Obtain this file from TagLibSharp. You don’t have to futz with nuget or anything – just download the zipped package, yank the dll out of it, and put it in a subdir you’ll reference in the script.

This script will prompt for the full path to the files you wish to update, and then the name you wish to update the Album Artist tag to.

Calibre Web in a Container, and Credentials

My Calibre Web installed via container in CasaOS decided to lose its admin account creds. To reset, access the container terminal from within CasaOS, navigate to:

and enter:

Where password is your updated passy. If you try to use ‘password’ you’ll probably be kicked back for it not meeting complexity requirements.

Cron for Dynamic DNS Updating

I use my commercial host, Ionos, for websites, including creating subdomains for ones I’m hosting at home. However, I don’t pay for a static ip. I was using a Windows Scheduled Task to curl the necessary URLs to keep the IP updated, but I’m switching everything I can over to Linux, and a Pi.

Start by creating your .sh file and making it executable. I created dnsupdate.sh in my home dir on my Pi, and populated it with my curl calls. I did this via Nano. Then make it executable:

Then I fired up cron by entering:

It’s going to ask you for an editor on first use. I say, stick with Nano.

After this it will present you with a crontab file. Scroll to the bottom and enter:

This will run your sh file every hour at the top of the hour.

Save the file.

If you want to see what’s up with Cron, enter:

If it’s running, it’ll show you the files – your sh file – in use by cron.

CasaOS and Caddy

Briefly – Caddy wouldn’t work out of the box for me on CasaOS. In this build, the default container path for the caddyfile is incorrect. Change the container path from

to

Also, don’t forget to adjust ports, our you’ll inevitably be running into CasaOS itself. I changed my HTTP ports to 85:

Then you can SSH into your CasaOS Pi, head to /DATA/AppData/caddy/caddyfile, create your Caddyfile, er, file, and populate it appropriately. If you’ve been running Caddy elsewhere, I recommend running the below to confirm your file’s format:

CasaOS and bash in Docker

I installed ArchiveBox on CasaOS and came upon a problem – I couldn’t figure out what the default credentials are, or even if there were any, and I didn’t know how to generate them from the command line. ArchiveBox told me to create a new superuser by running

From the command line, but doing so within the container terminal resulted in this:

But I found my way into the container bash thusly:

  • SSH into your pi running CasaOS
  • search for your ArchiveBox container ID:
  • You’ll see a path in your return with a long, long directory name, something like
  • This is your container ID. CD to /var/lib/docker/containers/and run the following, where containerID is the above ID:
  • This will invoke a bash within that container. From within it, run:
  • And follow the prompts to create a superuser for ArchiveBox. To drop out of bash, just input exit.

 

CasaOS – Tinkering

Somewhere in my intertoobs wanderings I came across CasaOS and, given I had an idle Pi 4 laying around, I decided to poke at it. After all, if it works worth a damn it could help consolidate all the disparate systems I have running locally.

CasaOS is basically a slick Docker manager that rides atop another OS. Getting it up and running on the Pi with a fresh Raspbian install was painless. Simple configs, like mounting network shares, is a breeze. So far I have the following running in it:

  • PiHole – Installed without a hitch. If this runs well it’ll replace the standalone PiHole Pi 3 I have running.
  • Calibre Web – Also installed without a hitch. Love this, because I hate running the Calibre thick client full time on my server simply for its web interface. Not a lot of instructions on this one – just make sure you have your library mounted and defined as a volume in the container settings.
  • Jellyfin – Another painless install (make sure to mount your files volume as described in the above Calibre Web settings). I installed this as a replacement for my current Jellyfin music server, which runs standalone in a fully fledged VM, gobbling unnecessary resources. But I stopped it midway through indexing my gajillion files because I discovered:
  • Navidrome – Will it be better than Jellyfin for audio? I don’t know, but I’m giving it a shot.  Currently still indexing – on directory number 12406. Heh. Now, Navidrome wouldn’t run initially, and CasaOS kept screaming that it was unhealthy. Its log filled with “exec /app/navidrome: exec format.” I discovered that the image I was pulling isn’t the most recent. I exported the ComposeFile from within the settings of the failed install, uninstalled it, and updated the image source in the ComposeFile to point to “ghcr.io/navidrome/navidrome:develop.” I then imported the file (Custom Install > Import from within the App Store) and it installed fine
  • Memos – Completely painless install. Came across this randomly and figured maybe it’d replace my TiddlyWiki instance running on my server. We’ll see.
  • Mealie – I ran across this neat app via some Youtubers Apps of The Year vid and was intrigued. An app that’ll scrape a online recipe page, pull the pertinent details of the recipe and ditch all the ads and fluff? Yes please! However, Mealie wasn’t in the default app store for CasaOS. I found CoolStore for Casa and added it as a source. From there Mealie installed no problem, and now I have a slew of other apps to sift through as well. Perhaps Casa can even replace my standalone VPN Pi. We shall see.

Powershell – Monitoring a log file

I had a situation at work where I needed to monitor a log file for a particular entry. I needed to be notified when that entry appeared. This log file gets created anew, with the current date, every day. Here’s what I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
while($true)
{
# get the date
$now = get-date
# create the log name from said date eg :20231223Err.txt
$fileName = '{0}{1}{2}Err.txt' -f $now.Year, $now.Month, $now.Day
# network path to said log
$fullPath = "\\path\e$\LogFiles\app\$($fileName)"

#I don't need this to run in perpetuity - it's a temp situation - so I'm just
#invoking this in a Powershell window and letting it rip.
Write-Host "[$(Get-Date)] Starting job for file $fullPath"
$latest = Start-Job -Arg $fullPath -ScriptBlock {
param($file)

# wait until the file exists, just in case
while(-not (Test-Path $file)){ sleep -sec 10 }
# matching the phrase Queue Count. could make all these variables
Get-Content $file -wait | where {$_ -match 'Queue Count'} |
foreach {
Send-MailMessage -SmtpServer SMTPSERVER -From me@email.com -To me@email.com -Subject 'Queue Count' -Body $_
write-host $_
}
}

# wait until date change
while($now.Date -eq (Get-Date).Date){ sleep -Sec 10 }

# kill the job and start anew
Write-Host "[$(Get-Date)] Stopping job for file $fullPath"
$latest | Stop-Job
}