Uptime

This blog site is hosted at OCI on an ARM64 processor host with 6GB memory. It has been very stable. I do maintain it occasionally by executing sudo yum update -y && sudo yum upgrade -y but other than that I haven’t had to do much with the host to serve my blog contents. Here is how long the host has been running without a reboot.

23:07:52 up 62 days, 55 min,  1 user,  load average: 0.00, 0.10, 0.08

Surely, this blog site is light on traffic, so there is not much going on so that helps but when I imagine if this host was a Windows server, it would probably need a few reboots per month. I don’t know… Windows server might have improved. It’s been a few years since I dealt with Windows server machines.

Built a PC

I’ve had the project to rebuild a PC in my mind for the last few years… I postponed so much that I finally decided to just work on it. I think I had my previous motherboard for about 7 years or more. It was about time for a new one, plus my son wanted to play Flight Simulator 2020, so I took a Sunday to build it.

Here are the parts I bought.

I already had a case, so I just went with the existing one this time. The whole thing cost me about $963.73 I planned to spend about $1,000 it came in within my budget.

The first hurdle I hit was the system wouldn’t even turn on at all. I was looking all over thinking I got a lemon motherboard… It turned out that the surge protector that the PC was connected to wasn’t turned on. Very basic mistake.

And then, I hit the second hurdle. When I turned it on, it would make one long beep and the three short ones. Beeeeep, beep beep beep… and then nothing showed up on the monitor. For a while, I couldn’t figure out what it was. When I looked it up on the Internet, it turned out the memory sticks may have been misplaced in wrong slots. I checked the manual of the motherboard to place them in the correct slots. And then it turned on OK.

Now it’s time to install the OS. I’m a Linux guy but then my son and I have a few games we would like to play on Windows, so I went for Windows 11 installation. It didn’t even install. Windows 11 is relatively new, so I thought I should upgrade the BIOS. So I went online to get the latest BIOS for my motherboard. I kept trying TUF-GAMING-X570-PLUS-ASUS-4204.zip or newer version of it but nothing worked. It said, the BIOS is not for the motherboard or something along those lines. I tried it for more than 30 mins. Then I searched online… It turned out that I downloaded the wrong BIOS. The one I needed to download was TUF-GAMING-X570-PLUS-WIFI-ASUS-4204.ZIP Notice “WIFI”? That’s the model I have, not the one without WIFI. I’m glad ASUS put a protection. If not, I would have bricked the motherboard.

Once the BIOS was upgraded, I was able to install Windows 11. I didn’t have an existing license for my new rig, so I purchased a Windows 11 home license.

So I probably spent a little more than $1,000 for the whole thing. But my gosh, this PC is really fast! I am able to play FF13, FF13-2 and Flight Simulator 2020 without any lag. This is an amazing PC.

In addition, I was able to install Ubuntu on it and dual boot the PC. I installed my 2 existing SSD. I checked the temperature of the CPU and it’s been running cool even after running some games. So I guess I built the PC correctly.

Copy Drives with rsync on Windows from WSL

I have E: drive that I have been using for years to dump my personal files. I just purchased 4TB drive for fear of failing drive, so I want to copy everything on E: to the new drive (F:). I could have drag and drop everything from E: to F: but I wanted a geekier way (well maybe more robust way) to copy files from E: drive too F: drive. Here is how I started the process with rsync.

rsync -avz --progress /mnt/e/* /mnt/f

I have like 1TB of data (that’s it?) and it will take hours for it to finish the copying process.

VPN Server After a Month Usage

It’s been more than a month since I started to provision a VPN server in Tokyo on Oracle Cloud Infrastructure. I’ve been watching TVs and movies in Japan whenever I have time. I analyzed how much it would cost me to have a semi-permanent VPN server in Japan on OCI previously and I estimated it at $1.8 per month. Has it been really that little? Here is the actual cost.

So for entire March (31 days), it was $1.98. If cost per day is $0.06, it would be $1.86 but it was $1.98. I found out the resource cost to the fraction of cent is $0.064, so it came up to $1.98. That said, a stable and reliable VPN server without noisy neighbor problem at less than $5 is very very reasonable.

One thing I found out is that if you connect multiple devices at the same time, it can get unstable. I have no problem with it because I can’t watch multiple TVs at the same time. If I wanted to have multiple devices connected, I’d provision one or two more VPN servers because one ARM host is at around $2 after all.

Text Wrap in Python

I was working on a problem at HackerRank. It’s called text wrap problem. I was able to solve it with the following code.

def wrap(string, max_width):
    result = ''
    lines = len(string) / max_width
    last_chars = len(string) % max_width
    for i in range(int(lines)):
        start_index = i * max_width
        result += string[start_index:start_index+max_width] + '\n'

    if last_chars > 0:
        result += string[-last_chars:]
    return result

Then, I headed to Discussions section to see if a smarter person posted a better and more concise code. There was one.

def wrap(string, max_width):
    return "\n".join([string[i:i+max_width] for i in range(0, len(string), max_width)])

In essence, it’s pretty much the same logic but it’s more concise though I think it’s kind of harder to read. One of the important things we have to consider when coding is whether the code is maintainable and readable. But there are smarter people out there… Always learning.

Validating Downloaded File with File Size from Object Storage on OCI

This is a note for myself.

#!/usr/bin/env python3

import oci.object_storage
import urllib3
import os

def download_backup(bucket_name, file_name, local_dir):
    signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
    object_client = oci.object_storage.ObjectStorageClient(config={},signer=signer)

    object = object_client.get_object('id4qji14rv70', bucket_name, file_name)
    restored_file = os.path.join(local_dir, file_name)
    with open(restored_file, 'wb') as f:
        for chunk in object.data.raw.stream(1024 * 1024, decode_content=False):
            f.write(chunk)

    object_meta = object_client.head_object('id4qji14rv70', bucket_name, file_name)
    content_length=object_meta.headers['Content-Length']

    file_stats = os.stat(file_name)

    if file_stats.st_size == int(content_length):
        print(f"Validated {content_length}")
    else:
        print(f"Validation failed. Expected: {content_length} Actual: {file_stats.st_size}")

if __name__ == '__main__':
    download_backup('backup', '2022-03-21.zip', '/home/opc')

Managing Your Own DNS on OCI

You can manage your public DNS for your domain on OCI.

But first, you have to change the DNS delegation to OCI’s name servers like the following.

Whatever domain registerer you use, I am pretty sure you can change name servers for your domain. Once you change the domain delegation, you can start to manage your DNS records within OCI console.

Once you navigate to DNS Management on OCI console, click Create Zone.

I have iriumi.study as a domain that I want to be hosted on OCI, so I am going to create it.

Once you create the zone, you can add records.

Select A record for the record type and enter the public IP address you want to assign. I am leaving subdomain as blank because I want the name to resolve to the IP address without any subdomain. Also enter the value of TTL. TTL stands for time to live and it’s a duration how long the DNS resolution is cached before reaches back out to collect new and updated details. I am setting it 60 seconds for now but longer or shorter TTL has their own purposes, so I’d recommend that you look it up.

Now you can click Submit button at the bottom of the screen.

Then, click Publish Changes button to get it published.

If you go to DNS Checker and see how it is propagating around the world, you get to see something like this.

How to Validate a Big Downloaded File from Object Storage (OCI)

When you upload relatively a big file to Object Storage in OCI, it doesn’t have the MD5 hash ready for you. It’s because the big file is split into multi parts and they are uploaded into separate space. Then, when you download the file, the multi parts are downloaded sequentially and they are put into one file on the client side. Object Storage does not calculate the MD5 hash putting the multi parts together on the service side due to its sheer required processing power it may need. When you try to view the information of the file on Object Storage, you don’t see the actual MD5 hash.

Tough opc-multipart-md5 looks promising, that’s just a part of the whole thing. To get my point crossed, when I uploaded a small file, MD5 hash is calculated and available on the service side.

Now, how do we solve this problem? The best way is to calculate the MD5 hash before you upload the file with md5sum and then attach the MD5 hash to metadata when uploading the file to Object Storage.

You can get the data by executing the following command.

 oci os object head --auth instance_principal -bn backup --name 2022-03-20.zip

Here is the data you get as JSON.

{
  "accept-ranges": "bytes",
  "access-control-allow-credentials": "true",
  "access-control-allow-methods": "POST,PUT,GET,HEAD,DELETE,OPTIONS",
  "access-control-allow-origin": "*",
  "access-control-expose-headers": "accept-ranges,access-control-allow-credentials,access-control-allow-methods,access-control-allow-origin,content-length,content-type,date,etag,last-modified,opc-client-info,opc-client-request-id,opc-meta-md5hash,opc-multipart-md5,opc-request-id,storage-tier,version-id,x-api-id",
  "content-length": "217286450",
  "content-type": "application/octet-stream",
  "date": "Sun, 20 Mar 2022 04:42:05 GMT",
  "etag": "500168df-c90a-4d35-b4f6-c7a6c99d5969",
  "last-modified": "Sun, 20 Mar 2022 04:40:27 GMT",
  "opc-client-request-id": "92C495DFAA8647C4B230B10580FED145",
  "opc-meta-md5hash": "1eed774bb61c15f8c50c7771e71bbb24",
  "opc-multipart-md5": "i1Ap4X2OnVAU7aK8RwxgMg==-2",
  "opc-request-id": "iad-1:mHbU0Aq4kW9abs3NCSv77cOKPDYdcQ74lsT4sPgfDI44xXLWLwYk8MKcX3WmPE7L",
  "storage-tier": "Standard",
  "version-id": "29ba4883-5fb3-4316-acbc-ceb218b5e3d1",
  "x-api-id": "native"
}

So the process would be to execute oci os object head on the object you are going to download and keep the MD5 hash in a variable. Then once you download the file, have md5sum calculate the MD5 hash on the downloaded file. And then see if the calculated MD5 matches the one from oci os object head.

Here is the bash script I came up with to upload the file with the metadata.

rm -rf /home/opc/backup.zip
zip -r /home/opc/backup.zip /home/opc/wordpress/*

md5=`md5sum backup.zip | awk '{ print $1 }'`
filename=`date +%Y-%m-%d`.zip
json='{"md5hash":''"'$md5'"}'
oci os object put --auth instance_principal -bn backup --file backup.zip --name $filename --force --metadata $json

I have cron’ed the bash script to run every day so the file backup is automated.

Bash Scripts

Bash scripting is my weakness as an engineer. I don’t like bash. Here are the reasons I don’t like it.

  • Bash depends on standard output. If you need to work on a complex scripting, it easily gets ugly dealing with a bunch of string mambo jumbo with regex.
  • Commands are each independent executable.
  • You cannot create functions with parameters. You have to use variables always at the global level.

So as a strong alternative, I use Python most of the time. Because I don’t prefer to use Bash script, my skill in bash scripting is limited. I believe bash does have a place to be but I tend to avoid it.

That said, I think I should spend more time on Bash to be at least fluent with it. I don’t consider myself to be fluent yet.

I used this bash script to install and configure openvpn. This is one of the most amazing script I have seen. There is a lot to learn from it.

My Linux Mint Desktop is Broken

My Linux Mint desktop has been broken. Somehow it doesn’t boot anymore. I tried to reinstall the OS but it still is not.

When I booted it and went into the BIOS screen, I saw a very high CPU temperature. It was like 91C but I went ahead and kept on using it anyway. It must have damaged the CPU itself and possibly the motherboard.

So the recovery plan I am thinking about is to buy new CPU, motherboard and memory and reinstall the whole thing. I am planning to save some money for it.