2014年9月24日水曜日

実はサンディエゴに行っていたのでいろいろと経験をメモしておく

事前準備

旅の予約

まずはこれがないと始まりません、今回はWebで予約しました

  • JTBのwebサイトで予約
  • 出発約3ヶ月前(6/29)にWebでの予約
  • 旅行代金は大人2人、3泊5日で336,220円
    • 内訳は
      基本旅行代金(319600円)+国内空港施設使用料(5220円)+現地空港諸税等(11400円)
  • 予約後はJTBの担当者とメールにてやりとりを実施

オプショナルツアーの予約

オプショナルツアーとはホテル、飛行機代、もろもろの諸税とは別の観光のためのツアー等の予約のことです
旅立つ前に事前に予約しておけば現地でチケットを買ったり支払いする必要がなくなるのでとても楽です
予約したのは以下の通り

  • 野球観戦・・・19,460円
  • シーワールド1日フリーパスポート・・・24,860円
  • トロリーバス1日乗り放題券・・・8,610円

申請関連

ESTA
パスポート
(短期滞在のためビザの発行は不要)
旅行の持ち物
円からドルへの換金(10万)

日程

箇条書きで何があったか記載していきます
重要だった点とかTips的なメモとか

初日

  • 成田空港、17:35発サンディエゴ行きJALに搭乗
  • 出国審査は特に問題なし(チェックイン -> 荷物検査で完了)
  • 入国手続きはサンディエゴ空港で実施、入国審査場で携帯電話の操作はご法度
  • 入国手続は指紋取得と顔写真の取得とパスポートの確認で終了(結構厳重なので時間は結構かかる)
  • 空港からホテルへの送迎は現地のスタッフの方がやってくれた(プランに含まれていた)
  • ホテルは「The Westin San Diego Gaslamp Quarter」に宿泊
  • ホテル到着後は休憩して、その後ペトコパークで野球観戦
  • 野球観戦はオプショナルツアーで購入したチケットをそのまま利用して入場(チケット売り場での引き換えは不要)
  • 日本同様、荷物検査を実施して無事入場、観戦時は適当に球場でメシを食って飲んで終了
  • 帰りにガスランプの通りにある、インド料理屋でメシを食って初日は終了

2日目

  • 朝9:00からオレンジのトロリーバスを使ってサンディエゴ市内とオールドタウンと言われる街をバスを乗り継いで観光
  • トロリーバスに関してはこちらを参照、いろいろと種類があって観光用とか現地用とかあるみたい
  • トロリーバスに乗る際は旨にオレンジ色のシールを貼っておけばパスは乗り放題になる
  • どこから乗ってもOKだがオールドタウンで必ずチケットの確認があるので、オールドタウンについた際に必ずオプショナルツアーで購入したチケットと交換すること
  • 全部の駅を止まって観光すると結構な時間がかかる、朝9:00に出発して7割くらいの駅で下車して観光して夕方17:00くらいにホテルに帰宅した
  • お土産を購入するならオールドタウンからリトルイタリアという街がおすすめ
  • 昼飯はリトルイタリアの有名なメキシコ料理屋で済ます
  • 夕飯はWest fieldというショッピングモールで買い物をしてホテルで済ます、2日目はこれで終了

3日目

  • 朝9:00からシーパークで遊ぶ
  • シーパークのチケットもオプショナルツアーで事前に購入済み、またホテルから送迎も付いているので移動手段も問題なし
  • シーパークのチケットの交換も送迎してくれた添乗員の方がやってくれた
  • あとはシーパークで遊ぶだけ
  • シーパークではショーとアトラクションで遊べば閉館の17:00まで問題なく遊べる
  • ホテルまでの送迎は行きと同じで添乗員付き
  • 昼飯はシーパーク内で済ませ、夕飯はホテルから600mほど離れた映画トップガンをモチーフにしたレストランで食事
  • その後は特になく3日目は終了

4日目

  • 帰国する、空港までの送迎もプランに含まれているので移動手段の手続きは不要だった
  • 出国審査はサンディエゴ空港で実施する、チェックイン -> 荷物検査 -> X線検査を実施して終了
  • その後は飛行機出発まで時間を潰して帰国
  • 日本への入国審査は特に問題なく終了(お土産で生物や植物がある場合や、病気になった場合は特別な審査が必要)

その他Tips

  • 英語しゃべれないとやっぱりキツイ
  • サンディエゴの気候は晴天がほとんど、雨はほとんど降らない、日差しが強め
  • 街の構造は碁盤目上になっていて覚えやすい
  • 観光地仕様になっているので現地の人はほとんどいないかもしれない、日本人は少ない
  • メシはアメリカンスタイルなのでデカいし油っぽいので1人前を1人で食べるのはキツイ
  • 米がタイ米なのでご飯料理はあまり期待しないほうがいいかも

利用金額合計

389,150円(旅行代金)+ 10万(現地利用料金) = 489,150円

2014年9月18日木曜日

Ubuntu14.04にDiscourseをインストールしてみた

概要

discourseというオープンソースのディスカッションツールがUbuntu14.04上で動作するか検証してみました

環境準備

  • Ubuntu 14.04 LTS
    サーバスペックは 2vCPU, 4GB Memory

セットアップ

Discourseを動作させるまでの手順を紹介します

dockerインストール

Ubuntu上にdockerをインストールします
ワンライナーのコマンドがあるので、それでdockerをインストールした後、Githubからdiscourseのソースコードを持ってきます

wget -qO- https://get.docker.io/ | sh
mkdir /var/discourse
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
cp samples/standalone.yml containers/app.yml

また、DNSがlocalhostの場合うまくindex.docker.ioが名前解決できないことがあるので以下を追記します

echo "nameserver 8.8.8.8" >> /etc/resolv.conf

curl https://index.docker.io/v1/search?q=ubuntu: を実行してJsonが取得できればOKです

設定ファイル編集

vim containers/app.yml

管理者のメールアドレスを記載します

DISCOURSE_DEVELOPER_EMAILS: 'admin@your.domain.com'

discourseを動作させるサーバのドメイン情報を記載します
ドメインがない場合はIPアドレスを記載します

DISCOURSE_HOSTNAME: 'xxx.xxx.xxx.xxx'

動作に必要なワーカーの数を指定します
今回4GBのメモリだったの3と設定していますが1か2GBの場合は2を指定すればいいと思います

UNICORN_WORKERS: 3

SMTPサーバの設定をします
今回はGmailのSMTPサーバを使いました
独自のメールサーバまたはは他のメールASPを利用の場合はその情報を入力すればOKです

DISCOURSE_SMTP_ADDRESS: smtp.gmail.com                 # (mandatory)
DISCOURSE_SMTP_PORT: 587                               # (optional)
DISCOURSE_SMTP_USER_NAME: your.account.name@gmail.com  # (optional)
DISCOURSE_SMTP_PASSWORD: your.password                 # (optional)

sslを使わないのでポートは587(TLS)を指定します

起動

以下のコマンドで起動します

cd /var/discourse
./launcher bootstrap app

途中、SSHの鍵を作成する際にY/Nの入力を求められるのでYとします
その後はいろいろなインストール作業やらダウンロード作業が自動で行われます
だいたい10分くらいで完了します
dial tcp: lookup index.docker.io: no DNS serversが出る場合は何度か起動コマンドを試してみてください
うまく名前解決できないことがあるようです

上記が完了したら

./launcher start app

でdiscorseが起動します
起動したら、ブラウザで http://xxx.xxx.xxx.xxx/ にアクセスします
xxx.xxx.xxx.xxx は DISCOURSE_HOSTNAME に設定したIPを入力してください
アクセスするとDiscourseのトップページが表示されるはずです
停止したい場合は./launcher stop appで停止できます

はじめにやること

起動したらまずDISCOURSE_DEVELOPER_EMAILSに登録したメールアドレスでサインアップしてください
メールが届いたらアクティベーションします
すると/adminにアクセスできるようになりDiscourseのいろいろな設定をすることができるようになります
admin_discourse.png

あとは他に作成したいユーザで Sign Up -> メール認証 -> Log In とすればTopicを作れたり問題なく使えると思います
その他、Discourseの詳しい使い方はここでは割愛致します

参考サイト

2014年9月17日水曜日

Parse.comの$selectというクエリについて調べてみた

概要

Parse.comの説明は省きます
REST-APIのGET系のAPIでクエリを指定していろいろな検索をすることができるのですが、その中に$selectというクエリがあります
$selectは副問い合わせを実行するためのクエリです
実際に試せばある程度動きはわかるのですが、そもそも動かし方もわかりづらいのでメモがてら説明しようと思います

環境

  • Mac OS X 10.8.5
  • Parse.com ( 2014/09/17 時点 )
  • curl

説明

UIでデータを投入しつつcurlでクエリを実行して動きを確認します

UIで事前にデータを投入

まず、サンプルのデータを投入します
Parse.comのダッシュボードにログインし会員の一覧を開いて以下のユーザを登録します
list_user.png

UIが新しくなってCoreというサービス配下にユーザ一覧はあります
ユーザを登録する際は、はじめにusernameをダブルクリックしてユーザ名を入力してEnter、その後にpasswordをダブルクリックしてパスワードを入力してEnter、すると登録することができます
登録が完了するとobjectIdが自動で入力されます

次にGameScoreというクラスを作成して以下のデータを登録してください
list_gamescore.png

ユーザ登録時と同様にCoreからクラスを追加します
クラスの追加は、もう少し下に「+Add Class」というボタンがあるのでそこからGameScoreクラスを追加します
また、クラスを追加したらscoreというフィールドも追加します
フィールドの追加は図にもある「+Col」から追加します
クラスの作成とフィールドの追加ができたらplayerName, scoreとデータを入力して登録します
こちらも登録が完了するとobjectIdが自動で入力されます

curlでクエリを作成する

いきなりですが、以下がサンプルクエリです

curl 
  -X GET
  -H "X-Parse-Application-Id: 1234567890abcdefghijklmnopqrstuvwxyz"
  -H "X-Parse-REST-API-Key: 1234567890abcdefghijklmnopqrstuvwxyz"
  -d 'where={"username":{"$select":{"query":{"className":"GameScore","where":{"score":{"$gt":50}}},"key":"playerName"}}}'
  'https://api.parse.com/1/users'

X-Parse-Application-IdX-Parse-REST-API-Keyは自分のアプリのキー情報に置き換えてください
注目するべきはwhere=の部分でこれが$selectを使った検索クエリになります
次でクエリの動作を詳しく説明します

動作の仕組み

流れとして3段階で

  1. GameScoreクラスのscoreというフィールドに対して、scoreが50以上のデータを検索
    {"className":"GameScore","where":{"score":{"$gt":50}}}の部分
  2. その結果からplayerNameフィールドの一覧を取得
    "key":"playerName"の部分
  3. 取得したplayerNameフィールドの一覧と同じusernameを持つユーザをusersクラスから取得する
    where={"username":{"$select":{"query":...の部分

となります
クエリを分解して考えるとちょっとわかりやすいかもしれません

今回のサンプルでの結果は以下の通りとなります

{
    "results": [
        {
            "createdAt": "2014-09-17T01:25:38.180Z", 
            "objectId": "2XQRFoaRg9", 
            "updatedAt": "2014-09-17T01:35:29.539Z", 
            "username": "Sean Plott"
        }
    ]
}

Sean Plottさんのみ取得されます
「Aliceさんも50点以上なのに含まれていないのはなぜ?」
という疑問に対してはAliceさんはusersクラスに存在しないからです

$selectクエリだけでしたが、すごい大げさに説明してみました
少しは理解していただけましたでしょうか
すごいニッチな情報ですがParse.comを使う方は参考にしてみてください

参考サイト

2014年9月16日火曜日

MongoDBで実行クエリを必ずログに出力する方法

概要

Mongoクライアントから実行されたクエリを毎回ログファイルに出力するようにします
例えばサードパーティのライブラリから実行されているクエリがどんなクエリか知りたい場合に使えると思います

環境準備

  • Mac OS X 10.8.5
  • MongoDB 2.6.4

設定

MongoDBを起動するときにprofileslowmsオプションを付与します

mongod --logpath=/var/log/mongodb/mongo.log --profile=1 --slowms=-1

profileを1に指定し、slowmsを-1にして起動します
--logpathは各自の環境に合わせて設定してください

ちょっとしたTips

slowmsの部分を「1にして起動してください」という記事を何個か見ましたが、そうすると1ms以下で処理されたクエリはロギング対象にならないため、データが少ない場合にロギングすることができません

ただ、slowmsを-1にするとすべてのクエリがスロークエリと判断されるため管理系のクエリも大量にロギングされてしまいます
例えば以下のようなログが大量にロギングされると思います

2014-09-16T19:45:42.585+0900 [conn56] command admin.$cmd command: buildInfo { buildinfo: 1 } keyUpdates:0 numYields:0  reslen:854 0ms

なので上記の設定で必要なクエリ情報だけ確認したい場合はgrepコマンドと合わせて使用するのがいいと思います

tail -f mongo.log | grep -v "command admin.\$cmd command:"

あとprofileオプションに関してですが、いくつか設定があり
「1」はスロークエリのみ表示することができる設定ですが、今回に限ってはすべてがスロークエリになるので関係ありません
また「2」という設定もあり、これはすべてのオペレーションを表示する設定となります
今回はオペレーション系の操作も1ms以下で処理されるので1でも2でも管理系のクエリがロギングされてしまいます

とりあえず開発環境でデバッグしたいときには使えると思いますが、本番でslowms=-1にするのは出力されるログの量も考えて、あまりおすすめはしません
あとは管理系クエリを除いたクエリがすべて1ms以上かかるのであれば--profile=1 --slowms=1で問題ないと思います

うーん、とは言え何かもうちょっといい方法はないのだろうか

参考サイト

2014年9月14日日曜日

Failed to connect to binary FirefoxBinary

概要

JavaでFirefoxDriverを使ってブラウザ起動しようとしたところタイトルのエラーが出て起動しなかった

エラーの詳細は以下

エラー詳細

org.openqa.selenium.WebDriverException: Failed to connect to binary FirefoxBinary(C:\Program Files (x86)\Mozilla Firefox\firefox.exe) on port 7055; process output follows: 
10570639060 addons.xpi  DEBUG   Skipping unavailable install location app-system-share
1410570639061   addons.xpi  INFO    Mapping {972ce4c6-7e08-4474-a285-3208198ce6fd} to C:\Program Files (x86)\Mozilla Firefox\browser\extensions\{972ce4c6-7e08-4474-a285-3208198ce6fd}
1410570639061   addons.xpi  INFO    Mapping fxdriver@googlecode.com to C:\Users\username\AppData\Local\Temp\anonymous6771863948985799219webdriver-profile\extensions\fxdriver@googlecode.com
1410570639062   addons.xpi  DEBUG   Ignoring file entry whose name is not a valid add-on ID: C:\Users\username\AppData\Local\Temp\anonymous6771863948985799219webdriver-profile\extensions\webdriver-staging
1410570639062   addons.xpi  DEBUG   checkForChanges
1410570639068   addons.xpi  DEBUG   Directory state JSON differs: cache [] state [{"name":"app-global","addons":{"{972ce4c6-7e08-4474-a285-3208198ce6fd}":{"descriptor":"C:\\Program Files (x86)\\Mozilla Firefox\\browser\\extensions\\{972ce4c6-7e08-4474-a285-3208198ce6fd}","mtime":1410549501858,"rdfTime":1410549501670}}},{"name":"app-profile","addons":{"fxdriver@googlecode.com":{"descriptor":"C:\\Users\\username\\AppData\\Local\\Temp\\anonymous6771863948985799219webdriver-profile\\extensions\\fxdriver@googlecode.com","mtime":1410570638589,"rdfTime":1410570638500}}}]
1410570639072   addons.xpi-utils    DEBUG   Opening XPI database C:\Users\username\AppData\Local\Temp\anonymous6771863948985799219webdriver-profile\extensions.json
1410570639073   addons.xpi  DEBUG   New add-on fxdriver@googlecode.com installed in app-profile
*** Blocklist::_loadBlocklistFromFile: blocklist is disabled
1410570639254   addons.xpi-utils    DEBUG   Make addon app-profile:fxdriver@googlecode.com visible
1410570639256   DeferredSave.extensions.json    DEBUG   Save changes
1410570639256   DeferredSave.extensions.json    DEBUG   Save changes
1410570639256   addons.xpi  DEBUG   New add-on {972ce4c6-7e08-4474-a285-3208198ce6fd} installed in app-global
1410570639259   addons.xpi-utils    DEBUG   Make addon app-global:{972ce4c6-7e08-4474-a285-3208198ce6fd} visible
1410570639259   DeferredSave.extensions.json    DEBUG   Save changes
1410570639259   DeferredSave.extensions.json    DEBUG   Save changes
1410570639265   addons.xpi  DEBUG   Updating database with changes to installed add-ons
1410570639265   addons.xpi-utils    DEBUG   Updating add-on states
1410570639265   addons.xpi-utils    DEBUG   Writing add-ons list
1410570640188   DeferredSave.extensions.json    DEBUG   Starting timer
1410570640222   addons.manager  DEBUG   shutdown
1410570640225   DeferredSave.extensions.json    DEBUG   Starting write
1410570640225   addons.xpi  DEBUG   shutdown
1410570640226   addons.xpi-utils    DEBUG   shutdown
1410570640312   DeferredSave.extensions.json    DEBUG   Write succeeded
1410570640312   addons.xpi-utils    DEBUG   XPI Database saved, setting schema version preference to 16
1410570640312   addons.xpi  DEBUG   Notifying XPI shutdown observers
1410570640314   addons.manager  DEBUG   Async provider shutdown done
1410570641494   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/addons/XPIProvider.jsm: ["XPIProvider"]
1410570641496   addons.manager  DEBUG   Loaded provider scope for resource://gre/modules/LightweightThemeManager.jsm: ["LightweightThemeManager"]
1410570641499   addons.xpi  DEBUG   startup
1410570641499   addons.xpi  DEBUG   Skipping unavailable install location app-system-local
1410570641500   addons.xpi  DEBUG   Skipping unavailable install location app-system-share
1410570641500   addons.xpi  INFO    Mapping {972ce4c6-7e08-4474-a285-3208198ce6fd} to C:\Program Files (x86)\Mozilla Firefox\browser\extensions\{972ce4c6-7e08-4474-a285-3208198ce6fd}
1410570641501   addons.xpi  INFO    Mapping fxdriver@googlecode.com to C:\Users\username\AppData\Local\Temp\anonymous6771863948985799219webdriver-profile\extensions\fxdriver@googlecode.com
1410570641501   addons.xpi  DEBUG   Ignoring file entry whose name is not a valid add-on ID: C:\Users\username\AppData\Local\Temp\anonymous6771863948985799219webdriver-profile\extensions\webdriver-staging
1410570641501   addons.xpi  DEBUG   checkForChanges
1410570641509   addons.xpi  DEBUG   No changes found
*** Blocklist::_preloadBlocklistFile: blocklist is disabled

Build info: version: '2.39.0', revision: 'ff23eac', time: '2013-12-16 16:11:15'
System info: host: 'WINDOWS-3RKIT3N', ip: 'xxx.xxx.xxx.xxx', os.name: 'Windows Server 2008 R2', os.arch: 'amd64', os.version: '6.1', java.version: '1.7.0_51'
Driver info: driver.version: FirefoxDriver
    at org.openqa.selenium.firefox.internal.NewProfileExtensionConnection.start(NewProfileExtensionConnection.java:130) ~[fndb_main_rank_getter.jar:?]
    at org.openqa.selenium.firefox.FirefoxDriver.startClient(FirefoxDriver.java:250) ~[fndb_main_rank_getter.jar:?]
    at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:110) ~[fndb_main_rank_getter.jar:?]
    at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:197) ~[fndb_main_rank_getter.jar:?]
    at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:190) ~[fndb_main_rank_getter.jar:?]
    at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:186) ~[fndb_main_rank_getter.jar:?]
    at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:103) ~[fndb_main_rank_getter.jar:?]
    at fndb.amazonapi.HTMLCreator.updateRanking(HTMLCreator.java:197) [fndb_main_rank_getter.jar:?]
    at fndb.main.MainRankGetter.create(MainRankGetter.java:68) [fndb_main_rank_getter.jar:?]
    at fndb.main.MainRankGetter.main(MainRankGetter.java:48) [fndb_main_rank_getter.jar:?]
Caused by: org.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms. Firefox console output:

環境

  • Windows 2008 R2
  • Java 1.7.0_51-b13
  • Selenium Driver 2.39.0

対処方法

SeleniumのJarのバージョンをアップデートするだけ
http://www.seleniumhq.org/download/ にアクセスして

  • Selenium Server (formerly the Selenium RC Server)から
    selenium-server-standalone-2.43.0.jar

  • Selenium Client & WebDriver Language Bindings のJavaから
    selenium-java-2.43.0.jar

をダウンロードしクラスパスに通せばOKです
Seleniumはブラウザがバージョンアップするたびにバージョンアップするのでこの辺ついていくのが面倒ですね
Mavenでもバージョンの部分を書き換える必要があるので結局作業が必要になっちゃいますね

2014年9月12日金曜日

改めてJenkinsのプラグインを開発する方法をまとめてみた

概要

過去にEclipseとMavenを使ってサンプルのプラグインを動作させる方法を紹介しました
JenkinsのプラグインはRubyでも書けるようになったようでいろいろと変わっていることもあるかなーと思い再びプラグインの作成方法をまとめてみました
でもまた、Java+Mavenで作っています
環境マシンはMacですが、Javaが動けばWindowsでもLinuxでも同様に開発はできるかと思います

環境準備

  • Mac
    Mac OS X 10.8.5
  • Java
    1.6.0_65
  • Maven
    3.2.3

プラグイン開発

Java+Mavenでプラグインの開発するための流れを紹介していきます

Mavenの設定

ユーザごとの設定を記述する~/.m2/settings.xmlに以下を追記します
ない場合は作成しちゃってください
すでにファイルがあり<settings>タグや<pluginGrups>タグがある場合は適切な場所に設定を追記してください

<settings>
  <pluginGroups>
    <pluginGroup>org.jenkins-ci.tools</pluginGroup>
  </pluginGroups>

  <profiles>
    <!-- Give access to Jenkins plugins -->
    <profile>
      <id>jenkins</id>
      <activation>
        <activeByDefault>true</activeByDefault> <!-- change this to false, if you don't like to have it on per default -->
      </activation>
      <repositories>
        <repository>
          <id>repo.jenkins-ci.org</id>
          <url>http://repo.jenkins-ci.org/public/</url>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>repo.jenkins-ci.org</id>
          <url>http://repo.jenkins-ci.org/public/</url>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>
  <mirrors>
    <mirror>
      <id>repo.jenkins-ci.org</id>
      <url>http://repo.jenkins-ci.org/public/</url>
      <mirrorOf>m.g.o-public</mirrorOf>
    </mirror>
  </mirrors>
</settings>

詳しい内容はよくわかりません
Jenkinsのプラグインを作成するためのおまじない程度に認識しとけばOKだと思います

プロジェクトの作成

コマンド一発です

mvn -U org.jenkins-ci.tools:maven-hpi-plugin:create

いろいろなダウンロードが始まりますので完了するまで待ちます
完了するとgroupIdとartifaceIdを入力するように促されるので適当に入力します(以下ではgroupIdはデフォルトでartifaceIdは「test」としています)

Enter the groupId of your plugin [org.jenkins-ci.plugins]: 
Enter the artifactId of your plugin (normally without '-plugin' suffix): test

とりあえずビルド

cd test
mvn clean package

またものすごい勢いでダウンロードが始まります
ダウンロードが完了するとコンパイルしテストが実行され、その後プラグインの実体となるhpiファイルを作成してくれます

ls -ltr target/test.hpi
-rw-r--r-- 1 user staff 8176  9 10 14:48 target/test.hpi

サンプルの実行

せっかくビルドできてhpiファイルもできたので早速プラグインがJenkins上で動作するか試してみましょう

mvnDebug hpi:run

8080番でJenkinsが立ち上がります
Jenkins is fully up and running と表示されば起動完了です
ブラウザでhttp://localhost:8080/jenkinsにアクセスしてみましょう
当たり前ですが、8080番がすでに使われているとエラーになるのでnetstat等で使われていないことを確認してから実行してください
か、-Djetty.port=8090オプションを指定することでポートを変更することも可能です
そしてあまり関係ないが起動するJenkinsのバージョンがやや古い

このサンプルはビルド手順に「Say hello world」を追加し、ビルド時に指定した文字列を受け取って「Hello hogehoge!」という出力をコンソールに出すことができます
なので適当にジョブを作成してビルド手順に「Say hello world」を指定すればプラグインの動作を確認することができます
plugin-test.png

サンプルの拡張

せっかくなんでサンプルを使って独自の機能も追加してみます
修正するファイルは
src/main/java/org/jenkinsci/plugins/test/HelloWorldBuilder.java

src/main/resources/org/jenkinsci/plugins/test/HelloWorldBuilder/config.jelly
になります
config.jellyでUIを定義し定義したUIの部品をJavaで操作する感じです
global.jellyというファイルもありますが、これはJenkinsの管理 -> システムの設定に設定項目を表示するためのファイルとなります

すごい簡単な拡張ですが、名前以外に年齢も入力させてビルド結果に出力できるようにしてみましょう

UI拡張

まず、UIを拡張します
config.jellyに以下を追加します

<f:entry title="Age" field="age">
  <f:textbox />
</f:entry>

Nameと同様に1つテキストフォームを増やす命令となります
とりあえずこの状態だけ修正してUIを確認してもフォームが増えていることは確認できます

ロジック修正

次に、HelloWorldBuilder.javaを修正してUIから取得した値を表示させるようにします
内容的には年齢を表示するようのフィールドを宣言して、それに対するGetterの追加とコンストラクタの修正をします
あとはperformというBulderクラスから継承したメソッドで宣言したフィールド情報を表示します
部分的にですが、HelloWorldBuilder.javaに追記、修正した部分を記載します

  • フィールド追加
    フィールドを定義している箇所に以下を追加してください
private final String age;
  • コンストラクタ修正
    既存のコンストラクタを以下のように修正してください
@DataBoundConstructor
public HelloWorldBuilder(String name, String age) {
    this.name = name;
    this.age = age;
}
  • Getter追加
    Getterを定義している箇所に以下のGetterを追加してください
public String getAge() {
    return age;
}
  • perform追加
    既存のperformメソッド内でprintlnしている箇所に以下を追加してください
listener.getLogger().println(name +" is " + age + " years old.");

さらにAgeは数字だけを入力するように制限してみたいと思います
以下のバリデーションチェック用のメソッドを追記してください

public FormValidation doCheckAge(@QueryParameter String value) throws IOException, ServletException {
    if (value.length() == 0)
        return FormValidation.error("Please set a age");
    try {
        Integer.parseInt(value);
    } catch (NumberFormatException e) {
        return FormValidation.error("Isn't the type of int?");
    }
    return FormValidation.ok();
}

チェックしているのは文字数が0以上かと数字かどうかを判断しています
バリデーションエラーの場合は警告ではなく、エラーとしています

ビルド&実行

さて、作ったものを動かしてみましょう

mvn clean package
mvnDebug hpi:run

でビルド&実行します
動いている場合はCtrl+cで停止してから上記を実行してください
ジョブの設定で「ビルド手順の追加」を確認するとAgeが入力できるようになっています
Ageを指定して実行するとビルド結果にAgeの情報も出力されます
またフォーマットチェックも実装したので数字以外だとエラーが表示されることがわかると思います(ただ、エラーでもジョブの設定保存自体はできてしまうので飾りみたいな感じです)

完成版の実行イメージは以下の通りです

  • ビルド手順の追加にAgeが追加されている
    adding_parameter_age.png

  • 入力されたパラメータが数字でない場合エラーを表示する
    check_parameter_age.png

  • 実行結果にAgeの情報が追加されている
    age_appear_in_result.png

とりあえず今回はサンプルの実行と簡単な拡張方法を紹介しました
あとは作成したhpiファイルを稼働中のJenkinsに組み込む方法やJenkinsCIに取り込んでもらい一般公開する方法などやることはありますが、それはまた機会があれば紹介したいと思います

今回紹介した方法は基本中の基本の部分なのであとはリファレンスを読んだりググったりしながら独自のプラグインを開発してみてください
それでも開発につまる場合はGithubで公開されているプラグインのコードを見れください

参考リンク

2014年9月11日木曜日

Bloggerの使い方メモ

PS. 20170712

結局 StackEdit からは HTML で送信して Blogger のテーマの HTML を編集して <head> タグに以下を入れるのが一番良いっぽいです

<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?lang=css&amp;skin=sunburst"></script>

https://github.com/google/code-prettify/blob/master/docs/getting_started.md

PS. 20170208

結論として以下だけを行えばキレイに表示されることがわかったので以下だけ実施するようにしています

  • 投稿時に custom template を選択
  • body タグ内にある <div class="container"> を削除する

post_setting_from_stackedit.png

これで stackEdit で編集しているときのプレビューと同じ表示方法で投稿されます
過去の記事に関しては上記の設定で再投稿し直す必要があるので素直に諦めましょう

概要

BloggerでSyntaxHighlighterを使うネタを過去に投稿して、その後StackEditを使うネタを投稿して、更に投稿はしていないがstackEditでprettifyを使うようになったりして、、、
いろいろとごちゃごちゃしてきたので自分なりの設定方法と使い方をまとめておきました

各種設定と使い方

テンプレート設定

Blogger -> テンプレート -> HTMLの編集から以下を追記

  • </head>の直前
    SyntaxHighlighterを有効にする
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPHP.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
<script language='javascript' type='text/javascript'>
 SyntaxHighlighter.config.bloggerMode = true;
 SyntaxHighlighter.all();
</script>
  • <title>の直後
    stackEditからの投稿がprettifyになっているのでスタイルだけ適用
<link href='https://raw.githubusercontent.com/google/code-prettify/master/styles/sunburst.css' rel='stylesheet' type='text/css'/>

P.S 20160512
sunbrust.css の URL が 404 になっていたので Github へのリンクに変更しました

https://google-code-prettify.googlecode.com/svn/loader/skins/sunburst.css

https://raw.githubusercontent.com/google/code-prettify/master/styles/sunburst.css

使い方

stackEditから投稿する場合

コードスニペット

コードを挿入する際にバッククオート3つを使うがその後ろに言語名を指定すること
```html
lisp等の拡張には対応していないためSyntaxColorがうまく適用されない場合はxmlを指定してSyntaxColorさせないようにする(とりあえず白黒になる)

画像の挿入

画像はstackEdit上にドラック&ドロップすればGoogle+上の保存されるのでそこから画像挿入すればOK

YAML Front Matter

冒頭のymlのラベル定義

---
tags: ["WebService", "随時更新メモ", "技術"]
---


Table of Contents[TOC]は必ず入れる

その他のMarkdownは特に気にせず使用してOK

Google+

tackEditから投稿するとGoogle+では自動で共有されないので、もしGoogle+に共有したい場合はBloggerの管理画面から共有すること

シンタックスハイライトの設定

# -> Settings -> Extentsions -> Markdown Extra -> Syntax highlighter -> Prettify

普通に投稿する場合

シンタックスハイライトの設定

コードを挿入する場合はSyntaxHighlighterを使う
<pre class="brush: java"></pre>
指定可能な言語はJava, Ruby, PHP, CSSなのでその他に必要であればテンプレートにJavaScriptの読み込み定義を追記する
言語がなくてどうしてもSyntaxHighlighterが使えない場合は以下を使用する(基本はしようしない)
<pre style="background: #fff; border: dashed 5px #ccc; color: black; line-height: 1.3em; margin: 0px; padding: 5px;white-space: pre-wrap;"></pre>

その他見出し

見出しは
<span style="color: #6aa84f;"></span>

ブロックは
<div style="padding-left:2em;"></div>
<div style="padding-left:3em;"></div>

リンク、画像、リスト等Bloggerで使える機能は普通に使ってOK
ラベルは適切なものを選択して必ず付与する
TOCは入れられない

タイトルの付け方

英語が入る場合、タイトルを元にBloggerが勝手にURLを生成してくれます
なので英語がタイトルに入る場合は必ず単語の左右にスペースを入れるようにする
そうすることでURLがいい感じになる(英単語の間にハイフンを入れてくれる)

2014年9月10日水曜日

Emacsで色(face)をカスタマイズする方法

概要

Emacsの文字色や背景色はfaceという仕組み(というか名称)で管理されています
ユーザはfaceをカスタマイズすることで見た目を変更ことができます
faceのカスタム方法はいろいろありますが、今回はEmacsに付属されている customize-face という機能を使って変更する方法を紹介します

環境準備

  • Emacs
    24.3.1

カスタマイズ

customize-face 起動

まずはcustomize-faceを起動します
ミニバッファで「customize-face」と入力すれば起動することができます
M-x customize-face

Customize face (defaultall faces’):` と聞かれるので Enter を入力します
face はカテゴリごとに管理されておりカスタマイズしたいカテゴリに絞ってからカスタムすることも可能です
とりあえず今回はデフォルトの all を使ってカスタマイズしてみます
起動すると以下のように表示されるはずです
customize-faces-start.png

目的のfaceを見つける

今回は試しにscratchバッファのコメント部分の文字色を変更してみたいと思います
scratch.png

faceでカスタムする際に一番大変な作業は、カスタムしようとしている場所が何というfaceなのかを知ることです
今回変更しようとしているfaceはfont-lock-comment-faceになります
これをどうやって知ったかというとdescribe-faceという関数がありこれを変更したい文字上で実行すると調べることができます

faceの名前がわかったのでcustomize-faceに戻って早速カスタムしてみます
customize-faceをallで開いたので大量のfaceがあると思います
EmacsなのでCtrl+sで検索してもいいですし、一番上の黄色部分が検索窓の役割にもなっているのでここにkeywordを入力してもOKです
検索するときにはfont-lock-comment-faceと入力してもマッチしません
customize-face上のface名は「font lock comment face」とハイフンなしでで検索することで目的のfaceに辿りつくことができます
font-lock-comment-face.png

scratchの文字色をカスタムしてみる

「Show」の部分をEnterするとfaceの設定項目が出てきます
元々の色はどうやら「yellow」が定義されているようです
yellow の部分にカーソルを合わせてEnterを入力するとミニバッファに色を指定するように言われます
Emacsで提供しているカラーテーマ以外は指定できません
Emacsが提供するカラーの一覧はlist-color-displayで表示することが可能です
ここでは試しに「red」と入力しましょう
change-red.png

カスタム情報を保存する

変更が完了すると状態が編集中になります
カスタム情報を保存する方法はEmacsの王道の「Ctrl+x, s」でも問題ありません
customize-faceの機能を使って保存する場合は「State」をEnterするとミニバッファに選択項目が出てくるので「1 = Save for Future Sessions」を選択すればOKです
するとカスタム情報が.emacsに書き込まれます
この状態まで来たらscratchバッファを再度見てみると黄色だったコメント部分が赤色になっていることがわかります
保存した際に.emacsにカスタム情報が記録されるためEmacsを再起動しても文字が赤になっていると思います

今回の紹介は以上です
-nw オプションでemacsを起動していると変更できないfaceもあるようなので、その辺りは実際に変更しながら試していくしかなさそうです

Enjoy Emacs life !

2014年9月9日火曜日

CentOSにAntをインストール

概要

CentOSにビルドツールであるAntをインストールする方法を紹介します

環境準備

  • CentOS
    6.5
  • Java
    OpenJDK 1.7.0_65 (yum で install した最新のバージョン)
  • Ant
    1.9.4 (今回インストールするバージョン)

インストールコマンド

cd /var/tmp/
wget http://ftp.tsukuba.wide.ad.jp/software/apache//ant/binaries/apache-ant-1.9.4-bin.tar.gz
tar zvxf apache-ant-1.9.4-bin.tar.gz
mv apache-ant-1.9.4 /usr/local/
cd /usr/local/
ln -s apache-ant-1.9.4/ ant
export ANT_HOME=/usr/local/ant
export PATH=$ANT_HOME/bin:$PATH

で、完了です

最新版をインストールしたいのとyumからだとインストールが難しいのでバイナリファイルを配置してインストール完了です
ant -version とすればバージョンを確認できるかと思います

実行しているantコマンド内でJAVA_HOMEを設定しているようなので意図的にexportする必要はないと思いますが、「JAVA_HOMEがない」とエラーが怒られるようであればJAVA_HOMEをexportしてあげてください

Tips

ant実行時に文字化けするようであれば適当なエンコードを指定してから実行してみてください

export ANT_OPTS=-Dfile.encoding=UTF-8 && ant

それでも「unmappable character for encoding UTF-8」とか出る場合はファイル自体の文字コードがUTF-8になっているか確認してみてください