アルパカ三銃士

〜アルパカに酔いしれる獣たちへ捧げる〜

sh: 1: node: Permission denied

root の node で npm install をした時に sh: 1: node: Permission denied もしくは /usr/bin/env: ‘node’: Permission denied が発生した時、

npm config set user 0
npm config set unsafe-perm true

で解決できた。

ubuntu に mongodb をインストールする

先日 ubuntu を 17.04 へアップデートしてしまい、インストールする時にしまったと思ったのですが、何も問題なかったので晒していきます。
インストールここの 16.04 の方を参考にした。理由は 17.04(zesty) 用のリポジトリを未だに提供してないからです。(もし 17.04 用のリポジトリが提供されたら、17.04 専用のリポジトリから使うようにしてください。)

sudo apt update && sudo apt install -y mongodb-org

のあとに sudo systemctl start mongod を行い、 mongo で起動する。

$ mongo
MongoDB shell version v3.4.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.3
Server has startup warnings:
2017-04-17T22:16:47.289+0900 I STORAGE  [initandlisten]
2017-04-17T22:16:47.289+0900 I STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2017-04-17T22:16:47.289+0900 I STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2017-04-17T22:16:48.496+0900 I CONTROL  [initandlisten]
2017-04-17T22:16:48.496+0900 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2017-04-17T22:16:48.496+0900 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2017-04-17T22:16:48.496+0900 I CONTROL  [initandlisten]
2017-04-17T22:16:48.496+0900 I CONTROL  [initandlisten]
2017-04-17T22:16:48.496+0900 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2017-04-17T22:16:48.496+0900 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-04-17T22:16:48.496+0900 I CONTROL  [initandlisten]
>

こんな感じで warnings が発生します。
2 つ目以降の warnings を潰すだけでなぜか全ての warnings が消えたのでその方法を書きます。

WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.

これは以下のページを参考に行いました。

askubuntu.com

この後に sudo reboot を行うと warnings が 1 個減っています。

WARNING: Access control is not enabled for the database.

  • mkdir /etc/mongod
  • openssl rand -base64 741 > /etc/mongod/mongodb-keyfile
  • chmod 600 /etc/mongod/mongodb-keyfile
  • chown mongodb.mongodb /etc/mongod/mongodb-keyfile

これが完了したら vim /etc/mongod.conf 以下を追記します。

security:
  keyFile: /etc/mongod/mongodb-keyfile

これで sudo systemctl restart mongod

管理ユーザの作成

admin データベースにユーザを管理する権限を追加しておきましょう。 userpwd は各自修正してください。

> use admin
switched to db admin

> db.createUser({user:"YOURUSERNAME",pwd:"PASSWORD",roles:[{role:"userAdminAnyDatabase",db:"admin"}]})
Successfully added user: {
    "user" : "YOURUSERNAME",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}

そのあと

vim /etc/mongod.conf
security:
  keyFile: /etc/mongod/mongodb-keyfile
  authorization: enabled

へ変更しておきましょう。 詳しくは以下の記事を参考にするといいです。

qiita.com

後から助かる設定

Ubuntu Firewall を使用している場合、mongodb サーバーのためにポートを許可しておかなければいけません。

ufw allow 27017

また、ubuntu を起動した時に自動で mongodb を起動したいという場合は

sudo systemctl enable mongod

を行っておきましょう。

Mac で SSTP 方式の VPN に接続する

研究室で VPN Azure Cloud を扱うことになって Mac でどうやるんや!?と格闘していて、解決したのでメモ。
sstp-clientbrew 経由でインストールするという方法があったけど、使い方が載ってねぇということで、GUI 探したら iSSTP といういいアプリがあった。

www.axot.org

開発者は日本人っぽいです。
使い方はこのブログが分かりやすい。(めっちゃシンプルなので見ないでもよさそう)

yesppp.me

そして実装に swift が使われてるっぽいです。

IPアドレスとサブネットマスクの考え方

久しぶりに考える機会を得たのでメモ。
@aokabin_ さんに教えてもらいました。

ネットワークアドレス 133.13.50.110 を与えられていて、サブネットマスク 255.255.255.0 を与えられている時、で降るとゲートウェイはどれくらいの範囲を割り当てられているかという考え方ですが、

255.255.255.0 を 32 bit の 2 進数へ修正すると 11111111 11111111 11111111 00000000 となる。この時下位 8 bit は 0 なので 255 - 0 = 255 なので 133.13.50.0 ~ 133.13.50.255 まで得ることが可能。

サブネットマスク 255.255.192.0 を与えられている時、同様に 2 進数へ変換すると
11111111 11111111 11000000 00000000 となる。この時 9 bit ~ 16 bit は 192 なので 255 - 192 = 63 そしてこの時下位 8 bit は 0 なので 255 - 0 = 255。つまり 133.13.0.0 ~ 133.13.63.255 まで得ることができる。

goveralls で カレントディレクトリのみ coverage を出したい

goveralls ってこれ。 github.com

よく travis-ci で goveralls を使って coverage を出すようにしてますが、今回プロジェクトディレクトリ内に example ディレクトリを入れてて、いつも通り goveralls を実行すると example ディレクトリ内まで見てしまい coverage を出すことができない問題がありました。
そのプロジェクトがこれ。 github.com

このプロジェクトの詳細は後日書きますが、goveralls の問題は以下に実行するようにすれば解決できました。
goveralls -package "."

最終的な .travis.yml はこんな感じになりました。

language: go
sudo: false
go:
  - 1.7
  - 1.7.5
  - 1.8
  - tip
script:
  - make test
after_script:
  - go get github.com/mattn/goveralls
  - goveralls -package "." -service=travis-ci

Okinawa.pm #4 に参加した

運営側でもありますが、最近やってた XS の知見を共有するために参加しました!

XS 始めは結構苦労したなぁ...

List::Flatten::XS をリリースしました

先日 Okinawa.pm の Slack で複雑なリストのフラット化を行う話で盛り上がりました。(Okinawa.pm の Slack へはこちらから参加できます!)
その中で @yasuXS さんが考案したフラット化のコードがシンプルの上に、フラット化が高速でした。以下がそのコードになります。

use strict;
use warnings;
sub flatten {
    my @args = @_ > 1 ? @_ : @{$_[0]};
    my @result;
    while (@args) {
        my $a = shift @args;
        if (ref $a eq 'ARRAY') {
                unshift @args, @{$a};
        } else {
                push @result, $a;
        }
    }
    return @result;
}

my $arr = [[1,2,3],[4,5,[6,7,[8,9,[1,2,3]]]]];

print flatten($arr);

リストを shift を使って取り出し、もし配列リファレンスなら、デリファレンスして元のリストへ unshift をして、それ以外なら返り値ように用意した変数へ push するといったシンプルなコードです。
これを XS で書き直そうと思い、List::Flatten::XS を作成し始めたんですが、メモリリークで悩んでいたところ、@tompng さんにRuby の flatten のコードを参考にしてはという助言をいただいて、「引数に渡されたレベルに合わせてフラット化する」機能も取り入れました。
以下は Pure Perl と List::Flatten::XS のベンチマークに使ったコードとその結果です。

use strict;
use warnings;
use v5.10;
use Data::Dumper;
use List::Flatten::XS 'flatten';

use Benchmark qw/cmpthese/;


my $arr = [[[[[[[[[[[[1], 2], 3], 4], 5], 6], 7], 8], 9], 1], 2], 3];

cmpthese 0, {
    nonrecursive => sub { flat($arr) },
    xs => sub { flatten($arr) }
};

sub flat {
    my $list = shift;
    my @args = @{$list};
    my @result;
    while (@args) {
        my $a = shift @args;
        if (ref $a eq 'ARRAY') {
            unshift @args, @{$a};
        } else {
            push @result, $a;
        }
    }
    return @result;
}

結果

                 Rate nonrecursive           xs
nonrecursive 117657/s           --         -70%
xs           394824/s         236%           --

約 2 倍の速さは出てるっぽいです。
以下が SYNOPSIS を少し弄ったコードです。ぜひ試してみてください。

#!/usr/bin/env perl

use strict;
use warnings;
use v5.10;
use Data::Dumper;
use List::Flatten::XS 'flatten';
 
my $ref_1 = +{a => 10, b => 20, c => 'Hello'};
my $ref_2 = bless +{a => 10, b => 20, c => 'Hello'}, 'Nyan';
my $ref_3 = bless $ref_2, 'Waon';
 
my $complex_list = [[["foo", "bar", 3], "baz", 5], $ref_1, "hoge", [$ref_2, ["huga", [1], "K"], $ref_3]];
 
# got: ["foo", "bar", 3, "baz", 5, $ref_1, "hoge", $ref_2, "huga", 1, "K", $ref_3];
my $flatted = flatten($complex_list);
say Dumper $flatted;
say "-"x20;

# got: ("foo", "bar", 3, "baz", 5, $ref_1, "hoge", $ref_2, "huga", 1, "K", $ref_3);
my @flatted_with_array = flatten($complex_list);
say Dumper @flatted_with_array;
say "-"x20;

# got: [["foo", "bar", 3], "baz", 5, $ref_1, "hoge", $ref_2, ["huga", [1], "K"], $ref_3]
my $flatted_level = flatten($complex_list, 1);
say Dumper $flatted_level;
say "-"x20;


# got: (["foo", "bar", 3], "baz", 5, $ref_1, "hoge", $ref_2, ["huga", [1], "K"], $ref_3)
my @flatted_level_with_array = flatten($complex_list, 1);
say Dumper @flatted_level_with_array;

最後に

明日は Okinawa.pm #4 です。
そこで XS で得た苦労して知見を共有しようと思います。

github.com