Swapfile Fix on Manjaro Linux Pinebook Pro

I wrote about a month ago of an update on my Pinebook Pro after switching to Manjaro Linux. I continue to make heavy use of my Pinebook Pro while I’m still social distancing and staying at home, giving me lots of time to work on personal projects without much else to do.

Today I ran into an interesting issue, though, after applying a round of updates. I mentioned in my last Pinebook Pro post about going through the process of creating a swapfile using the directions from the Manjaro wiki so that I could hibernate the machine and get much better battery life. I literally just opened the device back up, though, and saw a familiar message that there wasn’t enough swap space to successfully hibernate the machine, leaving me with about 20% less battery life than I had been expecting. Running htop quickly showed me that my swap space was back to nothing. Weird.

Following the instructions, my swapfile is literally called swapfile on the root of the filesystem. I verified it was still in place with:

ll / | grep swap

With the file still in place, I ran through the instructions again. These ones were both successful:

sudo mkswap /swapfile
sudo chmod u=rw,go= /swapfile

I got an error when running this, though:

sudo swapon /swappfile

This told me:

swapon: /swapfile: swapon failed: Invalid argument

Weird. I verified that I still had my swapfile entry in /etc/fstab to assign the swapfile on boot by running:

sudo cat /etc/fstab

I tried running the swapon command a different way to have it apply everything in the fstab file:

sudo swapon -a

This gave me another “Invalid argument” error still referencing “/swapfile”. At this point, I took to the Internet. After a couple of searches, I stumbled across a matching Stack Exchange question. The top answer claims that the issue is the initial fallocate command used to create the file (the same command used in the Manjaro wiki) doesn’t physically allocate the 4 GB on the storage for speed, but that’s apparently problematic for swapon. Following that answer, I ran a dd command to replace my swapfile with something physically allocated:

sudo dd if=/dev/zero of=/swapfile count=4096 bs=1MiB

This takes a few moments to run, especially on the eMMC storage of the Pinebook Pro. Once it completed, though, I repeated the other commands and verified they were all successful. Sure enough, running htop once again shows my 4 GB of allocated swap space.

Groovy Programming: Creating an ISO Date at a Specific Date and Time in UTC

I’ll be the first to admit that the title of this post is a bit too verbose, but if someone else had a post online with a title like this it could’ve potentially saved me a lot of time. Here’s to hoping it helps someone else in their search.

As is mentioned on my personal website, I do a lot of PowerShell and Python scripting for work. Recently, though, I started working in Groovy due to the fact that it’s treated as a first-class language in a system I’ve been integrating SaaS applications into. Without going into a big tl;dr, working in Groovy affords me a lot of convenience, security, and speed benefits. I just had to, you know, learn Groovy. Since there was a sale at Udemy at the time, I ended up snagging The Complete Apache Groovy Developer Course. It wasn’t a bad course in getting me up to speed; I went from never using Groovy (though I did use Java, upon which Groovy is based, many years ago in college) to being able to get things done for work with it in about 4 nights of binge-watching the course. Be warned, though, that some of the material is a little dated. For example, the way to build JSON objects covered in the course seems to have been superseded by a far easier method, and when covering REST API requests the instructor opted to use some janky 3rd party library that at the time of this writing hadn’t been updated in 6 years or something crazy. I was able to do some searches online and leverage Java tutorials to just figure out how to natively handle REST API calls; your mileage my vary with that depending on your comfort level with REST APIs.

One thing not covered in the course that I needed, though, was how to create a date object in a specific format (ISO) at a specific time (the first day of the current month) in a specific timezone (UTC.) This is a common need for me when filtering time-based events if true time UUIDs aren’t available. The key in my experience is to figure out how to get the timezone correct at the creation of the object when you need a specific hour; adjusting the timezone after the fact will result in a new offset that’ll make your hour value incorrect.

Being super out of the loop with Java and very new to Groovy, this was a little tricky for me, and it seemed like no one else I was able to find online had my specific need. So after a couple of hours of throwing spaghetti at a virtual wall (i.e. copying and pasting lots of stuff from Stack Overflow) I eventually got to this; it’s probably easier to read at the Gist link:

Integer year = Calendar.getInstance().get(Calendar.YEAR)
Integer month = Calendar.getInstance().get(Calendar.MONTH)
def then = new GregorianCalendar(year, month, 1, 0, 0, 0).time
// Desired format: 2020-06-01T00:00:00.000000+00:00
thenISO = then.format("yyyy-MM-dd'T'HH:mm:ss.SSSZ", TimeZone.getTimeZone("UTC")) 
thenISOFixed = thenISO[0..thenISO.length() - 3] + ":00"
println thenISOFixed

I essentially needed to take the current month and year in order to create a date object at midnight (00:00:00) on the first of the month. I need that to be in UTC, and the resulting string representation needs to be in ISO format. All of this gets me what I need so that I can plug it into an API URL for time-based filtering.

Everything works pretty much like you’d expect, though the format specified on line 6 gives me the offset for UTC as 0000. The endpoint I was passing the data to wanted it to be 00:00. Since I knew I’d always have no offsett, I just took a range of the string that cut off the last two zeroes so that I could replace them with “:00.” I probably could’ve done this slightly fancier with some type of “00$” regex replacement, but this works fine.

I’m far from the Groovy master, so as much as I hope this is helpful to someone who finds themselves in the same situation I was in, I’d equally welcome someone showing me the better way to do it if one exists. Regardless, hopefully someone else out there will bang their head against the keyboard for a shorter amount of time thanks to this. And if you happen to know a better way, feel free to give me a shout!

Keep coding, and stay #FF66CC!