2018年4月25日水曜日

Windows シャットダウンがブロックされるのを防ぐ - DockerToolbox + Windows 10 (VirtualBox)

Windows 10 + Docker Toobox (VirtualBox) 環境を構築。
スタートアップからホスト起動するようにして、個人的に使ってるサービスを立ててるのですが、シャットダウンするときに VirtualBox Interface が "Has active connections." となって終了を阻害してたので、それを解決したときのメモ。

VBoxHeadlessTray をインストールして常駐させておく
参考:
Windows 7 終了時にdockerを自動終了させる。 - イノベートな非日常
VBoxHeadlessTray - Topten Software

2つ目のリンクから VBoxHeadlessTray をダウンロードして、インストール。
VBoxHeadlessTray が常駐するようになります。
これだけで解決!
簡単でした。
(インストール直後はダメでしたが、再起動後からは終了が阻害されることがなくなった)

また、VBoxHeadlessTray により起動時に VM が PowerUp されるようになったので、スタートアップで Docker を起動する必要もなくなりました。
Windows Update とかもあって、この辺あやふやです。すみません。
Tray が自動で PowerUp してくれてる感じがありますが、それだけだとシャットダウンがブロックされました。(VM が headless で起動してない?)
Docker Toolbox の Quick Start をスタートアップに入れてるとエラーが出るのですが、Tray からの起動で正常に立ち上がるっぽい。(タイミングが衝突?)
スタートアップ直後じゃなくて、数秒待ってみると大丈夫そうだったので、しばらくこれで・・・

他にやったこと
常駐させておくよりも設定でなんとかできたらと思っていたので、こちらを先に試していました。
VirtualBoxでホストのシャットダウンにゲストのバーチャルマシンも連動させる パソコン鳥のブログ/ウェブリブログ

VBoxManage で設定をしてあげれば良さそうだったので、マニュアル見ながら試してみたものの結果としてはうまくいきませんでした。
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" setextradata default GUI/DefaultCloseAction savestate
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" setextradata global GUI/DefaultCloseAction savestate
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" setextradata default VBoxInternal2/Watchdog/APIMonitor/IsolationResponse shutdown

サービス化する
これを書いてて思ったのだが、サービス化するってのはどうだろうか?
VirtualBox をサービス化する情報はすぐに見つかったので、今度試してみたいと思います。


あとがき
この記事を書いて少し寝かせていたのですが、その間にたまーに Docker Host の起動状態がおかしくなって、Virtual Box Manager からシャットダウンして起動し直すということがありました。また、たまにシャットダウンがブロックされる症状が出ていたので、根本的な解決とはなってない感じ。。。
(この記事が公開されているということは、ネタ不足になったということだ。)


2018年4月17日火曜日

[MSVC] pragma warning での警告抑止はどこにでも書けばいいというものではなかった [2013]

Visual Studio 2013 なんてもう誰も使ってない気がしますが
Visual Studio 2013 で pragma warning による警告抑止が効かないケースがあったので、メモです。

気づいたのは、iutest で MSVC の警告撲滅をしていたのがきっかけです。

問題のコードはこちら
https://github.com/srz-zumix/iutest/blob/6a2a798458aa220f2d1a88b8a79be39a867e8709/include/internal/iutest_port.hpp#L283

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
template<int size="BUFSIZ">
class IUStreamBuffer
{
public:
    // __pragma(warning (push))
    // __pragma(warning (disable: 4996))
    IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
 
    explicit IUStreamBuffer(FILE* fp)
        : m_fp(fp)
    {
        m_buf[0] = '\0';
        fflush(fp);
        setvbuf(fp, m_buf, _IOFBF, SIZE);
    }
 
    ~IUStreamBuffer()
    {
        fflush(m_fp);
        setbuf(m_fp, NULL);
    }
 
    // __pragma(warning (pop))
    IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
</int>
setbuf が C4996 出るので pragma warning push/disble/pop をつけていました。
VS2017 や VS2015 では上記の書き方で問題がなかったのですが、Visual Studio 2013 では正しく警告抑止ができてませんでした。



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template<int size="BUFSIZ">
class IUStreamBuffer
{
public:
    explicit IUStreamBuffer(FILE* fp)
        : m_fp(fp)
    {
        m_buf[0] = '\0';
        fflush(fp);
        setvbuf(fp, m_buf, _IOFBF, SIZE);
    }
 
    ~IUStreamBuffer()
    {
    // __pragma(warning (push))
    // __pragma(warning (disable: 4996))
    IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
        fflush(m_fp);
        setbuf(m_fp, NULL);
    // __pragma(warning (pop))
    IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
    }
 
</int>

こうだとちゃんと警告が抑止されたので、どうやら書く場所が悪かったみたいです。
(今は setvbuf 使うようにして抑止しなくていいようにしたので、上記コードはなくなりました)


まとめ
最新のコンパイラーなら大丈夫なのかもしれませんが、pragmra warning はどこにでも書けるという認識が間違っていた、というのは良い収穫でした。
極力、警告抑止はない方がいいですが、使う場合はなるべく小さなスコープで書くようにしたいと思います。


今回は以上です。では。

2018年4月10日火曜日

[CI] Cirrus CI はじめました



新しい CI サービスを見つけたので、早速使ってみました。
今回使ったのは Cirrus CI です。
Cirrus CI の特徴は Github App であること、そしてシンプルかつ Windows にも対応しています(OS X も今後対応するようです)
また、気になる Pricing も OSS であれば無料です。


はじめる
Cirrus CI は他の CI サービスと異なり Github App で提供されているため Github 専用です。
使う場合も、Marketplace からインストールして開始します。
https://github.com/apps/cirrus-ci

Marketplace にアクセスしたら、「Install」ボタンを押します。


権限の確認画面が出ますので、自分のリポジトリ全部に権限を与えるか、一部のリポジトリのみに与えるか選択します。使い方にあったほうを選択したら、「Install」ボタンを押してください。


インストールはこれだけです。
完了すると「Quick Start」のページにジャンプします。
(ドキュメントは他のサービスと比べると少ない印象がありますが、シンプルな作りだったので十分でしたし、yml フォーマットも理解しやすかったです)


タスクを作成
Cirrus CI も多くの CI サービスと同様に yml ファイルをリポジトリに配置して、その記述に沿って CI が実行されます。
yml のフォーマットは公式ドキュメントに説明があります。

iutest では以下のようなタスクを作成しました。(コメント足してます)
# コンテナの指定はタスクごとに指定可能、グローバルデフォルトは以下のように書く
#container:
# 指定できる imgae はこちらを参照 (https://cirrus-ci.org/guide/supported-computing-services/#community-cluster)
# k8s を覚えたら追記
# image: node:latest
# cpu: 4
# memory: 12
# task(他の CI サービスでいうとジョブとか)
# task の前に好きな名前をつけられる、コミットステータスに表示される名称がこれになる
cirrus_gcc_test_task:
# コンテナ指定
container:
image: gcc:latest
# マトリックスも組める
# (コンテナのマトリックスも組める https://cirrus-ci.org/guide/writing-tasks/#matrix-modification)
env:
matrix:
STDFLAG: -std=c++14
STDFLAG: -std=c++17
#STDFLAG: -std=c++2a
# ***script に実行する処理を書く (https://cirrus-ci.org/guide/writing-tasks/#script-instruction)
# script の前には好きな名前をつけられる
test_script: cd test && make -j4 showcxxversion default && make test
#cirrus_use_gtest_task:
# env:
# USE_GTEST: 1
# container:
# image: srzzumix/googletest:latest
# test_script: cd test && make -j4 showcxxversion default && make test
view raw .cirrus.yml hosted with ❤ by GitHub


フォーマットはシンプルで、基本的には task と script を作成する感じです。
もちろん、マトリックスや、タスクの依存関係などを組みこともでき、メインの CI サービスとして使っていける機能が揃っています。

.cirrus.yml を push する
作成した .cirrus.yml を push するとタスクが実行されます。
タスクの状態は Github の Commit Status に表示されます。



Details から詳細ページにジャンプできます。
そちらでビルドログが確認できますので、失敗した場合はそちらを確認する感じ。




バッジを付ける
最後に、CI サービスお約束のバッジを付けていきます。
バッジの付け方は以下のページに説明があります。
https://cirrus-ci.org/guide/writing-tasks/#embedded-badges


iutest の場合は
のようになります。



最後に
たまたま Cirrus CI のことを発見して使ってみましたが、躓くところもなくすんなりと導入ができました。
今まで多くの CI サービスを使ってきたこともあってか、yml ファイルの記述が理解しやすかったように感じました。

また、今回は使用しませんでしたが Windows のワーカーも使えるとのことですし、OS X も今後対応予定なので複数 OS のテストが1つのサービスでできるようになる日も近そうです。
Travis CI や Circle CI で Linux/OS X、AppVeyor で WIndows の CI を回している方は、お引越しを検討してみてはいかがでしょうか。

今回は以上です。では。

2018年4月4日水曜日

shippable.yml が古かったため pip install に失敗してた

pip install requests 0s  
Downloading/unpacking requests
  Cannot fetch index base URL https://pypi.python.org/simple/
  Could not find any downloads that satisfy the requirement requests
Cleaning up...
No distributions at all found for requests
Storing debug log for failure in /home/shippable/.pip/pip.log

最近になって、上記のようにジョブが失敗していたのですが、それを直すのに少し手間取ったので記録として残しておきます。
(100% 失敗するのではなく成功したり失敗したりってのがまためんどくさかった…)

結論
結論だけ書きます。
shippable.yml の書き方を更新したら直りました。
(ワーカーが更新されて pip のバージョンが新しくなった)
shippable.yml は大分前に更新があったのですが、ずーーっと放置していたツケが回ってきましたね…
Migrating to the New Build Platform

before_install, install, before_script, script, after_script, after_success, and after_failure がなくなって build セクションに統一されました。

最後に
同じ問題にぶつかって困っている人の助けになれば幸いです。
では。

2018年4月2日月曜日

Github で検索するときに知っておくと便利な機能

検索することがちょくちょくあるので自分用備忘録。

検索ドキュメントはこちら
https://help.github.com/articles/searching-code/


言語の指定
検索後に言語選択 UI ありますが、テキストで指定できます。検索したい言語が候補にあがらない場合は試してみると良いかも。
language:dockerfile

拡張子の指定
言語指定とは別に絞り込みができそう。
extension:cpp

path の指定
path:/
CI の yml とかルートパスに置くのが一般的なので、path:/ でルートパスを指定したら、探しやすくなりそうですね。
CI の設定を書くときに他のリポジトリを参考にしたりするので、これは結構使えるかも。

記号が使えない
検索するときに困るのが記号が使えないことです。
使えない記号は以下。
. , : ; / \ ` ' " = * ! ? # $ & + ^ | ~ < > ( ) { } [ ]

これらを含めて検索をしても、記号は無視されてしまいます。
この仕様が結構不便なんですよね。。。

回避策
(コードは検索できなさそうなんですが…)Google 検索の site オプションを利用すると、記号も含めた検索ができます。
やり方は Google 検索で、検索したい文字列の前に site:https://github.com/ をつけるだけです。

これで https://github.com/ 内を検索してくれます。


記号の検索に対応してくれると一番嬉しんですけどね。
では。