cygwin+vagrant(virtualbox)+ansibleの動作確認メモ
virtual boxとvagrantのインストール
まず、virtual boxとvagrantのバイナリを公式サイトからDLしてインストールする。 特にハマリポイントはなし。
cygwinからvagrantを操作
vagrantの実行パスが環境変数に追加されており、cygwinのために 何も設定をすることなく普通にcygwinターミナルからvagrantコマンド実行可能。
ansibleのインストール
以下を参考に。
- http://qiita.com/kutsushitaneko/items/ad3ac7c712de4cb81963
- http://chiranoura.nobody.jp/articles/2014-03-04_01_how_to_install_pip_and_setuptools/
まず、以下をcygwinのsetup.exeを使ってインストール。
- python
- python-paramiko
- python-crypto
- python-setuptools
- gcc-core
- gcc-g++
- make
- wget
- openssh
- libyaml-devel
次に、setuptoolsのeasy_installコマンドを使ってpipをインストール。 単純に、easy_install pipとすると以下の様な感じでなぜかエラーになるので注意。
$ easy_install-2.7 pip Couldn't find a setup script in /c/Users/kj".
以下の様にして直接tar ballをインターネットからDLする。
$ easy_install https://pypi.python.org/packages/source/p/pip/pip-1.4.1.tar.gz
そして、pipを使ってansibleをインストール
$ pip ansible
ansibleの動作確認
下記を参考に。
- http://blog.s-uni.net/2013/08/27/ansible-running-on-cygwin/
- http://momijiame.tumblr.com/post/78187543848/vagrant-%E3%81%A8-ansible-%E3%82%92%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A6%E4%BD%BF%E3%81%86
vagrantでhost01という名前のVMを起動しているとき、以下のようにすることでansibleでhost01へアクセス、操作ができる。
$ vagrant ssh-config >> ~/.ssh/config $ sed -i 's/Host default/Host host01/' ~/.ssh/config
- ansibleでアクセスするhostの一覧を列挙。ここではhost01のみ列挙。
$ cat << EOS > hosts host01 EOS
$ cat << EOS > ansible.cfg [defaults] hostfile = hosts [ssh_connection] ssh_args = -o ControlMaster=no EOS
動作確認。
$ ansible host01 -m ping host01 | SUCCESS => { "changed": false, "ping": "pong" } $ ansible host01 -a 'uname -a' host01 | SUCCESS | rc=0 >> Linux ubuntu 4.2.0-30-generic #36-Ubuntu SMP Fri Feb 26 00:58:07 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
以上。
PythonでバイナリデータをパックしてUDPメッセージを送ってみる
はじめに
PythonでバイナリデータをパックしてUDPメッセージを送るには、struct
モジュールを使う。簡単な使い方はPy MOTW: struct – Working with Binary Dataで確認できる。本エントリでは、struct
モジュールの使い方を押さえ、UDP上のバイナリデータで構成されたプロトコルであるGTPv2のEcho Requestメッセージを試しに送信してみる。
GTPv2のEcho RequestメッセージのプロトコルフォーマットはドコモのネットワークにGTP接続(レイヤー2)するためのメモのエントリで参照した以下のドキュメントで確認できる。
- GTPv2-C: 3GPP TS29.274 v11.5.0
- ドコモ 技術的条件集
structモジュールでバイナリデータをパック、アンパック
前準備として、struct
モジュールの使い方を押さえる。
structモジュールはデータのパック方法として、関数レベルとクラスレベルの2つを用意している。データをパックするときには、フォーマット文字列(例えば、データがネットワークバイトオーダで4オクテットである、とか)を指定する必要がある。Py MOTW: struct – Working with Binary Dataによると、関数レベルのパッキングを利用する場合、フォーマット文字列はパッキングの際に毎度コンパイルされるのに対し、クラスレベルのパッキングを利用する場合、オブジェクトをインスタンス化するときにフォーマット文字列をコンパイルするため、データのパッキングが高速になるとのこと。 よって、ここでは、クラスベースのパッキングをしてみる。
まず、フォーマット文字列として、データがネットワークバイトオーダで4オクテットであることを指定してオブジェクトをインスタンス化するには以下のように、ネットワークバイトオーダを示す"!"と4オクテットであることを示す"i"をコンストラクタの引数に与える。フォーマット文字列の詳細はpythonのマニュアルで確認することができる。
>>> import struct >>> s = struct.Struct("!i") >>> s <Struct object at 0x7f7e09518880>
例えばバイナリデータとして、"0x04 0x03 0x02 0x01"で構成される4オクテットのデータを作り、上記のフォーマット文字列でパッキングするには以下のようにする。
>>> data = (0x04 << 24) + (0x03 << 16) + (0x02 << 8) + 0x01 >>> packed_data = s.pack(data) >>> packed_data b'\x04\x03\x02\x01'
上記の例は、フォーマット文字列として、ネットワークバイトオーダで1オクテットを4つ並べ、以下のようにもできる。
>>> s = struct.Struct("!BBBB") >>> data = [0x04, 0x03, 0x02, 0x01] >>> packed_data = s.pack(*data) >>> packed_data b'\x04\x03\x02\x01'
パックしたデータををUDPで送信するには、socket
モジュールのsendto
の引数にパックしたデータを渡せば良い。
パックしたデータをアンパックするときもパックするときと同様に、まずフォーマット文字列を指定してオブジェクトをインスタンス化し、パックされたデータをunpack
メソッドの引数に渡せば良い。
>>> s1 = struct.Struct("!BBBB") >>> packed_data = s1.pack(*data) >>> s1.unpack(packed_data) (4, 3, 2, 1)
GTPv2のEcho RequestメッセージをUDPで送信
それでは、試しにGTPv2のEcho Requestメッセージをバイナリデータとして構成し、パッキングし、UDPで送信してみる。 用意したプログラムは下記の2つ。 * gtpv2c.py - GTPv2のメッセージは、ヘッダと情報要素(Information Element, IE)で構成される。本ファイルでは、これらのデータを定義する。 - 本ファイルでは、パッキングするフォーマット文字列とバイナリデータの構築のみを行う。 * send_gtpv2c.py - 本ファイルにおいて、gtpv2c.pyを読み込み、そこで定義されたEcho RequestのヘッダとIEを組み立て、パッキングし、UDPでデータ送信する。
gtpv2c.py
#!/usr/bin/env python3 PORT = 2123 ECHO_REQUEST = 1 # ... RECOVERY_TYPE = 3 # ... def header(msg_type, msg_len, teid=None, seq_no=None): version = 2 p = 0 # piggyback off formatter = "!i" octets = [] octets1_4 = 0 octets1_4 += version << 29 octets1_4 += p << 28 if teid != None: octets1_4 += 1 << 27 octets1_4 += msg_type << 16 octets1_4 += msg_len octets.append(octets1_4) if teid != None: formatter += "i" octets.append(teid) if seq_no != None: formatter += "i" octets.append(seq_no << 8) return [ formatter, octets ] def recovery_ie(ins_id, recovery_val): ie_len = 5 formatter = 'ib' octets = [] octets1_4 = 0 octets1_4 += RECOVERY_TYPE << 24 octets1_4 += 1 << 8 octets1_4 += ins_id octets.append(octets1_4) octets.append(recovery_val) return [ ie_len, formatter, octets ]
send_gtpv2c.py
#!/usr/bin/env python3 import socket import time from contextlib import closing import gtpv2c import struct if __name__ == '__main__': host = '127.0.0.1' port = gtpv2c.PORT sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) with closing(sock): ie_len, ie_f, ie_msg = gtpv2c.recovery_ie(0, 100) hdr_f, hdr_msg = gtpv2c.header(gtpv2c.ECHO_REQUEST, ie_len, None, 1234) s = struct.Struct(hdr_f + ie_f) msg = hdr_msg + ie_msg packed_data = s.pack(*msg) sock.sendto(packed_data, (host, port))
サンプルプログラムの実行
以下のようにコマンドを実行し、ローカルホストにgtpv2 echoメッセージを送信し、
$ chmod +x send_gtpv2c.py $ ./send_gtpv2c.py
ドコモのネットワークにGTP接続(レイヤー2)するためのメモ
ドコモMVNOのSORACOMも使っているGTP接続について信号レベルのメモ。
参考URL
- ドコモ 技術的条件集
- 700ページ以上に渡る長大なドキュメントだけど、うまく整理されていて、ポイントが押さえられている感じ
はじめに
ドコモのネットワーク、具体的にはドコモのServing GW (SGW)にGTP接続するためには PDN GW (PGW)を用意する必要がある。 GTPプロトコルは、C-planeプロトコル (GTPv2-C)とU-planeプロトコル (GTPv1-U)がある。 ドコモが準拠しているプロトコル仕様は、2016.1.7現在、以下のとおり。
- GTPv2-C: 3GPP TS29.274 v11.5.0
- GTPv1-U: 3GPP TS29.281 v11.5.0
なお、GTPv2-Cに関するシーケンスは3GPP TS23.401v8.7.0に準拠している。
技術的条件集で使わている装置の用語と3GPPで使われている用語の対応 - 直収パケット交換機: SGW - 直収回線等接続事業者ノード: PGW
GTPv2-C
- 技術的条件集の別表10-1-1 アクセス制御プロトコル仕様 (pp.581-624)に詳細仕様の記述がある
- TS29.274を参照しなくても、基本的にここに書かれている情報で大体のことがわかる
- サポートする必要がある信号
- ノード監視処理(Echo Request/Echo Response)
- セッション設定処理(Create Session Request/Create Session Response)
- ベアラ更新処理(Modify Bearer Request/Modify Bearer Response)
- セッション削除処理(Delete Session Request/Delete Session Response)
- ベアラ切断処理(Delete Bearer Request/Delete Bearer Response)
複数のPGWノードと接続させたい場合
技術的条件集によると
ユーザが接続先として指定するAPN1アドレスに対し最大8台(※1)の直収回線 等接続事業者ノードに分散させることが可能です。 ... ※1 直収回線等接続事業者1ノードにつき1つのGTPv2-C用ノードIPアドレスを 付与することを前提とします。(複数のノードを論理的に1つのノードとして GTPv2-C用ノードアドレスを1つ付与する場合は、直収パケット交換機で分散し ません。)
つまり、APN 1アドレスにつき、8つのPGW (C-plane) IPアドレスをドコモネットワーク側で 登録してもらえる(のだと思う)。
GTPv1-U
- 技術的条件集の別表10-1-2 ユーザデータ転送プロトコル仕様 (pp.625-640)に詳細仕様の記述がある
- TS29.281を参照しなくても、基本的にここに書かれている情報で大体のことがわかる
- サポートする必要がある信号
- ユーザデータ転送処理(G-PDU)
- エラーデータ処理(Error Indication)
- ノード監視処理(Echo Request/Echo Response)
シーケンス
- 技術的条件集別表10-1-3 シーケンス (pp.662-676)に正常系・準正常系のシーケンス図が描かれている
- GTPv2-C関連 (カギカッコ内はTS23.401のInformation flow名に対応)
- 接続処理 [Attach]
- 接続終了処理(移動無線装置起動)[Detach]
- 接続終了処理(直収回線等接続事業者網起動)[PDN GW initiated bearer deactivation]
- 直収パケット交換機変更 [Tracking/Routing Area Update, Service Request, Handover]
- 監視制御(GTPv2-U) [対応なし]
- 再開 (対応なし) [対応なし]
- GTPv1-U関連
- ユーザデータ転送 [対応なし]
- 監視制御(GTPv1-U) [対応なし]
openstack+lxdのインストールメモ
参考URL
- http://events.linuxfoundation.org/sites/events/files/slides/ContainerCon%202015-%20LXD%20%26%20OpenStack.pdf
- http://ossan-engineer.blogspot.jp/2015/09/devstacklxd.html
- https://insights.ubuntu.com/2015/05/06/introduction-to-nova-compute-lxd/
- https://linuxcontainers.org/lxd/getting-started-openstack/
- https://github.com/lxc/lxd
- https://github.com/lxc/nova-compute-lxd/tree/master/devstack
前提条件
ubuntu 15.10 server editionを使用。
ubuntu server上でintel vtが有効になっているか確認
※lxcを使うなら不要かも
stack@devstack00:~$ cat /proc/cpuinfo |grep vmx flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf eagerfpu pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt aes xsave avx f16c rdrand hypervisor lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi ept vpid fsgsbase smep
ubuntu serverの設定(IPアドレスの固定化)
/etc/network/interfaceを以下のように編集
※以下でethXとしている部分は、enoxxxに読み替える
auto eth0 iface eth0 inet static address 192.168.1.20 netmask 255.255.255.0 gateway 192.168.1.2 dns-nameservers 192.168.1.2 auto eth1 iface eth1 inet static address 0.0.0.0
ネットワークの再起動
sudo ifdown eth0 && sudo ifup eth0 sudo ifdown eth1 && sudo ifup eth1
githubからdevstackのDL
$ cd ~ $ git clone https://github.com/openstack-dev/devstack.git -b stable/liberty
local.confの編集
$ cat << _EOT_ > ~/devstack/local.conf [[local|localrc]] SERVICE_TOKEN=azertytoken ADMIN_PASSWORD=nomoresecrete MYSQL_PASSWORD=stackdb RABBIT_PASSWORD=stackqueue SERVICE_PASSWORD=$ADMIN_PASSWORD HOST_IP=192.168.1.20 FIXED_RANGE=10.0.0.0/24 FIXED_NETWORK_SIZE=256 FLAT_INTERFACE=eth1 ENABLED_SERVICES=rabbit,mysql,key ENABLED_SERVICES+=,n-api,n-crt,n-obj,n-cpu,n-cond,n-sch,n-novnc,n-cauth ENABLED_SERVICES+=,neutron,q-svc,q-agt,q-dhcp,q-l3,q-meta ENABLED_SERVICES+=,g-api,g-reg ENABLED_SERVICES+=,horizon Q_PLUGIN=ml2 Q_AGENT=openvswitch Q_USE_DEBUG_COMMAND=True Q_L3_ENABLED=True Q_L3_ROUTER_PER_TENANT=True ENABLE_TENANT_TUNNELS=True LOGFILE=$DEST/logs/stack.sh.log LOGDAYS=2 enable_plugin nova-lxd https://github.com/lxc/nova-compute-lxd FORCE=yes GIT_BASE=https://git.openstack.org _EOT_
lxc用のイメージ登録
wget -O vivid-server-cloudimg-amd64-root.tar.gz https://cloud-images.ubuntu.com/vivid/current/vivid-server-cloudimg-amd64-root.tar.gz glance image-create --name='lxc' --container-format=bare --disk-format=raw < vivid-server-cloudimg-amd64-root.tar.gz
※このイメージには/etc/network/interfaces.d配下に、eth0.cfgしかない。 複数NICでdhcp使うなら、eth[1-N].cfgの設定ファイルも入れておく必要あり。
トラブルシューティング
コンテナが起動できない
No valid host was found. There are not enough hosts available を回避する方法。 n-condをみると、config-driveを使おうとしている模様。 nova.confでconfig-driveが強制的に使用するようになっているので、 それをやめる。
vi /etc/nova/nova.conf ... force_config_drive = False ...
screenに入って、n-condのプロセスを再起動
ダッシュボードからconsoleアクセス出来ない
TODO: novncの設定を見直す。未対処。 ただし、ubuntu cloudイメージはconsoleアクセスを許容していなかったような。 コンソールアクセスしたかったらイメージ側も対処する必要があるかもしれない。
openstack-lxdのコンテナをlxc-lsで確認
lxc-ls -P /var/lib/lxd/containers/ --fancy
openstack-lxdのコンテナの内部に入る
sudo lxc-attach -P /var/lib/lxd/containers -n instance-00000007
Nexus 7 (2012)をAndroid 5(公式)からAndroid 6 (カスタムROM)にするメモ
Nexus 7 (2012)をAndroid 5 Lollipopに更新してから、動作のモッサリ感が半端無く、 使用に耐えられなかったため、カスタムROM (pure nexus project)を使ってNexus 7を Android 6 Marshmallowにしてみたら、動作が非常に軽くなった!
今のところYoutubeくらいしか使っていないので、動作の安定性のほどはよく わかっていない使っているとアプリが落ちたり、急にリブートしたりというような ことにはなっていない。
以下はnexus 7 (2012)をandroid 5(公式)からandroid 6 (カスタムROM)にするメモ。
参考URL
- Android端末(Nexus)のroot化・カスタムROMの導入と更新
- このページからリンクをたどり、色々勉強させてもらいました
- Nexus 7 [2012]にThe Pure Nexus Project 20151221を焼いてみた
現在のnexus 7 (2012)のタブレット情報
事前準備
nexus 7から必要なデータをPCにバックアップしておく。
PC上でADBコマンドを使えるようにする
以下のページを参考に、PC (windows 10)にJDKとAndroid SDKをインストールする。 - 【ADB】Java(JDK)とAndroid SDKを導入してADBコマンドを使えるようにする - ADB,Bootloaderのドライバについては、自分でインストールせずとも自動的に 入る?ようだったので特にインストール作業をしていない
Bootloader(ブートローダ)のUnlock(アンロック)
以下のページを参考に、bootloaderをアンロックする。 - Bootloader(ブートローダー)の起動手順 - Bootloader(ブートローダー)のUnlock(アンロック) - NOTE: 参考ページでは、「※Android 5.0以上の端末では、あらかじめOS起動状態で 「開発者向けオプション」の「OEMロック解除」にチェックを入れておいて下さい。」と 書かれていたが、自分のNexus 7には「OEMロック解除」の項目が見当たらなかったので、 この手順はスキップ。
具体的には、 - Nexus 7をUSBでPCにつなぎ、PCのコマンドプロンプトから、下記のコマンドを実行 することでNexus 7のブートローダを起動する。
adb reboot bootloader
fastboot oem unlock
- この時点で全てのデータが消される。
- アンロックが完了して、Nexus 7が再起動すると5~10分程度たったあと、
"Welcome"のページが出る。
- 日本語を選択し、インストールを続行して、完了させるが、このインストールは 一時的なもので、再度カスタムROMをインストールするときにデータを消去するため 諸々の手続きはスキップしてよい
カスタムリカバリ(TWRP: Team Win Recovery Project)のインストール
下記のページを参考に、TWRPをNexus 7にインストールする。 - 【TWRP】Team Win Recovery Project(チームウィンリカバリプロジェクト:TWRP)の起動と操作・使用
具体的には、 - PCを使い、最新版のtwrp 2.8.7.0をDLする。 - TWRPをダウンロードしたフォルダでコマンドプロンプトを起動し、下記のコマンドを 実行することでTWRPを起動する。
fastboot boot twrp-2.8.7.0-grouper.img
- TWRP起動後、Backupのボタンをタップし、バックアップ
- デフォルトの選択状態(System, Data, Boot)でSwipe to Back Up
- データは/DATA/MEDIA/0/twrp/BACKUS/...配下に保存される
- 124秒でバックアップ完了→Reboot Systemをタップ。
- SuperSUをインストールされるか聞かれるので"Swipe to install"
- ※custom ROMを後でインストールするので、このタイミングでsuperSUのインストールは不要だったかも。
- 再起動後、念のため、PCにバックアップファイルをコピーする
- デフォルトの選択状態(System, Data, Boot)でSwipe to Back Up
SuperSUのインストール
TWRPでインストール時に部分的にSuperSUのインストールができている。 Nexus 7起動後、アプリのドロワー画面を開くと、SuperSu Installerがあるので タップ→Playを選択し、インストールを完了させる。 - あとから見返すと、このタイミングでsuperSUのインストールは不要だったかも。
カスタムROMのインストールに必要なデータをPCにDLし、Nexus 7にコピー
PCで[UNOFFICIAL][ROM][GROUPER][6.0.1_r3]★ The Pure Nexus Project ★ Layers ★ [12/21/15] のRom Builds からpure_nexus_grouper-6.0.1-20151221.zip をDL。
同様に [UNOFFICIAL][ROM][GROUPER][6.0.1_r3]★ The Pure Nexus Project ★ Layers ★ [12/21/15] のRecommended Gapps: Open Gapps (Nano or Pico) からPlaform: ARM, Android: 6.0, Variant: nano をDL。
DLしたファイルをNexsus 7のDownloadsフォルダにコピー。PCからNexus 7のフォルダが見えなかったので、 下記のページを参考にNexus 7の設定で開発者向けオプションを表示させてUSBデバッグをオンにして実施。 - Android 5.0 LollipopのNexus9の開発者向けオプションを表示させてUSBデバッグをオンにする方法。
TWRPでAndroidシステムをwipeし、DLしたAndoid6とGappsをインストール
以下を参考にwipe, インストール。インストール完了後、システムを再起動。 - Android端末(Nexus)のroot化・カスタムROMの導入と更新 - インストールするときには、android6とgappsのzipファイル両方を選択する。 - 【TWRP】Team Win Recovery Project(TWRP)でのカスタムROMの書き込み(ROM焼き)
具体的には、 - PC上で、TWRPをダウンロードしたフォルダでコマンドプロンプトを起動し、下記のコマンドを 実行することでTWRPを起動する。
fastboot boot twrp-2.8.7.0-grouper.img
- TWRP起動後、Wipeのボタンをタップし、更にAdvanced Wipeをタップする
- Internal Storage以外の項目にチェックを入れ、Swipe to Wipe
- Wipeが完了したらBackボタンをタップ
- Installボタンをタップし、DownloaddsフォルダにコピーしておいたAndroid 6 (pure_nexus_grouper-6.0.1-20151221.zip)を選択
- Add More Zipsボタンをタップし、DownloaddsフォルダにコピーしておいたGapp (open_gapps-arm-6.0-nano-20151225.zip)を選択
- Swipe to Confirm FlashでAndroid 6とGappをNexus 7に書き込む
- 書き込みが完了したら、Reboot Systemボタンをタップし、Nexus 7を再起動。
上記の手順を踏むことで、Nexus 7にカスタムROMのAnroid 6が起動する。