tohokuaikiのチラシの裏

技術的ネタとか。

vsftpdでuse_localtimeをYESにした場合、時刻が9時間ずれると言われた件でuse_localtimeオプションとは何であるかを考察した

結論から

言うと、このuse_localtimeをYESにすると9時間のズレはなくなるよっていう記事はわんさか見たけど、自分の場合は逆でuse_localtimeをNOにしたら直ったのである。

症状は・・・

vsftpdで、use_localtimeをYESにすると9時間のズレが起こる。

情報

サーバーのタイムゾーンJST日本標準時)。サーバーでtimedatectlを実行すると下記の通り。

$ timedatectl
      Local time: 金 2017-12-22 10:48:17 JST
  Universal time: 金 2017-12-22 01:48:17 UTC
        RTC time: 金 2017-12-22 01:48:16
       Time zone: Asia/Tokyo (JST, +0900)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no

WinSCPでログインして、ファイルを置くとこうなる。
f:id:tohokuaiki:20171222105027p:plain

一見問題ないように見える。先ほどのtimedatectlと同じ時刻を返している(1分違うけどな)。

9時間遅い…

が、サーバー側でlsコマンドを打つとこうなる。

$ ls -l
合計 4
-rw-r--r-- 1 tohokuaiki tohokuaiki 1 12月 22 01:49 hoge

あれっ?9時間遅い?これが症状。

chrootしてるからか?と思ったけど違うみたい

vsftpd - use_localtime
とか見ると、chrootしてると/etc/localtimeを見られないので・・・というエントリーがたくさんあったけど、chrootを外しても症状は同じだったのでこれではないようだ。

WinSCPで通信ログを見てみる。

f:id:tohokuaiki:20171222104014p:plain

でログチェックをONにしてファイルでやり取りを見てみる。

use_localtimeとは?

そもそもuse_localtimeとは何かというと、vsftpd.confには以下のように書いてある。

If enabled, vsftpd will display directory listings with the time
in  your  local  time  zone.  The default is to display GMT. The
times returned by the MDTM FTP command are also affected by this option.

この「in your local time zone」というののyourって誰やねん?サーバ側かFTPクライアント側かっていうのがってのが分からない。

普通に考えるとFTPでつなぐクライアント側だと思うのだけど、さてWinSCPのログを見るとタイムゾーンの情報なんて全く送っていない。以下、接続した時点でのWinSCPのログ。

.Working directory: F:\WinSCPPortable
.Process ID: 18424
.Command-line: "F:\WinSCPPortable\WinSCP.exe" 
.Time zone: Current: GMT+9 (東京 (標準時)), No DST
.Login time: 2017年12月22日 10:57:33
.--------------------------------------------------------------------------
.Session name: tohokuaiki@vsftpd.example.com(FTP) (Site)
.Host name: vsftpd.example.com (Port: 21)
.User name: tohokuaiki (Password: Yes, Key file: No, Passphrase: No)
.Transfer Protocol: FTP
.Ping type: Dummy, Ping interval: 30 sec; Timeout: 15 sec
.Disable Nagle: No
.Proxy: None
.Send buffer: 262144
.UTF: Auto
.FTPS: None [Client certificate: No]
.FTP: Passive: Yes [Force IP: Auto]; MLSD: Auto [List all: Auto]; HOST: Auto
.Local directory: C:\Users\itoh\Documents, Remote directory: /work/20171222, Update: Yes, Cache: Yes
.Cache directory changes: Yes, Permanent: Yes
.Recycle bin: Delete to: No, Overwritten to: No, Bin path: 
.Timezone offset: 0h 0m
.--------------------------------------------------------------------------
.Session upkeep
.Connecting to vsftpd.example.com ...
.Connected with vsftpd.example.com. Waiting for welcome message...
<220 (vsFTPd 3.0.3)
>USER tohokuaiki
<331 Please specify the password.
>PASS ***********
<230 Login successful.
>SYST
<215 UNIX Type: L8
>FEAT
<211-Features:
< EPRT
< EPSV
< MDTM
< PASV
< REST STREAM
< SIZE
< TVFS
<211 End
.Connected
.Got reply 1 to the command 1
.--------------------------------------------------------------------------
.Using FTP protocol.
.Doing startup conversation with host.
>PWD
<257 "/" is the current directory
.Got reply 1 to the command 16
.Changing directory to "/work/20171222".
>CWD /work/20171222
<250 Directory successfully changed.
.Got reply 1 to the command 16
.Getting current directory name.
>PWD
<257 "/work/20171222" is the current directory
.Got reply 1 to the command 16
.Session upkeep
.Retrieving directory listing...
>TYPE A
<200 Switching to ASCII mode.
>PASV
<227 Entering Passive Mode (160,16,132,242,238,127).
>LIST -a
.Connecting to 160.16.132.242:61055 ...
.Data connection opened
<150 Here comes the directory listing.
.Data connection closed
.drwxr-xr-x    2 1000     1000         4096 Dec 22 10:49 .
.drwx------    7 1000     1000         4096 Dec 22 10:49 ..
.-rw-r--r--    1 1000     1000            1 Dec 22 01:49 hoge
<226 Directory send OK.
.Directory listing successful
.Got reply 1 to the command 2
.Detecting timezone difference...
.Retrieving file information...
>PWD
<257 "/work/20171222" is the current directory
>CWD /work/20171222/hoge
<550 Failed to change directory.
>TYPE I
<200 Switching to Binary mode.
>SIZE /work/20171222/hoge
<213 1
>MDTM /work/20171222/hoge
<213 20171222014942
.Retrieving file information successful
.Got reply 1 to the command 1024
.Timezone difference of -9 detected using file /work/20171222/hoge (Listing: 2017-12-21T16:49:00.000Z, UTF: 2017-12-22T01:49:00.000Z)
...;D;0;1899-12-30T09:00:00.000Z;0;"" [0];"" [0];---------;0
.hoge;-;1;2017-12-22T01:49:00.000Z;1;"1000" [0];"1000" [0];rw-r--r--;0

ログで違うなーと思ったのは

use_localtime=YES

Timezone difference of -9 detected using file /work/20171222/hoge (Listing: 2017-12-21T16:49:00.000Z, UTF: 2017-12-22T01:49:00.000Z)

use_localtime=NO

Timezone difference of -9 detected using file /work/20171222/hoge (Listing: 2017-12-21T07:49:00.000Z, UTF: 2017-12-21T16:49:00.000Z)

となっているところ。しかし、これはWinSCPから送信している情報ではない。サーバーから受け取っている情報である。

考察

こう考えると都合はあう。

おそらく、use_localtimeのlocalとはFTPクライアントタイムゾーンであろう。ただし、これをどうやってvsftpdが受け取っているのかが分からない。

基本的にvsftpdはGMT世界標準時)でファイルのタイムスタンプを扱うようになっているらしい。なので、ファイルをFTPソフトアップする際に、クライアントが+9のJST日本標準時)であるなら、vsftpdはそのファイルをのタイムスタンプを-9してサーバー上に保存する。

ただ、今回のサーバーはそもそもサーバーのタイムゾーンJST日本標準時)なのである。そこで-9されてしまってはずれが生じてしまう。

そこで、use_localtime=NOとすることで私のケースではズレが収まった。

結論

サーバーのタイムゾーンJSTにしている場合、use_localtime=NOにしておく。

PHPで検索キーワードを「”」みたいなクォート区切りを有効にしたGoogleみたいな感じで抜き出す方法

Google

なにか "PHP function" で検索

みたいにすると、"PHP function"っていう文字列で検索してくれるじゃないですか。あのキーワードの取り出し方を知りたいなと思って検索してみたんですが、正規表現一発で取れるものとかなくってしょうがないなーって感じでPHPで日和ってみた結果です。

<?php
function getSearchKeywords($text) 
{
    $keywords = array();
    while (preg_match('/"([^\"]+)"/', $text, $m)){
        $text = str_replace($m[0], '', $text);
        $keywords[] = $m[1];
    }
    return array_filter(array_merge($keywords, explode(" ", $text)));
}
$text = 'aaa "bbb ccc" ddd eee "fff" ggg "hhh iii jjj" kkk';
var_dump(getSearchKeywords($text)); 

 ↓

array(8) {
  [0]=>
  string(7) "bbb ccc"
  [1]=>
  string(3) "fff"
  [2]=>
  string(11) "hhh iii jjj"
  [3]=>
  string(3) "aaa"
  [5]=>
  string(3) "ddd"
  [6]=>
  string(3) "eee"
  [8]=>
  string(3) "ggg"
  [10]=>
  string(3) "kkk"
}

Confluence6.5をインストールした時にちょっと躓いたのでメモ

何気に6系は初めてだったりする。

いつものようにMySQLでデータベースを作成

mysql> create database confluence_demo_20171205 default character set utf8 ;
Query OK, 1 row affected (0.01 sec)

で、confluence/WEB-INF/classes/confluence-init.properties にconfluence.homeを設定してインストールWizardを走らせる。

MySQLを選択したら

Confluence needs a driver to connect to MySQL. You'll need to:
Download the MySQL driver
Drop the .jar file in /home/confluence/xxx/confluence/WEB-INF/lib
Restart Confluence and continue the setup process.

とか言われてしまった。しまったうっかりとお約束のMySQLJDBCを入れ忘れ。

Database JDBC Drivers - Atlassian Documentationに従って、MySQLJDBCドライバをOracleからいただきまして、/home/confluence/xxx/confluence/WEB-INF/libに入れてConfluenceの再起動

MySQLの設定

JDBCを入れて再度Wizardを進めると、Databaseのテスト接続で

Collation error
The database collation 'utf8_general_ci' is not supported by Confluence. You need to use 'utf8_bin'. Learn more

f:id:tohokuaiki:20171204161213p:plain

と言われてしまった。

https://confluence.atlassian.com/confkb/how-to-fix-the-collation-and-character-set-of-a-mysql-database-670958160.htmlによると、ちゃんとCollationまで気にして作らないとダメっぽい。

ということで、作り直し。

mysql> drop database confluence_demo_20171205;
Query OK, 0 rows affected (0.05 sec)

mysql> create database confluence_demo_20171205 default character set utf8 collate utf8_bin;
Query OK, 1 row affected (0.00 sec)

まだだめっす

Incorrect isolation level
Your database must use 'READ-COMMITTED' as the default isolation level. Learn more

なんだこれは?

なんか、MySQL3.5からおかしかったらしいけど、なんか使えてたのがダメにされたっぽい。

詳細はConfluence fails to start and throws 'MySQL session isolation level 'REPEATABLE-READ' is no longer supported' error - Atlassian Documentationのあたりを読んでくれということで、結局my.cnfの[mysqld]セクションに

[mysqld]
transaction-isolation=READ-COMMITTED

という一行を付け加えてMySQLを再起動。

更にダメッす

これで一応最後まで行った…。とおもいきや。

なんか日本語が化けている。Confluenceのページ内は大丈夫だけどスペース名とかページタイトルが文字化けしてる。

んー、なんだこれはと思ったら、そういえば、以前のConfluenceのJDBCのDSNを決めるときって「useUnicode=true&characterEncoding=UTF8」とかつけてたよな…と思い出す。

一旦全部アンインストールして、DBのセットアップで「Setup type」を「By connection string」にしてさっきの文字を追加してやる。 f:id:tohokuaiki:20171204162206p:plain

jdbc:mysql://localhost/confluence_demo_20171205?useUnicode=true&characterEncoding=UTF8

ここまでやってようやく成功。

JIRA(Atlassian cloud)で自分の作業した時間の記録を閲覧する方法

とりあえず前提として

毎日作業したら「作業ログ」にて作業時間を記録しておくこと。

これを集計するための方法を以下に。

メニューを開いて

f:id:tohokuaiki:20171201120456p:plain

に行けばなんとなくわかります。

今更ながらPHP7でローカルにPEARを入れた話

今どきPEARって…という感じですが、HTTP_Request2とか意外と使い慣れてるので便利なんですよ。いい加減ComposerでGuzzle使ってくれって話なのですが、ことによってはHTTP_Requestの方がちょろっとPHPCLIスクリプト書く分には楽ですよね。と。

インストールは今どきは、go-pear.phpじゃない

インストールはgo-pearを取るんだったなと思いおもむろに

$ wget http://pear.php.net/go-pear
$ php go-pear

と打ち込んだところ

Sorry!  Your PHP version is too new (7.0.19-1) for this go-pear.
Instead use http://pear.php.net/go-pear.phar for a more stable and current
version of go-pear, more suited to your PHP version.

Thank you for your coopertion and sorry for the inconvenience!

ありゃりゃ。ということで、

$ wget http://pear.php.net/go-pear.phar
$ php go-pear.phar

としてインストール開始。

インストール場所の設定

どこにインストールするかを聞かれる。
ひっそりとこっそりとどこぞやの作業量ディレクトリに入れたいので

Below is a suggested file layout for your new PEAR installation.  To
change individual locations, type the number in front of the
directory.  Type 'all' to change all of them or simply press Enter to
accept these locations.

 1. Installation base ($prefix)                   : /home/tohokuaiki/pear
 2. Temporary directory for processing            : /tmp/pear/install
 3. Temporary directory for downloads             : /tmp/pear/install
 4. Binaries directory                            : /home/tohokuaiki/pear/bin
 5. PHP code directory ($php_dir)                 : /home/tohokuaiki/pear/share/pear
 6. Documentation directory                       : /home/tohokuaiki/pear/docs
 7. Data directory                                : /home/tohokuaiki/pear/data
 8. User-modifiable configuration files directory : /home/tohokuaiki/pear/cfg
 9. Public Web Files directory                    : /home/tohokuaiki/pear/www
10. System manual pages directory                 : /home/tohokuaiki/pear/man
11. Tests directory                               : /home/tohokuaiki/pear/tests
12. Name of configuration file                    : /home/tohokuaiki/.pearrc

と聞かれるけれども、「1」を選択してインストール先を変更

Installation base ($prefix) [/home/tohokuaiki/pear] : /home/tohokuaiki/test/hoge/lib/pear

で、4~11が変更される。ここで12の.pearrcも変更しておこう。

さて、おもむろにリターンを押下してインストール開始!!・・・と思いきや

1-12, 'all' or Enter to continue:
Beginning install...
XML Extension not found

あれれ?

$ php -m|grep xml
libxml

libxmlではダメなんだ。debianなので

$ sudo apt-get install -y php7.0-xml

でインストール後、再度go-pear.pharを実行する。今度は問題なく進行。途中で

Would you like to alter php.ini </etc/php/7.0/cli/php.ini>? [Y/n] : n

と聞かれるが、ひっそりとPEARを入れているのでそんなだいそれたことはするはずもなく、男は黙って「n」を押下。

すると、

I will add a workaround for this in the 'pear' command to make sure
the installer works, but please look over your php.ini or Apache
configuration to make sure /home/tohokuaiki/test/hoge/lib/pear/share/pear is in your include_path.

と「このディレクトリをinclude_pathにいれるんやで」と注意してくれた。

うーむ、/home/tohokuaiki/test/hoge/lib/pear/share/pearpearが被ってしまったな。

PEARパッケージのインストール

/home/tohokuaiki/test/hoge/lib/pear/share/pear/bin/pearPEARコマンドである。

HTTP_Request2を入れたいので

$ /home/tohokuaiki/test/hoge/lib/pear/bin/pear install HTTP_Request2

とすると、

WARNING: channel "pear.php.net" has updated its protocols, use "pear channel-update pear.php.net" to update
Cannot install, php_dir for channel "pear.php.net" is not writeable by the current user

と出る。んー、php_dirが書き込みできない…ということで、そういえば、さっきのPEAR環境設定ファイル.pearrcを指定してコマンドを打ち直す。

こんな感じ。このコマンドの長さがひっそり感を醸し出していて非常に素晴らしい。

念のためchannel-updateをした後で

$ /home/tohokuaiki/test/hoge/lib/pear/bin/pear -c /home/tohokuaiki/test/hoge/lib/pear/.pearrc channel-update pear.php.net

パッケージのインストール

$ /home/tohokuaiki/test/hoge/lib/pear/bin/pear -c /home/tohokuaiki/test/hoge/lib/pear/.pearrc install HTTP_Request2

これで無事完了。