それでも気分は高専生

元高専生が自分のやってきたことを記事として残すためのてきとーなブログ

matplotlibを動かす on Arch Linux

sudo pacman -Sy tk
pip install matplotlib
  File "plot.py", line 1, in <module>
    import matplotlib.pyplot as plt
  File "/home/takahiro/.pyenv/versions/3.6.3/lib/python3.6/site-packages/matplotlib/pyplot.py", line 115, in <module>
    _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
  File "/home/takahiro/.pyenv/versions/3.6.3/lib/python3.6/site-packages/matplotlib/backends/__init__.py", line 62, in pylab_setup
    [backend_name], 0)
  File "/home/takahiro/.pyenv/versions/3.6.3/lib/python3.6/site-packages/matplotlib/backends/backend_tkagg.py", line 4, in <module>
    from . import tkagg  # Paint image to Tk photo blitter extension.
  File "/home/takahiro/.pyenv/versions/3.6.3/lib/python3.6/site-packages/matplotlib/backends/tkagg.py", line 5, in <module>
    from six.moves import tkinter as Tk
  File "/home/takahiro/.pyenv/versions/3.6.3/lib/python3.6/site-packages/six.py", line 92, in __get__
    result = self._resolve()
  File "/home/takahiro/.pyenv/versions/3.6.3/lib/python3.6/site-packages/six.py", line 115, in _resolve
    return _import_module(self.mod)
  File "/home/takahiro/.pyenv/versions/3.6.3/lib/python3.6/site-packages/six.py", line 82, in _import_module
    __import__(name)
  File "/home/takahiro/.pyenv/versions/3.6.3/lib/python3.6/tkinter/__init__.py", line 36, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'

tkinterがないですってよ,奥さん.

matplotlib - tkinterをpyenv上で使用できるようにしたい - スタック・オーバーフロー

tkライブラリ→python本体の順に入れないとtkinterが生成されないのかー...

pyenv unistall 3.6.3
pyenv install 3.6.3
pip install --upgrade pip
pip install 

今度はマルチバイト文字が表示されない問題.

【Seaborn】日本語を表示する (フォントを変更する) に従って

import matplotlib as plt
print(plt.matplotlib_fname())

自分の場合は$HOME/.pyenv/versions/3.6.3/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrcに.

arch linuxの場合,フォントを探したければ

fc-list

で一覧が得られるので探す.

font.family  : IPAexGothic
font.style    : normal

を指定して無事日本語適用も完了.

KDEのデスクトップ環境がぶっ壊れた on Arch Linux

環境

  • OS: Arch Linux
  • Kernel: x86_64 Linux 4.13.12-1-ARCH
  • DE: KDE 5.40.0 / Plasma 5.11.4
  • Qt version: 5.9.3

症状

ログイン時に

$ exec startx /usr/bin/startkde

GUI環境を起動する.

起動直後,数秒すると壁紙が表示されなくなり,デスクトップが真っ暗になる.

特にKDE plasma環境をアップデートしたわけでもなく,競合しそうなパッケージを導入したわけでもない.

できること

  • Alt+Space によるKrunnerを通じてGUIアプリケーションの実行
  • GUIアプリケーションの操作
  • Alt+Tab によるカレントウィンドウの切替
  • ショートカットキーによる仮想デスクトップの切替 (どの仮想デスクトップも真っ暗)
  • KDE環境を切ってCUI上での操作

できないこと

  • メニューバーの表示と操作
  • windowキーによるメニューの表示
  • デスクトップの表示 (壁紙の表示,ウィジェットの表示)
  • デスクトップ上での右クリック

原因

plasmashell実行時にエラーが生じて処理がストップしてしまう.
(plasmashell実行時に一瞬だけ壁紙が表示)

$ plasmashell

kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator//metadata.desktop"
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator/metadata.desktop"
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator/metadata.desktop"
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator/metadata.desktop"
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator//metadata.desktop"
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator/metadata.desktop"
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator/metadata.desktop"
file:///home/takahiro/.local/share/plasma/plasmoids/com.github.zren.todolist/contents/ui/NoteItem.qml:324: TypeError: Cannot read property 'label' of undefined
qml: main.isDesktopContainment false
qml: TodoItemDelegate 1511965848725
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:365: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:364: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:363: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:362: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/TextArea.qml:905: TypeError: Cannot read property '__selectionHandle' of null
file:///usr/lib/qt/qml/QtQuick/Controls/TextArea.qml:941: TypeError: Cannot read property '__cursorHandle' of null
qml: TodoItemDelegate 1511965848915
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:365: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:364: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:363: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:362: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/TextArea.qml:905: TypeError: Cannot read property '__selectionHandle' of null
file:///usr/lib/qt/qml/QtQuick/Controls/TextArea.qml:941: TypeError: Cannot read property '__cursorHandle' of null
file:///home/takahiro/.local/share/plasma/plasmoids/com.github.zren.todolist/contents/ui/TodoItemDelegate.qml:90:5: QML RowLayout: Binding loop detected for property "height"
qml: TodoItemDelegate 1511965848925
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
trying to show an empty dialog
file:///usr/share/plasma/shells/org.kde.plasma.desktop/contents/views/Desktop.qml:147:19: QML Loader: Binding loop detected for property "height"
file:///usr/share/plasma/shells/org.kde.plasma.desktop/contents/views/Desktop.qml:147:19: QML Loader: Binding loop detected for property "height"
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
trying to show an empty dialog
file:///usr/share/plasma/shells/org.kde.plasma.desktop/contents/views/Desktop.qml:147:19: QML Loader: Binding loop detected for property "height"
file:///usr/share/plasma/shells/org.kde.plasma.desktop/contents/views/Desktop.qml:147:19: QML Loader: Binding loop detected for property "height"
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
No metadata file in the package, expected it at: "/home/takahiro/Pictures/wallpaper/"
trying to show an empty dialog
file:///usr/share/plasma/shells/org.kde.plasma.desktop/contents/views/Desktop.qml:147:19: QML Loader: Binding loop detected for property "height"
file:///usr/share/plasma/shells/org.kde.plasma.desktop/contents/views/Desktop.qml:147:19: QML Loader: Binding loop detected for property "height"
file:///usr/share/plasma/plasmoids/org.kde.desktopcontainment/contents/ui/FolderItemDelegate.qml:288:17: QML Text: Binding loop detected for property "width"
file:///usr/share/plasma/plasmoids/org.kde.desktopcontainment/contents/ui/FolderItemDelegate.qml:288:17: QML Text: Binding loop detected for property "width"
file:///usr/lib/qt/qml/QtQuick/Controls/Button.qml:99: TypeError: Cannot read property 'width' of null
Connecting to deprecated signal QDBusConnectionInterface::serviceOwnerChanged(QString,QString,QString)
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:365: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:364: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:363: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:362: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:365: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:364: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:363: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:362: TypeError: Cannot read property 'padding' of null
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator//metadata.desktop"
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator/metadata.desktop"
kf5.kcoreaddons.desktopparser: Unable to find service type for service "Plasma/PopupApplet" listed in "/home/takahiro/.local/share/plasma/plasmoids/rss_indicator/metadata.desktop"
Trying to use rootObject before initialization is completed, whilst using setInitializationDelayed. Forcing completion
"syntax error, unexpected MONTH"
"syntax error, unexpected MONTH"
Loading Calendar plugin HolidaysEventsPlugin(0x5588c39120c0)
Both point size and pixel size set. Using pixel size.
Both point size and pixel size set. Using pixel size.
Both point size and pixel size set. Using pixel size.
trying to show an empty dialog
trying to show an empty dialog
trying to show an empty dialog
trying to show an empty dialog
Both point size and pixel size set. Using pixel size.
trying to show an empty dialog
trying to show an empty dialog
file:///usr/lib/qt/qml/QtQuick/Controls/Button.qml:99: TypeError: Cannot read property 'width' of null
file:///usr/lib/qt/qml/QtQuick/Controls/Button.qml:99: TypeError: Cannot read property 'width' of null
trying to show an empty dialog
file:///usr/lib/qt/qml/QtQuick/Controls/Button.qml:99: TypeError: Cannot read property 'width' of null
file:///usr/lib/qt/qml/QtQuick/Controls/Button.qml:99: TypeError: Cannot read property 'width' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:365: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:364: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:363: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:362: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/Button.qml:99: TypeError: Cannot read property 'width' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:365: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:364: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:363: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:362: TypeError: Cannot read property 'padding' of null
error activating kdeconnectd: QDBusError("", "")
error activating kdeconnectd: QDBusError("", "")
Trying to use rootObject before initialization is completed, whilst using setInitializationDelayed. Forcing completion
file:///usr/lib/qt/qml/QtQuick/Controls/Button.qml:99: TypeError: Cannot read property 'width' of null
file:///usr/lib/qt/qml/QtQuick/Controls/Button.qml:99: TypeError: Cannot read property 'width' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:365: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:364: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:363: TypeError: Cannot read property 'padding' of null
file:///usr/lib/qt/qml/QtQuick/Controls/ScrollView.qml:362: TypeError: Cannot read property 'padding' of null
libkcups: Create-Printer-Subscriptions last error: 0 successful-ok
libkcups: Get-Jobs last error: 0 successful-ok
libkcups: Get-Jobs last error: 0 successful-ok
couldn't load "/usr/lib/qt/plugins/discover-notifier/DiscoverPackageKitNotifier.so" because "Cannot load library /usr/lib/qt/plugins/discover-notifier/DiscoverPackageKitNotifier.so: (libpackagekitqt5.so.0: cannot open shared object file: No such file or directory)"
couldn't load "/usr/lib/qt/plugins/discover-notifier/FlatpakNotifier.so" because "Cannot load library /usr/lib/qt/plugins/discover-notifier/FlatpakNotifier.so: (libflatpak.so.0: cannot open shared object file: No such file or directory)"
couldn't find any notifier backend ("/usr/lib/qt/plugins")
Plasma Shell startup completed
file:///home/takahiro/.local/share/plasma/plasmoids/rss_indicator/contents/ui/RssSourceDelegate.qml:32:9: QML Image: Error decoding: https://dot.kde.org/favicon.ico: Unsupported image format
libkcups: 6
KCrash: Attempting to start /usr/bin/plasmashell from kdeinit
KCrash: Application 'plasmashell' crashing...
KCrash: Attempting to start /usr/lib/drkonqi from kdeinit
QSocketNotifier: Invalid socket 8 and type 'Read', disabling...
QSocketNotifier: Invalid socket 11 and type 'Read', disabling...
QSocketNotifier: Invalid socket 35 and type 'Read', disabling...
QSocketNotifier: Invalid socket 9 and type 'Read', disabling...
QSocketNotifier: Invalid socket 22 and type 'Read', disabling...
QSocketNotifier: Invalid socket 36 and type 'Read', disabling...
QSocketNotifier: Invalid socket 38 and type 'Read', disabling...
Unable to start Dr. Konqi
Re-raising signal for core dump handling.

org.cups.cupsdとplasmashellの間でコンフリクトが起きているらしい.

対策

org.cups.cupsdをdisableにすればplasmashellが動くようになるみたいだが,そうするとプリンタが使えなくなってしまう.

同じバグを議論する326289 – plasma-desktop crashed after configuring printer applet [JobModel::updateJob]の中で,デスクトップウィジェットからorg.kde.printerのエントリを消したら解決したという投稿があった.

"$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc"にウィジェットの定義がされているが,書き換えてもシステムに上書きされるため,こちらのファイルは直接編集できない.

そこでデーモンを一度停め,plasmashellを実行することでウィジェットを触ることができる状態にする.

$ sudo systemctl stop org.cups.cupsd
$ plasmashell

次に下の画像のようにウィジェットにおけるPrinterの監視を無効にする. f:id:takahiro0914:20171130005740p:plain

最後にデーモンを動作するようにして再起動する.

$ sudo systemctl enable org.cups.cupsd
$ reboot

以上でデスクトップを正常に稼働しながらプリンタも利用できるようになるはず.

参考記事

[1] 326289 – plasma-desktop crashed after configuring printer applet [JobModel::updateJob]

KDEデスクトップ環境下で日本語が文字化けを起こす

問題

DolphinやAmarok上で日本語のファイル名が文字化けを起こしてしまう.

Konsoleを開いてロケールを確認すると,

$ locale
LANG=ja_JP.UTF-8
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=

KDEを使用せずCL上での確認でも同様の結果となった.

ロケールはきちんと日本語のUTF-8になっているのに文字化けを起こす.

f:id:takahiro0914:20171115030938p:plain
問題が発生した環境

解決方法

システムやコンソール上のロケールのように"$HOME/.zprofile"でLANG環境変数をエクスポートするのではなく,"$HOME/.config/plasma-locale-setting.sh"でエクスポートしてやるとKDE上でのロケールを設定できるらしい.

$ nvim ~/.config/plasma-locale-setting.sh

export LANG=ja_J.UTF-8 # 日本語は表示したい
export LANGUAGE=en_US # でもシステムの言語設定として日本語は使いたくない

参考サイト

  1. [SOLVED] Locale in KDE Plasma 5 / Applications & Desktop Environments / Arch Linux Forums

MacでneovimにAirline導入

導入

前提条件 : neovim,プラグイン管理はdein.vimでtoml形式での記述
導入自体は簡単.

[[plugins]]
repo = 'vim-airline/vim-airline'
hook_add = '''
let g:airline_powerline_fonts = 1
'''
[[plugins]]
repo = 'vim-airline/vim-airline-themes'

プラグイン管理しているtomlファイルに追記

neovimを起動して

call dein#install()

するだけ.

airlineの文字化け解消

neovimを再度起動すると f:id:takahiro0914:20170807235923p:plain こんな風にステータスラインの一部の特殊文字が文字化けする.

そこで iTerm2の Non-ANCII font を Ricty Regular for Powerline.ttf にすればいいらしい[1].

brew install --vim-powerline ricty

ricty_generatorがSegmentation fault起こした....
以下のIssueによると,どうやらbrewでのインストールはできないらしい. Latest fontforge (20170731) segfaults when running ricty_generator · Issue #49 · sanemat/homebrew-font · GitHub

しばらく調べているうちに,RictyDiminishedというフォントを発見.
GitHub - edihbrandon/RictyDiminished: Ricty Diminished --- fonts for programming
こいつをgit cloneして手元に持ってくる.
しかしこいつでも文字化けは直せない...さらに調べるととある記事[2]でパッチスクリプトの存在を発見.
GitHub - mzyy94/RictyDiminished-for-Powerline: Ricty Diminished with Powerline patched --- fonts for programming
スクリプトをgit cloneし,RictyDiminished-Regular.ttfをcloneして来た

cp RictyDiminished/RictyDiminished-Regular.ttf RictyDiminished-for-Powerline
cd RictyDiminished-for-Powerline
fontforge -lang=py -script ./scripts/powerline-fontpatcher RictyDiminished-Regular.ttf
cp Ricty\ Diminished\ Regular\ for\ Powerline.ttf ~/Library/Fonts

そしてiTerm2の Preferences → Profiles → Text → Non-ANCII Font → Ricty Diminished Regular for Powerline

文字化け解消!!
f:id:takahiro0914:20170807235929p:plain
綺麗なステータスラインが目の前に!!

参照サイト

[1]Ricty for Powerline フォントとvim Airlineでかわいくて実用的なPython開発環境を作る | Developers.IO
[2]Vim Powerline用のFont Patchをあてる

neovimの導入

しばらく放置していたブログに久しぶりの投稿.

この間neovimなるものを見つけ,移行を決心. プロジェクトとしては,レガシーなvimをモダンなコードで書き直そうといった趣旨のもの. (vimの開発者)

主な特徴は
* 非同期処理が使いやすくなった
* msgpack APIの利用により,任意の言語での非同期処理が可能
(ref. Related projects · neovim/neovim Wiki · GitHubAPI clients)
* terminal emulatorの導入 (vimでの:shで実行されるようなやつ)
* カーソルの表示やtrue colorが使えるなどモダンな仕様に
* vimrcなどの設定をそのまま流用可能
を掲げているらしい.

インストール

macOSbrewを使っているなら話は早い.

brew install neovim

neovimを呼び出すコマンドは

nvim <開きたいファイル>

で使い方はvimとほとんど変わらない.

ただし,設定ファイル等はDirectory Specificationに準拠するようになっているのでその辺は要留意. $HOME/.vimrc に書き込んでいた設定ファイルは
$XDG_CONFIG_HOME/.config/nvim/init.vim に移動.
※ $XDG_CONFIG_HOMEが設定されていないと$HOME/.config/nvim/init.vimを参照する(?).

今までvim使って来た人は.vimrcをinit.vimに移植する必要がある.

プラグイン管理

今までプラグイン管理はNeoBundleだったが,tomlでのプラグインやその依存関係管理が便利そうだったのでdein.vimに乗り換えることに. dein.vim:tomlファイルでプラグイン管理する この辺を参考にどうぞ.

terminal emulatorの便利さ

vimの:shでは:(v)splitで複数画面に分割,或いは:ntabで複数タブに分割したときに,全ての画面領域が同時にシェルに入ってしまう不便さがあった.(:! での実行でも同様)
neovimの:terminalで起動するterminal emulatorでは画面領域の一箇所のみで実行されるので以下のスクリーンショットのように,neovimを抜けずに並行してターミナル操作が可能.
この便利さだけでもneovim移行の理由には充分. f:id:takahiro0914:20170807175841p:plain ちなみにterminal emulatorを抜けるにはCtrl + \, Ctrl + nをタイプすればいい.
抜けたターミナルに戻るにはiやaなどのinputモードに入る類のコマンドをタイプする.
抜けた後はgtやCtrl + w, [h,j,k,l]で好きな画面に移動可能.

所感

terminal emulatorまじ便利.

参照サイト

neovim.io

giginet.hateblo.jp

Ubuntu16.0.4のrbenv導入後, rbenv installでrubyが入らなかった件

結論

  • ruby-buildのログちゃん"/tmp/ruby-build.hogehoge.log"におった
  • DockerHubにあがってるUbuntuのオフィシャルイメージにはcurlとかwgetとかが入っていなかった
  • ruby-buildのエラーだから(?)rbenvのインストール時にエラーとして吐き出されなかった

内容

オフィシャルなUbuntuのDockerイメージからコンテナ作ってrbenv入れようとしたら詰まった件

cat /etc/lsb-release  

# 以下実行結果
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04 LTS"

導入とか適当にやった

rbenv install 2.2.0

終わるのめっちゃ早い, おかしい, 前は数分とかかかってたのに...エラー文とか特にないから問題ないのかな?

rbenv versions

systemしかねぇ...(゜△゜;)
何度やり直してもできず, 「モウオシマイダー!」と匙を投げようとした時にこの記事にぶち当たった.

rbenv での Ruby 2.2.1 のインストールに失敗する - スタック・オーバーフロー

ruby-buildのログちゃん"/tmp/ruby-build.hogehoge.log"におったんか!と…覗いてみると

おい! テメェbzip2入ってねぇぞ!
あとwget, curl, alia2cのどれか入れろばかやろー!

とお叱りを受けてました.

可愛いruby-buildちゃんのためにしかなく入れてあげるか…というか最初からそれぐらい入れてくれててもよかったのにUbuntuさん…(^_^ ;)
そのあとBuild Fails on fiddle.so Ruby-2.2.0 Ubuntu 14.10 · Issue #692 · rbenv/ruby-build · GitHubの問題で一度詰まりましたが, ここではエラーメッセージが出てきたので割とすんなり解決策が見つかりました. エラーメッセージたんまじきゃわいい.
おかげでめっちゃ食われましたよ時間が. まあ最終的に導入できたのでよかったですが.

Jenkins + GitHubでRailsAppのCI構築を頑張る

先日の記事ではDocker上にJenkinsとRailsAppを同棲させた…OK?

前の記事Nginxを使ったRailsAppとJenkinsの同棲計画 - それでも気分は高専生の環境を前提としてローカルからGitHubにpushしたのをhookしてJenkinsが勝手にデプロイしてくれる. 所謂CI(Continuous Integration)というやつをやっていきます.

大まかな手順

  1. Jenkins上でJobを作成
  2. GitHubからWebHookを設定

以上(大雑把スギィ!)

JenkinsのJob作成

http://x.x.x.x/jenkinsに接続すると「お前本当に管理者かよ」って尋ねられるので, 指定されたpathにあるパスワード的なのを入力(詳細は忘れちゃったので誰か詳しい人情報plz). そのあとユーザ作ったらこんな画面になる.

f:id:takahiro0914:20160629211915p:plain

左端のメニューからManage Jenkins → Manage Plugins → GitHub Pluginを入れる.

Jenkinsトップページに戻って左端のNew Itemを選ぶと新しいJobの作成に入る. 適当な名前をつけてFreestyle project → OKが左下に現れるのでクリック.

  1. GeneralのGitHub projectにチェックを入れ, GitHubリポジトリのURLを入力.
  2. Source Code ManagementのGitにチェックを入れ, もう一度リポジトリのURLを入力.
  3. Branches to Buildには"*/branch_name"を入力.
  4. Repository browserはAutoでいいや.
  5. Build Triggersの"Build when a change is pushed to GitHub"にチェックを入れる.
  6. Poll SCMにチェックを入れ, Scheduleに" */15 * * * * "を入力(15分毎にリポジトリを参照して, pushされていれば6で入力するコマンドを実行). Scheduleに関してはユカイ、ツーカイ、カイハツ環境!(21):「Hudson」改め「Jenkins」で始めるCI(継続的インテグレーション)入門 (3/4) - @ITを参照されたし.
  7. BuildのExecute shellのCommandにweb hook時に実行するコマンドを入力.

ex.

sudo su app
whoami
cd /var/app/rails_app
sudo git pull
sudo bundle install
sudo bundle exec puma -d -C config/puma.rb restart

※ 以前まで"sudo bundle exec pumactl -F config/puma.rb restart"としてましたが, jobが働いた時にdaemonizeされないため, いつまでもjobが動きっぱなしになるようなので修正しました(2016/7/7)

っと, 忘れてましたがここで新しいユーザappちゃんを作っておいてください.

useradd app    # appユーザの追加
chown -R app /var/run/rails_app    # RailsAppの所有者をappユーザに変更
visudo

sudoersの設定に以下を追加.

jenkins    ALL=(ALL:ALL) NOPASSWD:ALL
app   ALL=(ALL:ALL) NOPASSWD:ALL

でappユーザにrbenvだの何だのとRailsAppを動かせるようにしてやらなきゃいけない. ちなみに僕はrbenv入れてrubyを入れて, bundler入れて, bundle installするだけでしょって油断してたら, Failed to build gem native extension · Issue #133 · github/pages-gem · GitHubでめっちゃ詰まってた().

※ appでsudo puma -dを実行するとなぜかpidファイルが生成されない. rootでpuma -dを実行してpumaを起動させる必要性がある. 知っている人がいたら教えて(もしかしたらpidの権限設定が-rw-r--r--. 1 rootになっているのが原因かも)...

※ sudoなしでsuしようとしたらsu: must be run from a terminalって言われて死んだ. ので忘れないように.

実際にJobがうまくいくかを見たい時はBuild Nowで実行する. f:id:takahiro0914:20160629232817p:plain 実行すると左下にBuild Historyが表示されるのでビルド番号上にマウスを重ねると横に逆三角が表示され, クリックすると下図のようにドロップダウンが表示される. f:id:takahiro0914:20160629233012p:plain その中のConsole Outputをクリックするとビルド結果のページへ移動する.

WebHookをふっかける

GitHubリポジトリを開き, 画面上部のSettingsタブを開く. f:id:takahiro0914:20160630005127p:plain 画面左端のOptionsから"Webhooks & Service"を選択. f:id:takahiro0914:20160630005234p:plain "Add Service"から"Jenkins(GitHub plugin)"を選択. "Jenkins url"にJenkinsサーバのURL(prefix含む)を指定, Activeにチェックを入れて"Add Service"をクリック. f:id:takahiro0914:20160630005649p:plain

最後に僕もよくわかっていないところも多々あると思うので, 何かご指摘があればどんどんください.

参考サイト

GithubからJenkinsへのServer Hook - Qiita sudo のパスワードを入力なしで使うには - Qiita linux - su in shell script started from ssh works in other terminal - Super User

Nginxを使ったRailsAppとJenkinsの同棲計画

雑記

おおよそ1年半ぶりの投稿になりますが…… 今回からは色々と挑戦してみたことの技術的備忘録として活用していく予定. (但し予定≒未定)

今回はdeployしたRailsAppとJenkinsを同一server上に置いてやろうぜ!ということをやってみました. ちなみに背景としては

  1. RailsApp作ってdeployする必要が生じる
  2. 自宅サーバ置いたら(物理的に)炎上
  3. cloud借りるか (Microsoft Azureの無料試用期間でVM使うことに)
  4. どうせならJenkinsでCIやりてぇ
  5. cloud/VPS高い, 複数借りるのなんてムリィ!
  6. RailsAppとJenkins共存させよ

目指す構成

目指している構成はこんな感じ. Nginxをreverse proxy serverとして, request URLのprefixで判断し, RailsAppとJenkinsに振り分ける. f:id:takahiro0914:20160625223337p:plain 理由としては

  • 可搬性を考えて(試用期間終わったらどっか他の安いところに移設予定)全部Docker containerにぶち込みたい
  • Docker contianer使うならOSはDocker導入が一番楽な(というかdefaultで入ってる)CoreOS使おう
  • VPSやCloudのお引越しの度にport設定をし直すの面倒臭い
    • Dockerのport forwardingで複数のportを使わない
    • 代わりにDocker container内のNginxをプロキシにしてsub directoryでRailsAppとJenkinsを使いわける

早速構成していく

  1. Core OSにssh login transmission !
  2. DockerHubからUbuntuのimageをpull
  3. Dockerでport forwarding(hostの80番とguestの80番を直結), でもってdive!
docker run -d -it -p 80:80 --name hoge ubuntu /bin/bash
docker -it exec hoge /bin/bash
  1. NginxとJenkinsはapt-getなんかを使ってうまいこと入れる (googleれば幾らでも出てくるさ)
  2. Rails環境もうまいこと入れる (僕の場合はrbenv使ってruby 2.2.0-devとRails5.0.0rcを導入)
  3. rails newする (ここではRailsAppのdirectoryを/var/app/rails_appとする)

RailsAppとJenkinsをNginxに繋げる

ここでの説明はcurrent directoryを/var/app/rails_appであることを前提として進める.

./config/puma.rbに以下を追記するぅ!

_proj_path = "#{File.expand_path("../..", __FILE__)}"  # RailsAppの絶対path
_proj_name = File.basename(_proj_path)  # RailsAppのおなまえ

pidfile "/var/run/#{_proj_name}.pid"  # Puma serverが動作しているprocess idを/var/run/rails_app.pidにぶち込むよう指定 (Puma serverはdaemonとして動作させた際に止めたい時, こいつが必要)
bind "unix:///var/run/#{_proj_name}.sock"  # Puma serverは/var/run/rails_app.sockからHTTP requestを頂く
directory _proj_path  # working directoryをRailsAppのpathに

/etc/nginx/conf.d/rails_app.conf(/etc/nginx/conf.d/*.confを読むようになっているので, 名前は多分なんでも可)を作成して以下を追記 (serverのIP addressはx.x.x.xを想定)

error_log /var/log/nginx/error.log warn;

upstream rails_app {
    server unix:/var/run/rails_app.sock fail_timeout=0; # /var/run/rails_app.sock を介してPumaとやりとりするよ
}

server {
    listen 80;  # port80で受け付けるよ
    server_name x.x.x.x;  # x.x.x.xでrequest来たら対応するよ

    error_page 500 502 503 504 /500.html
    client_max_body_size 4G;
    keepalive_timeout 10;

    include /etc/nginx/mime.types;
    try_files $uri/index.html $uri @rails_app

    location /rails_app/ {  # URLがhttp://x.x.x.x/rails_app/...だった場合
        root /var/app/rails_app/public;  # web pageなんかはpublicにぶち込まれるよ
        proxy_pass http://rails_app;  #  Pumaに横流しするよ
        proxy_set_header X-Forwarded-For $proxy_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header off;
    }
    location /jenkins/ {  # URLがhttp://x.x.x.x/jenkins/...だった場合
        proxy_pass http://127.0.0.1:8080;  # localhost:8080 (jenkisがわさわさしてるport) にぶん投げるよ
    }
}

ちなみにNginxの設定ファイルが「本来書いてはいけない場所に書いていないか」「文法的に間違っていないか」を確認するには以下を実行するとチェックできる.

nginx -t

次に /etc/default/jenkinsを以下のように変更

# JENKINS_ARGS = "hoge" を以下に変更 (Jenkinsのroot pathをx.x.x/jenkins/に変更)
JENKINS_ARGS = "hoge --prefix=/jenkins"

RailsAppのroutingにprefixを追加 (以下の内容を./config/routes.rbを以下のように変更)

Rails.application.routes.draw do
  # 全部のrouting pathの先頭に/rails_appを装着
  scope '/rails_app' do
    # All routing descriptions
  end
end

このままではJSや画像ファイルなどのassets以下が機能しなくなるので./config/public/environments/development.rb, ./config/public/environments/test.rb, ./config/public/environments/production.rbのRails.application.configure内に以下を追記

config.assets.prefix = '/rails_app/assets'

以下NginxとPuma, JenkinsをContainer起動時に自動で動作するよう設定 (Ubuntuだとchkconfがないっぽいのでsysv-rc-confで代用)

sysv-rc-conf nginx on
sysv-rc-conf puma on
sysv-rc-conf jenkins on

とするとどうもダメみたいですww バカ正直にcontainer侵入後に以下を実行.

cd /var/app/rails_app
bundle exec puma -d
# Pumaを停止させる場合は bundle exec pumactl -P /var/run/rails_app stop
service jenkins start
service nginx start

ちなみに今回はsocket通信を行うWebAppの開発ではないので, Action Cableの設定に関しては考慮していない.

以上, だいたいこんな感じでやってました. 何か不備, 間違いなどがありましたらどんどん指摘してください.

Tips

socket fileが仕事しているかを見るにはcurl --no-buffer -XGET --unix-socket /var/run/rails_app.sock http:/events でsocket fileを叩ける

参考サイト

vimからの初めまして

昨晩(今朝)投稿した記事にあったはてブロのvimプラグインhateblo.vimを入れてみた.

導入の参考にさせていただいたサイト

なのでこの記事の投稿がvimをつかたった初めての投稿となる.

自分がはてブロをこれから始めるかどうかはこいつの快適さにかかってくるかもしれない.

とりあえず完全放置してたのを思い出して適当に書いてみる

なんでこの時期この時間帯に思い出したのか自分でもわからない。
だが、思い出したということには意味があるのだろう。

ということで一つだけ記事を書くことにした。

そういえば……どうやらvimにははてブロのAPIを叩いて記事投稿ができるプラグインがあるよう……それが導入できたら本格的に始めるかも。

hateblo.vim