Cheapest Way to Blog with Your Own Domain

Most of the hosting services want you to buy domain and host your site there. As I was working on my blog site, I’ve learned how I could change DNS record to point to my free tier host on Oracle Cloud Infrastructure. I wanted to do it because iPage.com was too slow for me.

Then, I thought what if I could use a service that allows me to just buy domains and manage my own DNS records without any hosting and host my site on OCI’s free tier?

When I was watching Scott Hanselman‘s YouTube video, I noticed something. He was using DNSimple for his DNS management. So this is a site where you can buy domains and manage DNS records and SSL certs.

So I pay $6 every month for the service and I pay $16 every year for my domain. $6×12+$16=$88 My blog site is hosted at OCI’s free tier host, so it does not cost anything. So I can have my own blog with my domain name for $88 per year. I think it’s quite reasonable.

Of course, this method requires pretty good knowledge of DNS, Web Server and SSL but if you are an engineer or planning to be one, I’d highly recommend it.

zsh

I like z shell. z shell (zsh) is built on top of bash, so your bash script should run without any modification. Here is how you can install zsh.

sudo apt install zsh

Here is how you can make zsh your default shell.

sudo sh -c "echo $(which zsh) >> /etc/shells" && chsh -s $(which zsh)

You may be prompted to create ~/.zshrc (equivalent to ~/.bashrc) when you start your terminal with zsh.

Once you have zsh installed, it’s time to install oh-my-zsh. It’s another cool open source project that allows you to have cool prompt on your terminal.

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

We don’t stop here. To make your prompt even cooler especially for your git operations, we install p10k.

Install p10k manually.

git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>~/.zshrc

Close your terminal and restart it.

Now you get a prompt like the following. It doesn’t show the right glyphs because you don’t have the right fonts and set to be used on your terminal.

Let’s download and install Nerd Fonts. First, clone this repo.

git clone https://github.com/ryanoasis/nerd-fonts.git

It takes some time for the whole repo to be downloaded.

Install the fonts by running the script.

cd nerd-fonts
./install.sh FiraCode

Now change your font of your terminal profile to FiraCode Nerd Font Mono Regular and then run the following command.

p10k configure

If you run through the wizard, you get your cool prompt! 🙂

Linux is Ready for Prime Time

Over the years, I have had a lot of interest in Linux. I would download and install some distribution on my PC or virtual machines to try them out but it was hard mostly because of issues with drivers. And the desktop environments were not there yet.

About 5 to 6 years ago, I wanted a media PC for my TV and I gave Linux Mint a try. It was a great pleasant surprise that I didn’t have to struggle with drivers and the software I needed. I also tried Hacintosh for 10 years, so that gave me a good experience. A long time Windows guy slowly transitioned to Mac and Linux.

Please don’t get me wrong, but I’m not completely defying Windows at all. I do like Windows too but when it comes to performance and freedom I get from Linux, nothing can beat it. And I think Linux desktop environments are ready for prime time.

I’ve done quite a bit of distro hopping but I realized that it’s no use. What you can do with Linux distros are pretty much the same but what makes things different is the desktop environments such as GNOME, MATE and Xfce. You can install all of them and switch as you go. Unlike distro hopping, you don’t have to wipe out your disk to try them out.

Once you install Windows or macOS, you are stuck with it. But with Linux, you can use any desktop environment available. And all of them are free.

I have a Windows machine, Macbook Pro and 2 Linux Mint machines at home. I love what I have and I keep digging everyday. 🙂

How to Copy cat Output to Clipboard on Linux Mint

There may be times when you want to copy the output of cat command to your clipboard. cat foo.txt | pbcopy is available on macOS but how do we do something like that on Linux Mint (or Ubuntu)? xclip can be installed to accomplish that.

Install xclip.

sudo apt install xclip

By doing something like the following, you can copy the content of a text file to clipboard.

cat foo.txt | xclip -selection cliboard

This is too much typing just to copy contents from the text file. You could add the following alias in your ~/.bashrc or ~/.zshrc if you use zshell (which is my favorite shell).

alias "cs=xclip -selection clipboard"

Once you add the line, you can do source ~/.bashrc (or ~/.zshrc) and you should start to be able to use it like below.

cat foo.txt | cs

How to Install Google Chrome on Linux Mint

Linux Mint (and any Debian derivatives) does not come with Google Chrome. You can’t install it even from Software Manager. In this blog, I will show you how to install it from terminal.

Make sure you have vim installed on your machine. (sudo apt install vim)

Next create a new file under the directory.

sudo vim /etc/apt/sources.list.d/chrome.list

Paste the following source in the file.

deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main

Add the key.

wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -

Execute update.

sudo apt update

Install Google Chrome.

sudo apt install google-chrome-stable

Start Google Chrome

google-chrome

I’m not sure how you can add Google Chrome in the favorite menu yet. I will update this article when I find out.

Edit: It showed up in the menu the next day, so I am guessing it takes some time for the DE to cache the newly installed applications.

How to Install Jenkins Slave as Windows Service

It is time to review this article. “How to Install Jenkins Slave as Windows Service” has been one of the most popular blog article on this site. I just went through the steps because I needed to have a permanent Windows slave and I found myself trip over some steps because of some lack of information.

Here I am going to review and enhance the article.

Prerequisites

OpenJDK or Oracle Java (We’ll use OpenJDK in this article)

  • Java
  • Windows

Install OpenJDK

  • Download OpenJDK 17 (the latest one did not work).
  • Download the zip for Windows.
  • Unzip the contents and place all the files under C:\Users\[your username]\jdk (or it could be placed somewhere else if you want to)
  • From the Windows menu, enter “env” to show “Edit the system environment variables” menu and select it.
  • Click “Environment Variables” button.
  • Under System Variables, click New… button and enter JAVA_HOME for Variable name and the path to the JDK root path.
  • Click OK and close Environment Variables dialogue.
  • Open command line and make sure you can get an output from java.
    %JAVA_HOME%\bin\java --version

Create a Node

  • Logon to Jenkins with an administrative account.
  • Go to Manage Jenkins.
  • Click Manage Nodes and Clouds.
  • Click New Node.
  • Enter node name like “win-bld01” and click Permanent Agent and then click OK.
  • Enter a name like win-bld01 (or whatever you like) and enter the path to the directory where you plan to have Jenkins slave executable. In this example, I choose C:\Users\hiriu\jenkins and enter the same path for Custom WorkDir Path.
  • Click OK to save the setting. We’ll revisit it afterwards.

Jenkins Slave Download and Install

  • Download the latest Windows Service wrapper executable from https://repo.jenkins-ci.org/ui/native/releases/com/sun/winsw/winsw/
  • In this example, we will get winsw-2.9.0-net461.exe
  • Place the executable under C:\Users\hiriu\jenkins and rename it as jenkins-slave.exe
  • Create jenkins-slave.xml in the same directory with the following XML. Make sure to change the values in the XML according to your environment. You can get the jnlpUrl from the Configure page of the node.
<service>
  <id>JenkinsSlave</id>
  <name>Jenkins agent</name>
  <description>This service runs an agent for Jenkins automation server.</description>
  <executable>%JAVA_HOME%\bin\java.exe</executable>
  <arguments>-Xrs -jar &quot;%BASE%\slave.jar&quot; -jnlpUrl https://hoge.com/computer/win-bld01/jenkins-agent.jnlp -secret 18f9c0c497c0997e9f65buhie743868ae6d5e2e78a6ba77 -workDir "C:\Users\hiriu\jenkins"</arguments>
  <logmode>rotate</logmode>
  <onfailure action="restart">
    <download from="https://hoge.com/jnlpJars/slave.jar" to="%BASE%\slave.jar">
      <extensions>
        <extension className="winsw.Plugins.RunawayProcessKiller.RunawayProcessKillerExtension" enabled="true" id="killOnStartup">
          <pidfile>%BASE%\jenkins_agent.pid</pidfile>
          <stopTimeout>5000</stopTimeout>
          <stopParentFirst>false</stopParentFirst>
        </extension>
      </extensions>
    </download>
  </onfailure>
</service>

For more options, please refer to the official documentation.

Also make sure to create jenkins-slave.exe.config file with the following XML cotent to prevent the executable from running on the earlier version of the .NET Framework.

<configuration>
	<startup>
		<supportedruntime version="v4.0"/>
	</startup>
</configuration>

Execute the following command to install the Jenkins slave as Windows Service.

jenkins-slave.exe install

Once the installation is successful, you should see the output like below.

Also, you should be able to see “Jenkins agent” item in Windows Services console. You can open the Windows Services console by entering services.msc

Trust the SSL Certificate

The HTTP connection between your client computer and your Jenkins instance may be protected by SSL. When you try to connect your Jenkins slave via HTTPS (SSL) connection, it may fail with the following error.

Exception in thread "main" java.io.IOException: Failed to validate a server certificate. If you are using a self-signed certificate, you can use the -noCertificateCheck option to bypass this check.

It is optional to add -noCertificateCheck option in your jenkins-slave.xml file, but it is better for your Java process to trust the certificate and use the SSL connection to protect the data. To accomplish that, please follow the steps below.

  1. Open terminal.
  2. Execute openssl s_client -showcerts -connect hoge.com:443 < /dev/null | openssl x509 -outform DER > hoge.com.cer
  3. You obviously have to have openssl on your machine. Install Cygwin if you are on Windows and that will give you an ability to execute openssl. Or you could use Linux Subsystem for Windows.
  4. Once you get the .cer file, it’s time to tell Java to trust the certificate. For that, we use keytool.
  5. Execute the following command. If you are on Linux Subsystem, you may want to go back to the normal command prompt.
    %JAVA_HOME%\bin\keytool -trustcacerts -keystore "%JAVA_HOME%\lib\security\cacerts" -storepass changeit -alias ppd -import -file "C:\Users\hiriu\Downloads\hoge.com.cer"
  6. You will be prompted to enter “yes”. Once you enter yes, you are ready to start the Jenkins agent Windows Service.
  7. Navigate to Windows Service console (services.msc) and start the Jenkins agent Windows service.
  8. Once the communication between Jenkins slave and the Jenkins master is successful, you should see the node icon turning to normal like the image below.

How to Add an Additional Public Key to an Existing Instance on OCI

You may want to access an existing instance from another client machine that has a different public/private key pair on Oracle Cloud Infrastructure. I looked around the net and I could not find a solid documentation on how to do it. Basically, the OCI console itself does not have a support to add another public key.

I thought of my previous post on passwordless SSH article. Basically, you are adding public key to ~/.ssh/authorized_keys so that whoever has the public key in the list can SSH into it. I tried adding a new public key to ~/.ssh/authorized_keys on an existing instance and it was successful. I will describe the steps below.

  1. On a new client machine, execute ssh-keygen to generate a new public/private key pair. If you have already done it, you can skip this step.
  2. It generates ~/.ssh/id_rsa (private key) and ~/.ssh/id_rsa.pub (public key).
  3. Print the public key on your terminal by executing cat ~/.ssh/id_rsa.pub
  4. Copy the public key to the machine that you already have access to the instance. You could email it to yourself or use something like DropBox.
  5. SSH into your existing instance.
  6. Open authorized_keys file. vim ~/.ssh/authorized_keys
  7. Copy the new public key and paste it in the last line.
  8. Save the file and exit vim. (:wq)
  9. Go back to the machine where you generated the public key.
  10. SSH into the machine now and you now have access to the instance.

This method probably can be applied to other cloud services as well as long as you have a Linux distro instance.

How to Add Keys and Values to an Exisisting YAML with PyYAML

I found it rather harder than I thought to add key and value to YAML with Python. For example…

You have a YAML file like the following.

root:

And you want to add key1, value1 and key2, value2 and key3, value3 under the root node. I had thought it would be quite as simple as appending child nodes but it turned out that I spent a few hours to figure it out.

The goal YAML I would like in this example is the following.

root:
    key1: value1
    key2: value2
    key3: value3

Here is what you do to achieve it.

import io
import yaml

if __name__ == '__main__':
    with open("data.yaml", 'r') as stream:
        data_loaded = yaml.safe_load(stream)
        additional_data = {"key1": "value1", "key2": "value2", "key3": "value3"}
        for key, value in additional_data.items():
            if data_loaded['root'] is None:
                data_loaded['root'] = {key: value}
            else:
                data_loaded['root'].update({key: value})

        with io.open('data.yaml', 'w', encoding='utf8') as outfile:
            yaml.dump(data_loaded, outfile, default_flow_style=False, allow_unicode=True)

There might be simpler solutions but that’s what I came up with and it does what I want it to.

If you add an array data, then the YAML outcome would look like this, which is OK if it meets your requirement but it didn’t mine.

root:
- key1: value1
- key2: value2
- key3: value3

Checking DNS with dig

There are many DNS servers in the world. When you type hayato-iriumi.net in your browser, your browser goes out to your ISP’s DNS server or the specified DNS server to resolve it to the mapped IP address. (It’s a little more complicated actually but you get the idea)

When you change the A Record (IP address mapping to the name), it takes some time for it to propagate around the world. When you want to see which IP address certain domain name is resolved to, you can run the following command.

 dig +short hayato-iriumi.net

You can specify the DNS server to have it resolve the name.

dig +short hayato-iriumi.net @8.8.8.8

You should see the IP address as a result or no result if the DNS server doesn’t have the name mapped to the IP address yet. dig is a very useful command to check the DNS resolution in most of the Linux type of OS (dig is available on Linux Subsystem on Windows as well).