tmuxで一個[前|後]のwindowと入れ替えるやつ
入れ替えたいことが時々あるけど、swap-window でxとyを交換したいことがあんまりなくて、このwindowを0番に移動して、他の並びはそのままみたいにやりたいことが多い。
「move 0 って指定すると、現在のwindowを0に持ってって、他のはそのままずらす。」みたいなの作ろうかと思ったけど面倒だし、window切り替えみたいにそんなに頻繁にするもんじゃない気がして、一個ずつ前に持ってったり後ろに持ってったりするのでいいやと思ってそう定義した。
# window閉じたりした時に、番号詰める。これをセットしとかないと、欠番出てきてこの方法で移動が出来なくなる。 set-option -g renumber-windows on unbind h bind -r h run 'cw=$(tmux display-message -p \#I) && [ $cw -gt 0 ] && tmux swap-window -s $cw -t $(($cw - 1))' unbind l bind -r l run 'cw=$(tmux display-message -p \#I) && tmux swap-window -s $cw -t $(($cw + 1))'
■
世界を(:Ag 変更依頼)変えさせて(:Qfreplace)おくれよ(:%s/変更依頼/修正依頼/g) そしたら(:wq)君と(git add -A; git commit -m '変更依頼 -> 修正依頼') キスがしたい(git push)
みたいなことを散々言いながら、だるくて一向に手を付ける気にならない病を患って2日が経過してる。
Redigo(redis client)使う場合の注意
redis.Conn#Do(https://github.com/garyburd/redigo/blob/master/redis/conn.go#L368) はredis.Conn#Send -> redis.Conn#Flush -> redis.Conn#Receive みたいなことしてるんだけど、threadsafeではなく複数のgoroutineでコネクションを使いまわしてた場合、アレな感じになるのでredis.Pool使ったりして、コネクション使いまわさないようにしないといけない。
Gokuraku作った
Golang入門として、SoundCloudの曲をURL入れて追加していったやつを適当に再生してくれるみたいなやつを作った。 ToQoz/Gokuraku - GitHub
追記
こんな感じです。
Gokuraku, goweb/websocketのインストールにbzr, hgいるのダルい感じする
— ピヨちゃんです (@ToQoz) August 15, 2013
あと多分Go1.1以上でしか動かない感じする
— ピヨちゃんです (@ToQoz) August 15, 2013
■
「Railsのモデル = ActiveRecord」「いや別に違うけど」みたいなやりとりよく見るけど、100年後も言ってそうだなと思ってた。なんでかなと思ったんだけど、Railsのモデル、ActiveRecord使ってDBと便利に繋がりたい時
class SomeModel < ActiveRecord::Base end
って書くせいで誤解されている気がする。
これだと「SomeModelはActiveRecord::Baseの一種」みたいな感じになって、それが間違っているわけでもない気がするけど、そこから想像力豊かな各位により「全てのモデルはActiveRecord::Baseの一種」みたいな感じに思われそう。
class SomeModel include ActiveRecord::Base end
だったら、モデルが便利にDBと繋がりたいならActiveRecord使うといいよみたいなニュアンスになって、モデル = ActiveRecordみたいなこと言われなくて済むと思う。
銭湯のトイレ
■
class PostsController < ApplicationController respond_to :html, :json def index @posts = Post.all respond_with @posts end end
$.ajax('/posts', { dataType: 'json', contentType: 'application/json' })
みたいな感じのがあったとして、
/posts
に遷移- どっか他のページに遷移
$.ajax('/posts', { ... })
実行- /postsに戻る
で、キャッシュされたjsonが「Content-Type?ウェ?」みたいな感じで描画された。。。(Chrome)
とりあえず何が正しいのか調べてるけど、とりあえず cache: false
することで現実の問題から逃げました。
複数window開くときのテスト
turnip/capybaraでテスト書いてる時に、
あるリンクをクリックすると、ポップアップ開いたり新しいウィンドウ開いて、そこでなんか操作する
みたいなことがある。こんな感じでできる。
_, popup = page.driver.browser.window_handles within_window(popup) do expect(page).to have_content('message') end
開いたままのWindowがあるせいでテストが変なこけ方したから、メインのWindow以外を閉じるみたいな感じにした。
# spec/spec_helper.rb RSpec.configure do |config| config.after(:javascript => true) do page.driver.browser.window_handles[1..-1].each do |sub_window| within_window(sub_window) do page.execute_script "window.close();" end end end end
■
とにかくやる気がでない。だるいって感じが続きすぎていてだるい
■
クラスの責務を明確にする、単一にするみたいな話があるけど、なんかの資料みたいなものに関しても色んな責務をもたせると、ただでさえ怠い作業がもっと怠くなって全部中途半端になってしまう。この資料ではこれについての説明だけはちゃんと書いて他は書かないみたいな感じにしたほうが良い。
zshの起動はやくした
zshrcの読み込みに時間がかかっていたのでそれの短縮。
ちまちま他のとことかで無駄だったとこ削ったりしたんだけどほぼ関係なかった。
Functional Programming Principles in Scala
https://www.coursera.org/course/progfun
をやってるんだけど、結構面白い。この講義自体は http://shanon-tech.blogspot.jp/2013/04/top5.html で知った。
プログラミングパラダイムの話で
- imperative programming
- functional programming
- logic programming
の3つがあって
- object-oriented programming
はその3つとは直交する。で、ScalaではFPとOOPを混ぜたみたいなことを言っていた。
JVM上で動くしJavaの人が慣れやすいように〜とかってそういう感じだったのかなーと勝手に思ってたんだけど、そういう意思のもと入れたものだったんだなと知った。このへんでScalaに興味出てきた。ぶっちゃけscaleさせたいようなweb serviceを運用してるわけでもなく、scalability的な文脈ではさほど興味を持ってなかった。
また、SCIP(途中で投げ出してたのを再開中...)の例題とかが出てくるんだけど、課題にはテストがついてたり、動画の途中にQuizが出たり、一人で本読むより飽きにくいと思う。
あとはScala IDEのworksheetっていうのが柔軟なREPLみたいな感じで面白いし、Scalaで開発やりたい感じ出てきた。最近ChromeとIRC ClientとTerminal以外立ち上げずそこで完結するように頑張るみたいな原始的なことをしているおかげか、IDEもサクサク動いた。
dotCloud製Linux Container, Docker触ってみた
とりあえず、VM一個立てて、rackupしようと思った。
digitaloceanのvpsで試していたんだけど、なんかおかしいと思ったらkernelのバグの影響だったようで、3.5.0-21以上を使ったほうが良さそう。 https://github.com/dotcloud/docker/issues/25
ちなみにdigitaloceanのvpsでは
$ uname -r 3.5.0-17-generic
なので、Vagrantで適当なUbuntuのVM立てた。
def v10(config) config.vm.box = "ubuntu-quantal" config.vm.box_url = "http://cloud-images.ubuntu.com/quantal/current/quantal-server-cloudimg-vagrant-amd64-disk1.box" end Vagrant::VERSION < "1.1.0" and Vagrant::Config.run do |config| v10(config) end Vagrant::VERSION >= "1.1.0" and Vagrant.configure("1") do |config| v10(config) end Vagrant::VERSION >= "1.1.0" and Vagrant.configure("2") do |config| config.vm.provider :virtualbox do |vb| config.vm.box = "ubuntu-quantal" config.vm.box_url = "http://cloud-images.ubuntu.com/quantal/current/quantal-server-cloudimg-vagrant-amd64-disk1.box" end end
$ uname -r 3.5.0-26-generic
Install
$ sudo apt-get install lxc wget bsdtar curl $ sudo apt-get install linux-image-extra-`uname -r` $ wget http://get.docker.io/builds/$(uname -s)/$(uname -m)/docker-master.tgz $ tar -xf docker-master.tgz
基本(READMEに書いてる)
僕は当初Containerとimageを混同していて、$ sudo ./docker pull IMAGE_NAME
でVMのようなものを作っているのかと思ってたが、そうではなくimageはコンテナのひな形、インスタンスに対するクラスのようなもの。また、runで新しくコンテナを作ってコマンドを実行しても、コマンドが終了すればコンテナは消える。
# イメージのダウンロード $ sudo ./docker pull IMAGE_NAME # コンテナ上でコマンドを実行 $ sudo ./docker run -i -t IMAGE_NAME COMMAND # shell立ち上げることで、普通にそのコンテナにログインして作業みたいなこともできる $ sudo ./docker run -i -t IMAGE_NAME /bin/bash # Container の IDに対して操作出来る $ (sudo ./docker -d || echo "Docker daemon already running") & $ CONTAINER=$(docker run -d base /bin/sh -c "while true; do echo Hello world; sleep 1; done") $ echo $CONTAINER 2fa7019f6fdf3e85c249fa2c2eef093c294fc8c0d5262377e9754f491a3dc2e1 $ docker logs $CONTAINER 2013/03/29 07:33:54 docker logs 2fa7019f6fdf3e85c249fa2c2eef093c294fc8c0d5262377e9754f491a3dc2e1 Hello world Hello world Hello world Hello world Hello world Hello world $ docker logs $JOB 2013/03/29 07:33:56 docker logs 2fa7019f6fdf3e85c249fa2c2eef093c294fc8c0d5262377e9754f491a3dc2e1 Hello world Hello world Hello world Hello world Hello world Hello world Hello world Hello world $ docker kill $JOB 2013/03/29 07:34:23 docker kill 2fa7019f6fdf3e85c249fa2c2eef093c294fc8c0d5262377e9754f491a3dc2e1 # runはコンテナを新しく起動してコマンドを実行するもので、 # 永続的なコンテナを作るものではないので、コマンドの実行が終わると # コンテナは消える。 # コマンドの実行によりコンテナに与えた変更はcommitすることにより # 新たなimageが作成できる。 $ sudo ./docker run -i -t base bash root@ea19df583e44:/# adduser toqoz Adding user `toqoz' ... Adding new group `toqoz' (1000) ... Adding new user `toqoz' (1000) with group `toqoz' ... Creating home directory `/home/toqoz' ... Copying files from `/etc/skel' ... Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully Changing the user information for toqoz Enter the new value, or press ENTER for the default Full Name : Room Number : Work Phone : Home Phone : Other []: Is the information correct? [Y/n] root@ea19df583e44:/# su toqoz bash: no job control in this shell $ exit exit root@ea19df583e44:/# exit exit $ sudo ./docker run -i -t base bash 2013/03/29 08:08:37 docker run -i -t base bash bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell root@b612c0b3d72d:/# su toqoz Unknown id: toqoz
自分用のbase imageを作成
$ sudo ./docker pull base $ CONTAINER=$(docker run -d base apt-get install -y curl) $ docker commit -m "Installed curl" $CONTAINER $USER/sample $ docker push $USER/sample $ docker images 2013/03/29 08:16:58 docker images REPOSITORY TAG ID CREATED PARENT vagrant/sample latest c287f15311bfbb0c2e664f5e29561d5f8e03567b7a9f640140106213bbc6fa9d 45 seconds ago base:latest base latest b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc 5 days ago 27cf784147099545 base ubuntu-12.10 b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc 5 days ago 27cf784147099545 base ubuntu-quantal b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc 5 days ago 27cf784147099545 base ubuntu-quantl b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc 5 days ago 27cf784147099545 # ps でコンテナを探してattachすることもできる $ sudo ./docker ps 2013/03/29 09:12:28 docker ps ID IMAGE COMMAND CREATED STATUS COMMENT 307304dc7bd498f7ee3b8e76e3bbc492b8b1a7c698fb7e100c3b4d331e108d99 base:latest apt-get install -y r 5 minutes ago Up 5 minutes 61b385d5cd8ce70d3e6df7a256777aacdebf3cebb483285f50f006d6f0c17e00 base:latest echo hello 21 minutes ago Up 21 minutes 7ddd667b4edf3c603b89027a2f2f731b64c6b34487e2a03ab96daa4af3504cbe base:latest echo hoge 24 minutes ago Up 24 minutes $ sudo ./docker attach 307304dc7bd498f7ee3b8e76e3bbc492b8b1a7c698fb7e100c3b4d331e108d99
$ sudo ./docker commit -m 'dist-updated' $CONTAINER $USER/base # sudo ./docker run some_image apt-get update && apt-get install foo が # (sudo ./docker run some_image apt-get update) && apt-get install foo みたいな感じに解釈されてしまうので、とりあえず sh -c '' で実行してる $ CONTAINER=$(sudo ./docker run -d base sh -c '\ export DEBIAN_FRONTEND=noninteractive && \ echo "deb http://archive.ubuntu.com/ubuntu quantal-updates main universe multiverse" >> /etc/apt/sources.list && \ apt-get -y update && \ apt-get -y upgrade && \ apt-get -y dist-upgrade \ apt-get install -y build-essential openssl libreadline6 libreadline6-dev curl git-core' \ ) $ sudo ./docker commit -m 'Installed build-essential openssl libreadline6 libreadline6-dev curl git-core' $CONTAINER $USER/base
自分用のbase imageをベースにruby用のimageを作る
$ CONTAINER=$(sudo ./docker run -d $USER/base sh -c '\ export DEBIAN_FRONTEND=noninteractive && \ apt-get install -y libssl-dev zlib1g-dev libyaml-dev && \ cd /tmp && \ git clone git://github.com/sstephenson/ruby-build.git && \ cd ruby-build && PREFIX=/opt/ruby-build ./install.sh && \ /opt/ruby-build/bin/ruby-build --with-open-ssl-dir=usr 2.0.0-p0 /opt/ruby2.0.0' ) $ sudo ./docker commit -m 'Installed Ruby' $CONTAINER $USER/rubybase $ sudo ./docker run $USER/rubybase env PATH=/opt/ruby2.0.0/bin:$PATH ruby -v 2013/04/01 01:19:08 docker run vagrant/rubybase env PATH=/opt/ruby2.0.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games ruby -v ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
ruby用のimageをbaseにrack app用のimageを作る
$ CONTAINER=$(sudo ./docker run -d $USER/rubybase env PATH=/opt/ruby2.0.0/bin:$PATH gem install rack --no-ri --no-rdoc $ sudo ./docker commit -m 'Installed rack' $CONTAINER $USER/rackbase
rack appを起動するしてアクセスしてみる
$ CONTAINER=$(sudo ./docker run -d -p 9292 $USER/rackbase \ env PATH=/opt/ruby2.0.0/bin:$PATH \ sh -c 'rackup -b "run proc { |env| [200, { %{Content-Type} => %{text/html} }, %{Hello\n}.chars] }"' \ ) $ sudo ./docker logs $CONTAINER 2013/04/01 05:42:48 docker logs baa621dd4def [2013-04-01 05:42:38] INFO WEBrick 1.3.1 [2013-04-01 05:42:38] INFO ruby 2.0.0 (2013-02-24) [x86_64-linux] [2013-04-01 05:42:38] INFO WEBrick::HTTPServer#start: pid=5 port=9292 $ PORT=$(sudo ./docker port $CONTAINER 9292) $ HOST=$(ifconfig | grep 'inet ' | head -n1 | sed -e 's/^.*inet addr://' -e 's/ .*//') $ curl $HOST:$PORT Hello
実際にprivate paasみたいな感じで使うには
コンテナの存在をチェックして、再起動する仕組みと、ルーターを作れば、とりあえず簡素なの作れる気がした。
環境構築の自動化について
imageをpushすることも出来るので、chefなどを使った自動化というより、dockerのエコシステムの中でうまく自動化していくのがいいんじゃないかなと思ったりした。ただ現状、そのimageがどのように作られたかとかを知る術を僕は知りません。