• Moving Timezone to UTC in Jekyll

    At the very first, I haven’t think about the timezone of my blog. I had used to generate my blog on my local machine and deploy manually. At that time every content is released based on KST timezone, which is GMT+9.

    Right after that I tried to deploy my blog through Travis CI, I realized that something went wrong. Travis CI uses UTC by default, so the URL of every post between 0AM and 9AM was shifted by one day backward. I had to modify /etc/timezone or set environment variable TZ to restore the URLs.

    Yes, this can solve the problem I faced. But should I really use the KST for this whole blog? It’ll be nice if I can show the time based on timezone of each client, but I won’t be able to handle the date part of the post URL as well. So I decided to move the timezone of this site to UTC, global standard at least.

    First I should write some tests for the migration since I want to change URLs by only one push. You can access current posts by using jekyll gem. Place spec/support/jekyll_helper.rb with:

    require 'jekyll'
    
    module JekyllHelper
      def site
        unless @site
          @site = Jekyll::Site.new(
            Jekyll.configuration('serving' => false, 'full_rebuild' => true))
          @site.process
        end
      end
    end
    

    Note @site.process. This makes you be able to access @site.posts. The basic test is simple. I placed this on spec/site_spec.rb:

    RSpec.describe '_site' do
      include JekyllHelper
    
      describe 'timezone' do
        it 'uses UTC instead of local timezone' do
          expect(site.posts).to all(be_utc_post)
          expect(site.posts).to all(have_utc_filename)
          expect(site.posts).to all(have_utc_url)
        end
      end
    end
    

    So, what’s the be_utc_post, have_utc_filename, and have_utc_url? Each of them is RSpec custom matcher. I separated the validation into three parts.

    1. Does the date object of the post have UTC timezone?
    2. Does the post have filename with the UTC date?
    3. Does the generated URL have the UTC date?

    So the each matcher is like following:

    RSpec::Matchers.define :be_utc_post do
      match do |actual|
        expect(actual.date.zone).to eq('UTC')
      end
      failure_message do |actual|
        "expected #{actual.date} to have UTC timezone"
      end
    end
    
    RSpec::Matchers.define :have_utc_filename do
      match do |actual|
        date = actual.date.utc
        year = date.strftime('%Y')
        month = date.strftime('%m')
        day = date.strftime('%d')
    
        expect(actual.name)
          .to eq("#{year}-#{month}-#{day}-#{actual.slug}#{actual.ext}")
      end
      failure_message do |actual|
        "expected #{actual.name} to have UTC date"
      end
    end
    
    RSpec::Matchers.define :have_utc_url do
      match do |actual|
        date = actual.date.utc
        year = date.strftime('%Y')
        month = date.strftime('%m')
        day = date.strftime('%d')
    
        expect(actual.url).to eq("/#{year}/#{month}/#{day}/#{actual.slug}/")
      end
      failure_message do |actual|
        "expected #{actual.url} to have UTC date"
      end
    end
    

    Note that "/#{year}/#{month}/#{day}/#{actual.slug}/" is based on my permalink setting of _config.yml in Jekyll, so you may have to change the template appropriately.

    Update: Jekyll released 3.0.0, and there were some changes on Jekyll::Post. Following code is updated version of spec code. Also you can track the file on GitHub.

    RSpec::Matchers.define :be_utc_post do
      match do |actual|
        expect(actual.date.zone).to eq('UTC')
      end
      failure_message do |actual|
        "expected #{actual.date} to have UTC timezone"
      end
    end
    
    RSpec::Matchers.define :have_utc_filename do
      match do |actual|
        date = actual.date.utc
        year = date.strftime('%Y')
        month = date.strftime('%m')
        day = date.strftime('%d')
        slug = actual.data['slug']
        ext = actual.data['ext']
    
        expect(actual.basename)
          .to eq("#{year}-#{month}-#{day}-#{slug}#{ext}")
      end
      failure_message do |actual|
        "expected #{actual.basename} to have UTC date"
      end
    end
    
    RSpec::Matchers.define :have_utc_url do
      match do |actual|
        date = actual.date.utc
        year = date.strftime('%Y')
        month = date.strftime('%m')
        day = date.strftime('%d')
        slug = Jekyll::Utils.slugify(actual.data['slug'])
    
        expect(actual.url).to eq("/#{year}/#{month}/#{day}/#{slug}/")
      end
      failure_message do |actual|
        "expected #{actual.url} to have UTC date"
      end
    end
    
    RSpec.describe '_site' do
      include JekyllHelper
    
      describe 'timezone' do
        it 'uses UTC instead of local timezone' do
          expect(site.posts.docs).to all(be_utc_post)
          expect(site.posts.docs).to all(have_utc_filename)
          expect(site.posts.docs).to all(have_utc_url)
        end
      end
    end
    

    Tests are ready, so now we start migrating. See ‘Time Zone’ part of the documentation of Jekyll configuration.

    Set the time zone for site generation. This sets the TZ environment variable, which Ruby uses to handle time and date creation and manipulation. Any entry from the IANA Time Zone Database is valid, e.g. America/New_York. A list of all available values can be found here. The default is the local time zone, as set by your operating system.

    So when you add timezone: UTC to your _config.yml, you’re almost done! Remained things are boring file renames and making backward redirect links, using jekyll-redirect-from.

    You can see the full changes on this commit.

  • Revive the Tmux Sessions

    On the previous day, I accidently removed /tmp/tmux-1000/ directory. At first, there seems no problem with Tmux. But when I created another SSH connection, I saw this error message:

    $ tmux attach
    no sessions
    $ tmux list-sessions
    failed to connect to server
    

    But the Tmux prosesses were still there:

    $ ps -ef | grep tmux
    59277 16305  0 May06 pts/0    00:00:00 tmux attach
    

    Then I immediately noticed that the removing /tmp/tmux-1000/ things made the problem. And thankfully Tmux provides workaround. From the tmux manpage:

    -L socket-name

    tmux stores the server socket in a directory under /tmp (or TMPDIR if set); the default socket is named default. This option allows a different socket name to be specified, allowing several independent tmux servers to be run. Unlike -S a full path is not necessary: the sockets are all created in the same directory.

    If the socket is accidentally removed, the SIGUSR1 signal may be sent to the tmux server process to recreate it.

    Now we can revive our Tmux sessions by sending a signal to recreate sockets:

    killall -s SIGUSR1 tmux
    

    More simply, since the number of SIGUSR1 is 10:

    killall -10 tmux
    

    Then we can do tmux attach successfully. Yay!

  • Using Pinpoint with Docker

    Pinpoint

    Pinpoint is an open source APM (Application Performance Management) tool for large-scale distributed systems written in Java.

    Preliminary

    In this post, our goal is to run a sample Pinpoint instance with QuickStart scripts. You can find them on GitHub. Also note that we’re going to use Docker.

    Requirements

    First things first, install Docker.

    wget -qO- https://get.docker.com/ | sh
    

    You can verify docker is installed correctly.

    sudo docker run hello-world
    

    For more details, see the installation guides of Docker.

    Look into the Dockerfile

    In fact, I already made a Dockerfile for Pinpoint. You can see on yous/pinpoint-docker. From now on, I’ll describe the Dockerfile line by line.

    Read on →

  • Comparing binary files

    Seeing differences between files

    As using Git, looking changes of files with git diff is common. Always we can check the status of files with git status, including whether there is a new file that isn’t added to index, existence of changed files.

    I downloaded the syllabus of each course I registered before the start of the semester. This is the first week of semester, professors introduce their course with the adjusted syllabus. Of course I can access the updated ones, but I can’t sure that the files which already I have are the same with which I downloaded right before. I want to keep the old one and the new one both, avoid just overwriting them.

    Comparing binary files

    I just wanted to check whether two binary files are the same or not, no matter what the difference is.

    Windows

    You can use fc, file compare, which is Microsoft DOS command.

    fc /b file1 file2
    

    The /b flag is for a binary comparison. If two files are the same, it prints a message like ‘FC: no differences encountered’, if they’re not, it shows each byte of two files per line.

    Unix

    You can use cmp which compares two files byte by byte.

    cmp file1 file2
    

    When two files are the same, it prints no message and return 0. If they are different, it prints some message and return 1.

  • ChristmasCTF 2014 Write-up

    ChristmasCTF

    Read on →