五条の比較的自由な日記

ツイッターだと短くて書けないようなことを書くためのブログ

簡単なmongodbのインストールとphpでの使用方法

なんかmongodbの使い方とインストールがややこしいと思ってる人が結構いるみたいなので、イージーモードを伝えるために書きます。

インストール

# yumリポジトリを追加
cat  << 'EOF' > /etc/yum.repos.d/mongodb.repo

[mongodb]

name=MongoDB Repository

baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/

gpgcheck=0

enabled=1

EOF


# インストール

yum install -y mongodb-org

 
# mongodをサービスに追加

systemctl enable mongod

systemctl start mongod

systemctl is-enable mongod

 

 phpのmongoドライバ
mongodってのと mongodbってのがある。phpのドキュメントによると、mongodの方は古いらしいので、mongodbを使用する。

# php56のインストール
yum install --enablerepo=remi php56-php
yum install -y php56-php-pecl-mongodb.x86_64 --enablerepo=remi

 使い方

  • insert
    テーブルとインサートしたい配列を渡すだけ。配列ならなんでもいい。$listsが数字配列でソレを展開してからインサートしている。

static function write($lists,$table)
{
    $manager = new MongoDB\Driver\Manager('mongodb://127.0.0.1:27017');
    $bulk = new MongoDB\Driver\BulkWrite;

    foreach ($lists as $list)
    {
        $bulk->insert($list);
    }
    $manager->executeBulkWrite( $table , $bulk );
}

  • select
    テーブルとフィルターとオプションを渡すだけ。この例はフィルターの配列が空なので、全selectで、idを非表示で、dateで昇順ソート。

static function read($table)
{
    $manager = new MongoDB\Driver\Manager('mongodb://127.0.0.1:27017');

    $filter = array() ;
    $options = array(
        'projection' => array('_id' => 0),
        'sort' => array('date' => 1),
    );

    $query = new MongoDB\Driver\Query( $filter , $options );
    $cursor = $manager->executeQuery( $table, $query );
    foreach ($cursor as $ele)
    {
        foreach ($ele as $el)
            print $el."\t";
        print "\n";
    }
}

  • ダンプ
    test_db2test_db2という名前で、./dumpにダンプする。
mongodump --authenticationDatabase test_db2 -d test_db2 -o ./dump
  • リストア
    test_db2をdb_aaaにリストアする。

mongorestore --authenticationDatabase db_aaaa -d db_aaaa "./dump/test_db2"

  • コレクション名変更 
    コレクションaaaをbbbに変更する
db.aaa.renameCollection("bbb");

簡単。便利。高速。低セキュリティ。みんなも使おうぜ

リステリン(非ステマ)

なんとなくリステリン始めてみました。

リステリンには種類があり、ラベルを見たら「リステリンした後に歯磨きしろ!」とか書いてあって、かなりびびったので違いをレポします。

どうやらリステリンには二種類あるようです。

通常のリステリン

  • 口内洗浄液
  • 歯磨き後など好きなタイミングで実施

リステリントータルケア

  • 液体歯磨き
  • リステリンを多少口に含みながら歯を磨く

私のオススメはリステリントータルケアのノンアルコール!。ノンアルコールなので口内への刺激が少ないが、口の中の粘膜をすべて持って行かれる快感があり、その体感除去度はアルコール入りより何故か高い。代償としてリステリン後に2時間位食い物の味がしない。

二時間を味がしないのは嫌だと言う人は、アルコール入りにすると良い。こちらは20分ほど味がしない。

ステマじゃないからリンクは貼らないぜ!

追記

  • 1ヶ月くらいリステリントータルケア使った。その頃からホットコーヒー飲み始めたので、歯が大分黒くなった。
  • リステリントータルケアノンアルコール後二時間ほど味がしないと書いたが、今は慣れて(?)20分ほど味がしないだけに成った。

Inasoftさんの改行コード変換Liteに一方的対抗する記事

Inasoftさんの改行コード変換Liteに一方的に対抗しました。

 

# ファイル作成。1-10まで10行のファイルを作成
$ seq 10 > moji.txt

# nkfでCRLFに変換
$ file=moji.txt;nkf -Lu -c --overwrite $file;ls -l $file;nkf --guess $file

-rwxrw-r--+ 1 gojo gojo 31 10月 11 22:00 moji.txt
ASCII (CRLF) 

# nkfでCRに変換
$ file=moji.txt;nkf -Lm --overwrite $file;ls -l $file;nkf --guess $file

-rwxrw-r--+ 1 gojo gojo 21 10月 11 22:00 moji.txt
ASCII (CR)

# nkfでLFに変換
$ file=moji.txt;nkf -Ld --overwrite $file;ls -l $file;nkf --guess $file

-rwxrw-r--+ 1 gojo gojo 21 10月 11 22:00 moji.txt
ASCII (LF)

作成時間5分。私の勝ちですね。

 

ソウルナンバー検出器

ソウルナンバー検出器を作ってみました。単にJSの勉強したかっただけ。 リアルタイムで値を取得する方法ってこれで合ってるっぽいのかなー。 動作してるみたいだからいいでしょう。

●ソウルナンバー「1」の人の特徴:才能も運もあるがハートが弱く小心者 ・人を元気づける才能がある ・頭の回転が速い ・運が強いので、いざとなったら助けられる ・調子がいいところがある ・わがままになりやすい

●ソウルナンバー「2」の人の特徴:頭が良く直感も働くが短気で人からあれこれ言われたくない ・マイペースで人にああしろ、こうしろと言われることが嫌い ・頭が良くて、せっかち ・水の近くにいると精神的に安心する ・金運がない ・利益があるモノとないモノを判断するのが速い

●ソウルナンバー「3」の人の特徴:面倒見がよく芸術センスがあるが、ストレスを溜めやすい ・圧倒的にお母さんの影響を受けている ・優しくて面倒見がよい ・人を傷つけるのも傷つけられるのも嫌い ・一番になりたくない。2番手が好き ・アート的なセンスがある人が多い

●ソウルナンバー「4」の人の特徴:働き者でリーダーシップがあるが、クールで人間味がない ・働き者。失敗しても立ち直りが早い ・意志が強い、男っぽい ・男性に対しては理想が高い ・仕事がうまくいかないと暴力的になる可能性がある ・自分より仕事ができない人を見下す

●ソウルナンバー「5」の人の特徴:マイペースで安定志向だが、恋愛下手 ・家族の絆を大切にする ・安定することを好む ・マイペースでのんびりしている

●ソウルナンバー「6」の人の特徴:八方美人で愛情深いが、裏切りを許さない ・落ち着きがない。安定を嫌う ・飽きっぽい。新しいことに興味がある ・見かけよりも気を遣ったり神経質なところもある ・あれこれ何でもしゃべりたがる ・人間関係で自分の運勢が伸びていく

●ソウルナンバー「7」の人の特徴:お調子者でパワフルだが、デリケートで傷付きやすい ・家庭的で家族を大切にする ・車に関してマニアックな人が多い ・不思議なインスピレーションがある ・見かけよりもデリケートで傷つきやすい ・地に足つけてね。夢だけは追わないように

●ソウルナンバー「8」の人の特徴:こだわりが強く金運もあるが、ものの考え方が極端 ・自然体が好き。自然が好き。(町の中はゴミゴミしていて嫌い) ・物の考え方が極端 ・経済観念がありそうで、ない ・純粋だが、ちょっと変わり者 ・怠け始めたら怠け癖がつく ・信頼されるとスゴクつくすが、無視されると極端に豹変する

●ソウルナンバー「9」の人の特徴:記憶力がよく天才肌だが、寂しがり屋で1番浮気しやすい ・寂しがり屋のくせに、一人でいることが好き ・複雑な性格なところがある ・人に背を向ける割に自分が中心にならないとすねる ・たくさんの友人より数少ない友人に恵まれるので困った時に助けられる ・論理的で頭がいい。記憶力が優れている

zenfone3を買った

zenfone3を買った。結果結構良い。

 

■良い点

  • 中身がカチカチに詰まっている感じがしてiphoneみたいでかっこいい。

  • 物理ボタンが右側に電源とボリュームだけがついていて、フェイスはソフトボタンのみでかっこいい。
  • GalaxyS5から性能上がりまくりで快適。爆発する危険を完全に回避できる。
  • googleドライブの容量が2年間100GB増える。(1.99usd/month*24=4,700円くらい得)

■悪い点

  • 中身がカンカンに詰まっているので、落としたら壊れそう
  • 表面がテカテカなので指紋が若干気になる。
  • 表面にテープでSUICAを貼り付けてたのだが、テカテカなのでテープが剥がれる。
  • 防磁シートなしでSUICAを使うとSUICAが反応しない。
  • usb-cのケーブルが高い。

と言った感じです。あとつまらないことを言うと、

  • ポケモンgo動いた。
  • 海外版だけど普通に動いた。
  • やっとテザリングできるようになった。
  • 背面に貼り付けたSUICAが動作しなかったが、防磁シートを装着すると動作した。

総合ですごくいいです。zenfone3最高!ASUSに入社したくなった!

f:id:gojosan:20161009125558j:plain

chefでのサーバ設定確認に使えそうなメソッド

Chefでサーバの設定を行うのはいいとして、正常にファイルが配置されたかとか、ファイルの権限・所有者が正しいかとか確認するのもchefで行いたいよね。

というわけでChefで使える(かも知れない)メソッドを自分で書いてみました。いちいちクラスにする必要があるのか無いのかは置いておいて、これで最終確認用のChefレシピを使ってみましょう。

自分で動確していないものとかも幾つかあるのと、Ruby歴20時間くらいの私の書くコードなのであまり信用しないでください。あと、ブログに貼付け時にタブが落ちてしまいましたがそのままで行きます。引数を配列で返すところの変換周り、きっともっといい方法があると思いますが、私のRuby歴は20時かn(略)

require 'date'
require 'etc'
require 'fileutils'
require 'socket'

###########################
# クラス作成
class Std_class
def initialize()
end

######################################
# cpとchmod
def chprev(src,dest,user,group,prev)
if File.exist?(src)==false
return false
end
if File::ftype(src) == "directory" then
FileUtils.chmod_R(prev,src)
FileUtils.chown_R(Etc.getpwnam(user).uid , Etc.getgrnam(group).gid , src)
else
FileUtils.chmod(prev,src)
FileUtils.chown(Etc.getpwnam(user).uid , Etc.getgrnam(group).gid , src)
end
return true
end

######################################
# chmod
def chmod_r(src,prev)
FileUtils.chmod_R(prev,src)
end

######################################
# ファイルの存在確認
def file_exist (src)
return File.exist?(src)
end

######################################
# ファイルの存在確認
def dir_exist (src)
return Dir.exist?(src)
end

######################################
# ひとつ上のディレクトリがあるか確認し、なければ作成
def create_pdir (src)
src.gsub!(/\/$/,'')
data = src.split('/')
path = '/'
for i in 1..(data.length-2) do
path += data[i] + '/'
end
if File.exist?(path) == false
FileUtils.mkdir_p(path)
end
end

######################################
# preにバックアップ(存在していれば)
def back_pre (src)
if File.exist?(src)
create_pdir("#{$pre_root}#{src}")
FileUtils.cp("#{src}","#{$pre_root}#{src}")
end
end

######################################
# posにバックアップ
def back_pos (src)
# posにバックアップ
create_pdir("#{$pos_root}#{src}")
FileUtils.cp("#{src}","#{$pos_root}#{src}")
end


######################################
# 適用
def back_apply (src,user,group,prev)
FileUtils.cp("#{$chef_tmp}#{src}","#{src}")
# srcのオーナーとグループ変更
File.chown(Etc.getpwnam(user).uid , Etc.getgrnam(group).gid , src)
# srcの権限変更
FileUtils.chmod(prev,src)
end

######################################
# preにバックアップ。適用。posにバックアップ
def bak_apply (src,user,group,prev)
back_pre(src)
back_apply(src,user,group,prev)
back_pos(src)
end

######################################
# ポート番号チェック
# proはサーバ名
# 返り値は配列で返す
def port_check_net(pro)
com="sudo netstat -anp --tcp |grep #{pro}"
res=`#{com}`
headers, *scores = res.lines.map { |line| line.chomp.split(' ') }
j=0
port =Array.new()
for i in 1..(scores.length-1) do
@te1=scores[i][3].split(':')
if @te1.length >= 2
port[j] = @te1[@te1.length-1]
j += 1
end
end
port.sort!
port.uniq!
return port
end

######################################
# コマンド実行。
# 返り値は配列で、
# ['out'] 通常の返り値
# ['rtn'] 終了コード(boolでtrueが正常。falseが異常)
# ['arr'] 返り値を行で分割で返す。
def command(com)
com = com + ' ; echo $?'
res=`#{com}`
te1=res.split("\n")
kaeri={'out'=>'','err'=>'','arr'=>Array.new()}
if te1[te1.length-1] != '0' then
kaeri['err'] = te1[te1.length-1]
kaeri['out'] = false
return
end
for i in 0..(te1.length-2) do
kaeri['out'] += te1[i] + "\n"
kaeri['arr'][i] = te1[i]
kaeri['rtn'] = true
end
return kaeri
end

######################################
# ファイルが存在するか確認。
def exist (input)
return File.exist?(input)
end

######################################
# 日付を返す。
def date ()
day = Time.now
return day.strftime("%Y%m%d_%H%M%S")
end
# hostname
def hostname ()
return Socket.gethostname
end
end

 Rubyの所感として、

  • ループ周りがC言語臭くなくてやりにくいのと、i++が使えない(多分)で、やりにくかった。
  • 変数の$と@と@@があるとかかなりアレな言語だと思わざるを得ない。Perlのように「強引に拡張しましたァ」なら許せるが、普通にpublicとかstaticでいいのでは無いでしょうか。
  • bashpythonとかみたいにクセのある書き方の言語ですね。私はforがものすごく好きで、ほとんどループはforなんだけど、rubyのforは使いたくないと思った。なんでChefはrubyを採用したんだ、pythonでいいじゃないか。
  • やっぱりインタプリタ界最強の言語はphpだと確信できた。(書きやすさ的な意味で。javaは除く)

rubyがuid、gidでしか使用できないのを見てクラス化したのですが少しは役に立つと嬉しいです。

オススメのchef

どうも五条です。chefを使いたいという人がいたらknife-soloはいかがでしょうか?私はいろいろ調べた結果chefはknife-soloで運用しています。インストールはこれを見れば迷わないと予想される。

  • chefの大雑把な説明

chefとは①ローカルでサーバの設定ファイルを作成して、②リモートのサーバに変更を行い、③それら設定ファイルや変更事項がリポジトリ管理されていて、④誰が何回行っても同様の設定結果が行われ、⑤事前に変更内容を上司や同僚などに確認させて判子を押させてから実行することができ、⑥複数台に同様の変更・設定を加えるときに、手間が減るようにするためのアプリ。種類が沢山あるが、vagrantを使うまでも無いと私は考えているので、chefの一種であるknife-soloにする。

  • 使用上の注意

実行ユーザが鍵認証でリモートのホストへパスワード無しでログインでき、リモートでsudo -sでパスワード無しでrootになれることが必要。

  • knife-soloのインストール

# rubyのインストール。ruby-develはchefのコンパイルに必要。
yum install ruby ruby-deve

# gemでknife-soloをインストール(gemはruby専用のyumみたなもの)
gem install knife-solo

  • chefホームの設定

# chef用ディレクトリを作成し、chefホームにする。ここでは~/chefをchefのホームに設定する。(どこでもいいがユーザのホームディレクトリ内が正しい気がする)
mkdir ~/chef && cd ~/chef

# knife-soloに使用するファイルの展開。カレントに展開。
knife solo init .

# 初期設定。全部ディフォルトで良い。
knife configure

# 必要なら変更する。おそらく鍵の部分は変更になるかもしれない。
vim ~/.chef/knife.rb

# cookbookの作成
cookbook=test

#testというクックブックを作成。これで~/chef/bookcooks/testが作成される。
knife cookbook create $cookbook -o cookbooks 

# $hostにchef-solo(knife-soloを動作させるファイル郡の配置)
host=centlocal
knife solo prepare $host

  • rubyをインストール場合

vim cookbooks/$test/recipes/default.rb

yum_package 'ruby' do
 action :install
end

# run_list設定。recipeの中のtestはdefaultの場合はtestだけで良い。それ以外の場合は、「test::ファイル名」と書く。

vim nodes/$host.json # 先頭の方のみ追記

"run_list":[
  "recipe[test]"
],

# 実際にレシピを実行
knife solo cook $host

# 結果確認
ssh $host "rpm -q ruby"

  • ファイルコピーの場合の例

#ファイルコピーという名前でクックブックを作成
cookbook=filecopy
knife cookbook create $cookbook -o cookbooks

# レシピ作成
vim cookbooks/$test/recipes/default.rb

cookbook_file '/etc/hosts' do
source "etc.hosts"
owner "root"
group "root"
mode "0644"
end

vim nodes/$host.json # 先頭の方のみ追記

"run_list":[
 "recipe[filecopy]"
],

# knife-solo実行
knife solo cook $host

 # 結果確認
ssh $host "cat /etc/hosts"

cookbook=bash
knife cookbook create $cookbook -o cookbooks

vim cookbooks/$cookbook/recipes/default.rb

script "copy file" do
interpreter "bash"
code <<-EOH
 cp /etc/hosts /etc/hosts.`date +%Y%m%d_%H%M%S`
 sleep 1
 cp /etc/hosts /etc/hosts.`date +%Y%m%d_%H%M%S`
 sleep 1
 cp /etc/hosts /etc/hosts.`date +%Y%m%d_%H%M%S`
 sleep 1
 cp /etc/hosts /etc/hosts.`date +%Y%m%d_%H%M%S`
 sleep 1
 cp /etc/hosts /etc/hosts.`date +%Y%m%d_%H%M%S`
 EOH
end

# 先頭の方のみ追記
vim nodes/$host.json 

"run_list":[
"recipe[bash]"
],

# knife-solo実行
knife solo cook $host

# 結果確認
ssh $host "ls -l /etc/hosts*"

-rw-r--r-- 1 root root 183 7月 22 19:52 2016 /etc/hosts
-rw-r--r-- 1 root root 183 7月 22 20:12 2016 /etc/hosts.20160722_201205
-rw-r--r-- 1 root root 183 7月 22 20:12 2016 /etc/hosts.20160722_201206
-rw-r--r-- 1 root root 183 7月 22 20:12 2016 /etc/hosts.20160722_201207
-rw-r--r-- 1 root root 183 7月 22 20:12 2016 /etc/hosts.20160722_201208
-rw-r--r-- 1 root root 183 7月 22 20:12 2016 /etc/hosts.20160722_201209
-rw-r--r--. 1 root root 378 4月 19 22:10 2015 /etc/hosts.allow
-rw-r--r--. 1 root root 460 1月 12 22:28 2010 /etc/hosts.deny

  • 小技というか実際の使い方。

私に言わせれば使い方は二種類ある。①対象のホスト毎にクックブックを 作成する方法と、②サーバプログラム毎にクックブックを作成する方法。

  1. おそらくこのソフトを作った人は①を想定しているが、毎回同じ設定を必ず同じサーバプログラムに適用するというケースは考えにくいし、実際そうはならずに点在したファイルを追っかける羽目に何度もなった。提出時の可読性も下がる。よって現実的には②の使用方法でホスト毎にクックブックを作成するのが正解では無いだろうか。
  2. インフラエンジニアにいきなりrubyかつchefの記述をいきなり読めって言うのは酷である。chef独自の便利機能は多いが、実際問題はchefの中で使用するのはほぼbashのみになる。事前に設定済みのconfファイルを用意しておけば、bashだけでほぼ行けるし、今までもそれでやった。