tohokuaikiのチラシの裏

技術的ネタとか。

VagrantとChefで開発環境を作る

もらったアプリケーションが、VagrantとChefを使ってるぽかったのでWindows10でChefからVagrantを通して開発環境を作ってみるメモ。

とりあえず参考資料 Vagrant と Chef による仮想環境構築の自動化(VirtualBox編) | オブジェクトの広場

Vagrantはインストールして使ってるので、Chefのインストールから。

Chefのインストールとセットアップ

https://downloads.chef.io/chef-dk/ から最新版のChef Development Kitをダウンロードしてインストール。

セットアップ

さきほどのブログ記事には

Chef-DK にバンドルされた Ruby の利用が推奨されています。以下のコマンドで Chef-DK の Ruby を使うように指定して下さい。
% eval "$(chef shell-init SHELL_NAME)"
(注意)SHELL_NAME の箇所は自分が使っているシェル名に置き換えてください。

ってあるけど、よくわからない。こういう時は本家ドキュメントを読む。インストール手順からのhttps://docs.chef.io/dk_windows.html:title=Windowsでのセットアップ]

WindowsのスタートメニューからインストールされたChef DKを起動。PowerShellの管理者モードで起動する。
f:id:tohokuaiki:20180919142715p:plain

Chef実行時の環境設定を行う。rubyコマンドで C:/opscode/chefdk/embedded/bin にあるruby.exeが使われるようになる。

現在のセッションだけなら

chef shell-init powershell | Invoke-Expression

を実行。
パーマネントに設定したい場合は、下記のようにする。

"chef shell-init powershell | Invoke-Expression" >> $PROFILE

この時、$PROFILEファイルは、

PS C:\WINDOWS\system32> $PROFILE
C:\Users\t-ito\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

なのだけど、これが無い場合は

if(Test-Path $PROFILE){ chef shell-init powershell | Add-Content $PROFILE } else { New-Item -Force -ItemType File $PROFILE; chef shell-init powershell | Add-Content $PROFILE }

とする。

PowerShellスクリプト実行は、セキュリティ上実行されない場合があるので 

Set-ExecutionPolicy RemoteSigned

で「Y」を選択実行しておく。

chefコマンド-vでチェックしておく。cygwinだとうまくいかなかった。

Vagrant のインストール

本体はインストール済みなので、プラグインを。

$ vagrant plugin install vagrant-vbguest
$ vagrant plugin install vagrant-chef-zero
$ vagrant plugin install vagrant-omnibus

と3つインストールする。最初のvagrant-vbguestはおそらく既にインストール済みである。

次のvagrant-chef-zeroをインストールする所で引っかかる。

2> vagrant plugin install vagrant-chef-zero
Installing the 'vagrant-chef-zero' plugin. This can take a few minutes...
Building native extensions.  This could take a while...
Bundler, the underlying system Vagrant uses to install plugins,
reported an error. The error is shown below. These errors are usually
caused by misconfigured plugin installations or transient network
issues. The error from Bundler is:

ERROR: Failed to build gem native extension.

    current directory: C:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/ffi-yajl-1.4.0/ext/ffi_yajl/ext/encoder
C:/HashiCorp/Vagrant/embedded/mingw64/bin/ruby.exe -r ./siteconf20180919-1164-1h53pll.rb extconf.rb
 -IC:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/libyajl2-1.2.0/lib/libyajl2/vendored-libyajl2/include -march=x86-64 -mtune=generic -O2 -pipe
 -LC:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/libyajl2-1.2.0/lib/libyajl2/vendored-libyajl2/lib -L. -pipe
creating Makefile

current directory: C:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/ffi-yajl-1.4.0/ext/ffi_yajl/ext/encoder
make "DESTDIR=" clean

current directory: C:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/ffi-yajl-1.4.0/ext/ffi_yajl/ext/encoder
make "DESTDIR="
generating encoder-x64-mingw32.def
compiling encoder.c
encoder.c: In function 'Init_encoder':
encoder.c:382:20: error: 'rb_cFixnum' undeclared (first use in this function); did you mean 'rb_isalnum'?
   rb_define_method(rb_cFixnum, "ffi_yajl", rb_cFixnum_ffi_yajl, 2);
                    ^~~~~~~~~~
                    rb_isalnum
encoder.c:382:20: note: each undeclared identifier is reported only once for each function it appears in
encoder.c:383:20: error: 'rb_cBignum' undeclared (first use in this function); did you mean 'rb_cFixnum'?
   rb_define_method(rb_cBignum, "ffi_yajl", rb_cBignum_ffi_yajl, 2);
                    ^~~~~~~~~~
                    rb_cFixnum
make: *** [Makefile:242: encoder.o] Error 1

make failed, exit code 2

Gem files will remain installed in C:/Users/t-ito/.vagrant.d/gems/2.4.4/gems/ffi-yajl-1.4.0 for inspection.
Results logged to C:/Users/t-ito/.vagrant.d/gems/2.4.4/extensions/x64-mingw32/2.4.0/ffi-yajl-1.4.0/gem_make.out

よくわからない…無視して進める。

貰ったVagrantfileにberkshelfが使ってあるっぽいんでインストール、

>vagrant plugin install vagrant-berkshelf
Installing the 'vagrant-berkshelf' plugin. This can take a few minutes...
Fetching: vagrant-berkshelf-5.1.2.gem (100%)
The Vagrant Berkshelf plugin requires Berkshelf from the Chef Development Kit.
You can download the latest version of the Chef Development Kit from:

    https://downloads.chef.io/chefdk

Installing Berkshelf via other methods is not officially supported.
Successfully uninstalled hashie-2.1.2
Successfully uninstalled libyajl2-1.2.0
Successfully uninstalled mixlib-log-1.7.1
Installed the plugin 'vagrant-berkshelf (5.1.2)'!
Post install message from the 'vagrant-berkshelf' plugin:

The Vagrant Berkshelf plugin requires Berkshelf from the Chef Development Kit.
You can download the latest version of the Chef Development Kit from:

    https://downloads.chef.io/chefdk

Installing Berkshelf via other methods is not officially supported.

そして、vagrant upすると

vm:
* The host path of the shared folder is missing: ../projects

と出る。

Vagrantfileがある階層の1個上にprojectsというフォルダを作成し、再度vagrant upするとなにやら進みだした。Windowsから管理者権限チェックが入るがとりあえず「はい」を選択して進める。Windows Defenderからもなんか聞かれるが通す。

なんか、vagrant upすると同時にyumで色々とインストールが始まった。たぶん、chef-zeroはいらなかったっぽい。

で、進んでくと、

    default: SSH auth method: private key
==> default: Mounting shared folders...
    default: /vagrant => C:/Users/t-ito/VagrantBox/xxxxxxx/projects
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o dmode=777,fmode=666,uid=500,gid=500 vagrant /vagrant

The error output from the command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device

となった。mountで引っかかったのだけど、とりあえずVMは起動しててvagrant sshで接続は可能。

Vagrantfileのマウントの設定がMacOSのパス設定だったのでWindowsのものに変更。

  config.vm.synced_folder "C:\\hogehoge\\projects", project_path

という感じで書き換えた。(バックスラッシュ二重)

ネットワークアダプタの日本語が邪魔してる?

しかし、どうもローカルからVagrantへのマウントができない。

Vagrant was unable to mount VirtualBox shared folders. This is usually because the filesystem "vboxsf" is not available.

とか

C:/HashiCorp/Vagrant/embedded/gems/2.1.5/gems/vagrant-2.1.5/lib/vagrant/util/io.rb:32:in `encode': "\x80" on Windows-31J (Encoding::InvalidByteSequenceError)

とか言われる。日本語なんて使ってないのに…。

全うに取り組むのをあきらめて、VagrantコマンドでEncoding::InvalidByteSequenceErrorであったように直接 C:/HashiCorp/Vagrant/embedded/gems/2.1.5/gems/vagrant-2.1.5/lib/vagrant/util/io.rb を書き換えてやった。そしたら、マウントしてshefが動くところまで行った。

しかし、

$ vagrant vbguest

でヴァージョン合わすといいよとあったのでやってみるとむしろ悪化。再びマウントができなくなってしまい…。

NoMethodError: undefined method `tz=' for #<Chef

Chef v13でtimezone-iiを使う(なるべく使わない方が良い)

YouTubeの左上にあるロゴがワールドカップのアニメーションになってたが、GIF動画ではなかった。

これね。いつもはYouTubeのロゴ。 f:id:tohokuaiki:20180715205630p:plain

で、これのアニメーションがGIFアニメとかMP4とかでなくて、ただのバカでかいPNG画像だった。

https://www.gstatic.com/youtube/doodle/yt-doodle-worldcup-1x.png https://www.gstatic.com/youtube/doodle/yt-doodle-worldcup-1x.png

これの背景位置をずらしているだけという…

i=0;
var f = function(i, img){
    img.style.backgroundPositionX= i*110 + "px";
    if (i++ < 15840/110) {
        setTimeout(function(){
            f(i, img);
        }, 40);
    }
};
f(i, document.getElementById('animated-yoodle'));

なるほど、そういうのもあったのか。

データのどれだけの個数を調べれば、だいたい「まぁ、いいかな」って言えるか。

食品総合研究所 :食品のサンプリングに関するガイダンス〜品質情報解析ユニット から。

10000個、製品があってこの中の不良品を見つけられる確率の話。1個でも不良品があってその存在が致命的な場合は全品検査になる。 全品検査が大変な時は、サンプルN個だけを抜き出して検査をしたいが、どれだけのNを検査すればいいのかの妥当性を知りたい。

ポイントは、見逃し率。これをできるだけ下げたいが、Nが多すぎても面倒なのでその経済効率の最大リターンポイントを見つける。

ただし、1個の検査をするときにその検査による判定は100%の確からしさで判定できるものとする。

用語の設定

  • 不良品率:全体の何%が不良品かの確率。
  • 見逃し率:サンプルN個検査をした際に、どれくらいの確率でそれが「不良品が存在した」と発見できるかの確率。

計算方法

1個の製品をチェックする際に、それが不良品でありかつ不良品であると判定できる確率を計算する。パーセンテージで考えると100掛けたり割ったり面倒なので、確率は少数でやる。

合格品発見確率 = 1 - 不良品率
N個全てが合格品である確率 = (1 - 不良品率)^N (^はNの乗数を意味する)
N個のうち1個でも不良品が見つかる確率 = 1 - (1 - 不良品率)^N 

この「N個のうち1個でも不良品が見つかる確率」というのは、「不良品を発見できる確率」とも言えます。つまり、「1-見逃し率」

1 - 見逃し率 =  1 - (1 - 不良品率)^N 

となる。

Nについて解くと、

N = log(見逃し率) ÷ log(1 - 不良品率)

となる。

はてなスターAPIを使ってはてなブックマークコメントについた★の数を得る

はてなスター取得APIというのがある。

はてなスター取得 API - Hatena Developer Center

これで、はてなブックマークのコメントについた★の数を得ようとする。

例えば、https://anond.hatelabo.jp/20180518171957 に付けた私のブックマークの★の数はこの記事を執筆時点で91個。

このブックマークのURLは、http://b.hatena.ne.jp/entry/364742428/comment/tohokuaiki でカノニカルだと思われる。

なので、先ほどのAPIに従って、
http://b.hatena.ne.jp/entry/364742428/comment/tohokuaiki
をくっつけて
http://s.hatena.com/entry.json?uri=http%3A%2F%2Fb.hatena.ne.jp%2Fentry%2F364742428%2Fcomment%2Ftohokuaiki
で取得できるのかな?と思ったらだめだった。

正解は
http://b.hatena.ne.jp/tohokuaiki/20180525#bookmark-364742428
をくっつけて
http://s.hatena.com/entry.json?uri=http%3A%2F%2Fb.hatena.ne.jp%2Ftohokuaiki%2F20180525%23bookmark-364742428
なのである。なんだよ、このアンカー入りのURLでパーマリンク設定するのって…。

WordPressで特定の投稿タイプで特定の部分だけ自動整形のPタグを消す (wpautopを動作させない)

filterの削除・追加とショートコードを使う

custom_posttype投稿タイプの場合。

<?php
    /* 特定の投稿タイプはautopをしない */
    remove_filter('the_content','wpautop');
    add_filter('the_content' , function($content){
        $post_type = get_post_type();
        if ($post_type != 'custom_posttype'){
            $content = wpautop($content);
        }
        return $content;
    });
    add_shortcode('wpautop', function($attr, $content){
        $post_type = get_post_type();
        if ($post_type == 'custom_posttype'){
            $content = wpautop($content);
        }
        return $content;
    });

で、本文では、

この部分はautopが効く。

[wpautop]
この部分は、そのまま出る。
この部分は、そのまま出る。
[/wpautop]

という感じ。