そういや書いたことないな.と思ったので書いた.
作ってみると中々面白く, 色々なパターンを試してみたくなる.
引き込まれるというのも納得である.
バグってなけりゃいいけど.
(テストとか書いてないし)
こんな感じ
block
glider
ハチの巣
そういや書いたことないな.と思ったので書いた.
作ってみると中々面白く, 色々なパターンを試してみたくなる.
引き込まれるというのも納得である.
バグってなけりゃいいけど.
(テストとか書いてないし)
CentOS7で試します.
UbuntuでUpstartを使った例の延長です.
UbuntuでUpstartを使ってプログラムをデーモン化する
プログラムは前回と同様のサンプルを使います.
挨拶するだけの単純なものです.
package main import ( "net/http" "fmt" ) func main() { http.HandleFunc("/", helloHandler) http.ListenAndServe(":8080", nil) } func helloHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello\n") }
これをhelloというプログラム名でビルドします.
$ go build -o hello
CentOS7の場合は下記に作ります. 他のOSも同じかな?調べてませんが.
/etc/systemd/system
実は下記にもUnitファイルがあり, 上記を優先して利用する仕組みだそうです.
/usr/lib/systemd/system
管理者が変更する場合は/etc下へコピーして変更で運用するようです.
シンプルな例を探して試しました.
これを
/etc/systemd/system/hello.service
として保存します.
;はコメント #もコメント [Unit] # 説明文 Description = Hello Server [Service] # サービス起動時のコマンド ExecStart = /opt/hello-svr/hello # サービス停止コマンド$MAINPIDはメインプロセスのPID参照に利用できる ExecStop = /bin/kill -HUP $MAINPID # サービス再起動コマンド$MAINPIDは上述通り ExecReload = /bin/kill -HUP $MAINPID && /opt/hello-svr/hello # alwaysを指定するとプロセスが死んだ際に常に自動起動する # デフォルトのnoなら死んだまま Restart = no # 起動完了の判定条件. # フォアグラウンドで起動するプログラムはとりあえずsimpleでいい様なので指定. # forkしてコマンドが終わるタイプはforkingにすればいいらしい Type = simple [Install] # 旧来のrunlevelの概念にあたるようです. # multi-user.target: runlevel:3に相当 # graphical.target: runlevel:5に相当 # 他はman読む方がよさそう WantedBy = multi-user.target
当然ですが.
$ sudo cp ~/hello /opt/hello-svr/hello
$ sudo systemctl list-unit-files --type=service | grep hello hello.service disabled
$ sudo systemctl enable hello
$ sudo systemctl enable hello Created symlink from /etc/systemd/system/multi-user.target.wants/hello.service to /etc/systemd/system/hello.service. $ systemctl status hello ● hello.service - Hello Server Loaded: loaded (/etc/systemd/system/hello.service; enabled; vendor preset: disabled) Active: active (running) since 月 2017-07-17 19:03:03 PDT; 21s ago Main PID: 30660 (hello) CGroup: /system.slice/hello.service └─30660 /opt/hello-svr/hello
$ curl localhost:8080 Hello
$ sudo systemctl restart hello
$ sudo systemctl stop hello
他にも色々出来そうですが, とりあえず今はこれが精一杯.
Systemdを使ってさくっと自作コマンドをサービス化してみる
最初から入ってるかもしれない.
簡単だったけど, やったことなかったしメモ.
入ってたら必要なさそうだけど.
# yum install mariadb mariadb-server
UTF8へ.
必要ならどうぞ.
# vi /etc/my.cnf [mysqld] .... character-set-server=utf8 #<= 追記
# systemctl enable mariadb.service # systemctl start mariadb.service
# mysql_secure_installation [Y/n]がたくさん出るけど手抜きの時は基本全部[Enter] rootパスワードだけは入力した. 解説が親切なので特別心配も要らない.
普通にmysqlコマンド使えるんすね.
# mysql -u root -p Enter password:[rootのパスワード] Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 11 Server version: 5.5.52-MariaDB MariaDB Server Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]>
表示がMariaDBになっててようやく気付くレベル.
互換性意識されててよい.というかまぁ, forkだもんね.
データベースのマイグレーションツールで自分に合ったのを探していて, 割といいのを見つけたので使い方をメモしておく.
自分としては
を備えているのが欲しかった.
gooseは最後の以外は満たしているのでかなりいい感じ.
ここは定番で.
$ go get bitbucket.org/liamstask/goose/cmd/goose
ただし, Windowsの場合SQLiteを使うせいかビルドエラーになる.
$ go get bitbucket.org/liamstask/goose/cmd/goose # bitbucket.org/liamstask/goose/cmd/goose C:\Go\pkg\tool\windows_amd64\link.exe: running gcc failed: exit status 1 /usr/lib/gcc/x86_64-pc-msys/5.3.0/../../../../x86_64-pc-msys/bin/ld: -lmingwex が見つかりません /usr/lib/gcc/x86_64-pc-msys/5.3.0/../../../../x86_64-pc-msys/bin/ld: -lmingw32 が見つかりません /usr/lib/gcc/x86_64-pc-msys/5.3.0/../../../../x86_64-pc-msys/bin/ld: -lmingwex が見つかりません /usr/lib/gcc/x86_64-pc-msys/5.3.0/../../../../x86_64-pc-msys/bin/ld: -lmingw32 が見つかりません collect2: エラー: ld はステータス 1 で終了しました
ここで書いた時の現象と一緒だし, たぶんそう.
解決するにはTDM GCCを入れてコマンドプロンプトからgo getを実行しなおせばいい.
(MSYS2だと動作しないので注意.たぶんCygwinもじゃないかなぁ)
何がともあれディレクトリを作ります. 名前はdbでないとダメなようで.(-pathオプションで変えられますが)
$ mkdir db
設定ファイルが必要になるが, 面倒なのでサンプルをコピーしてくる.
$ cd db/ $ cp $GOPATH/src/bitbucket.org/liamstask/goose/db-sample/dbconf.yml ./
後は接続先に合わせて変更する.
サンプルはPostgresだったので, ここではMySQLにしておく.
(mymysqlは誤植ではない, 使うgolangのドライバを明示的に指定している)
development: driver: mymysql open: [DB名]/[ユーザ名]/[パスワード]
MySQLにログインして, データベースも作っておきましょう.
> CREATE DATABASE demo;
接続確認のために状態確認する.
$ goose status goose: status for environment 'development' Applied At Migration =======================================
ここまで来るとかなり単純.
というか単純なものが欲しかったんだけど.
マイグレーションファイルを作るには以下のコマンドを使います.
$ goose create [テーブル名] sql
とりあえずUsersテーブルを作ってみる.
$ goose create users sql goose: created C:\msys64\home\twinbird\dropbox\lab\sample\db\migrations\20170623171909_users.sql
出来たファイルを編集.
$ vi db/migrations/20170623171909_users.sql
こんなのが出来てます.シンプルでいいっすね.
-- +goose Up -- SQL in section 'Up' is executed when this migration is applied -- +goose Down -- SQL section 'Down' is executed when this migration is rolled back
それぞれ編集します.
-- +goose Up -- SQL in section 'Up' is executed when this migration is applied CREATE TABLE users( id SERIAL, name varchar(20), email varchar(20) ); -- +goose Down -- SQL section 'Down' is executed when this migration is rolled back DROP TABLE users;
いよいよ, マイグレーションしましょう.
$ goose up goose: migrating db environment 'development', current version: 0, target: 20170623171909 OK 20170623171909_users.sql
うまくいきました.
そのままです.
$ goose down goose: migrating db environment 'development', current version: 20170623171909, target: 0 OK 20170623171909_users.sql
バージョンはタイムスタンプそのままみたいですね.
$ goose dbversion
goose: dbversion 20170623171909
過去のコミットまで戻った時は便利そうです.
$ goose redo goose: migrating db environment 'development', current version: 20170623171909, target: 0 OK 20170623171909_users.sql goose: migrating db environment 'development', current version: 0, target: 20170623171909 OK 20170623171909_users.sql
自分が求めていたものが大体満たされていて非常に良い感じ.
自作しようかと思っていたけど, 作らなくてよかった.
ドキュメント読むとGo Migrationsってのもあるけど, これは使いそうにないなぁ.
要するに, CentOS7からSambaでWindowsネットワークをマウントしたい.
# yum install samba-client cifs-utils
# firewall-cmd --permanent --zone=public --add-service=samba
smbclient -L [Windowsホスト名]
# mount -t cifs -o user=[共有フォルダのマシンのユーザ],password=[共有フォルダのマシンのパスワード] //[サーバIP]/[共有フォルダ] [マウントポイント]
ちなみにパスワード指定が無い場合は以下.
# mount -t cifs -o user=[共有フォルダのマシンのユーザ],password= //[サーバIP]/[共有フォルダ] [マウントポイント]
書くまでもないけど....
# umount [マウントポイント]
CUIでやります.
過去の記事に譲ります.
ISOファイルが無いと始まらないのでダウンロードします.
上記から好きなバージョンを選べばよいかと.
今回はCentOS7で.
# mkdir /var/lib/libvirt/iso # cd /var/lib/libvirt/iso # curl http://ftp.iij.ad.jp/pub/linux/centos/7.3.1611/isos/x86_64/CentOS-7-x86_64-DVD-1611.iso > CentOS-7-x86_64-DVD-1611.iso
とりあえずqcow2フォーマットのディスクサイズは10Gで.
# cd /var/lib/libvirt/images # qemu-img create -f qcow2 CentOS-7-x86_64-DVD-1611.iso 10G Formatting 'CentOS-7-x86_64-DVD-1611.iso', fmt=qcow2 size=10737418240 encryption=off cluster_size=65536 lazy_refcounts=off
以下のコマンドで.
RAMは1GB, CPUコアは1にした.
長いから忘れそう.
# virt-install \ --name centos7 \ --hvm \ --virt-type kvm \ --ram 1024 \ --vcpus 1 \ --arch x86_64 \ --os-type linux \ --os-variant rhel7 \ --boot hd \ --disk /var/lib/libvirt/images/centos7.qcow2 \ --network network=default \ --graphics none \ --serial pty \ --console pty \ --location /var/lib/libvirt/iso/CentOS-7-x86_64-DVD-1611.iso \ --extra-args "console=tty0 console=ttyS0,115200n8"
上記を実行するとCentOS7のコンソールインストーラが実行されるので画面表示に従って進めていけばいい.
extra-argsを指定しないとコンソール接続できなくなるので注意.
インストール後は画面指示通り Ctrl+]
で脱出を.
# virsh list Id 名前 状態 ---------------------------------------------------- 3 centos7 実行中
# virsh console centos7
が、ここまでやってもゲストからネットワークにつながらない.
ホストに戻って以下を.
# virsh attach-interface --type bridge --source br0 centos7
上記でネットワークインターフェースをホットアタッチできるそうで.
再度コンソール接続するとちゃんとIPが取れてました.
ホストからゲスト上のDHCP割り当てIPを取得する方法がわからないのが辛い.
NAT状態なら以下で取れていたようですが.
# virsh net-dhcp-leases default
まぁ、ブリッジ作るとホストは関係ないともいえるので, 取得する方法はないのかも.
色んなところではまった.
いい加減まとまった知識を得たい.
良い本でもあればいいんだけど.
簡単だった.ポータビリティがすごい.
package main import ( "fmt" "runtime" ) func main() { switch runtime.GOOS { case "windows": fmt.Println("running on Windows.") case "darwing": fmt.Println("running on Mac OSX.") case "linux": fmt.Println("running on Linux.") case "freebsd": fmt.Println("running on BSD.") default: fmt.Println("running on Other OS.") } }
[実行結果]
$ ./sample.exe running on Windows.
くらいあればとりあえずは事足りる気がする. (調べてないけど, Plan9とかも対応してそうだよね....)