6.24.2014

Docker: How to Run 'nsinit' in the boot2docker VM

Docker: boot2docker VM の中で nsinit を実行する方法

 

2014-07-02 追記:
nsinit ではなく nsenter を使えば、同じことをよりシンプルに実現できました。

参考: docker - nsinit が上手く行かなくて困っていたら nsenter があまりにもあっさりだった件 - Qiita

環境

  • OS: Mac OS X 10.9 (Mavericks) (boot2docker が動作すれば他の環境でも手順は同じはず)
  • boot2docker: v1.0.1

 

事前準備

  • VirtualBox のインストール
  • boot2docker 最新版のインストール (OS X インストーラ の利用を推奨: 詳細手順)
    • インストール前に VirtualBox の全ての VM、GUI を停止すること
    • 既に boot2docker VM が存在している場合は以下のコマンドを実行 (元の環境は削除される)
      $ boot2docker halt
      $ boot2docker delete
      $ boot2docker download

 

作業手順

 

boot2docker VM の作成・ログイン
Mac$ boot2docker init
Mac$ boot2docker up
Mac$ boot2docker ssh
GCC + golang コンパイル環境の準備
docker@boot2docker:~$ tce-load -wil compiletc go
nsinit のビルド
docker@boot2docker:~$ sudo GOPATH=$HOME/go go get github.com/docker/libcontainer/nsinit
docker@boot2docker:~$ sudo cp -f $HOME/go/bin/nsinit /usr/local/bin/

これで /usr/local/bin/nsinit が作成される。

2014-07-02 追記
nsinit リポジトリの状況によって、ここでハマるケースがいくつか報告されています。

やはり nsenter の利用をお勧めします。

参考: RHEL/CentOS 6で Docker に nsinit/nsenter する - Qiita

 

コンテナアタッチ用 便利シェルの作成

以下の内容で /usr/local/bin/docker-attach というシェルを書き、実行権限を付ける。

#!/bin/sh
[[ -n "$1" ]] || { echo "Usage: `basename $0` <partial container ID or name>"; exit 0 ; }
FULL_ID=$(docker inspect --format='{{.Id}}' $1)
sudo /bin/sh -c "cd /var/lib/docker/execdriver/native/$FULL_ID && nsinit exec bash"
コマンドの永続化

このままだと、nsinit, docker-attach は boot2docker VM を停止すれば消滅してしまう。

永続化されるディスクの /var/lib/boot2docker の中にコマンドを移動し、bootlocal.sh を使って起動時に再配備されるようにする。

docker@boot2docker:~$ sudo mkdir /var/lib/boot2docker/bin
docker@boot2docker:~$ sudo mv -i /usr/local/bin/nsinit /usr/local/bin/docker-attach /var/lib/boot2docker/bin/

/var/lib/boot2docker/bootlocal.sh を以下の内容で作成し、実行権限を付与。

#!/bin/sh
ln -s /var/lib/boot2docker/bin/nsinit /usr/local/bin/nsinit
ln -s /var/lib/boot2docker/bin/docker-attach /usr/local/bin/docker-attach

シェルを実行してリンクを張り直す。

docker@boot2docker:~$ sudo /var/lib/boot2docker/bootlocal.sh

 

稼働中の Docker コンテナの中に入る例

 

適当なコンテナの起動

任意のコンテナをデーモンモードで起動し、コンテナIDを確認

docker@boot2docker:~$ docker run -d -t centos /bin/sleep 1000
af1ebb57b1cbd0c1f3e02e3f164deb30d2b2ead95f5291545c757c5d33ac6ef7
docker@boot2docker:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
af1ebb57b1cb        centos:latest       /bin/sleep 1000     3 seconds ago       Up 3 seconds                            jolly_poincare
コンテナにアタッチして bash で操作
docker@boot2docker:~$ docker-attach af1e
bash-4.1# cat /etc/redhat-release
CentOS release 6.5 (Final)
bash-4.1# exit
exit

sshd なしで、稼働中のコンテナで bash を扱うことができた。

 

ワンライナーでセットアップする

コピペも面倒、という人向け(自分も含む)にセットアップ用のシェルを書いた。

実行例

docker@boot2docker:~$ curl https://raw.githubusercontent.com/mogproject/docker-attach/scripts-for-nsinit/setup_boot2docker.sh |/bin/sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2552  100  2552    0     0   7973      0 --:--:-- --:--:-- --:--:--  9522
2014-06-24 15:59:05 [INFO] Script started.
2014-06-24 15:59:05 [INFO] Creating directory /var/lib/boot2docker/bin
2014-06-24 15:59:05 [INFO] Installing compilers
gcc.tcz.dep OK
gcc_libs-dev.tcz.dep OK
cloog.tcz.dep OK

(中略)

Downloading: compiletc.tcz
Connecting to repo.tinycorelinux.net (89.22.99.37:80)
compiletc.tcz        100% |*********************************************************************************************|  4096   0:00:00 ETA
compiletc.tcz: OK
Downloading: go.tcz
Connecting to repo.tinycorelinux.net (89.22.99.37:80)
go.tcz               100% |*********************************************************************************************| 36288k  0:00:00 ETA
go.tcz: OK
2014-06-24 16:02:15 [INFO] Building /var/lib/boot2docker/bin/nsinit
2014-06-24 16:03:19 [INFO] Downloading /var/lib/boot2docker/bin/docker-attach
2014-06-24 16:03:19 [INFO] Downloading /var/lib/boot2docker/bootlocal.sh
2014-06-24 16:03:20 [INFO] Linking commands in /usr/local/bin
2014-06-24 16:03:20 [INFO] Script ended successfully.

 

 

References

6.22.2014

Short Trip in Berlin - Helpful Tools

ベルリン出張で役に(立った|立たなかった)ものリスト

 

2014-06-16 〜 2014-06-22 の一週間、Scala Days 2014 に参加するためベルリンに出張していました。

Scala Days のレポートは会社の方に書くとして、なんとか無事帰国できたので
今回の旅で役に立ったもの、役に立たなかったものについて、記憶が新鮮なうちにまとめておきます。

役に立ったもの

  • HyperJuice 2 100W
    ほんとこれ、カンファレンスには必携のガジェットですね。
    MacBook Air を持参したのですがが、Mac自身のバッテリーと合わせて10時間くらいは余裕で稼働可能です。
    さらにUSBポートも付いているので、デジカメの充電にも役立ちました。
    • MacBook に給電するためには別売のケーブルが必要なので注意
    • 機内には手荷物として持参する必要あり
    • 帰りにテーゲル空港で特別室に連れて行かれてチェックを受けることになったのはご愛嬌
  • レンタル WiFi ルータ
    今回は イモトのWiFi を利用。出発時に羽田空港で受け取り。
    日本国内と比べると遅さが気になるものの、3G 通信は殆どの場所で網羅されているようです。
    ホテルの WiFi が非常に遅くストレスフルだったので、このルータがとても活躍しました。
  • 旅の指さし会話帳
    ドイツ語に関する本は何冊か買いましたが、一番役に立ったのはこの本でした。
    基本的に英語が通じるので必要に迫られてドイツ語を話す場面はありませんが、やはり現地の言葉を話すとコミュニケーションが捗ります。
    音声付きの書籍と併用するとベター。

     

役に立たなかったもの

  • 電子辞書
    日英翻訳で辞書をひく場面はなかったですね。
  • 乾電池
    電子辞書用に、と持っていったのですが結局使う機会なし。
  • 電源変換コネクタ
    イモトのWiFi と一緒にレンタルしたのですが、実際のところ殆どのガジェットはUSBで充電できるため、一個あれば十分でした。
    ルータに標準添付の変換コネクタ + 日本から持っていったタコ足ケーブルで事足ります。
  • 正装・革靴
    超高級店とかには行かなかったので、正装の必要性は全くなかったですね。
  • 暇つぶし用の書籍
    結局読む暇がなかった、というオチ。
    移動中の機内は暗いし、眠ってしまうと意外とあっという間に12時間は過ぎてしまいます。(本読むと若干酔うし……)

 

番外編

今回の旅路ではベルリンに在住経験のある、とあるお方と同行できたのが本当に幸運でした。
ベルリンをたっぷり満喫できたのも、その案内人の方のおかげです!

 

 

それにしても、日本語英語中国語ドイツ語を話して万能感に浸っていたところ、帰りの飛行機の隣席がフランス人で
最後にしてやられた感がありました。

Au revoir!

6.16.2014

IVA Reading: Chapter 02, Section 02 Exercises

IVA読書会 chap02-sect02 宿題

 

No.2

a)

$f(x,y,z)=7x^2 y^4 z - 2x y^6 + x^2 y^2$

$\left|(2,4,1)\right|=7, \left|(1,6,0)\right|=7, \left|(2,2,0)\right|=4$

$(2,4,1) \gt _{lex} (1,6,0) \lt _{lex} (2,2,0)$

$(2,4,1) \gt _{grlex} (1,6,0) \gt _{grlex} (2,2,0)$

$(2,4,1) \lt _{grevlex} (1,6,0) \gt _{grevlex} (2,2,0)$

よって grlex 順序。

 

b)

$f(x,y,z)=x y^3 z + x y^2 z^2 + x^2 z^3$

$\left|(1,3,1)\right|=5, \left|(1,2,2)\right|=5, \left|(2,0,3)\right|=5$

$(1,3,1) \gt _{lex} (1,2,2) \lt _{lex} (2,0,3)$

$(1,3,1) \gt _{grlex} (1,2,2) \lt _{grlex} (2,0,3)$

$(1,3,1) \gt _{grevlex} (1,2,2) \gt _{grevlex} (2,0,3)$

よって grevlex 順序。

 

c)

$f(x,y,z)=x^4 y^5 z + 2x^3 y^2 z - 4x y^2 z^4$

$\left|(4,5,1)\right|=10, \left|(3,2,1)\right|=6, \left|(1,2,4)\right|=7$

$(4,5,1) \gt _{lex} (3,2,1) \gt _{lex} (1,2,4)$

$(4,5,1) \gt _{grlex} (3,2,1) \lt _{grlex} (1,2,4)$

$(4,5,1) \gt _{grevlex} (3,2,1) \lt _{grevlex} (1,2,4)$

よって lex 順序。

 

No.8

不等式 (2) によって変数の順序付けが一意となれば、

任意の線型方程式系から得られる行既約階段形も一意的に定められることとなる。

 

6.09.2014

IVA Reading: Chapter 02, Section 01 Exercises

IVA読書会 chap02-sect01 宿題

 

No.1

a)

$f(x)=x^2-3x+2=(x-1)(x-2) \Rightarrow f \in I$

b)

$f(x)=x^5-4x+1=(x+1)(x^3-x^2+x) - x^2-4x+1 \Rightarrow f \notin I$

c)

$I=\langle\text{GCD}(x^4-6x^2+12x-8, 2x^3-10x^2+16x-8)\rangle=\langle1\rangle \Rightarrow f \in I$

d)

$I=\langle\text{GCD}(x^9-1, x^5+x^3-x^2-1)\rangle=\langle x^3-1\rangle \Rightarrow f \in I$

 

PARI/GP を使ってGCDを求めてみる

  • インストール => brew install pari (if Mac)
  • 実行
    $ /usr/local/bin/gp
                                                     GP/PARI CALCULATOR Version 2.5.5 (released)
                                             i386 running darwin (x86-64/GMP-6.0.0 kernel) 64-bit version
                                        compiled: Jun  8 2014, gcc-5.1 (clang-503.0.40) (based on LLVM 3.4svn)
                                                    (readline v6.3 enabled, extended help enabled)
    
                                                        Copyright (C) 2000-2013 The PARI Group
    
    PARI/GP is free software, covered by the GNU General Public License, and comes WITHOUT ANY WARRANTY WHATSOEVER.
    
    Type ? for help, \q to quit.
    Type ?12 for how to get moral (and possibly technical) support.
    
    parisize = 8000000, primelimit = 500509
    ? gcd(x^9 - 1, x^5 + x^3 - x^2 - 1)
    %1 = x^3 - 1
    ? \q
    Goodbye!
    

 

No.5

d)

$f(u,t), g(u,t), h(u,t)$ の全次数が高々 $n$ であるとする。

$a+b+c\le m$ を満たすとき、$[f(u,t)]^a[g(u,t)]^b[h(u,t)]^c$ の $u,t$ についての全次数は高々 $nm = \text{O}(m)$。
∵ $\text{deg}([f(u,t)]^a[g(u,t)]^b[h(u,t)]^c) \le na+nb+nc =n(a+b+c) \le nm$

一方、$x^a y^b z^c$ の線形結合の係数は、$x^a y^b z^c 1^d, a+b+c+d=m$ と考えると重複組合せ問題となり、
${}_{4} H _{m} = {}_{4+m-1} C _{m} = \begin{eqnarray} {}_{m+3} C _3 \end{eqnarray} = (m+3)(m+2)(m+1)/(3\cdot 2\cdot 1)=\Theta(m^3)$ 個存在することがわかる。

十分大きな $m$ に対しては $nm \le (m+3)(m+2)(m+1)/(3\cdot 2\cdot 1)$ が満たされるため
全問までの議論と同様、
$F(f(t),g(t),h(t))$ が $t,u$ の多項式として $0$ になるような $F \in k[x,y,z]$ をとることが可能。

従って、$S: x=f(t,u), y=g(t,u), z=h(t,u)$ に対して $S \subset {\bf V}(F)$ となる $F \in k[x,y,z]$ が存在する。

 

 

 

References

6.02.2014

IVA Reading: Chapter 01, Section 05 Exercises

IVA読書会 chap01-sect05 宿題

 

No.5

イデアルの基底から左辺右辺のお互いの多項式が生成できることを示す。

$ \forall q \in k[x], \\ 1\cdot(f-qg) + q\cdot g = f \\ 0\cdot(f-qg) + 1\cdot g = g $

より、 $\langle f - qg, g \rangle \supset \langle f, g \rangle$

また、

$ \forall q \in k[x], \\ 1\cdot f + (-q)\cdot g = f - qg \\ 0\cdot f + 1\cdot g = g $

より、
$\langle f - qg, g \rangle \subset \langle f, g \rangle$

従って、$\forall q \in k[x], \langle f - qg, g \rangle = \langle f, g \rangle$

 

No.11

a)

セクション1 定理7: あらゆる定数でない多項式 $f \in \mathbb{C}[x] $ は $\mathbb{C}$ 上に根を持つ

より、
$f \text{ is nonconstant polynomial} \Rightarrow \text{deg}(f) > 0 \Rightarrow {\bf V}(f) \ne \emptyset$

対偶を取ると、
${\bf V}(f) = \emptyset \Rightarrow f \text{ is constant}$

一方、明らかに
$f \text{ is constant} \Rightarrow \text{deg}(f) = 0 \Rightarrow {\bf V}(f) = \emptyset$

従って
${\bf V}(f) = \emptyset \Leftrightarrow f \text{ is constant}$

 

b)
${\bf V}(f_1,...,f_s) \ne \emptyset$ であるならば、$f_1 = \cdots = f_s = 0$ は$x$について1個以上の解を得る。

その解の一つを $x=a$ とすれば、$f_1,...,f_s$ は全て $(x-a)$ で割り切れるため、$\text{GCD}(f_1,...,f_s) \ne 1$ ...(1)

また、$\text{GCD}(f_1,...,f_s) \ne 1$ である場合を考える。

$\text{GCD}(f_1,...,f_s) = g$ とおくと、
${\bf V}(f_1,...,f_s) = {\bf V}(\text{GCD}(f_1,...,f_s)) = {\bf V}(g)$ と書ける。
$g$ は非定数であるから前問の対偶から、${\bf V}(f_1,...,f_s) = {\bf V}(g) \ne \emptyset$ ...(2)

(1), (2) の対偶を取れば
${\bf V}(f_1,...,f_s) = \emptyset \Leftrightarrow \text{GCD}(f_1,...,f_s)=1$

c)
前問より

$\text{GCD}(f_1,...,f_s) = 1 \Rightarrow {\bf V}(f_1,...,f_s) = \emptyset$

$\text{GCD}(f_1,...,f_s) \ne 1 \Rightarrow {\bf V}(f_1,...,f_s) \text{ is nonempty}$

 

No.17

$\begin{eqnarray*} & & {\bf I}({\bf V}(x^5 - 2x^4 + 2x^2 - x, x^5 - x^4 - 2x^3 + 2x^2 + x - 1)) \\ &=& {\bf I}({\bf V}(\text{GCD}(x^5 - 2x^4 + 2x^2 - x, x^5 - x^4 - 2x^3 + 2x^2 + x - 1))) \\ &=& {\bf I}({\bf V}(x^4 - 2x^3 + 2x - 1)) \end{eqnarray*} $

ここで $f = x^4 - 2x^3 + 2x - 1$ とすると、Exercise 15.b より

$\begin{eqnarray*} f_{\text{red}} &=& \frac{f}{\text{GCD}(f, f')} \\ &=& \frac{x^4 - 2x^3 + 2x - 1}{\text{GCD}(x^4 - 2x^3 + 2x - 1, 4x^3 - 6x^2 + 2)} \\ &=& \frac{x^4 - 2x^3 + 2x - 1}{x^2 - 2x + 1} \\ &=& x^2 - 1 \end{eqnarray*}$

Exercise 12.b より

$\begin{eqnarray*} & & {\bf I}({\bf V}(x^5 - 2x^4 + 2x^2 - x, x^5 - x^4 - 2x^3 + 2x^2 + x - 1)) \\ &=& {\bf I}({\bf V}(f)) \\ &=& \langle f_{\text{red}}\rangle \\ &=& \langle x^2 - 1 \rangle \end{eqnarray*} $

6.01.2014

Python: How to Send an E-mail

Python: Eメールの送信

 

何度も車輪の再発明を繰り返しているが、今のところちょっとしたスクリプトにおいては
以下の内容で落ち着いている。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import ConfigParser
import codecs
import smtplib
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate

# load config
CONF_PATH = os.path.join(os.path.dirname(__file__), 'mail_sender.conf')

config = ConfigParser.SafeConfigParser()
config.readfp(codecs.open(CONF_PATH, 'r', 'utf-8'))

SMTP_SERVER = config.get('system', 'smtp-server')
SMTP_PORT = config.getint('system', 'smtp-port')


class MailSender(object):
    """General mail sending class"""

    def __init__(self, project_id):
        self.from_addr = config.get(project_id, 'from-address')
        self.to_addr_list = [a.strip() for a in config.get(project_id, 'to-address-list').split(',')]

    def send(self, subject, body, from_addr=None, to_addr_list=None):
        """send a message using SMTP"""

        if from_addr is None:
            from_addr = self.from_addr
        if to_addr_list is None:
            to_addr_list = self.to_addr_list
        msg = MailSender.__create_message(from_addr, to_addr_list, subject, body)

        s = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        s.sendmail(from_addr, to_addr_list, msg.as_string())
        s.close()

    @staticmethod
    def __create_message(from_addr, to_addr_list, subject, body, encoding='iso-2022-jp'):
        """create MIMEText object"""

        msg = MIMEText(body.encode(encoding), 'plain', encoding)
        msg['Subject'] = Header(subject, charset=encoding, header_name='Subject')
        msg['From'] = from_addr
        msg['To'] = ','.join(to_addr_list)
        msg['Date'] = formatdate(localtime=True)
        return msg


if __name__ == '__main__':
    # test code
    #MailSender('awesome-project').send(u'TITLE', u'THIS IS A TEST MAIL!')
    pass

同じ階層に conf ファイルを置く。

[system]
smtp-server: {{ smtp_server }}
smtp-port: {{ smtp_port }}

[awesome-project]
from-address: {{ from_address }}
to-address-list: {{ to_address_list }}

{{ }} の部分は適宜書き換え。to_address_list はカンマ区切りで複数指定可能。

Python: How to Log Message to SysLog

Python: SysLog にメッセージを書き込む方法

 

syslog パッケージを使う。

 

使用例

スクリプトファイル中での使用を想定。

import sys
import os
import syslog

def log_syslog(priority, message):
    prefix = {
        syslog.LOG_ERR: 'ERROR',
        syslog.LOG_WARNING: 'WARN',
        syslog.LOG_INFO: 'INFO',
    }[priority]
    syslog.openlog(os.path.basename(sys.argv[0]))
    syslog.syslog(priority, '%-7s%s' % ('[%s]' % prefix, message))

def log_error(message):
    log_syslog(syslog.LOG_ERR, message)

def log_warn(message):
    log_syslog(syslog.LOG_WARNING, message)

def log_info(message):
    log_syslog(syslog.LOG_INFO, message)

log_error("error message")
log_warn("warn message")
log_info("info message")

SysLog の内容

May 31 15:11:34 xxxx syslog_test.py: [ERROR]error message
May 31 15:11:34 xxxx syslog_test.py: [WARN] warn message
May 31 15:11:34 xxxx syslog_test.py: [INFO] info message