https://naba-san.hatenablog.com/


NEC VersaPro J タイプVS+ウルトラブック プロ キーボード=?

ここに去年3万5千円でポチった*1NECタブレットがあるじゃろ。


ここに3万円でポチった、ThinkPad Helix ウルトラブック プロ キーボードがあるじゃろ。


これと


これを


こうして


こうじゃ!!


【補足】ひっくり返して装着すると…

スタンドモード、テントモードにもなります。まさにYOGA。


装着したままタブレットモードでも利用可能。クラムシェルモードの時、画面が狭いのと、重心が高い事が気になるくらい。

安く入手できるなら、買っておいても悪くないと思います。

製品情報とか

http://www.bizpc.nec.co.jp/pcseek/cgi-bin/cpu_smart.pl?KATA=PC-VK12CSKE56FK
http://amzn.to/2pIakPO

http://akiba-pc.watch.impress.co.jp/docs/wakiba/find/1027916.html
http://akiba-pc.watch.impress.co.jp/docs/wakiba/find/1029376.html

  • ThinkPad Helix ウルトラブック プロ キーボード - 日本語 (4X30G93920)

http://www3.lenovo.com/jp/ja/p/4X30G93920
http://amzn.to/2pHJDe7

独り言

あきばおー通販でタブレット買ってから、ここに至るまで、フォリオラップケースとか、2台目の ThinkPad ワイヤレス トラックパッド キーボードとか、色々買い込みました。

総額は結構な出費になってしまってます…

Bay-Trail M Atomの中華PCにUbuntu 16.04(.2)をインストールしました

使い慣れるのでCentOS入れたかったんですが、そのままではKernelがemmc諸々に対応してくれないとの事なので断念。

Ubuntu LTSを下地に、DockerなりKVMなり(動くのか?)何なり使えばいいかと割り切りつつ、Ubuntu Server入れてみました。

方針

メンテナンスが必要なものは増やしたくない*1

  • インストール後の環境へバイナリを差し込まない。
  • 同様に、カーネルビルドは極力避ける。

準備したもの

現物
  • 中華PC

Bay-Trail M なAtomを搭載した3735Fマシン。所謂32bit EFI

まだ円安だった頃に、1万円くらいで買ったやつ。今回、ジャンク箱の奥底から発掘してきました。

FAT32でフォーマットしておく。

インストーラの準備
  • Ubuntu 16.04.2 LTS (Xenial Xerus)

公式 または ftp.riken.jp から、「64-bit PC (AMD64) server install image」(ubuntu-16.04.2-server-amd64.iso)
ISOの中身を展開し、そのままUSBメモリにコピーする。

  • USB起動に使う、EFI GRUBイメージ

bootia32.efi (jfwells - github)
保存した bootia32.efi を、USBメモリの /BOOT/EFI/ へ配置する。

これでインストーラUSBメモリの準備はOK。

インストール手順

インストーラ起動からインストール完了まで

SecureBootを切った状態でUSBメモリ起動。

幾つかの問題点を避けつつ、一通りインストール。

一通りインストールが終わった時、GRUBの設定でコケました。この時点ではIA32 EFIに対応しないようです。

GRUBの手動設定か何かを選び、ガイドインストーラを抜け、インストールの完了操作を行いました。
(LVMルートを示すデバイスパスが表示されるので、予め控えておきます。)

USBメモリから対象環境起動

再度インストーラを入れたUSBを起動し、インストール済みの環境を立ち上げます。

  • GRUBの起動メニューで「c」キーを押下
  • コマンドを叩いて環境起動

ls (hd1,gpt2)
linux (hd1,gpt2)/vmlinuz-4.4.0-62-generic root=【控えておいたデバイスパス(「/dev/mapper/」で始まるやつ)】
initrd (hd1,gpt2)/initrd.img-4.4.0-62-generic
boot

※ hd1, gpt2は、LVMとは別に切られたbootパスを指定するように、適宜に読み替えて下さい。
※ デバイスパーティション「(hd1,gpt2)」等を指定した後は、tab補完が効きます。

これでインストール済みの環境が起動しました。

(番外編)ネットワーク接続(NIC)の追加、設定

今回の中華PCは、小型PCなので有線NICを搭載しておらず、インストール完了後にUSB NICを追加しました。

少し手間取りましたが、以下の手順でNICを確認し、認識させました。

  • まずはインタフェース名を確認

# lshw -C network

  *-network
       description: Ethernet interface
       physical id: 1
       bus info: usb@1:2.4
       logical name: enx0090******** (控えておく)
       serial: 00:90:**:**:**:**
       size: 1Gbit/s
       capacity: 1Gbit/s
       capabilities: ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=ax88179_178a duplex=full ip=**.***.*.*** link=yes multicast=yes port=MII speed=1Gbit/s
  • 続けて設定追加

# vim /etc/network/interfaces

auto enx0090********
iface enx0090******** inet dhcp

# ifdown enx0090********
# ifup enx0090********

  • 無事疎通

# ping 8.8.8.8

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=47 time=37.7 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=47 time=37.7 ms

これで apt-get できるようになりました!

EFI環境へのGRUBインストール
  • IA32 EFI GRUBはaptで入手できました。

# apt-get install grub-efi-ia32

# grub-install --efi-directory=/boot/efi

Installing for i386-efi platform.
Installation finished. No error reported.

※ 他のイメージを間違えて削除しないように注意。

  • GRUBの設定は、修正が必要でしたので、下記の通り書き換えます。

# vim /etc/default/grub

#GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX_DEFAULT=""

※ splash オプションが邪魔でした。quiet は、あってもなくても良さそうです。
※ nomodeset の設定が必要というページを散見しましたが、これも設定有無にかかわらず起動しました。

  • GRUB の設定内容を反映します。

# update-grub

Generating grub configuration file ...
Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.
Found linux image: /boot/vmlinuz-4.4.0-62-generic
Found initrd image: /boot/initrd.img-4.4.0-62-generic
Adding boot menu entry for EFI firmware configuration
done
  • (蛇足)EFIの設定状況確認

# efibootmgr

BootCurrent: 0000
Timeout: 5 seconds
BootOrder: 0000,0003,0001,0002,0004
Boot0000* ubuntu
Boot0001* UEFI:CD/DVD Drive
Boot0002* UEFI:Removable Device
Boot0003  UEFI: Built-in EFI Shell
Boot0004* UEFI:Network Device
  • 再起動して動作を確認

# shutdown -r now

EFI上で、起動順が正しく設定されているか確認する。

一通りの作業を終えて、とりあえず起動するようになりました。

*1:NonPAEの時、後々の運用が面倒だったので

*2:たぶんmmcのブロックに異常があって、LVMだからすんなり進んだ?

Servlet環境構築時の用語メモ

Struts1/Struts2のお仕事受けたのはいいけど、まじめにサーブレット環境構築した事なんてないぞ・・

とりあえず用語を並べてみる。設定ファイル大杉。。

Servlet

Javaを使ったサーバサイド処理の仕組みを決めた仕様。エンジンの実装は別で存在する。

コンテキスト

サーブレットエンジン上で動作させる、アプリケーションの単位のこと。
サーブレットエンジン(Tomcat)上では、複数のアプリケーションを同時に起動できる。
このとき、アプリケーション毎にセッションや設定(URLの解決等)を行っており、「コンテキスト」として管理する。

コンテキストルート

アプリケーションのルートに当たるディレクトリパス、またはそれに紐づくURL。

web.xml / デプロイメント ディスクリプタ(配置記述子)

サーブレットエンジンがコンテキストを初期化する際に必要となる、基本設定を書くところ。

Tomcat の場合、コンテキストルート内の /WEB-INF/web.xml に配置されたファイルを参照する。
※ デプロイメント ディスクリプタ自体は、Servlet の標準に則って配置するもの。

URLと各クラスのマッピング、メッセージ画面の定義などを記述する。
新しい画面を作成する場合、原則として編集が必要となる(または、WebServlet アノテーションでURLパターンを記述する)。

他にフレームワークを組み合わせる場合、ここでフレームワークの指定クラスを全URLパターンに紐づけたりする事も。

WEB-INF, META-INF

Servlet 上、クライアントから見せないディレクトリ。
設定ファイルなどを配置する場合、原則としてここに置く。

JVMの動作に必要なものは、原則として WEB-INF 以下に配置する。

[WEB-INF/classes] : コンパイル済み class ファイル (プロパティもここに配置する)
[WEB-INF/lib] 参照ライブラリ(jar)

Tomcat

言わずと知れたサーブレットエンジン。
Tomcatのバージョンにより、準拠しているServletのバージョンが異なる。

server.xml

Tomcat固有のサーバ環境設定ファイル。

原則として、Tomcat の環境毎に1つのみ存在し、待機ポートの指定、読み込むコンテキストなどを記述する。
コネクションプールを利用する場合、ここで Resource 要素を使ってDB資源を記述する。

※ 特定コンテキストのみに紐づく設定は、context.xml としてデプロイ対象に含めることが可能(Tomcat 5.5辺りから)。

context.xml

server.xml 同様、これも Tomcat 固有の設定ファイル。
/META-INF/context.xml に配置されたファイルを参照する。

server.xml から、 要素の中身をデプロイ対象のアプリケーションに吐き出したもの。
つまり対象アプリケーション(コンテキスト)固有の Tomcat に対する設定があれば、ここに書く。
(共用環境などでは、server.xml 側で許可されていない事もあるらしい。)

コネクションプールで使用するDB資源も、ここに記述可能。

Eclipse

ここもいろいろハマった。

動的Webプロジェクト

Tomcat と連携させた場合、プロジェクト名がそのままコンテキスト名になる。

WebContent/

Eclipseの動的Web プロジェクトを扱う場合のみ、ドキュメント ルートとなるディレクトリ(初期設定でそのようになっているだけ)。

デプロイの設定

プロジェクトのプロパティから「Web デプロイメント・アセンブリー」で変更可能。

動的にビルドされた、Tomcat が実際に利用するファイルは、
「workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps」
等に展開されるので、設定する際はココと突き合わせるとよい。(多少パスは変わるはず)

Windows 10 Pro向けのWindows Updateグループポリシー設定メモ

自動再起動させたくないので。

コンピュータの構成 > 管理用テンプレート > Windows コンポーネント > Windows Update

自動更新を有効にする
  • 有効
  • 自動更新の構成 : 2 - ダウンロードとインストールを通知
スケジュールされた時刻に常に自動的に更新する
  • 無効
スケジュールされた自動更新のインストールで、ログインしているユーザがいる場合には自動的に更新しない
  • 有効

SELinux扱うときの参考になるページ

Red Hat系をメインに、よさげな記事を備忘録として。(RedHatの資料読みづらい。。)

Qiita

SELinuxのせいで動かない」撲滅ガイド

SELinuxとのお付き合いで知っておくべき指針がまとまってる。考えれてみれば、言うまでもない事も多いけど。
http://qiita.com/yunano/items/857ab36faa0d695573dd

JavaScript 連想配列(オブジェクト)ツリーに対する複合キーのサンプル

単純な話ですが、データ取得にハマったので、備忘録としてサンプルをメモしておきます。

サンプルデータ

var testMap =({
  "depth1-a": {
    "depth2-a": {
        "depth3-x": "1",
        "depth3-y": "2"
    },
    "depth2-b": {
        "depth3-z": "3"
    }
  },
  "depth1-b": "depth1-value"
});

普通に取得しようとすると‥

こんな具合になります。(こうですよね?)

実行結果(正常ケース)
console.log(testMap["depth1-a"]["depth2-a"]["depth3-x"]);
1
実行結果(深さ違い、キー不一致)
console.log(testMap["depth1-b"]["depth2-a"]["depth3-x"]);
VM1132:1 Uncaught TypeError: Cannot read property 'depth3-x' of undefined(…)
実行結果(キー不一致)
console.log(testMap["depth1-X"]["depth2-a"]["depth3-x"]);
VM1133:1 Uncaught TypeError: Cannot read property 'depth2-a' of undefined(…)

内包オブジェクトの深さが異なる、または一部のキーが一致しない場合、途中にundefinedを挟むケースが生じる為、例外が発生して都合が悪いです。

深さに関係なく、一律にundefinedが帰ってくると嬉しいなーと。

探し方が悪いのか、良いサンプルが見つからないので書いてみた。

function getValue(map, keyArray) {
  for (var i = 0; i < keyArray.length; i++) {
    var key = keyArray[i];
    map= map[key];
    if(map == undefined) {
      return undefined;
    }
  }
  return map;
};
実行結果(正常ケース)
getValue(testMap, ["depth1-a","depth2-a","depth3-x"]);
"1"
getValue(testMap, ["depth1-a","depth2-b","depth3-z"]);
"3"
実行結果(異常ケース)
getValue(testMap, ["depth1-b","depth2-a","depth3-x"]);
undefined
getValue(testMap, ["depth1-X","depth2-a","depth3-x"]);
undefined

【Java クローラ】robots.txt食べてみた

bot動かすならrobots.txtも残さず食べましょう。

Javaから(直接的にでも間接的にでも)利用して動かせるものを探して彷徨いました。

Crawler-Commons

探すとGoogle codeとかGitHubとかで公開されてるJava用のライブラリ。
jarはMVN Repositoryから入手可能ですが、なぜかGoogle code時代のやつとGitHub時代のやつが別々に登録されてます。

ライブラリはcommons-io 2.4httpclient 4.3.5tika-core 1.8slf4j-api 1.7.7/nop 1.7.7で一通り動きました。

BaseRobotsParser parser = new SimpleRobotRulesParser();

String url = "http://www.hatena.ne.jp/robots.txt";
String robotsText = "User-Agent: *\r\n"+
	"Disallow: /prof/search\r\n"+
	"Disallow: /mobile/prof/search\r\n"+
	"Disallow: /faq/report/\r\n"+
	"Disallow: /api/\r\n"+
	"Disallow: /mobile/easylogin\r\n"+
	"Disallow: /hatenatypered\r\n";

String mime = "text/html";
String robotName = "oreoreBot";

BaseRobotRules rules = parser.parseContent(url, robotsText.getBytes(), mime, robotName);

// おk
System.out.println(rules.isAllowed("http://www.hatena.ne.jp/"));

// ダメー
System.out.println(rules.isAllowed("http://www.hatena.ne.jp/mobile/easylogin/"));

// ダメー?
System.out.println(rules.isAllowed("https://www.hatena.ne.jp/mobile/easylogin/"));

実行結果

true
false
false

robots.txtは素のHTTPですが、テストコードの3件目はhttpsでもDisallowに引っかかってますね。
サンプルの状態ではスキーマをうまく認識してない?(ちゃんとソース読んでないけど、そもそも区別してない?)

とりあえず動かすところまでは確認。最低限動いてるかな?

他の候補とか

気が向いたら試してみたいやつとか、そうじゃないやつとか。

RobotParser (Python 2.7)

Python 2.7 標準ライブラリに含まれるrobot parser。

Pythonド素人ですがが、WindowsPython入れて、EclipseにPyDev組み合わせてデバッグモードで立ち上げる所までは持っていけました。

第一関門、プロキシの越え方がわからない。諦めて手元に置いたファイルを食わせ、外からクラス内の値を直接触る強硬手段に出る。

第二関門、エントリーの適用順がおかしい。プロキシ越えらない都合上、#set_url とか #read を馬鹿正直に叩けないので、代替処理をクラスの外から呼び出してました。
そのせいなのか、サンプルのrobots.txtがよろしくないのか分かりませんが、対象パスをdisallow→allowの順に解釈してしまう現象に悩まされ(拒否られてないはずなのに拒否判定され)、うまく動かず。

Javaからの(コンソール経由での)制御諸々にも難点があり、内部処理のデバッグも程々にして利用を諦めました。

WWW-RobotRules-Extended

Perlで動くパーサで、CPANからモジュールとして入手可能とのこと。

Pythonと同じ問題が付きまといそうなのと、あまりシステム汚したくなかったので今回はパス。

jrobotx

同じjava向けのライブラリで、GitHubから入手可能。ずっと更新されてないので今回は見送り。