Translate

2015年2月25日水曜日

Docker上のCentOSコンテナでsystemdを使えるようにする方法

CloudStack、OpenStackときたら、Dockerにも手をつけないと..

というよくわからない強迫観念にかられ
私もついに Docker に手を出しました。


..こりゃ簡単だ..

できることはVMware PlayerのNATで仮想イメージ上げたような
感じだけど、むちゃくちゃ軽い。

OSはCentOS/ubuntuだけなのが残念。

だからこれまでのハイパーバイザ型の仮想化技術に
完全に取って代わることはできないけど、
アプリ開発をやっている人がちょいと
tomcatやhttpdを起動させたい時とか
開発で使うsubversion/redmine/jenkinsサーバを必要なときに起動して
必要なくなったらイメージで固めて保管すればいい。

インストールなんてCloudStackやOpenStackなんか死ぬほど難しいけど
CentOSやubuntuならyumapt-getでさっくりはいってしまう。

なによりホスト(?)OSはCentOSやubuntuのデフォルト最小構成インストールでOK
ゲストOSのインストールは一切不要(だからライセンス問題のある有料OSはなかなか対応できないだろうけど)。


デモ環境やアプリや向きの仮想化技術だ。

DockerfileもCentOS/ubuntuを普通につかってる人ならだれでも書ける。
コマンドラインに打ち込んでいたコマンドの先頭に"RUN"つけて列挙するだけ。
あとVOLUMEやEXPOSEやいろいろあるけど、
サンプルパクればさくっと作れる。


ただ..そこまでいくまでの情報が少ない。

現時点で紙で出版されている書籍はなく、
Kindleで以下の本が販売されていた。



(この記事を書いた時点で)星3つなのは、
最初の概要がとってもおざなりでどういう技術をもとに
動いているのか読んでもさっぱりわからない。
その後は、それなりにコマンドを理解している人なら有益だけど
さいしょのとっっかりには不親切な本だ。

..星3つなのはさいごの

「Dockerを
 ドカドカ使う
 春の空

  米村正明」
が、イラッとさせたのかもしれない..



雑誌ではSoftwareDesignがある。



Docker情報にみな飢えているのか
定価1220円の雑誌が2100円(この記事書いた時点)になってる..

こちらは、Dockerが登場することになったのかのLinux上の技術の変遷が
かたられており最初のKindle本の補填をしてくれた。

Docker上のネットワーク構成の絵があるのもありがたかった。

実際の動くところ紹介は端折り過ぎなので
初心者向きにはちょっと足りないかんじ。

たぶん初心者はここから入った方がいい。

いまさら聞けないDocker入門
http://goo.gl/uMIEv2

このリンクの周辺の記事をよんで
事前情報をえるとよいとおもう。


チュートリアルも英語だけど用意されている。
DockerHubへアカウント作った翌日にサイトから
チュートリアルのリンク付きメールが送られてきた。

The best way to understand Docker is to try it!
http://goo.gl/dB58ZF

このサイト、画面左側の英語を読んででてくる
指示にあったコマンドを右側のコンソールに入力して実行すると
つぎにすすめるこうせいになっていて、
Docker環境がなくてもよく使うコマンドをひととおりおぼえることができる。

チュートリアルを済ませた後
PC上にVirtualBoxなり、VMware playerなりでCentOS7を最小インストールで
たちあげて、「yum -y install docker」すればOK。

この環境で色々試していけばいい。




で、CentOSをdocker上でごそごそ動かしてみたら
色々と不都合なことがでてきた。

大きくは以下の2点。

  1. ネットワーク系のコマンドがないし設定できない
  2. systemdがない

最初の問題、Docker上のコンテナはIPアドレスがかえられない。
nmclientとかip addr showとかが使えない..

ホスト側のNICにブリッジ接続するからで、そのあたりは変えてくれるなということのようで、"ありき"で構築しないとダメらしい。

DNSは/etc/sysconfig/docker上のオプション指定でできるようだ。


で問題なのは2つめだ。

CentOSのバージョンが7になって
適応するのに困るのがsystemdfirewall-cmd/chconがらみ。

これまでserviceで起動停止していたのを
またこんどはsystemdに変えられて
必死で対応していたのに
おぼえたとおもったら
Dockerのデフォルトコンテナではsystemdが入っていない..

Googleってみると
みんないろいろがんばっている。

そもそもわざわざfakesystemdなんていれて
隠しているので何かこのデザインに意図があるように思えた。


で、ブログではなくDockerHubのCentOSサイトを開いてみたら
案の定systemdに関する記述が見つかった。

DockerHub: OFFICIAL REPO CentOS
http://goo.gl/aKYzXi

英語なので翻訳してみた。
以下翻訳した日本語であるが
当然 at your own risk で参照してほしい。


-------

サポートしているタグおよびDockerfile


    latest, centos7, 7 (docker/Dockerfile)
    centos6, 6 (docker/Dockerfile)
    centos5, 5 (docker/Dockerfile)
    centos7.0.1406, 7.0.1406 (docker/Dockerfile)
    centos6.6, 6.6 (docker/Dockerfile)
    centos5.11, 5.11 (docker/Dockerfile)

イメージと履歴については、docker-library/official-images GitHubリポジトリのマニフェストファイル(library/centos)を参照してください。

CentOS


CentOS Linuxは、RHEL(Red Hat Enterprise Linux)のために Red Hat により公式に提供されているフリーソースをもとに構成されたコミュニティサポートされたディストリビュージョンです。このため、CentOS LinuxはRHELと機能的に互換性を持つことを目的としています。CentOS プロジェクトは、主にベンダーの商標や意匠を必要とするものを削除したパッケージに変更しています。CentOS Linux はノーコストで再配布自由です。

CentOS Linux の各バージョンは10年以上維持され続けています(セキュリティアップデートの維持:Red Hatによるサポートの間隔はソース側リリースにより異なる)。CentOS Linux の新しいバージョンはほぼ2年毎にリリースされ、各バージョンは新規ハードウェアサポートのために定期的に更新されます(だいたい6ヶ月間隔)。この結果、安全で、低メンテナンスで、信頼性がたかく、予測可能で、再現可能なLinux環境を提供します。各々のCentOS Linux版は、最高10年の間維持されます(セキュリティ最新版によって Red Hatによる支持間隔の長さは、リリースされる源に関して、時間とともに異なりました)。 新しいCentOS Linux版は、ほぼ2年おきにリリースされます、そして、各々のCentOS Linux版は、より新しいハードウェアを支持するために、定期的に更新されます(ざっと6ヵ月ごと)。これは、安全で、低-メンテナンス、信頼できて、予想できて、再生可能なLinux環境に終わります。

https://wiki.centos.org/FrontPage


CentOS イメージ ドキュメンテーション


centos:latest」タグは現時点でほぼ最新な状態となっています。


定期ビルド


CentOS プロジェクトは、すべてのアクティブリリースのイメージを定期的に更新します。これらのイメージは毎月、もしくは緊急フィックスが必要な際に更新されます。これらのローリングアップデートはメジャーバージョン番号のみでタグ付けされています。

例:「docker pull centos:6」、「docker pull centos:7

マイナータグ


さらに、インストールメディアと一致するマイナーバージョンタグのついたイメージも提供します。これらのイメージは、インストール用ISOコンテンツとマッチさせることが目的なので更新しません。

もしこれらのイメージを選択するのであれば、「RUN yum -y update && yum clean all」をDockerfileに記述するか、もしくは利用者に潜在的なセキュリティ問題を含む可能性を申し入れることを強く推奨します。
これらのイメージを使用する場合は、マイナーバージョンタグを指定してください:

例:「docker pull centos:5.11」、「docker pull centos:6.6

パッケージ ドキュメンテーション


特に指定がない場合は、CentOSコンテナは、イメージのサイズを削減するために nodocs オプションを付けたyumをつかってビルドされます。
もしパッケージをインストールして行方不明になったファイルを発見するならば、「/etc/yum.conf」内の「tsflags=nodocs」をコメントアウトして再インストールしてください。

systemd インテグレーション


現時点では、CentOS7 に含まれる systemd は削除され、依存性解決のためにかわりに fakesystemd に入れ替わっています。これは、systemdが「CAP_SYS_ADMIN」ケーパビリティ(訳者注:root の持つ細かい権限のこと、CAP_SYS_ADMIN quotaswapmount などの操作が可能)を必要としているためです(ホストOS側の cgroups を読むことができるだけではありません)。
もしあなたが fakesystemd を置き換え systemd を不通に使いたいのであれば、以下のステップに従ってください。

systemd ベースイメージのための Dockerfile


FROM centos:7
MAINTAINER "あなたの名前" <あなたの@メールアドレス>
ENV container docker
RUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs
RUN yum -y update; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i ==
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]

この Dockerfilefakesystemd を実際のパッケージと交換しますが、問題を起こしそうな多くのユニットファイル群を削除します。ここからあなたのベースイメージファイルを構築することができます。

docker build --rm -t local/c7-systemd .」

systemd が使用可能なアプリケーションコンテナの例

上記で作成した systemd が使用可能なベースコンテナをつかって、以下のような Dockerfile を作る必要があります。


FROM local/c7-systemd
RUN yum -y install httpd; yum clean all; systemctl enable httpd.service
EXPOSE 80
CMD ["/usr/sbin/init"]

このイメージのビルド:

docker build --rm -t local/c7-systemd-httpd


systemd が使用可能なアプリケーションコンテナの実行


systemd が使用可能なコンテナを実行するためには、ホスト側のcgroupボリュームをマウントするだけでなく、「--privileged」オプションを使う必要があります。

以下は、事前に作成した systemd が使用可能な httpd コンテナを実行するためのコマンド例です。

docker run --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/c7-systemd-httpd

このコンテナは制限されたコンテキスト内でsystemdが使用可能な状態で実行していますが、ほぼcgroupsファイルシステムをマウントした特権が付与されたコンテナとしての実行となります。

サポートされている Docker バージョン


このイメージは Docker バージョン 1.5.0 を公式にサポートしています。

(1.0下の)古いバージョンのサポートは基本ベストエフォートで提供されています。

ユーザフィードバック

Issues


もしこのイメージについての問題や質問がある場合は、https://bugs.centos.org もしくは GitHub issue のチケットを発行してください。

Freenode(https://freenode.net/)上の「#docker-library」IRCチャネル経由で多くの公式イメージメンテナーへ連絡をとることができます。

寄贈・貢献(Contributing)


ぜひ新機能、フィックス、更新、大きいもの少ないものにかかわらず、寄贈(contribute)してください;私達はいつもぞくぞくして pull request を受け取り、可能な限り早く最善を尽くします。

コーディングを開始する前に、特に野心的な寄贈の場合は、 https://bugs.centos.org のチケットもしくは GitHub issue に計画を投稿して我々と議論することをおすすめします。ほかの寄贈に対しての正しい方向性を指し示すチャンスをあたえることになり、あなたの設計上のフィードバックを受けることができ、他の人が同様の作業をしているかどうかの発見を助けてくれます。

-------


なるほど、
ホスト側のcgroupsとの兼ね合いでゲスト・ホスト間の疎結合性が崩れるのと
パッケージコマンド管理による依存関係をだまくらかす意味で
fakesystemdをやむをえず入れたわけか..


このサイトに有るように systemd をむりくり入れてもいいけど..
わざわざ特権許可したコンテナでうごかすより
CMDで起動スクリプト叩いたほうが安全かもなあ..

ケースバイケースでえらぶしかないか..


2014年12月29日月曜日

Karotzを手に入れた後でサービス停止を知る





Jenkins実践入門という本の中(p17)に
eXreme Feedback Device(XFD)の例として
Nabaztagといううさぎ人形が紹介されていた。

調べてみるとNabaztagという会社から
別の会社にわたりKarotzという名前になった
ということを知った。

日本代理店もあったのだけど
リンクを辿って行くとコンサル会社のサイト
いきつく。

検索してもKarotzをやっているそぶりがない..


どうも日本国内では売ってないらしい..

ということで
AmazonサイトでKarotzを検索すると
並行輸入品でKarotz人形を手に入れることができるとわかった。


早速購入してみる。

..おもったよりでかい..

ほんとうに簡単なマニュアルが付いているだけだったのだけど
英語もあったのでなんとか読んでみると..

どうもこの人形、WiFi(オプションでEther接続可能)でインターネットに
直付しないといけないらしい。

しかもサーバ側にユーザ登録して、
そこにメールアドレスやらTwitterアカウントやらを登録しないと
だめらしい。

インストールもUSBデバイスが別途必要で
所定のサイトからダウンロードしたファイル群をUSBデバイスに入れて、
それを人形のおしりに挿し、スイッチをONにしないとだめらしい。


USBキーへ保存するファイル群をもらうためには
http://plug.karotz.com/
いけとあったのですすむと..


..あれ?白い画面しかでないんですけど..

で検索してみると
http://store.karotz.com/en_US/
のトップに「The end of Karotz's adventures」
という画像が..

「Karotz の冒険は、2015年2月18日に終わります 。」

なに?!

「詳細は http://store.karotz.com/en_US/ を見てください。」

とあったので開いてみたが、
トップページはあるものの
リンク先がない..
「Why stopping the server?」ってリンクくらい残してくれよ!



..途方に暮れていたが、
オープンソースにするナイスガイが
いるかもと検索してみると..


..あった、openkarotzプロジェクト..

http://openkarotz.filippi.org/

..でもフランス語..英語がない..

まあYahoo翻訳にかけるからどっちでも同じだけど;-p


で最初の記事を翻訳してみた。


L’assistant d’installation est disponible.
インストール支援サイトをオープンしました。

Vous n’avez désormais plus besoin d’aller sur
le site Karotz.com pour réinstaller votre lapin.
あなたはこれからうさぎをインストールするために
Karotz.com サイトへ行く必要はなくなりました。

Vous pouvez le faire directement depuis l’assistant
 disponible sur : plug.openkarotz.org

インストール支援サイト plug.openkarotz.org を利用してください。

http://plug.openkarotz.org/ へ進むと..


おおイギリスマークがある..ってことは英語サイトも用意されてる..

 これは..試してみるか..



でもkarotz pluginは..ダメだろうなあ..きっと..

2014年12月19日金曜日

SELINUX=enforcingのままでJenkinsを動かす

CentOS 7 LTS 環境に以下の手順でJenkinsサーバをインストールした。



yum -y updape
yum -y install httpd java wget
wget --retr-symlinks -O /etc/yum.repos.d/jenkins.repo \
 http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo
yum -y remove wget
rpm --import http://pkg.jenkins-ci.org/redhat-stable/jenkins-ci.org.key
yum -y install jenkins
vi /etc/sysconfig/jenkins
 JENKINS_LISTEN_ADDRESS="127.0.0.1"
 JENKINS_ARGS="--prefix=/jenkins"
vi /etc/httpd/conf.d/jenkins.conf
 ProxyPass         /jenkins  http://127.0.0.1:8080/jenkins nocanon
 ProxyPassReverse  /jenkins  http://127.0.0.1:8080/jenkins
 ProxyRequests     Off
 AllowEncodedSlashes NoDecode
 <Proxy http://127.0.0.1:8080/jenkins*>
     Order deny,allow
     Allow from all
 </Proxy>
systemctl enable jenkins.service
systemctl enable httpd.service

SELINUX=enforcingのままで動かしたかったので

chcon -R -t httpd_sys_content_t /var/lib/jenkins/
chcon -R -t httpd_sys_rw_content_t /var/lib/jenkins/
firewall-cmd --permanent --zone=public --add-service=http

を実行して再起動し、http://server/jenkins をブラウザから
開こうとしたのだけど..

なぜか開かない..

/var/log/auth/auth.log を調べてみると


type=AVC msg=audit(1418962121.878:241): avc:  denied  { name_connect } for  pid=2129 comm="httpd" dest=8080 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket

というのを見つけた。

どうもhttpdから127.0.0.1:8080へ通信しようとしてるのを
SELINUXが弾いているようだ..

このため

setsebool -P httpd_can_network_connect true

を実行してブラウザからひらいてみたら..

..うまくいった..

SELINUX=disabledにするのは簡単だけど
パブリックIaaSとかに自動で仮想マシン作るChefとかかこうとなると
やはりenforcingで動かしたい..

ためしていないが、
yumhttpdtomcatをインストールして
jenkins.war$TOMCAT_HOME/webappsデプロイしていれば
たぶんさっくりうごくんじゃないかな
yumsetseboolしてくれているのだろう..

めんどくさいぞSELINUX..

2014年11月27日木曜日

CentOS7上のRedmine2.6.0にXLS Exportプラグインをインストールする



AWSとかの上でRedmine運用する際
SELINUXは有効にしたまま使いたくなるだろうとおもい、
CentOS7最小構成インストールしたサーバ上に
/etc/sysconfig/selinux
SELINUX=enforcing
にしたままで
Redmine2.6.0をインストールした。
Redmine以外のパッケージはすべてyum(かgem、bundle install)でインストールした。

Redmineは/opt/redmine以下にインストールした。

Redmineはapache(+passenger+ruby)で動作するWebアプリケーション
なので
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --reload

だけでなく
systemctl stop httpd.service
chown -R apache:apache /opt/redmine
chcon -R -t httpd_sys_content_t /opt/redmine
chcon -R -t httpd_sys_rw_content_t /opt/redmine
systemctl start httpd.service

と、アプリの入っている/opt/redmineに対して/var/www/html同様のルールをはらなくてはならない


chownしているのは、rootで操作しているためだ。
yumで導入したhttpdapacheアカウントで動作するので
rootで導入操作した後オーナを変更している。


で、プラグインをインストールする際も
この面倒な操作が必要になる。

たとえばXLS Exportをインストールする場合は


/rootにプラグインredmine_plugin_views_revisions_v001.zipredmine_xls_export-0.2.1.t6.zipをダウンロードしておいた状態で
cd /root/
unzip redmine_plugin_views_revisions_v001.zip
mv ./redmine_plugin_views_revisions /opt/redmine/plugins/
unzip redmine_xls_export-0.2.1.t6.zip
mv ./redmine_xls_export-0.2.1.t6 /opt/redmine/plugins/redmine_xls_export
cd /opt/redmine
bundle install
rake redmine:plugins:migrate RAILS_ENV=production
rake redmine:plugins:process_version_change RAILS_ENV=production
systemctl stop httpd.service
cd /opt
chown -R apache:apache ./redmine
chcon -R -t httpd_sys_content_t /opt/redmine
chcon -R -t httpd_sys_rw_content_t /opt/redmine
systemctl start httpd.service

としないと新規導入した/opt/redmine以下のファイルにアクセスできず
config.ruがどうのこうのという白い画面が出てしまう..


SELINUX=disabledにしないと、超めんどくさい..

2014年10月29日水曜日

Google Book APIを使って本のサムネイル画像を表示するJavaScriptを作る

ISBNコードを元に
本の表示の画像を表示したかったので
いろいろREST APIを公開しているサービスをみてみた。

ほとんどがアカウントを作成しないと取得できないタイプだったので
半分あきらめかけていたのだけど、
Google Book API ならセキュリティキーとか作成せずにできそうだったので
ためしてみた。

Google Book APIはISBNコードをハイフン無しのコード部分だけ
数字部13桁をGETのパラメータとして渡してやれば
JSONで情報がもどってくるしくみだ。

なのでjQuery1.11.1 (IEも対応する必要があったので..) を使って
JavaScript関数をつくり、



<script type="text/javascript">
function loadBookImage(){
 var isbnCode = $("#isbn").val();
 isbnCode = isbnCode.trim().toUpperCase().replace(/[^\dX]/gi, '');
 var googleUrl ="https://www.googleapis.com/books/v1/volumes?q=" + isbnCode;
 $.ajax({
  type: "GET",
  url: googleUrl,
  dataType: "json"
 }).done(function(json){
  var thumb = json.items[0].volumeInfo.imageLinks.thumbnail;
  if(thumb){
   $("#bookImage").empty();
   $("#bookImage").prepend("<img src='" + thumb + "'/>");
  };
 });
};
</script>



bodyタグ内に
  • id値がisbnのinputタグ(onBlurにloadBookImage()を定義)
  • id値がbookImageのdivタグ
を作って試すと、簡単に表示できた。

でも、たまにISBNコードと同じでないサムネイル画像が出る..

上記関数で1件目のサムネイル画像のみ使用しているのだけど、
候補が複数帰ってくる場合もあって
それでたまに違う画像が出てくる..

そのあたりは、もうすこし jQuery のAjax に慣れてからにしようかな..

2014年10月10日金曜日

Javaで書いたWebアプリをBluemixへデプロイする




Struts2+VelocityでMVCを、
Spring Framework でDIとセキュリティを、
MyBatisでDAOを
それぞれ使ってPostgreSQL上のデータベースの入出力させる
ごくごくふつうのアプリをEclipse上で作った。

テスト環境としてローカルにTomcatとPostgreSQLを入れて
Eclipse上からテストしているが、
Bluemixをテスト環境にすればいいんじゃないかとおもい試してみた。

Bluemixサイトにログインして、
「CATALOG」タブから「Liberty for Java」を選択
名前、URL(ホスト名だけ)、選択プランを選ぶ。
でCREATEする。

そうすると作成したサーバ(?)のダッシュボードに遷移するので
「ADD A SERVICE」を選択する。
そして「Data Management」の「ElephantSQL」を選択する。
#PostgreSQLでAWSで動いているらしい

で、App欄は先ほど作成したサーバの名前をいれ、プランを選択する。
Service name欄にはプログラム内で使っているJNDI名の"jdbc/"を
除いた文字列でCREATEする。

リスタート云々言ってくるのでOKボタンを押して再起動する。

作成したデータソースをクリックし、
Launch ElephantSQL Dashboard
を押すと、
URLが表示されるのでメモる。




そしてbluemixプラグインを入れたEclipseでサーバを作成、
同一アカウントでの接続を設定しておく。
で、Webアプリプロジェクトを作成したサーバへドラッグ&ドロップすると
ダイアログがでてくるので、先ほど作成したAppsを選択すれば
デプロイ処理をしてくれる。

当然DB上にテーブルなどを作成しなくてはならないので
ローカルのpgAdmin(PostgreSQLをローカルにインストールすると
入ってくる管理コンソール)をたちあげ
コンセントマークのアイコンを押して
先ほどメモったURLを元にプロパティタブへ入力する。

例えば
postgres://hogehoge:fugafuga@foo.bar.com:5432/tar
である場合、
ホスト欄に「foo.bar.com」
Portに「5432」※もちろんproxy環境ではつながらない
データベースメンテナンス欄に「tar」
ユーザ名欄に「hogehoge」
パスワード欄に「fugafuga」
といれ(名前などは適当に入れて)「OK」ボタンを押すと接続できる。

データベース名は「tar」でこていになっているようなので
「tar」を選択して虫眼鏡アイコンを押してSQLを押し流せば良い。




本当はよくある組合せセット(boiler plate)のなかから選べばいいのだけど、
課金されることになったらをかんがえると一つ一つ必要な物だけ選んでいくのが
いいかな、とおもう。




とうぜん、tomcat-users.xmlでBASIC認証しているような場合は
アプリとしてログインを実装する必要がある。


簡単ではあるけど、SSLトンネリングとかの設定しないと
開発環境としてはめんどくさい。
なによりステップ実行できるわけではないし...

とりあえず、JNDI名で実装しとけばDBにはつながることが分かっただけでも
よしとしよう。

2014年9月9日火曜日

ISBNコードのチェックサム判定するJavaScript関数をつくってみた


ISBNをJavaScriptで扱わないといけなくなり、
チェックサム判定の関数と
ハイフン付き形式にする関数を
ISBN10とISBN13それぞれでつくってみた。
あとISBN10をISBN13にする(978を先頭につけてチェックサムを計算しなおす)関数
もつくってみた。


function isValidISBN (target) {

 var targetCode = target.trim().toUpperCase().replace(/[^\dX]/gi, '');
 if(targetCode.length == 10){
  return isValidISBN10(targetCode);
 };
 targetCode = target.trim().toUpperCase().replace(/[^\d]/gi, '');
 if(targetCode.length == 13){
  return isValidISBN13(targetCode);
 };
 return false;
};

function toISBN13(isbn10){
 var modulas = 10;
 var weight = 3;
 var targetCode = isbn10.trim().toUpperCase().replace(/[^\dX]/gi, '');
 targetCode = "978" + targetCode;
 var checkSum = 0;
 var chars = targetCode.split('');
 for (var i = 0; i &t; (chars.length-1); i++) {
  if( (i % 2) == 0 ){
   checkSum += parseInt(chars[i]);
  }else{
   checkSum += ( weight * parseInt(chars[i]) );
  };
 };
 checkSum = modulas - (checkSum % modulas);
 var isbn13 = "";
 for(var i = 0; i &t; (chars.length-1); i++){
  isbn13 = isbn13 + chars[i];
 };
 isbn13 = isbn13 + checkSum;
 return isbn13;
};

function isValidISBN13(isbn13){
 var modulas = 10;
 var weight = 3;
 var targetCode = isbn13.trim().toUpperCase().replace(/[^\d]/gi, '');
 if(targetCode.length!=13){
  return false;
 };
 var checkSum = 0;
 var chars = targetCode.split('');
 for (var i = 0; i &t; (chars.length-1); i++) {
  if( (i % 2) == 0 ){
   checkSum += parseInt(chars[i]);
  }else{
   checkSum += ( weight * parseInt(chars[i]) );
  };
 };
 checkSum = modulas - (checkSum % modulas);
 return (checkSum == (parseInt(chars[chars.length-1])));
}

function isValidISBN10(isbn10){
 var modulas = 11;
 var weight = 10;
 var targetCode = isbn10.trim().toUpperCase().replace(/[^\dX]/gi, '');
 if(targetCode.length!=10){
  return false;
 };
 var checkSum = 0;
 var chars = targetCode.split('');
 for (var i = 0; i &t; (chars.length-1); i++) {
  checkSum += ( weight * parseInt(chars[i]) );
  weight--;
 };
 checkSum = modulas - (checkSum % modulas);

 var actualCheckSum = 10;
 if(chars[chars.length-1] != "X"){
  actualCheckSum = parseInt(chars[chars.length-1]);
 }
 return (checkSum == actualCheckSum);
}

function formatISBN(target){
 if(isValidISBN10(target)){
  return formatISBN10(target);
 };
 if(isValidISBN13(target)){
  return formatISBN13(target);
 };
 return target;
};

function formatISBN13 (isbn13) {
 var chars = isbn13.toUpperCase().trim().replace(/[^\d]/gi, '').split('');
 var reformedIsbn13 = "";
 for(var i=0; i&t;chars.length; i++){
  if( i == 3 || i == 4 || i == 7|| i == 12){
   reformedIsbn13 = reformedIsbn13 + "-";
  };
  reformedIsbn13 = reformedIsbn13 + chars[i];
 };
 return reformedIsbn13;
};

function formatISBN10 (isbn10) {
 var chars = isbn10.toUpperCase().trim().replace(/[^\dX]/gi, '').split('');
 var reformedIsbn10 = "";
 for(var i=0; i&t;chars.length; i++){
  if( i == 1 || i == 5 || i == 9){
   reformedIsbn10 = reformedIsbn10 + "-";
  };
  reformedIsbn10 = reformedIsbn10 + chars[i];
 };
 return reformedIsbn10;
};


ISBN10はもうつかわれないので、
入力された場合はやはりISBN13にしてあげたほうがよいとおもい
変換する関数も作った(もとに戻す関数はつくっていない)。

やはりDBとかにはISBN13で統一して入れておいたほうが良さそうだし..

にしても..JavaScript直書きはデバッグしにくいなあ..
みんなどうやってるのかなあ..




使う場合はat your own riskでお願いします。

2014年7月28日月曜日

Vaadinの英語サイトのごく一部(Learn)を翻訳してみる

GWT.create(GWTをテーマにしたイベント、ドイツとアメリカで開催)の
ページを見ていると、Vaadinというフレームワークがよく出てくる。

どうも出自は2010年ころからでているが、日本はGWTがなぜか流行らないので情報が殆ど無い。どこぞの記事に紹介があったが3ページ目辺りで会員登録しないと見せないよっていう意地悪をされたので萎えてそのままだった。

でも、せっかくなのでイントロくらいは読んでおこうと思い、以下のページだけ翻訳してみた。

Introduction to Vaadin Development
https://vaadin.com/learn

以下私の翻訳ですが、直訳しているだけなのでとっても読みにくいです。
Yahoo翻訳よりまし程度で読んでください。
(もちろん、at your own riskで)

------

Vaadin開発へのイントロダクション


[YouTube] Vaadin Step-by-Step
https://www.youtube.com/watch?feature=player_embedded&v=KsvvF1zgMQM

この短いビデオは、Vaadin7、Vaadin Eclipse プラグイン、Apache Tomcatを使った開発のチュートリアルです。


Vaadinとは何?


Vaadinは リッチインターネットアプリケーション(RIA)のためのWebアプリケーションフレームワークです。ソリューションベースのJavaScriptライブラリやブラウザプラグインとは対照的に、Vaadinは、強力なサーバサイドプログラミングモデル、そしてGWTやHTML5ベースのクライアント再度開発ツールが特徴です。RPCやクロスブラウザ互換性、全てのレイヤをまたがったフルコントロールといった実装時の細々としたことから分離された短期開発モデルを要約します。

VaadinはUIコンポーネントの巨大な集まりです。「ボタン(http://demo.vaadin.com/sampler/#Buttons)」、「テーブル(http://demo.vaadin.com/sampler/#GridsAndTrees)」、「ツリー(http://demo.vaadin.com/sampler/#GridsAndTrees)」や「レイアウト(http://demo.vaadin.com/sampler#ComponentContainers)」といったコンポーネントからアプリケーションユーザ・インタフェイスを構築します。コンポーネントはビジネスロジックや相互にコミュニケーションをとるイベント、リスナ、データバインディングを使用します。

Vaadinは短期アプリケーション開発のための強力なアーキテクチャです。コンポーネントベースのアーキテクチャ、ならびに静的Java言語、そしてデータバインディングは、より簡単にモジュール化され必要に応じて再分解されたアプリケーション構築を支援する特徴を持ちます。「ビジュアルデザインツール(http://vaadin.com/eclipse/#visual-designer)」を含む「IDEやツール化支援(http://vaadin.com/tooling)」により、ユーザインターフェイスを高速に開発することができます。


詳細は「Vaadinの特徴(https://vaadin.com/features)」へ


Vaadinを使うと...


衝撃的なWebアプリケーション、ルックアンドフィールが違いを生む。Vaadinは素晴らしいコンポーネントや多くのカスタマイズ可能なテーマを提供します。

GWTベースのウィジェットによるブラウザ独立したウェブアプリケーション構築、Vaadinアプリケーションはリッチなユーザエクスペリエンスを提供し、かつプラグインのインストールなしですべてのモダンなブラウザをサポートします。

Vaadinを使った短期開発、数分でWebアプリケーションを作成します。数行のJavaコードだけでVaadinがのこりを世話します。複雑なXML設定なし、JavaScriptなし、RPCなし。

セキュアなWebアプリケーション、Vaadinコンポーネントを使うことで、証明されたサーバサイドアーキテクチャがアプリケーションコードをブラウザに送信しないことを保証します。

保守しやすいアプリケーション、ピュアJavaによるアプリケーション構築ががより簡単な拡張性と長期の保守性をもたらします。

オフラインかつステートレスなアプリケーション、必要に応じてブラウザ上で実行するJavaScriptへコンパイルすることで、Vaadinはクライアント側の機能をJavaで記述することを許可します。



フリーなオープンソース


VaadinはApache Software License 2.0に準拠します。これは非商用、商用プロジェクトどちらも無料であることを意味します。

ライセンスの詳細はこちら(http://vaadin.com/license


簡単なプログラミングモデル



サーバサイドJava


XML、JavaScript、ブラウザ、RPCについては忘れなさい、サーバサイドJavaコードが動作します。この分離はVaadinがGWTのようなクライアント中心のJavaフレームワークであることを示しています。

クライアントサイドJava


新たなユーザインターフェイスコンポーネントを構築するため、あるいはオフラインのアプリケーションを構築するためのHTML5、JavaScript、GWTを使用している拡張されたクライアントサイドVaadin。

コード例


 Hello World - 伝統的な例
  HelloWorld.java(http://demo.vaadin.com/docs/example-source/com/vaadin/demo/HelloWorld.java.html
  アプリの実行(http://demo.vaadin.com/HelloWorld
 Calculator - 単純なイベントハンドリング&ロジック
  Calc.java(http://demo.vaadin.com/docs/example-source/com/vaadin/demo/Calc.java.html
  アプリの実行(http://demo.vaadin.com/Calc
 Addressbook Tutorial – アノテートされたアプリの例
    vaadin.com/tutorial(https://vaadin.com/tutorial



Vaadin アーキテクチャ


どのようにしてVaadinが動作するか、そして異なるプラットフォームやほかのフレームワークと統合しているかを見てください。
https://vaadin.com/image/image_gallery?uuid=453a301a-798c-4daf-aea7-3fd115c0d88a&groupId=10187&t=1349442259604
詳細なアーキテクチャはBook of Vaadinにかかれています。

・Vaadin Introduction(https://vaadin.com/book/-/page/intro.html#intro.overview
・Application Architecure(https://vaadin.com/book/-/page/application.html)
・Communication Architecture(https://vaadin.com/book/-/page/architecture.client-side.html



ブラウザ独立


Vaadinはブラウザ互換性問題を引き離し、アプリケーションの開発に集中させてくれます。すべてのVaadinコンポーネントは以下のブラウザと互換性があります。

・Internet Explorer
・Mozilla Firefox
・Safari
・Opera
・Google Chrome


完全互換性情報はこちら(https://vaadin.com/features


ブラウザプラグイン不要


VaadinはGWT、JavaScriptベースなのでエンドユーザにプラグインのインストールを要求しません。


フレームワーク比較


VaadinとほかのJava Web フレームワークのサイドバイサイドな比較。
「フレームワーク比較(https://vaadin.com/comparison)」へ進んでください。


------
ビデオはまだ見ていないが、わかったことはGWTベースのフレームワークでUIのデザインツールなんかがあって短期開発アプリ向けだということ。

Apache2.0準拠のオープンソースであることはわかった。

数行のJavaコードでWebアプリつくれまっせ..っていうのは眉唾だなあ..やっぱり画面の作り方がどれだけ簡単かみてみないとなあ..


というかGWT関連の記事ってことごとくPVが一回り桁数少ないんだよなあ..
日本のGWTユーザはレッドコード扱いになっているのかもしれないなあ..

2014年7月10日木曜日

【解決しました】Proxy環境だとIBM BlueMix Tools EclipseプラグインからBlueMixサイトへ繋がらない




IBM BlueMixのハンズオンへ行ってきた人の資料を借りて
とりあえずデプロイするところまでためそうとしたのだけど..

プラグインをマーケットプレイスからインストールした後
サーバにあらかじめBlueMix上に作ったサーバを登録しようと
サーバタブ選択→右クリック「新規」>「サーバ」>「IBM: IBMBlueMix」
を実行、サーバを作ったアカウントのメールアドレスとパスワードを入れて
Validate Account」ボタンを押したら

Unable to communicate with server - I/O error on GET request for "https://api.ng.bluemix.net/info": api.ng.bluemix.net; nested exception is java.net.UnknownHostException: api.ng.bluemix.net





というエラーが出た。

ブラウザから「https://api.ng.bluemix.net/info」をたたくと

{"name":"BlueMix","build":"169001","support":"http://ibm.com","version":2,"description":"IBM BlueMix","authorization_endpoint":"https://login.ng.bluemix.net/UAALoginServerWAR","token_endpoint":"http://uaa.ng.bluemix.net","allow_debug":true}

上記のJSONデータが帰ってくる..

..ので見れないわけないんだけど..


で例によってプロクシかな..とおもい
プロクシではない環境で実行したら
すんなり次へ行った..


Cloud Foundry(MicroCloudFoundry)やOpenShift(LiveCD)はローカルの仮想環境イメージも提供しているので
BlueMixにもあるかと探したけど..ない..

検索力がないから見つからないのかもしれないけど..


IBMのサービスだから企業向けかと思ったけど..

企業なんかProxy前提の環境ばかりなのに
こんなんじゃ使い物にならないよ...

どのポート使ってるのか調べようかと思ったけど
たぶんPivotalみたいにMCFにかわるイメージをくばるんじゃないかなとおもい
諦めました..


だれか、プロクシ経由でもBlueMix上のサーバへデプロイできる環境作れたら
教えてください..



《2014/10/07追記》
実は、
IBMの担当者に聞いて"proxy経由で接続できる" との回答をもらった人がいて、
あきらめず再度試してみました。

どうも、
ウィンドウ>設定>一般>ネットワーク接続 で、
ネイティブ」設定でやっていると失敗するようで、
ここを「マニュアル」にしてプロクシサーバやポートなどをEclipse上に直接設定したら
うまくつながりました。

なんかβ版もでているようなので
最新のプラグインでは治っているかもしれませんが..


マーケットプレイスつながるんだから、
「ネイティブ」設定で全然大丈夫だったのに..


ハマった人、ご注意ください。

2013年12月11日水曜日

CloudStack4.2.0用の簡単なUIプラグインを作ってみる

※本投稿は、CloudStack Advent Calendar 12月11日のエントリです。


CloudStack4.2.0から管理サーバのWeb UIに対してプラグインが作れる
ようになった。
リリースノートにはUIプラグインの作り方については
詳しくはDeveloper Guideを読んでね」と書いてあった。

しかしDeveloper Guideが4.2.0リリースされて1ヶ月以上経つのに
ちっともでてこない..

なので、自分でちょっと管理サーバのWebコンテンツ内を
覗いてみることにした。

管理サーバのWebコンテンツディレクトリ内には

/usr/share/cloudstack-management/webapps

が管理サーバWeb UIのコンテンツが入っている。

更に下の

/usr/share/cloudstack-management/webapps/client/plugins

というディレクトリをみてみると、
plugins.jstestPluginディレクトリがおいてあった。


plugins.js上のcloudstack.plugins
プラグイン名を入れれば、
その名前のディレクトリ上のJavaScriptを読んでくれそうだな
と直感的にわかれよ、ということらしい。

むかしCloudStackのAPIを呼び出すURL文字列を作成する
AppEngineアプリ

CloudStack API Creator
https://cloudstacktools.appspot.com/

CloudStack API Creatorサイト作成に関する投稿
http://fight-tsk.blogspot.jp/2013/03/cloudstack-apiurl.html

を作ったのでこれをなんちゃってプラグインにしてみることにした。




まずプラグインIDを決める(apiUrlCreatorにした)。

そして、

/usr/share/cloudstack-management/webapps/client/plugins/plugins.js



    (function($, cloudStack) {
      cloudStack.plugins = [
         'testPlugin',
         'apiUrlCreator'
      ];
    }(jQuery, cloudStack));


と書き換え、

testPluginディレクトリを丸々

/usr/share/cloudstack-management/webapps/client/plugins/

ディレクトリ下にプラグインIDとおなじディレクトをつくってコピーして

/usr/share/cloudstack-management/webapps/client/plugins/apiUrlCreator
/usr/share/cloudstack-management/webapps/client/plugins/apiUrlCreator/apiUrlCreator.js
 
(testPlugin.jsをリネーム)
/usr/share/cloudstack-management/webapps/client/plugins/apiUrlCreator/apiUrlCreator.css (testPlugin.cssをリネーム)
/usr/share/cloudstack-management/webapps/client/plugins/apiUrlCreator/config.js
/usr/share/cloudstack-management/webapps/client/plugins/apiUrlCreator/icon.png


を作成し(念のためroot.rootで同じパーミッションにしておき)、

cofig.js は以下のソースに書き換え、

(function (cloudStack) {
  cloudStack.plugins.apiUrlCreator.config = {
    title: 'API URL String creator Plugin',
    desc: 'To create URL string with CloudStack API',
    externalLink: 'http://fight-tsk.blogspot.jp/',
    authorName: 'Hara Hara Development',
    authorEmail: 'SammoHungGambou@gmail.com'
  };
}(cloudStack));

apiUrlCreator.jsも以下のソースに書き換え、

(function (cloudStack) {
  cloudStack.plugins.apiUrlCreator = function(plugin) {
    plugin.ui.addSection({
      id: 'apiUrlCreator',
      title: 'API URL Creator',
      preFilter: function(args) {
        return true;//isAdmin();
      },      show: function() {
        return $('<div>').css('width', '100%').css('height', '700px').css('overflow', 'auto').html('<iframe height="98%" width="100%" src="https://cloudstacktools.appspot.com/" />');
      }
    });
  };
}(cloudStack));

最後に

service cloudstack-management restartをかけて
管理サーバWeb UIを使って一般ユーザ(ロールがuser)でログインすると..

左下に「プラグイン」と「API URL Creator」ってのができた。





以下の画面スナップは「プラグイン」を押下したところ。
現時点で有効なプラグイン情報が表示されていて、
今回作成した「API URL String creator plugin」も表示されている。




「API URL String Creator Plugin」を選択すると、
config.jsに書いた詳細情報がでてくる。




次に左側のメニューの一番下の「API URL Creator」の方をクリックすると
以下のスナップのようにGoogle App Engine上のWebサイトが表示される。



高さがあふれたのはご愛嬌..


apiUrlCreator.jspreFilterで常にtrueを返すようにすれば
一般ユーザも見えるプラグインになる。

<プラグインID>.js というファイルのshow部分
divタグにhtmlを埋め込むサンプルコード部分)を、
うまく書き換えてやれば複雑なプログラムも組むことができる。

DOM対象となる実際のHTMLファイルのdivタグにidが振られていないので
jQueryの呼び出しをそのまま使った。
#一つ上にid=shadowというdivタグがあって
#こっちを操作してやろうとしたらうまく行かなかった

UIプラグイン作成の鍵はCloudStack側が用意している
plugin.ui.addSessionというJavaScript関数。

この使い方のドキュメントがあればもっといろいろできるのに..


今回プラグイン関連ファイルをさわっているうちに
iframeが使えるがわかったので
前に作ったApp Engineサイトを流用したが、
同じコンテンツ内にServlet/JSPなりを書いてアプリを組む
なんてことも可能だろう。


CloudStackはAPIがREST通信なので同じサーバでなくてももちろん可能だが、
どうせならログイン中のユーザIDの権限でAPI操作できるような
JavaScriptを組みたい。



にしても..最近はJavaScriptを直接書く技術が必要なケースが増えてきた。
jQueryとかいちいちGoogleって書いていると生産性が悪いし..




企業内でCloudStackを使用する場合、
足りないのは利用などの申請系のワークフローと
課金機能なんだけど..

..誰か作ってくれんかなあ..

2013年11月12日火曜日

ガラポンTVを使ってみる

前から気になっていたガラポンTVを購入した。


ガラポンTVは、
ワンセグ局全局を内蔵もしくは外付けHDDへ記録するサーバで
価格は最近はだいたい約4万円前後で販売されている。

Regzaサーバは地デジを記録するので内蔵4TBでせいぜい1週間が
いいところだが、このガラポンTVはワンセグなので
画像は荒くはなるが記録する時間は内蔵ストレージだけで2週間、
3TB HDDを増設すれば90日間録画することができる。

Regzaサーバは同一セグメント内で他デバイスで再生可能であるのに対し、
ガラポンTVはユニバーサルプラグアンドプレイ対応のルータを使っていれば
外部のインターネット回線経由で再生が可能である。
但し特殊なポートを通信に使用しているため、
プロクシ経由での視聴はポートフォワーディングなどを行わない限りできない。

ルータのWAN側がグローバルIPアドレスであれば、
DHCPでの割り当てであっても屋外からも視聴できる。

どうもガラポンTVがIPアドレス変更を認識すると
ガラポンTVサイトへ変更されたことを伝達するしくみになっているらしい。

なので
屋外から視聴する場合は一旦ガラポンTVサイトへログインしてから
自宅のガラポンTVへ接続するので、
DHCPであっても受信可能なのだとおもう。


Regzaは画像品質重視であるのに対して
ガラポンTVは記録期間重視で
iPhoneやAndroidなどのスマートフォン、
iPadなどのデバイスでも視聴可能だ。
#無料の専用アプリが用意されている


私の自宅はインターネットマンションで
ユニバーサルプラグアンドプレイ対応のルータ経由で
使用しているが、
こんな環境であっても屋外からLTE回線で
iPhoneでTVを見ることができる。




自宅では無線LANで同一セグメントにつないでいたiPad経由で設定を行ったが
ルータの設定変更などややこしいルーティング関連の設定は自動だった。
#ユニバーサルプラグアンドプレイでないルータとか一部のルータは
#個別せってし無くてはならない

時間も30分くらいかな。
#一番長いのがワンセグのチャンネル検索だったがそのほかはほとんど時間がかからなかった。
必要なのは同軸ケーブルとLANケーブル(両方同梱されていない)。




国内の動画サイトは海外からの利用が不可な場合が多いが
このガラポンTVを使えば海外常駐者でもブロードバンド環境さえあれば
いつでも日本のTVを視聴することができる、というのが宣伝文句だ。

でもインドに半年いたけど
国内にあるサーバまでは距離が遠すぎて
回線速度が確保できなかった。
ニコニコ動画は当時国内サーバしかなかったので
ぶつぶつきれてしまいほぼ使い物にならず
もっぱらyoutubeへアップされた番組をちょこちょこみていた。

回線品質の良い国なら使い物になるかな..
くらいで思っていたほうが良いと思う。



本音を言えばストレージをクラウド上においてほしいところなのだけど、
たぶんTV業界の既得権益ホルダーな人たちがやいのやいのいうから
できないのだとおもう。
もしそうなっちゃったら
「TVの電波、いらないんじゃないの?」ってなっちゃうからね。

..生きてる間は難しそうだなあ..

【ハーネスエンジニアリングを始める前に】gpt-oss:20b の入出力データから、LLMの動作を理解する

  1. はじめに 最近は、 Cursor や Antigravity などのAIエージェント前提の統合開発環境や、 Claude Desktop や Codex アプリ などのPC上のオブジェクト操作が可能なデスクトップアプリ、 Open Claw といったPC全体の...