シングスブログ

中小企業のマーケティングやブランディングのコンサルティング。事業開発 (ビジネスモデルの開発)、ウェブマーケティングやウェブサイト改善など事業の持続的・長期的な成長・発展に貢献できるサービスを提供しています。

Vagrant 共有フォルダが同期できないときの対処法 /sbin/mount.vboxsf: mounting failed with the error: No such device

最近各 Linux ディストリビューションがリリースしている Vagrant Box を使うようになりました。
以前は、Bento project など良さそうな Vagrant Box を採用していましたが、
Linux ディストリビューションの Vagrant Box が整備されつつあるので、もっぱら使っています。

ただ Virtualbox Guest Additions がインスールされていない状態の Vagrant Box なので、
プロビジョニングの時にプラグイン vagrant-vbguest で入れるようにしています。
Vagrant では、いくつかフォルダ共有のタイプがあるのですが、
VirtualBox の共有フォルダ機能を使う場合は、Virtualbox Guest Additions が必須になります。

今回その時に遭遇した不具合対処メモ。

環境

  • Vagrant
  • VirtualBox
  • Vagrant Box は、centos/7
  • プラグイン vagrant-vbguest で Virtualbox Guest Additions をインストール
  • Provisioner は、ansible_local、Ansible でプロビジョニング

不具合現象

vagrant up すると、共有フォルダが同期できない現象。

==> default: Mounting shared folders... default: /vagrant => /Users/thingsym/vaw 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 uid=1000,gid=1000 vagrant /vagrant The error output from the command was: /sbin/mount.vboxsf: mounting failed with the error: No such device

遡って調べて診てみる。
Virtualbox Guest Additions はインストール完了したが、
vboxadd.service が立ち上がっていない。
結果、共有フォルダがマウンドできない。

Installing Virtualbox Guest Additions 5.2.12 Redirecting to /bin/systemctl start vboxadd.service Job for vboxadd.service failed because the control process exited with error code. See "systemctl status vboxadd.service" and "journalctl -xe" for details.

カーネルのバージョンが不一致になっている。

Please install the Linux kernel "header" files matching the current kernel for adding new hardware support to the system.

原因

Virtualbox Guest Additions をインストールするときに
必要なパッケージをインストールするのですが、
そのなかに kernel-headers が含まれていて
kernelのアップデートのタイミングの問題? なのか
アップデートしてしまう。

ゲスト側でカーネルを調べると、
カーネルのバージョンが不一致になっている。
今回は、パッチ番号 (693と862) が不一致に。

rpm -qa kernel\* | sort kernel-3.10.0-693.21.1.el7.x86_64 kernel-headers-3.10.0-862.2.3.el7.x86_64 kernel-tools-3.10.0-693.21.1.el7.x86_64 kernel-tools-libs-3.10.0-693.21.1.el7.x86_64

kernel-headers が kernel の最新バージョンに対応していない状態。

解決

vagrant ssh

ゲスト側に入り、kernelをアップデート

sudo yum -y update kernel sudo yum -y install kernel-devel kernel-headers kernel-tools kernel-tools-libs

カーネルのバージョン (パッチ番号862) を揃える

rpm -qa kernel\* | sort kernel-3.10.0-693.21.1.el7.x86_64 kernel-3.10.0-862.2.3.el7.x86_64 kernel-devel-3.10.0-862.2.3.el7.x86_64 kernel-headers-3.10.0-862.2.3.el7.x86_64 kernel-tools-3.10.0-862.2.3.el7.x86_64 kernel-tools-libs-3.10.0-862.2.3.el7.x86_64

再度プロビジョニング

vagrant reload

BashテストフレームワークBatsのヘルパースクリプト「Bats Assertion」をつくりました

Bash のシェルスクリプトは、エンジニアが片手間に書いて使う DIY 的な使い捨てスクリプトになりがちぎみだけれども。
Bash のシェルスクリプトを作ってオープンソースとして公開している手前、
「きちっとテストを入れたいなぁ」と思っていろいろ Bash のテストどうやるの? というところから始まって
どんなアプローチがあるのだろうといろいろ調べたり試したり。
結果、Bashテストフレームワークとして「Bats」がシンプルすぎるぐらいに良かったので採用してみました。

Bashテストフレームワーク「Bats」とは

Bats の正式名称は、Bash Automated Testing System。

ドキュメントには、

Bats is a TAP-compliant testing framework for Bash.
(訳: BatsはBash用のTAP準拠のテストフレームワークです。)

とある。

使い方は、.bats 拡張子を付けたファイルにテストケースを書いていくだけ。
例えば、example.bats に以下を書いて

#!/usr/bin/env bats @test "status - return 0 exit code" { run bash -c 'exit 0' [ "$status" -eq 0 ] } @test "output" { run bash -c 'echo -e "abc"' [ "$output" = "abc" ] } @test "lines" { run bash -c 'echo -e "abc\ndef\nghi"' [ "${lines[0]}" = "abc" ] [ "${lines[1]}" = "def" ] [ "${lines[2]}" = "ghi" ] }

テストを走らせると、

bats --tap example.bats

テスト結果が得られます。

1..3 ok 1 status - return 0 exit code ok 2 output ok 3 lines

テストケースのプロセスは、
run でコマンドを実行し、
その結果が 3つの変数に保存されます。

  • $status - exit status を保存
  • $output - 標準出力またはエラー出力を保存
  • $lines - 標準出力またはエラー出力を行単位で配列で保存

それら変数を確かめたり、アサーションしたりする。

setup, teardown もあるので、
いろんな設定を想定したテストケースが作れると思います。

Bash だけでなくいろんな言語のコマンドラインツールで使えて
シンプルなテストには、もってこいのテストフレームワークです。

ヘルパースクリプト「Bats Assertion」

今回、その Bats のヘルパースクリプト「Bats Assertion」をつくりました。

Assertion 系のヘルパースクリプトは、ほかにもありましたが、
テストを書くこと自体がテストドキュメントになる。
もっとシンプルに書けて、テストを書くことが億劫にならず、
テストを育てていく感じにならないかなぁと思って設計してみました。

使い方は、ヘルパースクリプト「Bats Assertion」をダウンロードして
テストファイル内で Bats の load コマンドで読み込むだけ。

load bats-assertion/bats-assertion

読み込むと、以下の assertion 系のコマンドが使えるようになります。

  • assert_success
  • assert_failure
  • assert_status
  • assert_equal
  • assert_fail_equal
  • assert_match
  • assert_fail_match
  • assert_lines_equal
  • assert_fail_lines_equal
  • assert_lines_match
  • assert_fail_lines_match

それぞれのコマンドの詳細は Assertion Reference を参照してみてください。

ヘルパースクリプト「Bats Assertion」で書き換えると

先の example.bats をヘルパースクリプト「Bats Assertion」で書き換えると、
こんな感じになります。

#!/usr/bin/env bats load bats-assertion/bats-assertion @test "status - return 0 exit code" { run bash -c 'exit 0' assert_success } @test "output" { run bash -c 'echo -e "abc"' assert_equal "abc" } @test "lines" { run bash -c 'echo -e "abc\ndef\nghi"' assert_lines_equal "abc" 0 assert_lines_equal "def" 1 assert_lines_equal "ghi" 2 }

assertion 系のコマンドを体系化することでテストが書きやすく、
一目見ただけで分かりやすいテストケースになって
そのままテストドキュメントにもなればなぁと思います。

ドキュメント

リソース

バックアップに最適 Amazon S3でバケットのファイル数を制限するワンライナーコマンド (AWS CLI)

バックアップやビッグデータ分析などバッチ処理する大容量のデータ保存に使われているクラウドストレージ Amazon S3。

ファイルの整理せずに使っていると大容量のデータがバケット内に溜まってしまうことも。
Amazon S3 の課金は、保存データ容量によって決まるので、
ムダなデータを削除してコントロールしながら使っていきたいものです。

Amazon S3 には、
オブジェクトのライフサイクル管理で有効期限を決めて、その有効期限が切れたならば、
オブジェクト (ファイル) を削除することができます。
これでファイルの整理をすることができます。
参考: オブジェクトのライフサイクル管理

しかし、ライフサイクル管理は時間な面を見てコントロールできますが、
ファイル数など物理的な数値の面からコントロールするアプローチがなかったので、
今回 AWS CLI でバックアップに最適なワンライナーコマンドを紹介したいと思います。

バケット内でファイル数で制限してファイルのローテーションをするバックアップに最適な環境が実現します。

バケット内のファイル一覧を取得して、削除対象ファイル名を抽出・削除するワンライナーコマンド

aws s3 ls <S3_URI> | sort -n | head -n -<MAX_SAVED_FILES> | awk '{ print $4 }' | xargs -I% aws s3 rm <S3_URI>%

解説

1. バケットまたは prefix (ディレクトリorフォルダ) にあるファイル一覧を取得

aws s3 ls <S3_URI>

<S3_URI> S3の仮想ホスト形式の URL

参考: バケットへのアクセス

2. ファイル一覧を昇順でソート

sort -n

3. ファイル一覧から保存しておくファイル数分を取り除いた削除対象ファイル一覧にする。

head -n -<MAX_SAVED_FILES>

-<MAX_SAVED_FILES> 保存しておくファイル数

保存しておくファイル数にマイナスを付けて、
昇順でソートした一覧の最後から -<MAX_SAVED_FILES> 分だけ取り除くことで
削除対象のファイル一覧を取得。

4. 削除対象のファイル名を抽出する

awk '{ print $4 }'

AWK (オーク) でレコードのファイル名に当たる4番目のフィールドを取得。

フィールドは、日付 時間 ファイルサイズ ファイル名の順番が

2018-01-21 02:21:03 21819150 file-001.tar.gz 2018-01-22 02:21:10 21824555 file-002.tar.gz 2018-01-23 02:21:00 21821971 file-003.tar.gz

こうなる。

file-001.tar.gz file-002.tar.gz file-003.tar.gz

5. コマンドを組み立ててファイルを削除

xargs -I% aws s3 rm <S3_URI>%

<S3_URI> S3の仮想ホスト形式の URL

xargs (エックスアーグズ) で
改行で区切られたファイル名を標準入力として読み込み、
それを引数としてコマンドへ渡して、コマンドを組み立てる。

-I オプションを付けて、標準入力から読み込んだファイル名を
コマンドテンプレート aws s3 rm <S3_URI>% を元に
% をファイル名に置き換えて削除対象の S3 の URL の引数を作る。

そして組み立てた aws s3 rm コマンドを実行してファイルを削除。

以上できあがり。

バケットの管理は、一つの目的で管理した方がシンプルでいいと思いますが、
管理の仕方によっては、ファイルの種類やファイル拡張子がいろいろ混ざっていたり、
prefix を付けてファイルを管理していたりする場合もあると思います。

その場合、ワンライナーコマンドは、パイプで繋いでいるだけなので、
途中フィルタリングを追加したりしてファイルの抽出など応用ができます。
是非参考にしてみてください。

関連サイト

カテゴリー : AWS コメント : 0 件

ログ監視ツール Logwatch を使ってみる (アップデート版)

以前の記事から Logwatch のコマンドが変わっていたので、再度書き直しました。

以前から変わったところは、出力のところ。
前は、logwatch --print とするだけで標準出力できましたが、
logwatch --output stdout と出力指定をする必要があります。

Logwatch は、いろいろなログをまとめて集計し、レポートとして毎日定期的にメールで届けてくれる。不正アクセスや不具合の発見とサーバの監視に便利なツール。

Logwatch のインストール

Logwatch は Perl で書かれていて Perl 5.8 以上が必要です。

yumからのインストールは、

$ yum install logwatch

で、

ソースからのインストールは、こちらから

Logwatch をインストールした時点で cron に登録されているので、毎日指定した時刻または anacronでランダムな時刻に Logwatch のスクリプト (/etc/cron.daily/0logwatch) が実行されてレポートが届く。

logwatch の設定

logwatch の設定は、/usr/share/logwatch/default.conf/logwatch.conf を編集する。標準設定のままで十分ですが、以下の項目を確認して設定。

#ログが保存されているディレクトリ
LogDir = /var/log
#メールの送信先
MailTo = user@hoge.com
#アーカイブされたログも含めるかどうか
Archives = Yes
#レポートの日付範囲を3つのオプションから。All, Today, Yesterday
Range = Yesterday
ログの詳細度、Low (=0), Med (=5), High (=10) または 0から10までの数字で
Detail = High
# チェックの対象となるサービスを /usr/share/logwatch/scripts/services/ 以下、あるいは All で指定。
Service = All
# メールコマンドパス
mailer = "/usr/sbin/sendmail -t"

サービスごとの個別設定は、/usr/share/logwatch/default.conf/services/ に用意されている。各サービスの設定ファイルを編集することで個別設定できる。

logwatch コマンドを使ってみる

標準出力

logwatch --output stdout

または、デフォルトで標準出力

logwatch

出力は、標準出力 (stdout) ほか、メール (mail) とファイル (file) への出力がある。

特定のサービスだけ出力

logwatch --output stdout --service http

複数のサービスにも

logwatch --output stdout --service http --service sshd

ログの詳細度を変えてみる

logwatch --output stdout --detail 10 --service http

メールに出力

logwatch --output mail --mailto user@hoge.com

ファイルに出力

logwatch --output file --filename /path/to/logwatch.txt

logwatch --help

Usage: /sbin/logwatch [--detail ] [--logfile ] [--output ]
   [--format ] [--encode ] [--numeric] [--no-oldfiles-log]
   [--mailto ] [--archives] [--range ] [--debug ]
   [--filename ] [--help|--usage] [--version] [--service ]
   [--hostformat ] [--hostlimit ] [--html_wrap ]

--detail : Report Detail Level - High, Med, Low or any #.
--logfile : *Name of a logfile definition to report on.
--logdir : Name of default directory where logs are stored.
--service : *Name of a service definition to report on.
--output : Report Output - stdout [default], mail, file.
--format : Report Format - text [default], html.
--encode : Enconding to use - none [default], base64.
--no-oldfiles-log: Suppress the logwatch log, which informs about the
                   old files in logwatch tmpdir.
--mailto : Mail report to .
--archives: Use archived log files too.
--filename : Used to specify they filename to save to. --filename  [Forces output to file].
--range : Date range: Yesterday, Today, All, Help
                             where help will describe additional options
--numeric: Display addresses numerically rather than symbolically and numerically
           (saves  a  nameserver address-to-name lookup).
--debug : Debug Level - High, Med, Low or any #.
--hostformat: Host Based Report Options - none [default], split, splitmail.
--hostlimit: Limit report to hostname - host1,host2.
--hostname: overwrites hostname
--html_wrap : Default is 80.
--version: Displays current version.
--help: This message.
--usage: Same as --help.
* = Switch can be specified multiple times...

関連サイト

WordPressバックアップスクリプト「WP Offsite Backup」をリリースしました

仕事柄「WordPress (ワードプレス) 保守管理サービス – シングスマネジメント」でバックアップ体制をつくったり。
プラグインでバックアップを試してみたり。
そうこうしているうちに WordPress サイトをバックアップするスクリプトをつくっていました。

WordPressバックアップスクリプト「WP Offsite Backup」は、WordPressのファイルやデータベースのデータを Amazon S3 など外部ストレージに遠隔バックアップするスクリプトです。

WP Offsite Backup - GitHub

使い方は簡単

あらかじめデフォルトの設定をして

bash wp-offsite-backup

とコマンドを走らせるだけ。手動でバックアップします。

また、自動で走らせるには、Cron でスケジュールを設定するだけ。

MAILTO=hoge@example.com
 
20 0 * * * bash /path/to/wp-offsite-backup/wp-offsite-backup

とすると、毎日0時20分にバックアップします。

WordPressバックアップスクリプト「WP Offsite Backup」の特長

  • ワードプレスのファイルとデータベースをバックアップ
  • ストレージサービスにバックアップファイルを保存 (今のところ Amazon S3 だけに対応)
  • Cron で自動バックアップ
  • 設定のカスタマイズでいろいろなバックアップができます
  • バックアップファイルのローテーション
  • ログ履歴の管理

サポートしているストレージサービスは、いまのところ Amazon S3 だけですが、
おいおい Google Cloud Storage や Microsoft Azure Storage などにも対応してみたいと思います。

基本設計は、依存関係の解決やメンテナンスを極力減らすため、
WordPress のプラグイン、WP-CLI などコマンドラインツールに依存せず、
Linux コマンドとストレージサービスのコマンドラインツールだけで済ませるようにしました。
またデータをローカルサーバに残さないようにセキュリティに配慮してみました。

使い方もデフォルトの設定をしたら、コマンドを走らせるだけでバックアップができるを目指してみました。

WordPressバックアップスクリプト「WP Offsite Backup」を導入するには、
いまのところ AWS Command Line Interface などストレージサービスのコマンドラインツールをインストールする必要があるので、
root 権限を持っている VPS やクラウドサーバーに導入に限られてしまいますが、
レンタルサーバーでも動かないかなぁと模索中です。

設定のカスタマイズでバックアップいろいろ

インストールや設定の仕方は、ドキュメントの「Getting Started」を参考にどうぞ。

もちろんバックアップのカスタマイズもできます。

カスタマイズした設定に名前を付けるだけ。

設定も保存して複数持てるので、
WordPressファイルをフィルタリングしたり、
データベースだけバックアップということも。
一つのサーバに複数の WordPress サイトがあっても、
それぞれのウェブサイト用に設定を切り替えてバックアップできます。

その場合のコマンドは、カスタマイズした設定を渡すだけ。

bash wp-offsite-backup customized-config

Cron で自動バックアップも
環境変数 WP_OFFSITE_BACKUP_CONFIG にカスタマイズした設定を渡すだけ。

MAILTO=hoge@example.com
 
20 0 * * * WP_OFFSITE_BACKUP_CONFIG=customized-config bash /path/to/wp-offsite-backup/wp-offsite-backup

設定のサンプルもあるので参考にしてみてください。

  • db-only-backup-config (データベースだけバックアップ)
  • full-backup-config (フルバックアップ)
  • partial-backup-config (wp-content とデータベースだけバックアップ)
  • wp-content-only-backup-config (wp-content だけバックアップ)

バックアップファイルのローテーションで費用負担を減らす

ストレージサービスをバックアップに利用すると、
いつの間にかバックアップファイルがたくさんできてしまします。
気が付かないでいると、ムダな費用を払うこともあると思います。
バックアップの性格上、何かがあったときの復旧に必要な直近のバックアップファイルだけあれば、
充分済むことが大半だと思います。

ファイルの整理をするには、Amazon S3 だと、ライフサイクルで有効期限を決めて、
その有効期限が切れたならば、ファイルを削除するということを
ストレージサービス側で設定する必要があります。

これはこれで便利なのですが、
できたらファイル数で制限してファイルのローテーションをしたいと思い、実装してみました。

ストレージサービスの課金は、ディスク使用量によって決まるところが大半なので、
ファイルサイズが大容量になりやすいバックアップファイルにとってより大切なこと。

バックアップファイルのファイル数で制限することで費用をコントロールしながらバックアップシステムが構築できます。

是非WordPressバックアップスクリプト「WP Offsite Backup」を試してみてね。

ドキュメント: wp-offsite-backup - GitHub