INNOBASE技術ブログ

技術的なことエンジニア的なこと制作的なこと全般

botでgitリポジトリをS3にアップロードする

S3にアップロードしたコンテンツをwebサイトとして公開する機能、
静的HPをwebサーバーの管理をせずに安心して便利ですね
S3へのアップロードユーティリティーソフト、かなり出てきていますがそこそこ手間がかかる気がします。

botでアップロードできればとてもお手軽!
ついでにcssのcontent-typeがたまにバクって「text/x+c」になってしまう問題にもbotで対応してみました。
いちいちcontent-typeを確認する手間ともおさらばです。

# Description
#   website s3 deploy script.
#   ### 事前準備
#   - /home/bot/website/ に対象のgit repositoryをgit clone
#   - s3cmdの初期設定を実施
#
#   ### 処理内容
#   - /home/bot/website/htdocs/ をs3cmdでbacket直下にsync
#   - cssのcontent-typeが稀におかしくなるので、content-typeを修正
#
# Commands:
#   deploy s3website - deploy web page (s3)
child_process = require 'child_process'

module.exports = (robot) -> 
    robot.hear /^deploy s3website/i, (msg) ->
        command  = "cd /home/bot/website;git pull origin master;s3cmd sync /home/bot/website/htdocs/ s3://BACKET_NAME/;"
        command += "cd /home/bot/website/htdocs;find . -name \"*.css\" |sed 's/^\\.\\///'|awk '{system(\"s3cmd --add-header=Content-Type:text/css modify s3://BACKET_NAME/\"$1)}';"

        msg.send "deploy website 実行します。\n===================================\n"
        command += "echo \"==================================\n\";"
        command += "echo \"deploy website を実行しました。\";"
        child_process.exec command, (error, stdout, stderr) ->
            msg.send stderr
            msg.send stdout
実行するとこんな感じ

差分も見れてそこそこ良い感じ

deploy s3website 実行します。
===================================
Updating bb0c50f..38d58b3
Fast-forward
htdocs/css/styles.css  |  26 ++-
htdocs/img/logo.png    |  Bin 1648 -> 2675 bytes
htdocs/img/logo@2x.png  |  Bin 0 -> 4592 bytes
htdocs/index.html      |    4 +-
4 files changed, 20 insertions(+), 685 deletions(-)
delete mode 100644 htdocs/css/styles**.css
create mode 100644 htdocs/img/logo@2x.png
File '/home/bot/website/htdocs/css/styles.css' stored as 's3://<<BACKET_NAME>>/css/styles.css' (30431 bytes in 0.2 seconds, 169.16 kB/s) [1 of 3]
File '/home/bot/website/htdocs/img/logo.png' stored as 's3://<<BACKET_NAME>>/img/logo.png' (2675 bytes in 0.1 seconds, 37.54 kB/s) [2 of 3]
File '/home/bot/website/htdocs/index.html' stored as 's3://<<BACKET_NAME>>/index.html' (8569 bytes in 0.1 seconds, 75.98 kB/s) [3 of 3]
Done. Uploaded 41675 bytes in 1.0 seconds, 40.70 kB/s. Copied 0 files saving 0 bytes transfer.
File s3://<<BACKET_NAME>>/css/styles.css modified
===================================
deploy s3website を実行しました。
このスクリプト含めたbotの実装サンプルをこちらで公開しています。

mr51/hubot_recipe · GitHub



FTPでアップロードするサンプルはこちら

botでgitリポジトリをFTPアップロードする - INNOBASE技術ブログ

botでgitリポジトリをFTPアップロードする

以前の記事でFTPしかアップロード手段のないwebsiteをGit管理する方法を紹介しました。
FTPでアップロードしているレンタルサーバ上のWEBページをgit管理する方法 - INNOBASE技術ブログ

しかしこの方法だと、websiteの更新にサーバーサイドでコマンドを実行するスキルをもったエンジニアが介在する必要が出てきます。
できればwebデザイナだけでオペレーションを行いたいですよね?
弊社ではこれをbotで解決したので hubotの実装サンプルをご紹介します。
※ bot化しただけ

# Description
#   web site ftp deploy script.
#   ### 事前準備
#   /home/bot/website/ に対象のgit repositoryをgit clone
#   ### 処理内容
#   /home/bot/website/htdocs/ をFTPでカレント直下htdocsフォルダにsync
#
# Commands:
#   deploy website - deploy web page  (ftp)
child_process = require 'child_process'

module.exports = (robot) -> 
    robot.hear /^deploy website/i, (msg) ->
        command = "cd /home/bot/website/;git pull origin master;lftp -u <<ftpaccount>>,<<ftppass>> <<ftphostname>> -e \"mirror -R ./htdocs htdocs ;exit;\""

        msg.send "deploy website 実行します。\n===================================\n"
        command += ";echo \"==================================\""
        command += ";echo \"deploy website を実行しました。\""
        child_process.exec command, (error, stdout, stderr) ->
            msg.send stderr
            msg.send stdout

実際実行するとこんな感じ、差分も見れたりして結構良いです。

deploy website
deploy website 実行します。

===================================
Updating 96adc5c..7157fa4

Fast-forward

htdocs/index.html |    2 +-

1 files changed, 1 insertions(+), 1 deletions(-)
===================================

deploy website を実行しました。

hubotレシピ(実装例)をこちらで公開しています。
mr51/hubot_recipe · GitHub

関連記事
【chatops】 サーバー上で簡単なcommandを実行するbotのサンプル - INNOBASE技術ブログ

Dropbox x sambaでファイル共有を幸せに

Dropboxチームのアカウントに納品される納品物、自分のアカウントに同期させるには自分のアカウントの容量が…
そんな時は社内サーバーにDropboxデーモンとsambaを仕込めば解決です!
個々のHDDの容量も消費せず、マウントでもしておけばそれほどストレスなく利用できるので中小規模のチームでかなりオススメ!

Dropboxのlinuxデーモンのインストール方法はこちら www.dropbox.com

f:id:mr51:20150331115212p:plain

samba の設定とかはまあ、いい感じにググって下さい。

【chatops】 サーバー上で簡単なcommandを実行するbotのサンプル

chatops便利ですね!
多人数開発を行うにあたって、共通環境でのオペレーションを同時多重に行う事故を防いだり
デザイナーやアプリエンジニアなどサーバーサイドの専門知識をもたないメンバーによる
安全なサーバー上でのオペレーションを実現できたりと弊社ではchatopsを活用しています。

HUBOTによるchatops少しノウハウが溜まってきたので、
サーバー上でコマンドを実行するテンプレート的なsampleとtipsをこちらの記事で公開します。

サンプルコード on GitHub

https://github.com/mr51/hubot_servercommand_template
こちらのsampleはnodejsがインストールされている環境ですぐに動作させられます。

サンプルコード

# Description
#   hey yo! script.  
#   heyと呼びかけるとyoと返事します。
#   返事はechoでサーバー上で実行した結果です。
#   shellのコマンドを組み替えることでサーバー上で処理を行うbotのテンプレートです。
# Commands:
#   hey
child_process = require 'child_process'

module.exports = (robot) -> 
    robot.respond /^hey/i, (msg) ->
        command = "echo \"yo\";"
     
        msg.send "実行します。\n===================================\n"
        command += ";echo \"==================================\""
        command += ";echo \"実行しました\""
        child_process.exec command, (error, stdout, stderr) ->
            msg.send stderr
            msg.send stdout

Tips

child_process を使えばコマンド実行できる!

あとはshellが使えればやりたい放題ですね!

commandの自然さ重要
@deploybot deploy staging
deploy staging

上のコマンドを当初採用していましたが、多くのメンバーが@deploybotを忘れるので下のコマンドに変更しました。
bot名との組み合わせでコマンドが決まりますが、自然に思えるコマンドになるように意識するとストレスが無くなります。

msg.send は順番を保証しない

API開発全般に言えることですが、msg.send は順番を保証しません、短い時間でメッセージをpostした時postした順番にメッセージがチャット上に表示されないことが良く起こります。(※筆者hipchat環境)
順番を保証したい場合、一回のsendで改行を利用したり、sampleのようにサーバー上のコマンドにメッセージ出力を任せたりと工夫が必要になってきます。

S3ディレクトリ内のファイル全てにワンライナーでヘッダーを追加する(s3cmd & awk編)

aws コマンドラインインターフェース編は他で見かけたのですが、s3cmdしか環境に載せていなかったのでs3cmdでコマンドをくんできました。
cache-control など一括で追加したいときなどにどうぞ
(記事にする程でもなかったのですが自分用メモの意味合いが強い)

s3cmd ls s3://backet_name/path/|awk '{if ($4 != "s3://backet_name/path/"){system("s3cmd --add-header=Cache-Control:max-age=86400 modify " $4)}}'

ProxyPass と RewriteRule を同時に使用する場合の適応順番について Apache2.2

概要

Apache2.2上で ProxyPass (mod_proxy) と RewriteRule (mod_rewrite) が入り乱れた時どのように動作するかまとめる。
そもそも RewriteRule だけで書きなおしたほうがスッキリしますが、本番環境などすでに歴史的経緯で混ざってしまった状況で影響範囲を最低限にしたいときとかの参考に(なぜこの記事を書くことになったかお察し下さい)

ProxyPassだけで書かれた場合、RewriteRule だけで書かれた場合は上から順に処理

ProxyPass だけで書かれているパターン

ProxyPass /aaa/bbb/ http://192.168.0.2/aaa/bbb/
ProxyPass /aaa/ http://192.168.0.3/aaa/
ProxyPass /aaa/ccc/ http://192.168.0.4/aaa/ccc/  #2行目で /aaaa/ にproxyされてしまうのでこの設定は効かない

RewriteRule だけで書かれているパターン

RewriteEngine On
RewriteRule  ^/bbb/aaa/(.*)$ http://192.168.0.10/bbb/aaa/$1 [L,R]
RewriteRule  ^/bbb/(.*)$ http://192.168.0.11/bbb/$1 [L,R]
RewriteRule  ^/bbb/ccc/(.*)$ http://192.168.0.12/bbb/ccc/$1 [L,R] #2行目で /bbb/ にredirectされてしまうのでこの設定は効かない

※ RewriteRule の場合[L]をつけることで、それ以降のRewriteRule を無視することを指示できます。逆に[L]を付けないと次のRewriteRuleを実行します。

ProxyPass RewriteRule 両方ある場合は RewriteRule が先に処理される

ProxyPass /aaa/ http://192.168.0.3/aaa/  #3行目のRewriteRuleが優先されてしまいこの設定は働かない
RewriteEngine On
RewriteRule  ^/aaa/(.*)$ http://192.168.0.11/aaa/$1 [L,R]

わからなくなったら RewriteRule で全て書き直すとよいかも

RewriteEngine On
RewriteRule  ^/aaa/(.*)$ http://192.168.0.11/aaa/$1 [L,P]

[P] 指定をすることで RewriteRule でProxyを設定できる。ReverseProxyも重ねて書くことができるのでReverseの問題もない

大量のwordファイルをtxtファイルに変換するマクロ

概要

うっかり納品形式指定し忘れたり 原稿がword (*.docx)で納品されたけどscriptで一括登録したいからtxtファイルに変換したい。
そんなシーンに遭遇する人ゼロではないでしょう。
word にはtxt保存機能があるので一つ一つ開いて保存しなおしても良いのですが、大量にあると大変です。
そんな時に便利なVBAを必要に迫られて作成したので公開しておきます。

マクロ

Sub docx2txtマクロ()
'
' docx2txt Macro
'
'
Dim wordFile As String, msg As String, txtFileName As String, hoge As String
wordFile = Dir("C:¥before_docx¥*.docx")
Do While wordFile <> ""
    txtFileName = "C:¥conver_txt¥" & Replace(wordFile, ".docx", ".txt")
    wordFile = "C:¥before_docx¥" & wordFile
    Documents.Open wordFile
    Documents(wordFile).Activate
    ActiveDocument.SaveAs2 FileName:=txtFileName, FileFormat:=wdFormatDOSTextLineBreaks
    ActiveDocument.Close
    msg = msg & txtFileName & vbCrLf
    wordFile = Dir()
Loop
MsgBox msg

End Sub

GitHub上ではこちら mr51/docx2txt · GitHub

あとがき

officceファイルの操作はなんだかんだVBAがお手軽、wordでもマクロが使えることを覚えておくと何かと便利だと思います。