4.30.2014

How to Integrate Clipboard; Mac + tmux + Emacs in Terminal

Mac + tmux + ターミナル上のEmacs でクリップボードを連携する方法

 

tmux 上で Emacs を利用する場合、
OS のクリップボードとその内容をシームレスに連携するためには多少の手順が必要となる。

 

手順

 

1. Emacs の設定

Emacs 初期設定ファイル (~/.emacs/init.el など) に以下の内容を記述。

(defun copy-from-osx ()
  (shell-command-to-string "pbpaste"))

(defun paste-to-osx (text &optional push)
  (let ((process-connection-type nil))
    (let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
      (process-send-string proc text)
      (process-send-eof proc))))

(setq interprogram-cut-function 'paste-to-osx)
(setq interprogram-paste-function 'copy-from-osx)

 

2. reattach-to-user-namespace のインストール

tmux 内部での Mac OS X クリップボードのやりとり (pbcopy/pbpaste) を可能にするツール。

Homebrew でインストールするのが一番簡単だ。

$ brew install reattach-to-user-namespace

 

3. tmux の設定

tmux 初期設定ファイル (~/.tmux.conf) に以下の内容を記述し、tmux を再起動。

set-option -g default-command "reattach-to-user-namespace -l zsh"
  • 参考: tmux 再起動
    $ tmux kill-server

 

これで

  • Mac でクリップボードにコピー => tmux 上の emacs で貼付け (C-y)
  • tmux 上の emacs でコピー (M-w) => Mac で貼付け

が可能となった。

 

References

Ansible Playbook for MySQL Replication

Ansible: MySQL レプリケーションを実現するためのプレイブック 

 

目的

OSインストール済みの CentOS 6.5 サーバ 2台に対してそれぞれに MySQL をインストールし、
master - slave 構成のレプリケーション環境を構築したい。

普通にやっても面白くないので、Python製のオーケストレーションツール(構成管理ツール) Ansible を使って
インフラの状態をコードとして管理する。

とはいえ実際にやったことと言えば、こちらの素晴らしい playbook のミックスイン写経にすぎない。 

 

コード

説明するよりコードを見たほうが早いと思う。こちらにアップしている。

ファイル、ディレクトリ構成はこのような感じ。

.
├── README.md                    簡単な説明
├── Vagrantfile                  CentOS 6.5 x2台をVirtualBoxで
├── host_vars
│   ├── mysql-master             レプリケーションに関わるホスト単位の定義
│   └── mysql-slave
├── hosts                        インベントリ用
├── roles
│   └── mysql
│       ├── handlers
│       │   └── main.yml         conf書き換え時にサービス再起動
│       ├── tasks
│       │   └── main.yml         メインディッシュ
│       ├── templates
│       │   ├── .my.cnf.j2       rootユーザ用の認証情報を書いておく
│       │   └── my.cnf.j2        設定ファイルのテンプレート
│       └── vars
│           └── main.yml         バージョン設定やユーザのアカウントなど
└── site.yml

 

ポイント

 

Vagrantfile

opscode の CentOS 6.5 イメージをダウンロードして使用。
SELinux が有効だったので、libselinux-python を事前にインストールする必要があった。
IPアドレスは適当に振った。

 

site.yml

とりあえず vagrant ユーザで、sudo してタスクを実行する設定。

 

roles/mysql/tasks/main.yml

一連の処理を 5個のフェーズに分けている。

  • 1. Install packages
    • jaist.ac.jp から新しめのパッケージを一式ダウンロード
    • ローカルファイルを yum モジュールでインストールする際、
      /usr/local/src/{{ item }} のような指定ができなかったので、やむを得ずパスを echo するだけのタスクを一個作っている (need improvement)
    • MySQL関連の操作をするため、MySQL-python のインストールが必要
    • 今回、スローログを /var/log/mysql-slow.log として書くため、パーミッションの関係で事前にファイルを touch している
  • 2. Change credentials for root
    • /root/.mysql_secret ファイルが存在する場合にはパスワードが初期設定のままと判断し、roles/mysql/vars/main.yml の方で指定した root パスワードに設定し直す
    • 新しいパスワードは、/root/.my.cnf に記録しておく
  • 3. Setup users
    • ゲストアクセスを停止し、アプリユーザ、レプリケーション用ユーザを作成
  • 4. Create database
    • test データベースを削除し、vars で指定したDB (今回は awesome) を作成
  • 5. Replication settings
    • mysql_replication モジュールを活用
    • ハマったのが、changemaster する時に以下のようなエラーが出て、コマンドが success にならないこと。

      _mysql_exceptions.Warning: Sending passwords in plain text without SSL/TLS is extremely insecure. 

      MySQL 5.6 の仕様変更の影響で、start slave の時にパスワードを指定するのが新しいお作法のようだが、どうにもうまくいかず。
      結局、不本意ながら (ignore_errors: True) を設定した。(need improvement)

 

roles/mysql/templates/my.cnf.j2

jinja2 のテンプレートファイル。if や for を活用している。
slave 側には read_only の設定を入れた。

 

遊び方

Vagrantfile を作ったので手元でも試せる。README 参照。

4.07.2014

How to Send a Message to HipChat Room by Python Script

Python で HipChat に通知を投げる方法

 

API認証トークンの準備
  • ブラウザで Group admin -> API のページを開く
    https://YOUR_GROUP_NAME.hipchat.com/admin/api 
  • Create new token
    • Type: Notification <- 通知のみが目的なら、Admin にする必要はない
    • Label: トークンの名前を適当に
    • 生成され表示されたトークン文字列をコピー
  • Group admin -> Rooms から、メッセージを送りたい部屋を開いて API ID を確認

 

Python スクリプトの書き方
  • 使用するライブラリを選ぶ
  • 初期化
    >>> import hipchat
    >>> hipster = hipchat.HipChat(token=トークン文字列)
    
  • メッセージ送信
    >>> hipster.message_room(送信先の部屋のAPI_ID, '送信者名', 'メッセージ')
  • 送信者名やメッセージが UTF-8 だった場合は、エンコードしてから渡す
    >>> hipster.message_room(送信先の部屋のAPI_ID, '送信者名', u'UTF-8メッセージ'.encode('utf-8'))

 

とてもヒップ。

Docker: b2d-pipework - Installation Helper Script

b2d-pipework - 固定IPアドレス持ちDockerコンテナ環境構築のためのヘルパースクリプト

 

Mac + boot2docker + pipework を導入するための一連の作業をシェルスクリプトにした。

たとえば、インストール処理は以下のような流れ。

  • Homebrew を利用して docker および boot2docker パッケージの最新版をインストール
  • あらかじめ作成した profile ファイルに従って boot2docker VM (VirtualBox) を作成
  • SSH鍵($HOME/.boot2docker/id_rsa)を新規作成し、boot2docker VM にパスワードなしでログイン可能に
  • boot2docker VM 内に最新版の pipework をインストール
  • 192.168.99.0/24 のアドレスで、VirtualBox ホストオンリーネットワークを構築

ドキュメントは今のところ日本語のみ。 

 

 

Related Posts

3.24.2014

Docker: How the networking of Mac + boot2docker + Pipework works

Docker: Mac + boot2docker + Pipework で構築した環境のネットワーク周りについて

 

自分自身の理解のためにネットワーク構成を可視化してみる。

 

環境

  • OS: Mac OS X 10.9 (Mavericks)
  • VirtualBox: 4.3.6
  • boot2docker: v0.7.0 (Docker 0.9.0 を含む)
  • jpetazzo/pipework (最終コミット: 2014-03-15 時点)

 

構成イメージ

 

1. boot2docker インストール直後

Docker の内部ネットワークとして 172.17.0.0/16 のIPアドレスが各コンテナに割り当てられるが、
静的なアドレスを指定することはできない。
また、Macから直接そのIPアドレスへは到達できないので、VirtualBox と Docker の二段階の
ポートフォワーディングを経由してアプリケーションへアクセスするのが一般的である。

コンテナ間通信可否については、Docker デーモンの -icc オプション、および
コンテナ起動時の --link オプションによって制御可能。

1

2-1. Pipework でブリッジを作成

boot2docker VM上で Pipework を実行し、各コンテナをブリッジインタフェース br1 に対応させたところ。
コンテナ内部に eth1 インタフェースが作成され、指定した IPアドレスが割り振られる。

これで固定のIPアドレスを使ったコンテナ間通信が可能になる。
ただし、boot2docker VM からそのアドレスへのアクセスはまだできない。

以下は、コンテナに 192.168.99.0/24 ネットワークのアドレスを割り当てる例。

2 1

2-2. ブリッジにIPアドレスを割り当てる

boot2docker VM 上で、ブリッジに接続するためのIPアドレスを割り振れば、
boot2docker VM から各コンテナに固定アドレスを使った接続が可能になる。

ただし、この方法では Mac から直接コンテナにアクセスすることはできない。

2 2

3-1. VirtualBox のホストオンリーアダプタを作成する

VirtualBox の機能でホストオンリーネットワークを作成し、boot2docker VM のアダプタにも静的なIPアドレスを
設定する。

これで、Mac から boot2docker VM へ固定のIPアドレスでアクセスできるようになる。

3 1

3-2. ホストオンリーアダプタに対して Pipework を実行する

さいごに、boot2docker のホストオンリーネットワーク用アダプタ eth1 に対して Pipework を実行する。
ブリッジインタフェース以外に対して Pipework を実行すると、macvlan ブリッジが設定されるようだ。 

このようなネットワーク構成であれば、もはや VirtualBox + Docker の多段ポートフォワーディングは必須でない。

3 2

 

 

 

Related Posts

 

References

3.23.2014

Docker: boot2docker SSH Login without Password

Docker: boot2docker VM にパスワード無しで SSH 接続する方法

 

通常の Linux サーバ同様、ssh-keygen コマンドで作ったキーペアの公開鍵をリモートサーバ上に置けば
boot2docker VM に対してもノンパスワードで接続できる。

ただし、例によって boot2docker を再起動しても設定が永続化されるようにするためには
少々の細工が必要となる。

 

作業手順

 

1. 秘密鍵、公開鍵のペアを作成

キーペアを新規に作成し、~/.boot2docker/id_rsa として保存する例。

Mac$ ssh-keygen -t rsa -f $HOME/.boot2docker/id_rsa

プロンプトが出るのでパスフレーズを2回入力。(空でもよい)

 

2. 公開鍵を boot2docker VM の中に置く

公開鍵を永続化するため、/home/docker などではなく、/var/lib/boot2docker/keys というディレクトリを作って
そこに配備することにする。

(ちなみに /var/lib/boot2docker/ssh という既存のディレクトリには sshd サーバの設定情報が保存されている)

Mac$ scp -P 2022 ~/.boot2docker/id_rsa.pub docker@localhost:
docker@localhost's password:    ### tcuser と入力
Mac$ boot2docker ssh
docker@localhost's password:    ### tcuser と入力
boot2docker$ sudo mkdir /var/lib/boot2docker/keys
boot2docker$ sudo mv -i ./id_rsa.pub /var/lib/boot2docker/keys/

 

3. VM起動時に実行されるシェルスクリプトを記述する

もちろん、このままではSSH鍵を使ったログインを行うことはできない。

以下にような内容の /var/lib/boot2docker/bootlocal.sh を作成して、authorized_keys ファイルを動的に生成する。
このシェルスクリプトはVM起動時に自動的に実行される。

boot2docker$ sudo vi /var/lib/boot2docker/bootlocal.sh
boot2docker$ cat /var/lib/boot2docker/bootlocal.sh
#!/bin/sh

mkdir -p /home/docker/.ssh
cat /var/lib/boot2docker/keys/*.pub > /home/docker/.ssh/authorized_keys
boot2docker$ sudo chmod +x /var/lib/boot2docker/bootlocal.sh
boot2docker$ exit

 

4. boot2docker の再起動と接続確認

これで、boot2docker を再起動し ssh コマンドに秘密鍵のパスを渡せば、
ノンパスワードでのログインができるはずだ。

Mac$ boot2docker restart
Mac$ boot2docker ssh -i ~/.boot2docker/id_rsa

問題が発生した場合は、boot2docker ssh -v コマンド(-vvv でも可)で調査。

 

作業シェル記述例

楽をするため、この一連の作業をシェルスクリプトで書く。

適当な作業ディレクトリで実行。

#!/bin/bash

KEY_NAME=id_rsa
PRIVATE_KEY=$HOME/.boot2docker/$KEY_NAME
PUBLIC_KEY=$PRIVATE_KEY.pub
BOOTLOCAL_TMP=/tmp/bootlocal.sh

# Create SSH key pair
if [[ ! -f $PRIVATE_KEY ]]; then
    mkdir -p $HOME/.boot2docker
    ssh-keygen -t rsa -f $PRIVATE_KEY
fi

# Create bootlocal.sh
cat <<EOF > $BOOTLOCAL_TMP
#!/bin/sh

mkdir -p /home/docker/.ssh
cat /var/lib/boot2docker/keys/*.pub > /home/docker/.ssh/authorized_keys
EOF

# Upload public key and bootlocal.sh to VM
boot2docker start
scp -P 2022 $PUBLIC_KEY $BOOTLOCAL_TMP docker@localhost:

# Install files in VM
boot2docker ssh sudo install -D -o root -g root -m 644 ./$KEY_NAME.pub /var/lib/boot2docker/keys/
boot2docker ssh sudo install -o root -g root -m 755 ./bootlocal.sh /var/lib/boot2docker/

# Clean bootlocal.sh
rm -f $BOOTLOCAL_TMP

# Restart boot2docker
boot2docker restart

途中でプロンプトが何回か出るので、その都度、手で入力すること。(改善の余地あり)

 

 

 

Related Posts

3.22.2014

How to Connect Directly to the Docker Container on boot2docker with Static IP Address

Docker: boot2docker 上の Docker コンテナに狙ったIPアドレスで直接接続する方法

 

boot2docker を導入した Mac OS 環境で {Mac, boot2docker VM, Dockerコンテナ} の三者を
同一のネットワークに所属させ、それぞれに対して固定IPアドレスでアクセスできるようにしたい。

ただし pipework の README にもあるように、闇雲にこの方式を採用するのはお勧めしない。

 

環境

  • OS: Mac OS X 10.9 (Mavericks)
  • VirtualBox: 4.3.6
  • boot2docker: v0.7.0 (Docker 0.9.0 を含む)
  • jpetazzo/pipework (作業手順の中でダウンロードする)

 

事前準備

  • boot2docker のセットアップ
    boot2docker ssh が実行できる状態となっていること。
  • Mac から docker コマンドが利用できること
    Docker クライアントがインストールされていて、環境変数 DOCKER_HOST が
    tcp://127.0.0.1:4243 のように設定されていること
  • IP アドレス/ネットワークの決定
    VirtualBox のホストオンリーネットワーク上に静的に設定するIPアドレスを決める。
    今回の例では以下のように設定。
    • Gateway: 192.168.99.1/24
    • boot2docker VM (Dockerホスト): 192.168.99.2/24
    • Dockerコンテナ1: 192.168.99.101/24
    • Dockerコンテナ2: 192.168.99.102/24

作業手順

コマンドはすべて Mac上で実行するべく記述している。

1. boot2docker VM 起動時処理の追加

boot2docker では、Docker の実行環境それ自体が Docker コンテナとして構築されている。
そのため、boot2docker ssh でネットワーク周りの設定をしても、boot2docker VM を再起動すると
設定が初期化されてしまう。

/var/lib/boot2docker/bootlocal.sh を作成すれば、VM(の中のコンテナ?)起動時にこのシェルが実行される。
永続化したい処理はここに書くのがセオリーだ。

  • boot2docker 起動
    $ boot2docker up
  • pipework 最新版のダウンロード
    $ boot2docker ssh " \
    sudo mkdir -p /var/lib/boot2docker/bin && \
    sudo curl -o /var/lib/boot2docker/bin/pipework https://raw.githubusercontent.com/jpetazzo/pipework/master/pipework && \
    sudo chmod +x /var/lib/boot2docker/bin/pipework"
    

    pipework の実行ファイル(実態はシェルスクリプト)を永続化対象の /var/lib/boot2docker/bin 配下に
    置き、VM 起動時に /usr/local/bin/pipework へシンボリックリンクを張る戦略。
  • bootlocal.sh の作成
    $ boot2docker ssh "sudo bash -c '
    echo -e \"ln -s /var/lib/boot2docker/bin/pipework /usr/local/bin/pipework
    \nip addr add 192.168.99.2/24 dev eth1
    \nip link set eth1 up\" > /var/lib/boot2docker/bootlocal.sh
    && chmod +x /var/lib/boot2docker/bootlocal.sh
    '"
    

    ここで、boot2docker VM のIPアドレスを指定する。

    実際の bootlocal.sh は以下のような内容になる。(shebang を付けたほうがいいかもしれない)

    ln -s /var/lib/boot2docker/bin/pipework /usr/local/bin/pipework
    ip addr add 192.168.99.2/24 dev eth1
    ip link set eth1 up

 

2. VirtualBox ホストオンリーアダプタの設定

VirtualBox の GUI でも操作可能だが、スクリプト化したいのでコマンドで実行してみる。

  • 目的に適したアダプタが既に存在するかどうか確認
    $ VBoxManage list -l hostonlyifs
    IPアドレス(192.168.99.1)、ネットワークマスク(255.255.255.0)が一致するものが存在していれば、
    そのアダプタを利用する。
  • アダプタが存在していなければ、新規作成
    $ VBoxManage hostonlyif create
    0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
    Interface 'vboxnet0' was successfully created
    $ VBoxManage hostonlyif ipconfig vboxnet0 --ip 192.168.99.1 --netmask 255.255.255.0
    $ VBoxManage list -l hostonlyifs
    
    表示されたインタフェース名に対して変更を施し、確認。
  • boot2docker 停止
    $ boot2docker stop
  • boot2docker VM にホストオンリーインタフェースを追加
    $ VBoxManage modifyvm boot2docker-vm --nic2 hostonly --hostonlyadapter2 vboxnet0
    $ VBoxManage modifyvm boot2docker-vm --nicpromisc2 allow-all
    先ほど作成したホストオンリーアダプタの名前(ここでは vboxnet0)を指定。
    nic1 は NATアダプタとして既に存在しているので、ここでは nic2 を作成する。
    Docker コンテナ間の通信を可能とするため、Promiscuous Mode の設定を変更する。
  • boot2docker 起動
    $ boot2docker up
  • 疎通確認
    $ ping 192.168.99.2
    $ ssh docker@192.168.99.2
    まずは boot2docker VM (Dockerホスト) に対して直接アクセスできるようになった。

 

3. コンテナの起動と pipework の実行

ここでは、CentOS 6.4 上で sshd が動くだけの Docker コンテナ (mogproject/sshd Repository | Docker Index) を
2つ立ち上げて、pipework の動作を確認してみる。

  • コンテナの起動
    $ CID1=$(docker run -d -t mogproject/sshd)
    $ CID2=$(docker run -d -t mogproject/sshd)
    $ docker ps
  • pipework の実行
    $ boot2docker ssh sudo pipework eth1 $CID1 192.168.99.101/24
    $ boot2docker ssh sudo pipework eth1 $CID2 192.168.99.102/24
    コンテナID と IPアドレスを指定し、boot2docker VM上のホストオンリーアダプタ(eth1)と対応付ける。
  • 疎通確認
    $ ping 192.168.99.101
    $ ping 192.168.99.102
    $ ssh ssh-user@192.168.99.101    ### パスワードも ssh-user
    [ssh-user@xxxxxxxxxxxx ~]$ ping 192.168.99.102
    [ssh-user@xxxxxxxxxxxx ~]$ exit
    $ ssh ssh-user@192.168.99.102
    [ssh-user@xxxxxxxxxxxx ~]$ ping 192.168.99.101
    [ssh-user@xxxxxxxxxxxx ~]$ exit
    
    Mac から Docker コンテナに直接アクセスできる。
    さらに、そのIPアドレスを使ってコンテナ間通信もできるようになった。

このように、pipework のおかげで Docker コンテナの活用の幅はますます広がりそうだ。

なお、pipework の設定は、コンテナが停止すると同時に削除される。

 

 

 

References