2016/10/23

dockerをインストール@Ubuntu14:04

基本は以下の手順通りに行う * https://docs.docker.com/engine/installation/linux/ubuntulinux/

  1. Prerequisitesのインストール apt source listを追加する際に書き込みがsudoできないのでできないのでteeとか使ってやる。
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates
$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

apt sourceの追加(sourceUbuntu versionごとに違うので注意)
$ echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee /etc/apt/sources.list.d/docker.list

aufs storage driverなるものが使えるようになるので以下をインストールしろと言われるがlinux-image-extra-virtualを入れようとすると以下の依存エラーが起きた

$ sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual

依存エラー

The following packages have unmet dependencies:
 linux-image-extra-virtual : Depends: linux-image-generic (= 3.13.0.100.108) but 3.13.0.92.99 is to be installed
E: Unable to correct problems, you have held broken packages.

これはいったん、linux-image-genericをpurgeしてreinstallすることで対応できた

$sudo apt-get purge linux-image-generic
$sudo apt-get install --reinstall linux-image-generic
  1. dockerインストール
    Log into your Ubuntu installation as a user with sudo privileges.

    Update your APT package index.

     $ sudo apt-get update

    Install Docker.

     $ sudo apt-get install docker-engine

    Start the docker daemon.

     $ sudo service docker start

    Verify docker is installed correctly.

     $ sudo docker run hello-world

    This command downloads a test image and runs it in a container. When the container runs, it prints an informational message. Then, it exits.

hello-worldを実行すると以下がでて正しくインストールできたっぽいことがわかる

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

Tips

proxy

docker.ioへ接続する際のproxy設定は /etc/default/dockerへ以下を記載する

export http_proxy="http://proxy.hoge.com:XXXXXX"

変更後はdockerのrestartが必要

$sudo service docker restart

sudoなしdocker実行

installation pageにもあるがdockerグループを作成して、そこにユーザを入れることでsudoなしでもdockerコマンドが実行できるようになる。

グループへ追加後、対象ユーザで作業している場合にはログアウト → 再ログインが必要なので注意


dockerをインストール@Ubuntu14:04

基本は以下の手順通りに行う https://docs.docker.com/engine/installation/linux/ubuntulinux/

  1. Prerequisitesのインストール apt source listを追加する際に書き込みがsudoできないのでできないのでteeとか使ってやる。
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates
$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

apt sourceの追加(sourceUbuntu versionごとに違うので注意)
$ echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" | sudo tee /etc/apt/sources.list.d/docker.list

aufs storage driverなるものが使えるようになるので以下をインストールしろと言われるがlinux-image-extra-virtualを入れようとすると以下の依存エラーが起きた

$ sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual

依存エラー

The following packages have unmet dependencies:
 linux-image-extra-virtual : Depends: linux-image-generic (= 3.13.0.100.108) but 3.13.0.92.99 is to be installed
E: Unable to correct problems, you have held broken packages.

これはいったん、linux-image-genericをpurgeしてreinstallすることで対応できた

$sudo apt-get purge linux-image-generic
$sudo apt-get install --reinstall linux-image-generic
  1. dockerインストール
    Log into your Ubuntu installation as a user with sudo privileges.

    Update your APT package index.

     $ sudo apt-get update

    Install Docker.

     $ sudo apt-get install docker-engine

    Start the docker daemon.

     $ sudo service docker start

    Verify docker is installed correctly.

     $ sudo docker run hello-world

    This command downloads a test image and runs it in a container. When the container runs, it prints an informational message. Then, it exits.

hello-worldを実行すると以下がでて正しくインストールできたっぽいことがわかる

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

Tipsとしてはdocker.ioへ接続する際のproxy設定は /etc/default/dockerへ以下を記載する

export http_proxy="http://proxy.hoge.com:XXXXXX"

変更後はdockerのrestartが必要

$sudo service docker restart

2016/07/30

Macに挿して使うubuntu USBメモリ作ってみた

MacにUSBメモリをさしてUbuntuインストール

ちょっと家でも使えるLiveUSBじゃないUbuntu環境が欲しくて家のMacにUSBメモリをさしてそこにUbuntuをインストールしてみた。

参考にさせてもらったのはこことかです。

参考サイトではrEFItを使ってたが、すでにメンテされてないのでそこから
forkされたrEFIndを使いました。

手順としては以下。今回はUbuntu14.04 LTSを入れました。

  1. ubuntuインストールLiveUSBを(UbuntuをインストールするUSBメモリとは別に)作成
  2. インストール先のUSBメモリでrEFInd用パーティションを切る
  3. rEFInd用のパーティションをマウントしてrEFIndをインストール(ここまでMac側で作業)
  4. LiveUSBで起動
  5. インストール先USBメモリをマウント
  6. Ubuntu用のパーティションを切る
  7. Install UbuntuからUbuntuをインストール

OSをインストールして使うとなると容量だけでなく速度が非常に重要になり、最初東芝のUSBメモリ(TransMemory THN-U301W0320)に インストールしたのですが遅くて非常に使い勝手が悪い結果になってしまいました。

結局下の速度に定評のあるSnaDiskのメモリを使う事で快適になりましたw

このくらいのサイズ感です。もっと小さいほうが理想的だけどまぁまぁ支障はないでしょう。

  1. ubuntuインストールLiveUSBを(UbuntuをインストールするUSBメモリとは別に)作成 こちらはUbuntuの公式ページに説明があるので省略 → How to create a bootable USB stick on OS X

  2. インストール先のUSBメモリでrEFInd用パーティションを切る まず、EFI用にUSBメモリの先頭に30MB(後記:20MBでもいいっぽい)のHFS+(ジャーナリング)パーティションと残り全部のパーティションに分けます。 Macのディスクユーティリティ.appからだとうまくできずにUSB全体で1パーティションにしかできず、色々悩んだ結果コマンドのdiskutilからやりました。

以下でUSBメモリの/dev/disk? の?を確認。下の場合は/dev/disk2
% diskutier list
/dev/disk0 (internal, physical):
省略
/dev/disk1 (internal, virtual):
省略
/dev/disk2 (external, physical):
省略
以下でパーティションを分割。最初にGPTJHFS+(HFS+ジャーナリング)でrefiという名前で30MB、次に残り全部をubuntuという名前で切る。ubuntu側はインストール時に再度パーティションを切るのでここでは2つに分割だけできればよし。
% diskutil partitionDisk /dev/disk2 GPT JHFS+ refi 0.03g JHFS+ ubuntu 0b
  1. rEFInd用のパーティションをマウントしてrEFIndをインストール(ここまでMac側で作業) rEFIndのサイトからrEFIndをダウンロード(自分の時はversion0.10.3)し解凍。 2.で作成したrefiパーティションをFinderで開き、efiという名前のフォルダを作成。
    次に回答したrEFIndフォルダのルートにあるrefindというフォルダをフォルダごと↑で作ったefiフォルダにコピー(/efi/refind/にする)

解凍後のrefindフォルダには32bitやARM向けのファイルも入ってるんですが、今回は不要なのでx64のみを残して削除します。
左:削除前、右:削除後

コピーが終わったら、blessというコマンドを使ってブートエントリに加えて貰う必要があるようです。以下はrEFItに付属しているenable.shというものをベースにrEFInd用にUpdateしたものですが、これを/efi/refind/フォルダにコピーし、以下の要領で実行します。

#!/bin/bash

LOADERNAME="refind_x64.efi"

expand_dir () {
  pushd "$1" >/dev/null
  DIR="`pwd`"
  popd >/dev/null
}

expand_dir .
if [ ! -f "$DIR/$LOADERNAME" ] ; then
  expand_dir "`dirname "$0"`"
  if [ ! -f "$DIR/$LOADERNAME" ] ; then
    echo "You must run enable.sh from the directory where you put $LOADERNAME"
    echo "or put enable.sh where $LOADERNAME is!"
    exit 1
  fi
fi

if [ "$(uname -p)" != "i386" ]; then
  echo "You must run enable.sh on an Intel-based Macintosh!"
  exit 1
fi

set -x
sudo bless --folder "$DIR" --file "$DIR/$LOADERNAME" 
%cd /Volume/refi/efi/refind/
%./enable.sh
sudoパスワードを入力

*blessコマンドに--setBootオプションをつけるとNVRAMに保存してくれるようなのですが、YosemiteかEl Capitanあたりから入ったSIP(System Integrity Protection)により
sudoでもNVRAMに書き込む処理はできなくなってるっぽい。Safe Modeで起動してSIPをdisableしてbless --setBootして再度enableとやればいいらしいが、--setBootなしでもそれっぽく動作はしてるので今回は無しで。

これでMac側で行う処理は終了。

  1. LiveUSBで起動 起動してください。LiveUSBをさして再起動しOptionキーを押しっぱなしにすると起動時にMacかLiveUSBか選べる。 選択画面がでたら"Try Ubuntu without Install"みたいなやつを選ぶ。

  2. インストール先USBメモリをマウント 指す。

  3. Ubuntu用のパーティションを切る

今回は参考サイトにならってMacやWinからアクセスしてファイル共有できるFAT32パーティションを4Gくらい作った残りをUbuntuにします。 LiveUSBから起動したUbuntu上でGPartedを起動。Commandキー → 検索でGPartとか打つとでてくる

右上のリストメニューからインストール先のUSBのデバイスを選んで、新しいパーティションを作成(未割り当てのパーティションを選んで右クリックで「新規」)
ファイルシステム FAT32を選び、サイズを指定して「追加」

さらに、Ubuntuを入れるパーティションを作成するために残りの未割り当てパーティションを選んで同様に右クリック+新規
ファイルシステム ext4、サイズはデフォルトで残り全部が入ってるのでそのまま、割り当てを"/" ルートに(このあたりは好きな様に)

結果、こんな感じにする。確認できたらツールバー上の✓みたいなボタンを押して実際に反映させる。

  1. Install UbuntuからUbuntuをインストール

デスクトップ上にある”Install Ubuntu”というショートカットをダブルクリックしてインストール画面を出す。

注意点は以下の”インストールの種類”の画面で6.で作ったext4パーティションを選ぶ事と、ブートローダーをインストールするデバイスでインストール先のUSBデバイスを指定する事(↓画像はTOSHIBA USBでやった時のもの)

あとはひたすらインストールが終わるのを待つだけ!

USBを挿してOptionを押しながら起動するとmacOSを起動するかEFI bootか選択画面がでるのでEFI boot側を選択。
rEFIndが起動して何を起動するか選択画面へ進むのでUbuntuを選択すると無事Ubuntuが起動します。
SDXZ80 USBメモリを使うと体感で数秒〜十数秒程度でログイン画面が表示されます。

以下、設定などメモリ書き

Fnキー

デフォルトではFnキーを押さないと、ファンクションキーがF1、F2等々として働かずディスプレイ照度の上げ下げになってました。
デフォルトでは通常のF1として使いたいので以下をセット

sudo bash -c "echo 2 > /sys/module/hid_apple/parameters/fnmode"

TouchPadのnatural scroll

デフォルトではTouchPadの2本指スクロールはPCと同じなんですが、同じMac上でMacでは逆だとややこしいので
Mac側の仕様に統一。

エディタで~/.Xmodmapファイルを開く(なければ作成)。以下を記述。

pointer = 1 2 3 5 4 6 7 8 9 10 11 12

一回ログアウトして再度ログインすると反映される。

ディスプレイの輝度設定が保存されない

そのままだとディスプレイの輝度設定を下げても再起動すると最大に戻ってしまう。GPUに何が使われているモデルかで違うかもしれないが、 自分のMBA('12/Mid)だと以下をする事で保存されるようになった。

エディタで/etc/default/grubを開く。要sudo

以下を修正

修正前
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

修正後
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash acpi_backlight=vendor acpi_osi=Linux"

修正後以下で設定を反映

$sudo update-grub

再起動するとディスプレイ輝度が保存されるようになった。

Mac Ubuntu Community

後から気がついたがMacでUbuntuを動かす時のドライバ情報(何が動いて何が動かないとか)などの詳細な情報ページあった・・。

https://wiki.ubuntu.com/MactelSupportTeam/CommunityHelpPages#MactelCommunityDocumentation


2016/02/18

自分用git コマンドメモ

ファイル部分的にstaging

$ git add -p <file>
hunk毎にどうするか聞いてくれる

diff

# diff staged vs working copy
$ git diff 

# diff staged vs head
$ git diff --cached

branch削除

local branch

$ git branch -d <local_branch>

remote branch

remote branchはダイレクトに消すコマンドでなくて。local branchに空を指定して、それをPushする

$ git push origin :<remote_branch>

git diff

difftoolを使うとmeldなどGUIツールが起動できる。

$ git difftool hoge.cpp

-dを付けるとディレクトリ比較になる(らしい)

$ git difftool -d .

リモートのタグ表示

$ git ls-remote --tags

リモートブランチも含めたブランチ一覧を表示する。

$ git branch -a

リモートブランチへCheckOut

$ git checkout -b local_branch_name origin/remote_branch_name

個人的によくあやふやになるgit pushの構文メモ

$ git push origin <local_branch>:<remote_branch>

branchを切って作業すべき所をうっかりmaster(もしくは別のbranch)にコミットしてしまった時の対処

他の人がpullしてcheckoutしてると混乱の元なので非常手段

まず、本来branchを切るべきだったコミットのhashを確認

$ git log --oneline --decorate --graph 
* zzz (HEAD -> master)
* yyy
* xxx
* www

例えばhash www(本来branchを切るべきだったコミット)で, xxx,yyy,zzzの3つが本来branch上でコミットすべきものだったとする

本来branchを切るべきだったbranchを切ってcherry-pickする

$ git branch mybranch www     # mybranchを本来切るべきだった箇所から切る
$ git checkout mybranch       # mybranchへ移動
$ git cherry-pick www...zzz   # mybranch上でxxx,zzz,zzzをpick。hashは新しくなる。注意点は...の左側はxxxじゃなくてwww(ひとつ前)にすること

mybranchとmasterにそれぞれ同じコミットが別hashで追加されてるのでmasterを戻す

$ git checkout mater
$ git reset --hard www      # masterを戻す。HEAD-2とかHEADから2つ戻すような記述も可

pushする(他のユーザ注意喚起が必要)

$ git checkout mybranch
$ git push origin mybranch        # mybranchをpush
$ git checkout master
$ git push --force origin master  # masterを強引にpush

2016/01/28

import matplotlibでハング

ここで紹介した方法でmatplotlibやspicyをinstallしたが、実際にmatplotlibを使おうとするとハングする問題が発生。

アクティビティモニターでチェックしてみると"fc-list"なるプロセスがCPUを食ってるよう。

色々調べてみるとここで、同じ現象が取り上げられてる。対策は以下のコマンドを打てとのこと。

$ cd ~/.matplotlib/
$ fc-list 

上をうつと大量のログが出力されたのち、普通に使えるようになった。


2016/01/19

PyQtでvtkをWidget表示

PyQtでvtkの3次元表示ViewをWidgetとしてEmbbedしたい場合の自分メモ

普通はQVTKWidgetPlugin.dll/.soなりをQt Designerのpluginsフォルダに入れる事によって、 Qt DesignerのサイドバーにQVTKWidgetが表示され、それをDrag&DropするだけでLayoutされる!というスマートなやり方が正しいはずなんだが。

ことpython + QVTKWidgetに限ってはなんか以下の理由でできない(なんで?と思うが) (Windows + Anaconda環境と、MacOS + homebrew環境で確認)

  • そもそもQVTKWidgetというモジュールがvtkをpython + qtで使う環境に存在しない。

↓のサイトによるとfrom QVTKWidget import QVTKWidgetに存在しない。from vtk import QVTKWidgetなら存在するとかあるが、これも存在しないと起こられる。

で、色々探してみるとfrom vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor を使えというサイトを見つけた。

ためしにこれで試すとうまくいくが、もしQt DesignerでQVTKWidgetPlugin.dll/soを使ってDrag&DropでLayoutをすると強制的にQVTKWidgetをloadされちゃうので できない。

なのでQt Desingerのpromote toを使って、

  1. まずWidgetをvtkを配置したい箇所に配置
  2. promote toでpromotionの設定を開く
  3. headerにvtk.qt4.QVTKRenderWindowInteractor.hをpromotion classにQVTKRenderWindowInteractorを書いて追加
  4. 1.で追加したWidgetを右クリックしてpromote to -> QVTKRenderWindowInteractorを選択してpromoteさせる

  5. のQVTKRenderWindowInteractorクラスをPromotion用に追加した所↓

4.の後↓のようになる

という手順を踏むとQt Designderでの変更に対して何もしなくても以下のpythonコードで呼べる。 (C++と.uiファイルが共通化できなかったりというデメリットもあるが、現状これしかない気もする。)

import sys
import vtk

from PyQt4 import QtCore, QtGui, uic

#from ui_mainwindow import Ui_MainWindow

class testPyQt(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        Ui_MainWindow = uic.loadUiType("ui_mainwindow.ui", self)[0]

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # setup connection
        self.ui.pushButton.clicked.connect(self.onClickButton)

        ### !!! Added from here !!! ###
        self.renderer = vtk.vtkRenderer()
        self.ui.qvtkWidget.GetRenderWindow().AddRenderer(self.renderer)
        self.ui.qvtkWidget.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())

        # Add initial actores
        self.axes = vtk.vtkAxesActor()
        transform = vtk.vtkTransform()
        transform.Translate(0.0, 0.0, 0.0)
        self.axes.SetUserTransform(transform)
        self.axes.GetXAxisCaptionActor2D().GetTextActor().SetTextScaleModeToNone()
        self.axes.GetYAxisCaptionActor2D().GetTextActor().SetTextScaleModeToNone()
        self.axes.GetZAxisCaptionActor2D().GetTextActor().SetTextScaleModeToNone()
        self.axes.SetTotalLength(1, 1, 1)
        self.renderer.AddActor(self.axes)

        self.renderer.ResetCamera()
        ### !!! Added until here !!! ###

    # Added to draw call should be called after open window
    def show(self):
        QtGui.QMainWindow.show(self)
        self.ui.qvtkWidget.Initialize()

    @QtCore.pyqtSlot()
    def onClickButton(self):
        self.ui.label.setText("Pushed!!")

def main():
    app = QtGui.QApplication(sys.argv)
    window = testPyQt()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

show()関数をoverrideしているのは、RenderingがWindowが開かないうちに実行されるのを避ける為。例えば、Mac環境でinit内でself.qvtkWidget.Initialize()をやってしまうと以下の様なエラーが大量に出る

ERROR: In /tmp/vtk20151007-9396-c4u0qe/VTK-6.2.0/Rendering/OpenGL/vtkOpenGLPolyDataMapper2D.cxx, line 442
vtkOpenGLPolyDataMapper2D (0x7f9d3c171460): failed after RenderOverlay 1 OpenGL errors detected
  0 : (1286) Invalid framebuffer operation

以下のForumで議論されている内容で、Forumでもshowを明示的に呼んでからRenderしろのような事が書かれている(と思う)。 http://paulklemm.com/zenf/blog/2012/08/20/install-python-together-with-vtk-using-homebrew-for-mountain-lion/ なのでmain()内で呼ばれるshow()の後にInteractorのInitialize()が呼ばれる様にするためにこの構成。


PyQtでGUI:.uiファイルのload

PyQt(PyQt4)でGUIプログラムする自分用メモ

.uiファイル+Qt Designerが使いやすいのもQtのメリットだと思ってるのでpythonからもUIのレイアウトはこれでやりたい。

.uiでレイアウトしてpythonで読み込むには2つ方法があるらしい。

  1. pyuic4を使って.ui -> .pyに変換しimport
  2. uicを使って直接import

1.は.pyに統一できていいが、開発中は毎UI変更の度に変換が必要でめんどい。 2.は変換は不要だが.uiファイルをPackageに含まないといけない(それでもいい場合もある?)。 ↓によると開発中は2.でお手軽に、配布時に1.で変換するみたいのが良いってことかな?
https://riverbankcomputing.com/pipermail/pyqt/2010-September/027970.html

というわけでサンプル作ってみた。

まずQt Designerで簡単なUI(PushButtonを押すと、Labelの文字が変わるというだけ)を作成

.uiファイルをloadして表示するコードが以下。

import sys

from PyQt4 import QtCore, QtGui, uic

# form classを直接importする場合は必要
#from ui_mainwindow import Ui_MainWindow

class testPyQt(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        # form classを直接importする場合は↓の行が不要になる
        Ui_MainWindow = uic.loadUiType("ui_mainwindow.ui", self)[0]

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # setup connection
        self.ui.pushButton.clicked.connect(self.onClickButton)

    @QtCore.pyqtSlot()
    def onClickButton(self):
        self.ui.label.setText("Pushed!!")

def main():
    app = QtGui.QApplication(sys.argv)
    window = testPyQt()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

testPyQtクラスのself.uiにform class(C++ではUi::MainWindowClassとかでmoc_*.cppファイルに生成されてたやつだと思う)をnewする。

検索するとtestPyQtクラス自体をform classから継承する例や、self.uiにuic.loadUi()で生成されたQMainWindow(or QWidget)を直接showするコード(下記)もあったというか結構多い。

前者はUIと制御コードが一緒のclassになっちゃうので避けたい実装、後者はtestPyQtでQMainWindowを継承している意味がわかんなくなるので、その辺のやり方を避けると上のやり方に落ち着きそう。

class testPyQt(QtGui.QMainWindow):
    def __init__(self):
    # uic.loadUi returns QMainWindow
    self.ui = uic.loadUi("ui_mainwindow.ui")
    self.ui.show()

def main():
    app = QtGui.QApplication(sys.argv)
    window = testPyQt()
    # window.show() # ここでshowしない
    sys.exit(app.exec_())

結果、こんな感じにできる。