Tag: Kubernetes
自宅のKubernetesサーバ用にメモリがたくさんほしい
おうちでKubernetesクラスタを作って動かしているとメモリがたくさん欲しくなります。
あるアプリケーションを動かしたいというような場合にKubernetes流にやろうとすると便利な管理機能も一緒に動かすのでリソース的にはオーバーヘッドがあります。冗長構成のためのオーバーヘッドや監視や管理のためのオーバーヘッドなどがあります。
そういうものをなるべく使わないようにすることもできますが、それはそれで面倒ですし、それらを使うのは勉強の観点からも必要です。
そういうわけで、あれもこれもやろうとするとどんどんメモリが欲しくなります。 足りないとOOM-Killerが発動してしまってこれも面倒なのでなんとかしたいものです。
Infrastructure as Code関連の書籍紹介(GWアドベントカレンダー 6日目)
この記事はGWアドベントカレンダーの6日目の記事です。
IaCに関連する最近読んだ本の紹介です。 読んだ順に書いていますが、Ansible実践ガイドはまだ記事を書いていないのでここで簡単に紹介します。 Ansible を自由に利用できるようになるための基礎が幅広く記載されています。そのため、「インフラCI 実践ガイド」にもAnsibleが使われていますが、この内容を理解するのにも役立ちました。 また、これから新規にプレイブックを作るときの設計のポイントも記載されています。 Linuxサーバ向けだけでなく、Windowsやネットワーク機器向けの設定についても記載されており、これらを理解することでAnsibleのエコシステムや思想の理解が深まり様々な応用ができるようになります。
- 「Infrastructure as Code」
- 「しくみがわかるKubernetes」
- 「インフラCI 実践ガイド」
- Ansible 実践ガイド 第3版
PC上でのIaC環境の概要(GWアドベントカレンダー 4日目)
この記事はGWアドベントカレンダーの4日目の記事です。
自宅のPCにIaC環境を構築中ですが、その環境について少し説明します。
使用するツール
1台の物理Linuxサーバ上にすべての環境を構築します。 仮想マシンはVagrant + Virtual Boxで構築します。 コンテナはDockerで構築します。 構築ツールとしてAnsibleを使います。 CI/CDを実現するためのツールとしてGitlab、Gitlab Runnerを使います。
Gitlab、Gitlab Runnerの構築
GitlabとGitlab RunnerはAnsibleを使って、仮想マシンから作成します。 本番用とテスト用があり、テスト用の構築は本番用のGitlabのバックアップデータを使ってリストアすることで本番と同じデータを持つようにしています。
物理Linuxサーバの構築
OSインストール後の各種設定類はAnsibleにまとめようと思っていますが、まだできていません。
AnsibleとVagrantの連携
Ansibleのプレイブック(Gitlabのパイプラインからの呼び出しや手動実行)によって、Vagrant経由で仮想マシンを作成することがあります。 しかし、AnsibleのInventory PluginとしてはVagrant用のものが正式にはありません。そのため、作成した仮想マシンに対してプレイブックを実行するためには何らかの方法を考える必要があります。 一つはInventory PluginもしくはScriptを作ること、もう一つは作成する仮想マシン情報をあらかじめインベントリファイルに記載しておくことが考えられます。 どちらの方法でも実現できそうですが、どのようにするか検討中です。
今後の展望
- 物理Linuxサーバ構築用のパイプライン構築
- Kubernetesを動かす。 その上で、各種アプリケーションを動かす予定です。
「しくみがわかるKubernetes」を読んだ。
「しくみがわかるKubernetes」を読みました。
ほんとに仕組みがわかった気になりました。 これまでminikubeでhello worldをやっただけの経験でしたが、kubernetesがどういう仕組みになっているかの全体像を掴むことができました。
この本ではDockerなどのコンテナそのものについての説明はほとんどありません。
コンテナそのものを知らないとそもそもkubernetesの良さもわからないかもしれませんが、
この本で説明しているのはコンテナの管理をするkubernetesの仕組みです。 コンテナがどのような仕組みのものなのか、コンテナイメージはどのように作るのかというようなことは知らなくても読み進めることができると思います。
しくみを説明する本ですので、kubernetsの全体像としてどのようなコンポーネントで構成されているのかや、それぞれのコンポーネントの役割が説明されています。
また、Infrastructure as Codeの観点から、すべての定義をファイルに残すべきということも随所で述べてあります。
本文中に登場する定義ファイルはダウンロードできるようになっており、実際に試すことも可能です。
読者自身が実機で試す際も、細かな定義はすべてファイルに記載されているので、実際に打つコマンドはそれを適用するためのコマンドばかりです。
Kubernetesの環境を自分で構築するのは大変ですが、Azureで提供されているAKS(Azure Kebernetes Service)を使うことで簡単に利用を開始できます。
提供されているサンプルコードもAKS向けのものとなっているので、手軽に動作確認ができるようになっています。
この本ではKubernetesの主要コンポーネントの紹介と構成検討のポイントなどが述べられています。
含まれていないのは構築手順やオプションのコンポーネント等です。
例えば、ネットワークやストレージのコンポーネントについてはあまり説明がありません。
そのため、この本だけを見て自分でKubernetesを構築したいという方には向きませんが、クラウド上のマネージドサービスとしてKubernetesを使いたいという人には向いていると思います。
自分で環境を構築したいという人でも、この本を読むことで全体像がイメージできるようになりますので、具体的な検討へのステップとしては有効と思います。
Tag: Android
Unable to find Gradle tasks to build [:app] build mode ASSEMBLE
Android Studio Koala 2024.1.1 Canary 4で、Run ‘app’としたら、以下のメッセージが出てビルドできない事象が発生した。 特に何も変更した覚えがないので、Build CleanしてMakeしたらまたBuildできるようになりました。 Unable to find Gradle tasks to build [:app] build mode ASSEMBLE
W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
Google Map SDKを使ったAndroidアプリを作っていて、以下の警告が出た場合の対処について紹介します。
このエラーが出る場合は地図のコントロールの表示はあっても地図そのものが表示されない状態になりました。
W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
stackoverflowの記事ではエミュレータを再作成する案が載っていましたが、エミュレータをCold Bootしたところ直りました。
結局原因がなんなのかわかりませんが、とりあえずCold Bootしてみるのは一つの手かもしれません。
Android Developersサイトの歩き方 2022
Androidアプリを作成するのに公式ドキュメントを参照しますが、どこにどんなことが書いてあるのかや、初心者が知っておくと良いかもしれないことについて書きます。
場合により記事公開後にも修正や加筆するかもしれません。
公式サイト
公式サイトは以下です。 基本的にすべてのリンクは日本語(向け)ページになっています。
画面上部(PCの場合)にプラットフォーム、Android Studio、Google Play、Jetpack、Kotlin、ドキュメント、ニュースとあります。
よく見ることになるのはドキュメントだと思います。
ドキュメント
では、さっそく見ていきましょう。
勉強の中心になるのは「ドキュメント」の中でも、「ガイド」というところです。
ここには「アプリの基本」から始まり、多様な内容について説明があります。
初心者が見て理解できるかはさておき、理解しておくべき概念から実際のコードまで一通り記載されていると思います。
「アプリの基本」と「主要トピック」を見るとなんとなくアプリの全体像がわかってくるんじゃないかと思います。
ちなみにアプリを公開しようという段階になるとここの説明だけだと足りずほかのところも見ることになると思います。
また、ここにないライブラリを使おうと思ったりすると別のところを見る必要が出てきます。
GoogleのライブラリのGoogle Map SDKとかFirebaseとか。ほかにも色々。
アプリの基本
Hello World的な感じでなんとなくの全体像をつかめれば良いと思います。 色々わかってくると後で戻って読むことになるとも思いますが、まずはなんとなくわかれば十分かと思います。
主要トピック
主要トピックは、アクティビティの概要から始まります。
ここは重要な概念の説明が多く説明されているので理解すべきですが、最初は理解できないと思います。 なんとなくの用語がわかるようになればまずは良いような気がします。
フラグメント
とても重要な用語、概念のフラグメントは、「アクティビティの概要」の中の一節となっているのでフラグメントを探すときはアクティビティのところを探しましょう。
ちなみになぜか日本語化されていないドキュメントが多いです。重要なのに。
Android アーキテクチャ コンポーネント
これはJetpackの一部ということになっています。
Android デベロッパーのトップレベルに「Jetpack」というのがありましたが、それです。
比較的新しいライブラリ群のことです。基本的にこれを使いましょう。
以下の項目はここにありますが、これらがアーキテクチャ コンポーネントだと知らないとわからないので難しいです。
- DataStore
- ビューバインディング
- データバインディング
- ライフサイクル(Lifecycleライブラリ、クラス)
- LiveData
- ViewModel
- Work Manager
- ページングライブラリ など
Navigation コンポーネント
これも比較的新しいライブラリです。
フラグメントのところでFragment Managerの使い方が紹介されていますが、これをラップしてくれるライブラリなのでこちらを使いましょう。
フラグメントのところのFragment Managerの使い方はどんなことができるのかの概念として知っておくと良いと思いますが、こちらを使う場合は直接使うことはないか少ないでしょう。
インテント
ここにインテントについて説明がありますが、アクティビティの中の以下でも言及があります。両方見ましょう。
Tag: Kotlin
Unable to find Gradle tasks to build [:app] build mode ASSEMBLE
Android Studio Koala 2024.1.1 Canary 4で、Run ‘app’としたら、以下のメッセージが出てビルドできない事象が発生した。 特に何も変更した覚えがないので、Build CleanしてMakeしたらまたBuildできるようになりました。 Unable to find Gradle tasks to build [:app] build mode ASSEMBLE
W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
Google Map SDKを使ったAndroidアプリを作っていて、以下の警告が出た場合の対処について紹介します。
このエラーが出る場合は地図のコントロールの表示はあっても地図そのものが表示されない状態になりました。
W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found.
stackoverflowの記事ではエミュレータを再作成する案が載っていましたが、エミュレータをCold Bootしたところ直りました。
結局原因がなんなのかわかりませんが、とりあえずCold Bootしてみるのは一つの手かもしれません。
Android Developersサイトの歩き方 2022
Androidアプリを作成するのに公式ドキュメントを参照しますが、どこにどんなことが書いてあるのかや、初心者が知っておくと良いかもしれないことについて書きます。
場合により記事公開後にも修正や加筆するかもしれません。
公式サイト
公式サイトは以下です。 基本的にすべてのリンクは日本語(向け)ページになっています。
画面上部(PCの場合)にプラットフォーム、Android Studio、Google Play、Jetpack、Kotlin、ドキュメント、ニュースとあります。
よく見ることになるのはドキュメントだと思います。
ドキュメント
では、さっそく見ていきましょう。
勉強の中心になるのは「ドキュメント」の中でも、「ガイド」というところです。
ここには「アプリの基本」から始まり、多様な内容について説明があります。
初心者が見て理解できるかはさておき、理解しておくべき概念から実際のコードまで一通り記載されていると思います。
「アプリの基本」と「主要トピック」を見るとなんとなくアプリの全体像がわかってくるんじゃないかと思います。
ちなみにアプリを公開しようという段階になるとここの説明だけだと足りずほかのところも見ることになると思います。
また、ここにないライブラリを使おうと思ったりすると別のところを見る必要が出てきます。
GoogleのライブラリのGoogle Map SDKとかFirebaseとか。ほかにも色々。
アプリの基本
Hello World的な感じでなんとなくの全体像をつかめれば良いと思います。 色々わかってくると後で戻って読むことになるとも思いますが、まずはなんとなくわかれば十分かと思います。
主要トピック
主要トピックは、アクティビティの概要から始まります。
ここは重要な概念の説明が多く説明されているので理解すべきですが、最初は理解できないと思います。 なんとなくの用語がわかるようになればまずは良いような気がします。
フラグメント
とても重要な用語、概念のフラグメントは、「アクティビティの概要」の中の一節となっているのでフラグメントを探すときはアクティビティのところを探しましょう。
ちなみになぜか日本語化されていないドキュメントが多いです。重要なのに。
Android アーキテクチャ コンポーネント
これはJetpackの一部ということになっています。
Android デベロッパーのトップレベルに「Jetpack」というのがありましたが、それです。
比較的新しいライブラリ群のことです。基本的にこれを使いましょう。
以下の項目はここにありますが、これらがアーキテクチャ コンポーネントだと知らないとわからないので難しいです。
- DataStore
- ビューバインディング
- データバインディング
- ライフサイクル(Lifecycleライブラリ、クラス)
- LiveData
- ViewModel
- Work Manager
- ページングライブラリ など
Navigation コンポーネント
これも比較的新しいライブラリです。
フラグメントのところでFragment Managerの使い方が紹介されていますが、これをラップしてくれるライブラリなのでこちらを使いましょう。
フラグメントのところのFragment Managerの使い方はどんなことができるのかの概念として知っておくと良いと思いますが、こちらを使う場合は直接使うことはないか少ないでしょう。
インテント
ここにインテントについて説明がありますが、アクティビティの中の以下でも言及があります。両方見ましょう。
FireBase AuthのidTokenを同期的に取得する方法
こういうのってどうしたら情報を自分で得られるようになるのだろうか。
FirebaseAuthのidTokenをawait()で取れるようにする
こういうのをちゃんと見てどんなのがあるか把握しておけってことかなぁ。。
Tag: テレマーク
今、私がスキー(ブーツ)を買うなら何が良い?
悩んでいます。
スキーブーツが壊れてしまったので、新しいのを買いたいのですが何を買うべきか。。
壊れたブーツ
壊れたのはテレマーク用のプラスチックブーツです。
75mm NormのEner-Gというものです。
蛇腹が割れてしまいました。左右とも。
75mm Norm
普通に考えたら75mm Normのブーツを買えば良いのですが、75mmの歴史は古く、そのうちなくなりそうな気配。。
今はNTNという新しいテレマーク規格がありますが、75mmとの互換性がないのです。
そのため、NTNのブーツを使うためにはビンディングもNTNに変える必要があり、痛い出費です。
75mmのブーツはまだ売ってますが、撤退したメーカーも多く、そもそもあまり売ってません。
Scottのスキーブーツ一覧には、Voodooというブーツがありますが、実売10万円くらいして高いです。
Scarpaのテレマークブーツには、T2 ecoとT4の2種類があります。
ちなみにScarpaにはtelemark selectorというのがあって、自分に合うブーツを選ぶ仕組みがあります。私はT4でした。
Scarpa T4
ということで、Scarpa T4が候補になります。
ところが、ほとんど在庫なく、売ってません。予約販売しているサイトでも入荷は早くて2024年1月と書いてありました。・・・遅い。。
メルカリ、ヤフオクなどを見てもサイズが合わないのもあり、買えません。。
Scarpa T1はサイズが合いそうなのを売ってるのを見つけました。87,000円。う~ん。。
革ブーツ
Crispiのもの、Fischerのものがありました。 一応、これらも候補。
NTN
75mmへの執着みたいなものはないのでNTNでも良いのですが、ビンディングだけで60,000円くらいするのでちょっと高い。。
ブーツもビンディングも板もとなると結構な額。。
まとめ
というわけで、多分安いのは75mmでサイズの合うのを買うのが一番安いんだと思います。
NTNにすると十数万円くらいは掛かりそう。
Tag: CISSP
CISSPになるメリットとデメリット
CISSPでない方が、CISSPになった場合のメリットとデメリットについて書きます。
CISSPとは
(ISC)²の日本語版サイトによると以下の通りです。
https://japan.isc2.org/cissp_about.htmlに説明があります。
CISSP(Certified Information Systems Security Professional)とは、(ISC)² (International Information Systems Security Certification Consortium)が認定を行っている国際的に認められた情報セキュリティ・プロフェッショナル認定資格です。
なお、 (ISC)² は、安全で安心なサイバー世界の実現に向けて活動する国際的な非営利会員団体です。 https://japan.isc2.org/に記載があります。
試験に合格するだけでは会員として認められず、以下が追加が必要ですが、詳しくは上記サイト等を確認してください。
- 会員からの推薦
- 5年以上のセキュリティ分野の実務経験
- 年会費
なお、実務経験のみが不足する場合、アソシエイトとして登録することができ、実務経験を積んで正会員になることができます。
メリット
CISSPは国際的な資格ですので、世界中で知名度があり、信頼も得られます。
発言の説得力が増したり、相手の信頼を得やすくなる可能性があります。
日本にはまだ数千人しかいませんので国内での希少価値もあると思います。(2022年1月1日現在で3339人)
資格維持のためには3年間のうちに120時間相当(120CPE)の学習が必要ですので、継続的な学習が半強制的に行われます。
1CPEが1時間の学習に相当します。ウェビナーの受講で自動的にカウントされるものがありますが、読書等でも自己申告でCPEを獲得できます。
申告内容は監査対象となるので追加の証拠を求められることもありますが、幅広い活動がCPEの対象になります。
会員向けのPDIコース(オンライン学習コンテンツ)が無償で提供されていたり、セキュリティ系のイベントの割引を受けられたりと学習の機会やその案内を受けられます。
日本チャプターという支部があり、日本向けの情報提供や国内での有志による活動等も行われています。
情報セキュリティ監査人補の資格取得の特例を受けて、簡単に資格取得することができます。 受講期間が通常5日間のところ、1日だけで済みます。
情報セキュリティの専門家として自信がつきます。国際的な資格で権威ある資格と言って良いと思います。 また、発言に責任を持つような意識が芽生えるので、成長にもつながると思います。
CISSPが担当することを求める案件に対応することができます。 入札条件等として制限がある場合があるかもしれません。
デメリット
資格の登録、維持に費用と時間が掛かります。
資格維持のためには120CPEの獲得が必要で、3年で120時間相当です。 年会費は125 USDです。今後変わるかもしれません。
Tag: Linux
Red Hatのリモート試験受験時の部屋やカメラの状況について
Red Hat Remote ExamsでRHCEを受験しましたので気になる受験環境等について少し説明しようと思います。
Remote Examsではテストセンターに行かなくても自宅等からリモートで受験することができます。
ちなみにテストセンターは国内だと東京都内にあるようですが数が少ないのか予約できる日を見つけられませんでした。
台湾のテストセンターは空いている日も見つけられましたが国内では見つけられませんでした。
対象の資格はRHCEのほかにも、RHCSA等多数あります。
具体的には以下のURLで確認できます。
https://www.redhat.com/ja/services/certification/remote-exams
準備
基本的に、上に挙げたURLにある情報で足りると思いますが、部屋の片付け具合やカメラ位置等が気になって仕方がなかったのでそのあたりについて書きます。
部屋
部屋の片付け具合は、上記URLの動画に登場する部屋を参考にしました。
部屋を片付けている様子(?)もありますが片付いているのは机の上だけで、周りの本棚等は変わっていないようです。
準備についてのほかの方のブログなどを見ると、念のため本もすべて片付けたというものがいくつかありましたが、動画では片付けていなかったのでこれを信じて本は片付けずに受験しました。
結果としては特に何も言われず問題ありませんでした。
部屋の写真はここに載せませんが、以下のような部屋で受験しました。
6畳くらいの部屋で、壁に向かって左右中央あたりにテーブルを置き、そこにノートPCを置きました。
手の届く範囲にはなにもない状態にしました。
テーブルに向って座った場合の背中側に棚があって、そこに本や少しの小物が置いてあります。
横の手の届かないところには小さなテーブルやデスクトップPCなどいろいろ置いてありました。
カメラ
ノートPC付属のカメラだけではだめなので、USB接続の安いカメラを買いました。
ロジクールのC270です。結局これを使いましたが、証明書を見せるときにこれだとピントが合わずだめでした。
結局、ノートPC付属のカメラで見せました。
この場合、外部ディスプレイを使って受験しようとしている場合はノートPCは閉じていないといけないのでこのカメラだけだと受験できない可能性があります。
カメラ画像のサンプルは以下にあります。
FAQは日本語ページがないのでFAQ自体がないのかと最初戸惑いますが英語ページはちゃんとあります。カメラ画像のサンプルもFAQから辿れます。
FAQからさらにリンクで示されているのが以下。
カメラは2台使ってもよく、顔と手(キーボード)が映るようにする必要があります。
私は、上述のようにUSBの外部カメラとノートPCのカメラの二つを使いました。
USBカメラは机の横に三脚を立ててそこに置きました。購入したロジクール C270は三脚に固定する仕組みがありませんでしたが、載せるだけの感じで設置できました。念のためセロテープで落ちないようにしました。
カメラの高さは顔の高さくらいで少し下向きにしました。
試験監督から指示があるかもしれないので調整できるようにしておくと良いと思います。
また、試験中にもroom scanといって部屋を見せる必要があるので、すぐに取り外せるようにしておく必要もあります。
ネットワーク(Wifi)
有線が推奨とのことですが、私のノートPCには差すところがないので無線で受験しました。
特に気になるところもなく、問題ありませんでした。
Let's Encryptの証明書を使っているサーバにcURLで接続してもSEC_ERROR_UNKNOWN_ISSUERで失敗しません
body of this entry
以前書いた記事、Let’s Encryptの証明書を使っているサーバにcURLで接続するとSEC ERROR UNKNOWN_ISSUERで失敗するですが、Let’s Encryptは悪くなかったです。自分のWebサーバの設定が悪かったです。
Nginxを使っていて、サーバ証明書にcert.pemを指定していましたが、fullchain.pemを指定するのが正しいようです。証明書と同じフォルダにあるREADMEを見ても、cert.pemは古いので使われないということが書いてありました。 完全に動かないということではないようで気づきませんでした。
Let's Encryptの証明書を使っているサーバにcURLで接続するとSEC_ERROR_UNKNOWN_ISSUERで失敗する
Let’s Encryptの証明書を使っているサーバにcURLで接続するとSEC ERROR UNKNOWN_ISSUERで失敗する場合がありました。 ROOT CAは信頼済みになっていますが、中間証明書を信頼できずに失敗していました。 なお、Widows上のGoogle Chromeからは問題ありませんでした。
curl -vの結果は以下のようになっていました。
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: cacert.pem
CApath: none
* Server certificate:
* subject: CN=www.sei-yo.jp
* start date: Jul 25 15:26:52 2020 GMT
* expire date: Oct 23 15:26:52 2020 GMT
* common name: www.sei-yo.jp
* issuer: CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US
* NSS error -8179 (SEC_ERROR_UNKNOWN_ISSUER)
* Peer's Certificate issuer is not recognized.
中間証明書は以下にあります。
https://letsencrypt.org/ja/certificates/
https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt
Linux Kernelが対応していないUSBデバイスを使用する方法
ここで言うLinux Kernelが対応していないUSBデバイスというのは、デバイスのベンダーID(VID)とプロダクトID(PID)がカーネルのドライバが知らないために、ドライバはあるのにデバイスを認識しないということになってしまうデバイスのことを指します。 つまり、ドライバが知らないVID、PIDのUSBデバイスを使用する方法ということです。 以下の二つがあります。一つ目しか知らなかったのですが二つ目を知って便利になったのでここに書きます。
- ドライバをコンパイル
- ドライバに/sys のnew_idを使ってIDを伝える
ドライバをコンパイル
私の知る限り、USBデバイス用のドライバは通常、いくつかの(と言っても多数の)VIDとPIDの組み合わせを知っています。そしてその情報はソースコードに埋め込まれています。そのため新しいUSBデバイスに対応するためにはソースコードの修正を行って、コンパイルして利用する必要があります。 Linux Kernelに付属のドライバを使う場合には、以下の記事にあるような方法でコンパイルして利用する必要があります。しかし、Linux Kernelに付属のドライバはKernelバージョン毎にあるためKernelのアップデートをする度にドライバのコンパイルが必要になってしまいます。
Kernel アップデートの度にコンパイルするのはかなりの手間なのでこれを防ぐには、Kernelのアップストリームに取り込んでもらう手があります。修正内容としてはVIDとPIDが列挙されている個所に1つ追加するだけなので軽微ですが、Linux Kernelの修正の流儀がわかっておらず依頼していません。
ドライバに/sys のnew_idを使ってIDを伝える
ドライバに動的にVID PIDを伝えることでデバイスを使えるようにする方法があります。 /sys/bus/usb/drivers/の下にドライバ名のディレクトリがあればその下のnew_idにVID PIDを書き込みます。 するとドライバがそのデバイスを利用可能にしてくれます。 ドライバ名のディレクトリがない場合は該当のドライバが読み込まれていないのでmodprobeコマンドで読み込む必要があります。
echo "0411 014F" > /sys/bus/usb/drivers/rt2800usb/new_id
modprobeコマンドで読み込むのを自動で行うには/etc/modulesファイルにドライバ名を書きます。 また、/etc/modprobe.d/の下に拡張子を.confにしたファイルを置いて以下のように書くとOS起動時に上記コマンドまで実施してくれて便利です。
install rt2800usb /sbin/modprobe -i rt2800usb; echo "0411 014F" > /sys/bus/usb/drivers/rt2800usb/new_id
cpanm XML::LibXML::SAXでEnv.pmが必要
cpanm XML::LibXML::SAXでXML::LibXML::SAXをインストールしようとしたところ、以下のエラーとなりました。 cpanm EnvでEnv.pmをインストールしたところ、エラーがなくなりました。
cpanm (App::cpanminus) 1.7044 on perl 5.016003 built for x86_64-linux-thread-multi
Work directory is /root/.cpanm/work/1592575613.22094
You have make /bin/make
You have LWP 6.45
You have /bin/tar: tar (GNU tar) 1.26
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by John Gilmore and Jay Fenlason.
Searching XML::LibXML::SAX () on cpanmetadb ...
--> Working on XML::LibXML::SAX
Fetching http://www.cpan.org/authors/id/S/SH/SHLOMIF/XML-LibXML-2.0205.tar.gz
-> OK
Unpacking XML-LibXML-2.0205.tar.gz
Entering XML-LibXML-2.0205
Checking configure dependencies from META.json
Checking if you have ExtUtils::MakeMaker 6.58 ... Yes (6.68)
Checking if you have Alien::Base::Wrapper 0 ... No
Checking if you have Alien::Libxml2 0.14 ... No
Checking if you have Config 0 ... Yes (undef)
==> Found dependencies: Alien::Base::Wrapper, Alien::Libxml2
Searching Alien::Base::Wrapper (0) on cpanmetadb ...
--> Working on Alien::Base::Wrapper
Fetching http://www.cpan.org/authors/id/P/PL/PLICEASE/Alien-Build-2.26.tar.gz
-> OK
Unpacking Alien-Build-2.26.tar.gz
Entering Alien-Build-2.26
Checking configure dependencies from META.json
Checking if you have ExtUtils::ParseXS 3.30 ... Yes (3.35)
Checking if you have ExtUtils::MakeMaker 6.64 ... Yes (6.68)
Checking if you have File::Which 0 ... No
Checking if you have ExtUtils::CBuilder 0 ... Yes (0.280234)
==> Found dependencies: File::Which
Searching File::Which (0) on cpanmetadb ...
--> Working on File::Which
Fetching http://www.cpan.org/authors/id/P/PL/PLICEASE/File-Which-1.23.tar.gz
-> OK
Unpacking File-Which-1.23.tar.gz
Entering File-Which-1.23
Checking configure dependencies from META.json
Checking if you have ExtUtils::MakeMaker 6.58 ... Yes (6.68)
Configuring File-Which-1.23
Running Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for File::Which
Writing MYMETA.yml and MYMETA.json
-> OK
Checking dependencies from MYMETA.json ...
Checking if you have Test::More 0.47 ... Yes (1.302175)
Checking if you have ExtUtils::MakeMaker 0 ... Yes (6.68)
Building and testing File-Which-1.23
cp lib/File/Which.pm blib/lib/File/Which.pm
Manifying blib/man3/File::Which.3pm
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
#
#
#
# HARNESS_ACTIVE=1
# HARNESS_VERSION=3.42
# LANG=C
# LC_ALL=C
# LC_MESSAGES=C
# PERL5LIB=/root/.cpanm/work/1592575613.22094/File-Which-1.23/blib/lib:/root/.cpanm/work/1592575613.22094/File-Which-1.23/blib/arch
# PERL_DL_NONLAZY=1
# PERL_MM_USE_DEFAULT=1
# PERL_USE_UNSAFE_INC=1
# SHELL=/bin/bash
#
#
#
# PERL5LIB path
# /root/.cpanm/work/1592575613.22094/File-Which-1.23/blib/lib
# /root/.cpanm/work/1592575613.22094/File-Which-1.23/blib/arch
#
#
#
# perl 5.016003
# ExtUtils::MakeMaker 6.68
# Test::More 1.302175
#
#
#
t/00_diag.t ..... ok
t/01_use.t ...... ok
Can't locate Env.pm in @INC (@INC contains: /root/.cpanm/work/1592575613.22094/File-Which-1.23/blib/lib /root/.cpanm/work/1592575613.22094/File-Which-1.23/blib/arch /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at t/file_which.t line 3.
BEGIN failed--compilation aborted at t/file_which.t line 3.
t/file_which.t ..
Dubious, test returned 2 (wstat 512, 0x200)
No subtests run
Test Summary Report
-------------------
t/file_which.t (Wstat: 512 Tests: 0 Failed: 0)
Non-zero exit status: 2
Parse errors: No plan found in TAP output
Files=3, Tests=2, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.12 cusr 0.01 csys = 0.15 CPU)
Result: FAIL
Failed 1/3 test programs. 0/2 subtests failed.
make: *** [test_dynamic] Error 2
-> FAIL Installing File::Which failed. See /root/.cpanm/work/1592575613.22094/build.log for details. Retry with --force to force install it.
-> FAIL Installing the dependencies failed: Module 'File::Which' is not installed
-> FAIL Bailing out the installation for Alien-Build-2.26.
Searching Alien::Libxml2 (0.14) on cpanmetadb ...
--> Working on Alien::Libxml2
Fetching http://www.cpan.org/authors/id/P/PL/PLICEASE/Alien-Libxml2-0.16.tar.gz
-> OK
Unpacking Alien-Libxml2-0.16.tar.gz
Entering Alien-Libxml2-0.16
Checking configure dependencies from META.json
Checking if you have ExtUtils::MakeMaker 6.58 ... Yes (6.68)
Checking if you have Alien::Build::Plugin::Build::SearchDep 0.35 ... No
Checking if you have Alien::Build::Plugin::Probe::Vcpkg 0 ... No
Checking if you have Alien::Build 2.12 ... No
Checking if you have Alien::Build::MM 2.12 ... No
Checking if you have Alien::Build::Plugin::Prefer::BadVersion 1.05 ... No
Checking if you have ExtUtils::CBuilder 0 ... Yes (0.280234)
==> Found dependencies: Alien::Build::Plugin::Build::SearchDep, Alien::Build::Plugin::Probe::Vcpkg, Alien::Build, Alien::Build::MM, Alien::Build::Plugin::Prefer::BadVersion
Searching Alien::Build::Plugin::Build::SearchDep (0.35) on cpanmetadb ...
Already tried Alien-Build-2.26. Skipping.
Searching Alien::Build::Plugin::Probe::Vcpkg (0) on cpanmetadb ...
Already tried Alien-Build-2.26. Skipping.
Searching Alien::Build (2.12) on cpanmetadb ...
Already tried Alien-Build-2.26. Skipping.
Searching Alien::Build::MM (2.12) on cpanmetadb ...
Already tried Alien-Build-2.26. Skipping.
Searching Alien::Build::Plugin::Prefer::BadVersion (1.05) on cpanmetadb ...
Already tried Alien-Build-2.26. Skipping.
-> FAIL Installing the dependencies failed: Module 'Alien::Build::Plugin::Build::SearchDep' is not installed, Module 'Alien::Build::Plugin::Probe::Vcpkg' is not installed, Module 'Alien::Build' is not installed, Module 'Alien::Build::MM' is not installed, Module 'Alien::Build::Plugin::Prefer::BadVersion' is not installed
-> FAIL Bailing out the installation for Alien-Libxml2-0.16.
-> FAIL Installing the dependencies failed: Module 'Alien::Base::Wrapper' is not installed, Module 'Alien::Libxml2' is not installed
-> FAIL Bailing out the installation for XML-LibXML-2.0205.
cpanm XML::SAX::ExpatXSでFatal.pmのインストールが必要
cpanm XML::SAX::ExpatXSでXML::SAX::ExpatXSをインストールしようとしたところ、以下のエラーメッセージが出ました。 cpanm FatalでFatal.pmをインストールしたらエラーが出なくなりました。
cpanm (App::cpanminus) 1.7044 on perl 5.016003 built for x86_64-linux-thread-multi
Work directory is /root/.cpanm/work/1592574714.18422
You have make /bin/make
You have LWP 6.45
You have /bin/tar: tar (GNU tar) 1.26
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by John Gilmore and Jay Fenlason.
Searching XML::SAX::ExpatXS () on cpanmetadb ...
--> Working on XML::SAX::ExpatXS
Fetching http://www.cpan.org/authors/id/P/PC/PCIMPRICH/XML-SAX-ExpatXS-1.33.tar.gz
-> OK
Unpacking XML-SAX-ExpatXS-1.33.tar.gz
Entering XML-SAX-ExpatXS-1.33
Checking configure dependencies from META.yml
Checking if you have ExtUtils::MakeMaker 6.58 ... Yes (6.68)
Configuring XML-SAX-ExpatXS-1.33
Running Makefile.PL
Warning: prerequisite XML::SAX 0.96 not found.
Writing XML::SAX::ExpatXS::Preload
Checking if your kit is complete...
Looks good
Do you want to alter ParserDetails.ini? [Y] Y
Writing Makefile for XML::SAX::ExpatXS
Writing MYMETA.yml and MYMETA.json
-> OK
Checking dependencies from MYMETA.json ...
Checking if you have XML::SAX 0.96 ... No
Checking if you have ExtUtils::MakeMaker 0 ... Yes (6.68)
==> Found dependencies: XML::SAX
Searching XML::SAX (0.96) on cpanmetadb ...
--> Working on XML::SAX
Fetching http://www.cpan.org/authors/id/G/GR/GRANTM/XML-SAX-1.02.tar.gz
-> OK
Unpacking XML-SAX-1.02.tar.gz
Entering XML-SAX-1.02
Checking configure dependencies from META.json
Checking if you have ExtUtils::MakeMaker 6.58 ... Yes (6.68)
Configuring XML-SAX-1.02
Running Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for XML::SAX
Writing MYMETA.yml and MYMETA.json
-> OK
Checking dependencies from MYMETA.json ...
Checking if you have XML::NamespaceSupport 0.03 ... Yes (1.12)
Checking if you have XML::SAX::Base 1.05 ... Yes (1.09)
Checking if you have ExtUtils::MakeMaker 0 ... Yes (6.68)
Checking if you have File::Temp 0 ... Yes (0.2301)
Building and testing XML-SAX-1.02
cp lib/XML/SAX/PurePerl/EncodingDetect.pm blib/lib/XML/SAX/PurePerl/EncodingDetect.pm
cp lib/XML/SAX/PurePerl/Reader/UnicodeExt.pm blib/lib/XML/SAX/PurePerl/Reader/UnicodeExt.pm
cp lib/XML/SAX/PurePerl/Reader/Stream.pm blib/lib/XML/SAX/PurePerl/Reader/Stream.pm
cp lib/XML/SAX.pm blib/lib/XML/SAX.pm
cp lib/XML/SAX/PurePerl/DTDDecls.pm blib/lib/XML/SAX/PurePerl/DTDDecls.pm
cp lib/XML/SAX/PurePerl/Reader/NoUnicodeExt.pm blib/lib/XML/SAX/PurePerl/Reader/NoUnicodeExt.pm
cp lib/XML/SAX/DocumentLocator.pm blib/lib/XML/SAX/DocumentLocator.pm
cp lib/XML/SAX/PurePerl/Reader/String.pm blib/lib/XML/SAX/PurePerl/Reader/String.pm
cp lib/XML/SAX/PurePerl/UnicodeExt.pm blib/lib/XML/SAX/PurePerl/UnicodeExt.pm
cp lib/XML/SAX/PurePerl/Exception.pm blib/lib/XML/SAX/PurePerl/Exception.pm
cp lib/XML/SAX/PurePerl/DocType.pm blib/lib/XML/SAX/PurePerl/DocType.pm
cp lib/XML/SAX/PurePerl/DebugHandler.pm blib/lib/XML/SAX/PurePerl/DebugHandler.pm
cp lib/XML/SAX/Intro.pod blib/lib/XML/SAX/Intro.pod
cp lib/XML/SAX/ParserFactory.pm blib/lib/XML/SAX/ParserFactory.pm
cp lib/XML/SAX/PurePerl/Reader/URI.pm blib/lib/XML/SAX/PurePerl/Reader/URI.pm
cp lib/XML/SAX/PurePerl/XMLDecl.pm blib/lib/XML/SAX/PurePerl/XMLDecl.pm
cp lib/XML/SAX/PurePerl/Reader.pm blib/lib/XML/SAX/PurePerl/Reader.pm
cp lib/XML/SAX/PurePerl.pm blib/lib/XML/SAX/PurePerl.pm
cp lib/XML/SAX/PurePerl/NoUnicodeExt.pm blib/lib/XML/SAX/PurePerl/NoUnicodeExt.pm
cp lib/XML/SAX/PurePerl/Productions.pm blib/lib/XML/SAX/PurePerl/Productions.pm
Manifying blib/man3/XML::SAX::ParserFactory.3pm
Manifying blib/man3/XML::SAX.3pm
Manifying blib/man3/XML::SAX::Intro.3pm
Manifying blib/man3/XML::SAX::PurePerl::Reader.3pm
Manifying blib/man3/XML::SAX::PurePerl.3pm
Manifying blib/man3/XML::SAX::DocumentLocator.3pm
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00basic.t ....... ok
t/01known.t ....... ok
t/10xmldecl1.t .... ok
t/11xmldecl2.t .... ok
t/12miscstart.t ... ok
t/13int_ent.t ..... ok
t/14encoding.t .... ok
t/15element.t ..... ok
parsed 80085 bytes in 0 seconds
t/16large.t ....... ok
t/19pi.t .......... ok
t/20factory.t ..... ok
Can't locate Fatal.pm in @INC (@INC contains: /root/.cpanm/work/1592574714.18422/XML-SAX-1.02/blib/lib /root/.cpanm/work/1592574714.18422/XML-SAX-1.02/blib/arch /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at t/21saxini.t line 6.
BEGIN failed--compilation aborted at t/21saxini.t line 6.
t/21saxini.t ......
Dubious, test returned 2 (wstat 512, 0x200)
No subtests run
t/30parse_file.t .. ok
t/40cdata.t ....... ok
t/42entities.t .... ok
t/99cleanup.t ..... ok
Test Summary Report
-------------------
t/21saxini.t (Wstat: 512 Tests: 0 Failed: 0)
Non-zero exit status: 2
Parse errors: No plan found in TAP output
Files=16, Tests=105, 1 wallclock secs ( 0.05 usr 0.01 sys + 0.66 cusr 0.12 csys = 0.84 CPU)
Result: FAIL
Failed 1/16 test programs. 0/105 subtests failed.
make: *** [test_dynamic] Error 255
-> FAIL Installing XML::SAX failed. See /root/.cpanm/work/1592574714.18422/build.log for details. Retry with --force to force install it.
-> FAIL Installing the dependencies failed: Module 'XML::SAX' is not installed
-> FAIL Bailing out the installation for XML-SAX-ExpatXS-1.33.
Infrastructure as Code関連の書籍紹介(GWアドベントカレンダー 6日目)
この記事はGWアドベントカレンダーの6日目の記事です。
IaCに関連する最近読んだ本の紹介です。 読んだ順に書いていますが、Ansible実践ガイドはまだ記事を書いていないのでここで簡単に紹介します。 Ansible を自由に利用できるようになるための基礎が幅広く記載されています。そのため、「インフラCI 実践ガイド」にもAnsibleが使われていますが、この内容を理解するのにも役立ちました。 また、これから新規にプレイブックを作るときの設計のポイントも記載されています。 Linuxサーバ向けだけでなく、Windowsやネットワーク機器向けの設定についても記載されており、これらを理解することでAnsibleのエコシステムや思想の理解が深まり様々な応用ができるようになります。
- 「Infrastructure as Code」
- 「しくみがわかるKubernetes」
- 「インフラCI 実践ガイド」
- Ansible 実践ガイド 第3版
PC上でのIaC環境の概要(GWアドベントカレンダー 4日目)
この記事はGWアドベントカレンダーの4日目の記事です。
自宅のPCにIaC環境を構築中ですが、その環境について少し説明します。
使用するツール
1台の物理Linuxサーバ上にすべての環境を構築します。 仮想マシンはVagrant + Virtual Boxで構築します。 コンテナはDockerで構築します。 構築ツールとしてAnsibleを使います。 CI/CDを実現するためのツールとしてGitlab、Gitlab Runnerを使います。
Gitlab、Gitlab Runnerの構築
GitlabとGitlab RunnerはAnsibleを使って、仮想マシンから作成します。 本番用とテスト用があり、テスト用の構築は本番用のGitlabのバックアップデータを使ってリストアすることで本番と同じデータを持つようにしています。
物理Linuxサーバの構築
OSインストール後の各種設定類はAnsibleにまとめようと思っていますが、まだできていません。
AnsibleとVagrantの連携
Ansibleのプレイブック(Gitlabのパイプラインからの呼び出しや手動実行)によって、Vagrant経由で仮想マシンを作成することがあります。 しかし、AnsibleのInventory PluginとしてはVagrant用のものが正式にはありません。そのため、作成した仮想マシンに対してプレイブックを実行するためには何らかの方法を考える必要があります。 一つはInventory PluginもしくはScriptを作ること、もう一つは作成する仮想マシン情報をあらかじめインベントリファイルに記載しておくことが考えられます。 どちらの方法でも実現できそうですが、どのようにするか検討中です。
今後の展望
- 物理Linuxサーバ構築用のパイプライン構築
- Kubernetesを動かす。 その上で、各種アプリケーションを動かす予定です。
Docker Desktop for Windowsの導入
Docker Desktop for Windowsを導入してみました。
dockerコンテナを作って動かしたいのが目的です。 Windowsを使うのは、普段使っているOSがWindowsだからで、コンテナはLinuxのものを使います。 そうしたときに、docker Engineをどこで動かすかの選択肢があります。
- Windows (Docker Desktop for Windows)
- Windows上のLinux VM(Hyper-VやVirtual Box上のLinux VMでLinux用のDocker Engineを動かす)
開発用にLinux VMを動かしているのでそちらでDockerを使っても良いのですが、わざわざVMを起動して使うのも面倒そうなのでWindows上で動かすことにしました。 ただ、Windows上で動かすと言っても、実際にはDocker用のLinux VMがHyper-Vを使って起動します。 そのため、自分でLinux VMを用意して動かすのと仕組みはそれほど変わりません。
Docker Desktop for Windowsの場合、Docker ClientはWindows上で動きますが、Docker EngineはLinux VM上で動きます。 自分でLinux VMを用意して使う場合はDocker ClientもDocker EngineもLinux VM上で動きます。 コンテナそのものはどちらもLinux VM上で動きます。
Docker Desktop for Windowsを使う場合、DockerfileやコンテナにコピーするファイルをLinux VMから利用できるようにする必要があります。 どのドライブをアクセス可能にするかは、settingsから設定できます。 なお、コンテナからマウントして使うようなデータ領域としてはWindows上の領域は不向きで、data volumeやdata containerを使う方が良いようです。これには二つの理由があって、一つはWindows上の領域はLinux上からみて、rwxrwxrwxのモードで見えます。もう一つは、SMBを使ってLinux VMに領域を見せる際、NOBRLオプションが付いているため、ロックができない場合がある点です。 これらはDocker Desktop for Windowsのドキュメントの最初の方(Shared drives)に書いてあります。
と、ここまでやってから大事なことに気づきました。 開発用にLinux VMを動かしていますが、そちらはVirtual Boxを使っています。 Docker Desktop for WindowsはHyper-Vを使います。 これらの共存はできないので、どちらを使うか選ぶ必要があります。。つづく。。
cgroupを使った負荷生成ツール
必要にせまられて(?)、指定したCPU使用率、メモリ使用率の負荷を掛けるツールを作りました。 cgroupを使ってツールのCPU使用率とメモリ使用率を制限します。 特別なツールを使わずに負荷を掛けられるのでstressパッケージをインストールしなくても負荷を掛けられるのがポイントです。と言いつつも、中でperlを使ってしまったのでこれも不要にする予定です。
stressパッケージを使わない方法はyesコマンドを使う方法やtmpfsをマウントする方法が検索すると見つかりますが、実行時間を指定できないために開始終了が煩雑(特に複数CPUコアの場合)だったり、メモリがbuff/cache扱いになって参照したい指標によってはメモリ使用率が高くないように見えてしまうために、変数領域として確保するようにしました。
使用率の指定はOS全体の使用率は指定できず、ツールの使用率しか指定できないので、注意が必要です。ここは今後改善したいと思っている部分です。
Tag: Node.js
Scrapbox から LINEに通知するスクリプトを書いた
Scrapboxというサービスを使っていて、コンテンツの更新をした際の通知をLINEにするためのスクリプトを書きました。 ScrapboxはSlackへの通知機能を提供していますが、それ以外については自分で仕組みを作る必要があります。
通知方法を検索するとGASを使ってscrapboxの更新をLINEで通知するというページが見つかります。これを参考にしたものの、GASではなくAzure App Serviceに実装したり、そのほか色々変更したので様々異なる点があります。
Tag: Scrapbox
Scrapbox から LINEに通知するスクリプトを書いた
Scrapboxというサービスを使っていて、コンテンツの更新をした際の通知をLINEにするためのスクリプトを書きました。 ScrapboxはSlackへの通知機能を提供していますが、それ以外については自分で仕組みを作る必要があります。
通知方法を検索するとGASを使ってscrapboxの更新をLINEで通知するというページが見つかります。これを参考にしたものの、GASではなくAzure App Serviceに実装したり、そのほか色々変更したので様々異なる点があります。
Tag: Books
Vue関連の書籍を読んだ
最近、Vue関連の書籍を読みましたのでその紹介です。
Webサービスを作るにあたり、フロントエンドの処理のためにVueを採用することにしたので、 その勉強のために読みました。
読んだのは以下の3冊です。 どの本も2020年にリリースされたVue.js3に対応しています。
- Vue.js3 超入門
- これからはじめる人のJavascript/Vue.jsの教科書
- みんなのVue.js
Vue.js3超入門はVue.jsについて一通り説明されていて、Vue.jsについて知るのに良いと思います。
これからはじめる人のJavascript/Vue.jsの教科書は、JavascriptとTypescriptについても説明があります。
Vue.js3超入門よりも薄いので、ボリュームは少な目ですが、広く浅くという感じで記載があります。
みんなのVue.jsはVue.jsを知っている人向けに、実装時の注意点や考え方などが記載されています。例えば、国際化対応についての記述があります。
Ansible実践ガイドを読んだ。(GWアドベントカレンダー 7日目)
この記事はGWアドベントカレンダーの7日目の記事です。
「Ansible 実践ガイド 第3版」を読みました。 この本は、これからAnsibleを始めようとする方や少し触ってみたものの、実際の環境にどのように適用すべきか検討し始めたくらいの方に最適と思います。 ただ、既に色々とAnsibleを適用しているものの構成が複雑で保守しづらくなってしまうというような方にも向いていると思います。 具体的なプレイブックの例がいくつも紹介されており、それぞれにプレイブックのノウハウがあります。
AnsibleやYAMLについての基本的な説明から始まっていて、その後具体的なプレイブックの紹介や保守性を考慮したディレクトリ構成等の実践的な内容へと移っていきます。 プレイブックのデバッグ方法についても様々な手法が説明されており、Ansibleを利用していく上で必要なことが一通り学べるようになっていると思います。
Infrastructure as Code関連の書籍紹介(GWアドベントカレンダー 6日目)
この記事はGWアドベントカレンダーの6日目の記事です。
IaCに関連する最近読んだ本の紹介です。 読んだ順に書いていますが、Ansible実践ガイドはまだ記事を書いていないのでここで簡単に紹介します。 Ansible を自由に利用できるようになるための基礎が幅広く記載されています。そのため、「インフラCI 実践ガイド」にもAnsibleが使われていますが、この内容を理解するのにも役立ちました。 また、これから新規にプレイブックを作るときの設計のポイントも記載されています。 Linuxサーバ向けだけでなく、Windowsやネットワーク機器向けの設定についても記載されており、これらを理解することでAnsibleのエコシステムや思想の理解が深まり様々な応用ができるようになります。
- 「Infrastructure as Code」
- 「しくみがわかるKubernetes」
- 「インフラCI 実践ガイド」
- Ansible 実践ガイド 第3版
「チューリングの計算理論入門」を読んだ
「チューリングの計算理論入門」を読んだ。 チューリングマシンってどんなだっけ?と思って、手に取った本。 シャノンの情報理論入門の著者と同じで、本の位置付けも入門で同じ。 チューリングについて語る前に、その頃の時代背景の説明や関係しそうなしなさそうな人物の紹介などについて述べて、その後チューリングの話に入るという展開。 チューリングマシンというものは、そもそも物理的な機械でなくて、数学的な理論の実装機械というものであり、その説明のために時代背景やチューリングが達成したかった数学的課題を説明している。そして、チューリングマシンは数学的な基礎だけでなく、現代のコンピュータの基礎としての位置付けとなった。
チューリングマシンとは、無限長のテープ(記憶装置)と状態を持った機械であり、状態遷移とテープの読み書きのルールを定義することであらゆるアルゴリズムを実行できるものです。
「シャノンの情報理論入門」を読んだ
「シャノンの情報理論入門」を読んだ。
学生時代の教科書として使っていたもっと堅い情報理論の本を読み返しているのだけれども、よく理解できないところがあったので、違う本も読んでみて理解を深めようと思って手にした本です。 情報理論というのは、情報というのをどのように伝達するのが効率良いのかとか意味のある情報とは何かとかそういうものを定義するものです。ある通信路を通して情報を一方から他方へ伝える場合の符号化の方法として何が最適かということを考える学問です。
堅い方の本で特によくわからなかったのは情報エントロピーでした。シャノンの情報理論入門では、エントロピーを期待値と説明していましたが、あぁ、なるほどと理解が深まりました。
本書はなるべく平易な表現で大まかに理解することを目指したものなので、タイトル通り、入門に良いと感じました。
「なっとく!アルゴリズム」を読んだ
「なっとく!アルゴリズム」を読んだ。
イラストを多く使って分かりやすくしているのがウリのアルゴリズム本とのこと。 しかし、読んでみるとなんとなくわかりづらかった。何がわかりづらいのか考えてみると、おそらく定義が無いか曖昧か後に出てくるのが原因だろうと思う。問題点の説明はできているので、問題の共有は読者との間にできていると思うが、アルゴリズムの定義がやや曖昧で、なるほどと納得するのに時間が掛かった。また、Pythonでアルゴリズムを表現しているが、全体のコードが後に出てくるため、全体を把握してから読み進めるというよりは、小さな部品から初めて完成させるというボトムアップ型の作りになっているのも関係しているかもしれない。
ただ内容については、「初めてのコンピュータサイエンス」に記載のなかったダイクストラ法等もあって幅広いアルゴリズムについて触れている。そこに惹かれたのが、本書を読んだ理由の一つでもある。
以下に、言及のあったアルゴリズムを挙げる。キーワードの紹介だけのものも含む。
二分探索
分割統治
クイックソート
幅優先探索(グラフ)
- ダイクストラ法 : 正の重みを考慮した重み付きグラフの最短経路に利用
- ベルマンフォード法 : 負の重みを考慮した重み付きグラフの最短経路に利用
貪欲法
動的計画法
k近傍法
B 木
赤黒木
スプレー木
転置インデックス
フーリエ変換
ブルームフィルタ
HyperLogLog
Simhash
「実例で学ぶRaspberry Pi電子工作 作りながら応用力を身につける」を読んだ
「Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる」を読んだ。 図書館で何か面白い本は無いかなと探していて目に留まったのがこれ。 以前から気になっていたラズパイ。何かしてみたいもののこれといってやりたいことも見当たらなかったので、本を読んで具体化できたら何か思い浮かぶかと思って読んでみた。 買い方から始まってLEDの点灯に慣れたところで、スイッチの導入、カメラ画像の入力、サーボモーターを使った4足歩行など、一通り面白そうなことをやって示していて、非常に興味深く読むことができた。
電子回路は詳しくないが、色々と説明があるためにどういう課題に対して、この回路が役に立つのかということがわかりやすく記載されていて、自分で様々な電子回路部品を購入して使ってみようという気にさせる内容であった。 カメラ画像の扱いについても基本的な画像処理まで触れられており、実践的であった。この本を借りたのもそこが決めてであった。 まだ購入に至っていないが、カメラ画像を機械学習して何かを検知、通報するような用途に使うのが面白そうなので監視カメラとしての役割で何かできないか考えてみようと思う。
「初めてのコンピュータサイエンス」を読んだ
「初めてのコンピュータサイエンス」を読んだ。 最近、Googleの入社エントリが話題になったが、やはりコンピュータサイエンスの基礎はきちんとしておかねばならないと再認識する良いきっかけになった。 大学の講義の教科書として使っていた本を読もうかと思ったが、手元になかったので図書館で何か良いものはないかと探して選んだのがこの本。 Pythonを使って説明する内容となっているためにPythonの説明から始まるが、アルゴリズムの説明などは多言語にも応用の利くように記載されていてPython以外の言語を書く人に対しても有効な記載ぶりである。 大学の講義を思い出すような内容であったが、プログラミングスタイルなどにも触れてられていて、大学の講義にはなかった内容もあって有意義であった。
今後しばらくはコンピュータサイエンス系の本を中心に読もうと思う。 次はアルゴリズム系として以下の本を読む予定。
Tag: Vue
Vue関連の書籍を読んだ
最近、Vue関連の書籍を読みましたのでその紹介です。
Webサービスを作るにあたり、フロントエンドの処理のためにVueを採用することにしたので、 その勉強のために読みました。
読んだのは以下の3冊です。 どの本も2020年にリリースされたVue.js3に対応しています。
- Vue.js3 超入門
- これからはじめる人のJavascript/Vue.jsの教科書
- みんなのVue.js
Vue.js3超入門はVue.jsについて一通り説明されていて、Vue.jsについて知るのに良いと思います。
これからはじめる人のJavascript/Vue.jsの教科書は、JavascriptとTypescriptについても説明があります。
Vue.js3超入門よりも薄いので、ボリュームは少な目ですが、広く浅くという感じで記載があります。
みんなのVue.jsはVue.jsを知っている人向けに、実装時の注意点や考え方などが記載されています。例えば、国際化対応についての記述があります。
Tag: Website
Vue関連の書籍を読んだ
最近、Vue関連の書籍を読みましたのでその紹介です。
Webサービスを作るにあたり、フロントエンドの処理のためにVueを採用することにしたので、 その勉強のために読みました。
読んだのは以下の3冊です。 どの本も2020年にリリースされたVue.js3に対応しています。
- Vue.js3 超入門
- これからはじめる人のJavascript/Vue.jsの教科書
- みんなのVue.js
Vue.js3超入門はVue.jsについて一通り説明されていて、Vue.jsについて知るのに良いと思います。
これからはじめる人のJavascript/Vue.jsの教科書は、JavascriptとTypescriptについても説明があります。
Vue.js3超入門よりも薄いので、ボリュームは少な目ですが、広く浅くという感じで記載があります。
みんなのVue.jsはVue.jsを知っている人向けに、実装時の注意点や考え方などが記載されています。例えば、国際化対応についての記述があります。
Nginxでのレスポンスボディの書き換え
Nginxでのレスポンスボディの書き換え方法を調べていたら、HTTP Substitutions Filterというのがあったので、Nginx Plusで使うかモジュールコンパイルして使うしかないのかと思っていたら、sub_moduleというモジュールがsub_filterディレクティブを提供していてこれで実現可能でした。
ちなみにApache2の場合にはExtFilterというのがあって、ここで好きなプログラムを使って自由にレスポンスを書き換え可能です。 Nginxのsub_moduleの場合は変数は利用可能であるものの単純な文字列の置換しかできないようです。HTTP Substitutions Filterの場合は、正規表現も使えるようです。 外部コマンドを使った書き換えを簡単に定義するものはないのでしょうか。
Tag: Go
VS Codeで利用するGoのバージョンを指定する方法
VS CodeのGo拡張機能を利用していると、新しいバージョンのgoがありますと良く言われます。 新しいバージョンを使うには以下の2通りの方法が考えられます。
- 古いバージョンを新しいバージョンで上書きする
- 古いバージョンを残したまま新しいバージョンを別名で用意する
後者の別名を用意する場合、どのバージョンを使うかをどこかで明示的に指定する必要があります。 プロジェクト毎にバージョンを指定する場合はgo build する際のコマンド指定で対応しても良いかもしれませんが、 一括で変更するには、VS Code側(Go拡張機能)で設定することもできます。 以下のようにsettings.jsonに記載することで使うバージョンを指定できます。
"go.alternateTools": {
"go": "/home/user/go/bin/go1.16.2"
},
肝心の別名での用意の仕方は以下です。
go install golang.x/dl/go1.16.2
go1.16.2 download
GoのEchoフレームワークのsessionの無効化
GoのWebフレームワークのEchoを使っています。Echoにはミドルウェアとしてsessionというものがあり、これを使ってセッション管理を行うことができるようになっています。 このsessionミドルウェアはバックエンドとして、gorilla/sessionsを使っています。
この仕組みを使ってセッションを実装したときに、クライアントのクッキーにセッション情報が記録されます。 これをサーバ側で無効にしたい場合等に、セッションキーをサーバ側で変えてしまうということができます。 セッションキーを変更した後で、クライアントが接続すると古いセッション情報を使うために、これは無効と判定されます。 このとき、実現したい挙動としては、古いセッション情報をクッキーから削除して新しいセッション情報を作成できるようにすることです。
Echoでは、以下のような書き方でセッション情報を取得することができます。 しかし、Getに対応するDeleteというような関数は用意されていません。
sess, err = session.Get("session", c)
セッションが存在しない場合(新規の場合)は、session.Get()でセッションが新規作成されますが、無効なセッション情報である場合には、session.Get()の結果エラーとなり有効なセッション情報が得られません。 そのため、無効なセッション情報は削除してからsession.Get()を実行する必要があります。 session.Get()がエラーになった場合に削除するということも考えましたが、処理を継続したい場合はsession.Get()より前に削除してある必要があります。 処理を継続できなくて良い場合は、削除後に再度HTTPリクエストを出してもらうように促すことで対処できます。
削除の方法として、HTTPレスポンスを返す以外に、JavaScriptで削除する方法も考えられますが、HTTP Only属性を有効にすべき種類のものなのでこれはできません。 そのため、HTTPレスポンスとしてクッキー削除のヘッダを返すことで削除する方法を採用します。 このとき注意が必要なのが、HTTPレスポンスのキャッシュです。 キャッシュが有効になっていると、HTTPクライアントはコンテンツのみをキャッシュから読み込み、HTTPヘッダによるクッキー削除が行われません。 そのため、クッキー削除のヘッダを付ける可能性のあるURLはキャッシュ無効のヘッダも併せて返す必要があります。
つまり、以下のようなヘッダを返す必要があるということです。 もちろん、動的に生成するページの場合はCache-Controlヘッダを付けなくてもキャッシュされないので、Cache-Controlヘッダは不要です。
Cache-Control: no-store Set-Cookie: session=; Path=/; Max-Age=0
もし、ほかに良いやり方があるようでしたら教えてもらえると嬉しいです。
Goのnet/httpでWebサーバを作って確認したこと
Go のnet/httpパッケージを使うと簡単にWebサーバが構築できます。 実際に動作を確認した内容について備忘録としてメモしています。
並列処理可能
特に何も工夫せずにWebサーバとして動作させるだけで、goroutineによる並列処理が可能です。
動作確認のため、Apache Bench(ab)を使って確認しましたが、1000セッション同時に処理できていました。
動作確認の際は、リクエストの応答にsleepを1秒入れて1000セッションが10リクエストを発行しました。
すると、10秒くらいですべてのリクエストが処理されました。
動作確認に使ったコマンドは以下です。
実行すると約1秒毎に1000リクエストが処理されて、約10秒後に完了します。
結果のサマリを見ても、ほとんどのリクエストが約1秒で完了していました。
ab -c 1000 -n 10000 http://localhost:8080/
レスポンスのContent-Type自動設定
レスポンスをhtmlにすると、自動的にContent-Typeがtext/htmlになりました。
レスポンスをダブルクォートで囲んだ文字列にすると、中身がhtmlでもtext/plainになりました。
強制的に変更したいときは、以下のようにして指定できます。
w.Header().Set("Content-Type", "text/html; charset=utf-8")
コード
実際の動作確認の際は、不要なものを削除したりコメントアウトしたりしながら実施していますが、
上記の確認に必要なものはこれで足りると思います。
package main
import (
"fmt"
"html"
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/", uploader)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func uploader(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-type" , "text/html; charset=utf-8")
time.sleep(1 * time.Second)
fmt.Fprintf(w, "%s", html.EscapeString(r.URL.Path)
}
A Tour of Go の split関数
A Tour of GoというGo言語のチュートリアルがあるのでそれを見ていたら、サンプルコードにsplit関数というのがあった。 split関数に17という値を渡すと、7と10の二つの値を戻り値として返す関数なのだが、1の位と10の位に分けられたの!?と驚いたので整理。
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
上記関数に17を与えると x = 7, y = 10 のそれぞれの値が返る。 x は4/9を掛けているだけで、yはxを引くだけ。なんでそれで7と10に分けられるのか。。 単純に計算すると以下の通り。
x = 17 * 4 / 9
= 68 / 9
= 7 余り 5
= 7 (intなので切り捨て)
y = 17 - 7
= 10
ふーむ。
一つ目のxの式をyの式に代入してみる。
y = sum - sum * 4 / 9
= sum * 5 / 9
sum = 17
y = 17 * 5 / 9
= 9 余り 4
= 9(intなので切り捨て)
!= 10
一致しない。 今度はsumの式として二つ目の式を一つ目の式に代入。
Goはじめ
Goを触ることにしたので、色々なドキュメントを読んだメモを書こうと思って始めたものの二つで力尽きたので続きはまた別に。
Go のインストール
tarボールを展開するだけでとりあえず終わり。 GOPATH環境変数は設定しない場合は/goが設定される。設定しなくても良い。 /go以外にしたい場合に設定すれば良いとのこと。
インストールした後に、普通設定すべきこととしてパスの設定がある。
export PATH=$PATH:$(go env GOPATH)/bin
https://golang.org/doc/install
Go の基本
以下のURLに基本が書いてあるのでとりあえずこれを読むのが良さそう。
https://golang.org/doc/code.html
$GOPATH(~/go/)が唯一のワークスペース。複数作らないで一つにする。と書いてある。 Go以外の言語では、プロジェクト毎にワークスペースがあるけれども、Goでは単一のワークスペースであることが違い。 そこ代わりに、単一のワークスペースに複数のリポジトリが含まれており、さらにそれらは複数のパッケージを含む。 リポジトリというのはバージョン管理の対象の単位。.gitディレクトリが存在するディレクトリのこと。 パッケージとは、ディレクトリ一つ毎にパッケージ一つであり、例えばパッケージ毎に異なる実行ファイルを提供する。 パッケージは複数のソースファイルを含んで良いが、ディレクトリは単一。
ワークスペースには、src/とbin/というディレクトリがあり、src/配下に複数のリポジトリを配置する。bin/には、それらの実行ファイルを配置する。
ワークスペースにはシンボリックリンクは使うべきではないとのこと。 現在のワークスペースは以下のコマンドで確認できる。
go env GOPATH
パッケージパス
自分で作ったGoソースファイルや誰かの作ったパッケージ等は、$GOPATH/src/の下のディレクトリパスを使って指定する。 fmtパッケージのような標準パッケージは短い。自分でパッケージを作成するときは将来的にも標準パッケージと同じにならないように注意する必要がある。ただし、github.comで公開するような場合は、github.com/ユーザ名 がそのベースパスとなり、その下にパッケージ名が続くようになる。
build and install
ソースファイルをビルドしてインストールするには、 go install コマンドを使う。 パッケージパスを引数に指定するか、パッケージディレクトリにcdしてからコマンドを実行する。
go install github.com/hseiyo/hello
or
cd $GOPATH/src/github.com/hseiyo/hello
go install
installできたコマンドは実行可能。 GOPATH/binをPATHに追加してあればコマンド名だけで実行可能。 go build コマンドを代わりに使うと、ビルドして実行ファイルは作成されるが、$GOPATH/binにはコピーされずにパッケージディレクトリに作成される。これも実行可能ではあるが、このパッケージが実行コマンドではなくライブラリの場合にはinstallではなく、buildを実行してパッケージディレクトリにバイナリファイルを置いておく。 他のソースファイルからimportする際に利用される。
パッケージ名
ソースファイルには必ず以下のようにようにしてパッケージ名を指定する。 同一のパッケージに所属するソースファイルはすべて同じパッケージ名を指定する。これは必ず指定が必要。 ディレクトリ名と同じ文字列をパッケージ名として指定する。
パッケージ名はほかのパッケージと同じものを利用しても問題ないが、インポートパス名は異なる必要がある。
テスト用ソースファイル
_test.goで終わるファイル名のファイルはテスト用に使用する。
testingパッケージをインポートした上で、Test<関数名>(t *testing.T)という関数を定義する。 そして以下のコマンドを実行する。
go test github.com/hseiyo/hello
or
cd $GOPATH/src/github.com/hseiyo/hello
go test
go get
例えば以下のコマンドは、リモートからファイルを取得(ダウンロード)して、ビルドしてインストール($GOPATH/bin/へのコピー)を行う。
Tag: VS Code
VS Codeで利用するGoのバージョンを指定する方法
VS CodeのGo拡張機能を利用していると、新しいバージョンのgoがありますと良く言われます。 新しいバージョンを使うには以下の2通りの方法が考えられます。
- 古いバージョンを新しいバージョンで上書きする
- 古いバージョンを残したまま新しいバージョンを別名で用意する
後者の別名を用意する場合、どのバージョンを使うかをどこかで明示的に指定する必要があります。 プロジェクト毎にバージョンを指定する場合はgo build する際のコマンド指定で対応しても良いかもしれませんが、 一括で変更するには、VS Code側(Go拡張機能)で設定することもできます。 以下のようにsettings.jsonに記載することで使うバージョンを指定できます。
"go.alternateTools": {
"go": "/home/user/go/bin/go1.16.2"
},
肝心の別名での用意の仕方は以下です。
go install golang.x/dl/go1.16.2
go1.16.2 download
Tag: セキュリティ
セキュリティガイドラインの一覧
最近、セキュリティの勉強をしているのですが、世の中にはセキュリティガイドライン(セキュリティ基準、参照すべきセキュリティ文書)がたくさんあって簡単には覚えられないので、自分で列挙しながら調べることにしました。 ただし、ガイドラインそのものは基本的に読めていません。 なお、本記事は随時更新します。
ISO/IEC 27000シリーズ
ISMSとしても知られるマネジメントについての規格。
ISO/IEC 27001
組織の ISMS を認証するための要求事項
ISO/IEC 27002
情報セキュリティ管理策の実践のための規範 ISO/IEC 27001に対して具体的な内容となっていて、27001は要求事項であり、27002は実践の要領などが記載されている。
ISO/IEC 27017
ISO/IEC 27002 に基づくクラウドサービスのための情報セキュリティ管理策の実践の規範 クラウドサービスの提供者側、利用者側に対するセキュリティ基準。
NIST SP 800シリーズ
NIST(米国国立標準技術研究所)が公開している情報セキュリティの文書群。
NIST SP 800-18
連邦情報システムのためのセキュリティ計画作成ガイド
NIST SP 800-30
リスクアセスメントの実施の手引き 数少ないらしい?リスクアセスメントに関する文書。
NIST SP 800-34
ITシステムのための緊急時対応計画ガイド
NIST SP 800-37
連邦政府情報システムに対するリスクマネジメントフレームワーク適用ガイド: セキュリティライフサイクルによるアプローチ 同様の文書として、COSOの「Enterprise Risk management - Integrated Framework」というものがある。
NIST SP 800-53
連邦政府情報システムおよび連邦組織のためのセキュリティ管理策とプライバシー管理策
NIST SP 800-57
鍵管理における推奨事項
NIST SP 800-61
コンピュータインシデント対応ガイド
NIST SP 800-63
電子的認証に関するガイドライン 上位ポリシーとして、OMB M-04-04がある。
NIST SP 800-64
システム開発ライフサイクルにおけるセキュリティの考慮事項
Tag: 準備
これから登山を始めようとする人に準備してもらいたいこと
はじめに これから登山を始めようとする人と経験者としての私が、一緒に登山に行くことを前提に、持ってきてもらいたい装備や事前準備について書いています。 登山は特別な技術を持たなくても気軽に始められる運動ですが、大怪我をする危険性もあるため安全に気を配る必要があります。 装備品によるリスク低減はできますが、絶対的なものではありません。 安全に登山を行うには、自身の体力や歩行技術をベースに、様々な知識と判断力も必要です。 はじめのうちは、安全に歩けるように体力をつけることと歩行技術を身に着けるのが良いと思います。 知識や判断については一緒に歩く経験者にある程度任せて良いと思いますので、徐々に身に着けてください。 ___ # 体づくりと靴慣らし 登山の基本は歩くことです。ザックを背負って長時間歩きます。 荷物を持った状態で数時間歩くことができる体力が必須ですので、日ごろから運動をしていない場合には、積極的に体を動かすようにして数時間の歩行ができるようにしてください。 よく知っている道を実際に荷物を持って歩いてみるのも良いです。できれば、坂道や階段のある道を上ったり下りたりして実際の登山のような負荷を掛けるようにすると、より良いと思います。 長時間歩くためには靴も重要です。登山用の靴は整地されていないでこぼこの地面で重い荷物を持って歩いても足が疲れにくいように固めに作られています。 ランニングシューズのような柔らかさはなく、足に合わないと当たって痛くなります。また、靴擦れを起こすこともあります。 靴擦れを起こした状態で長時間歩くことはかなり苦痛で、基本的に歩けません。そのため、足に合った靴を選ぶことが重要です。 また、足に合った靴だとしても、靴紐の結び方によって足に当たって痛くなったり靴擦れを起こすこともあります。新品の靴の場合には革もしくは繊維が固く歩きずらいこともあります。そのため、実際に自分で靴を履き、適切な靴紐の締め具合を知り、靴を履き慣らすことも重要です。 登山を始めたばかりの人は靴紐を緩く締めがちなので、経験者に見てもらうこともお勧めします。 ___ # ザック(リュックサック) 歩行の際に両手が自由になるようにザックを用意してください。 ザックは容量によるサイズの違いのほかに、背面長によるサイズというものがあります。 背面長によるサイズというのは身長に合わせたサイズのことです。背面長が合わないザックを使うと重く感じたりして疲れやすくなる場合があります。 登山用品店や経験者にも見てもらって選んでください。 ザックの容量は30~40リットルくらいが良いと思います。 なお、肩掛けのカバンのようにぶらぶらするものや紐が長く枝などに引っ掛かりやすいものは危険なので、基本的には使いません。 ___ # 服装(ウェア) 季節によらず長袖長ズボンがおすすめです。ケガの防止と日焼けの防止が理由です。 暖かい季節は暑そうと想像するかもしれませんが、夏用の涼しい素材のものであればそれほど暑くありませんし、日焼けによる火照りに比べればずっと涼しいです。 登山は歩くだけですが、基本的に傾斜のある道を歩くため、意外に負荷の高い運動になります。また、荷物による負荷も加わります。そのため、歩行中は体が暖かくなり汗をかきます。 そして、休憩中は汗冷えにより寒く感じることもあります。寒い時期には歩き始めは寒くても、しばらくすると汗ばむようになります。 このように体感温度はその時々で変わります。そのため、薄手のウェアを着たり脱いだりすることで温度調節をするのがおすすめです。 厚手のウェアでは暑すぎて快適な状態を作り出せないことがあります。 寒い時期で歩き出しは暖かい恰好だったとしても、30分以内くらいに暑くなり1枚脱ぐことがよくあります。その後の休憩では脱いだものをまた着て、昼食の休憩ではさらに1枚着るというような感じで薄手のものを複数枚重ねて着たり、脱いだりできるようにしておくのがおすすめです。 素材としては化学繊維のものが扱いやすいです。ウールも良いです。ダウンは濡れると保温性がなくなるのでそこに注意すれば小さく軽いという利点が活きます。 ___ # 装備(持ち物) ザックにすべて入れて持ち運ぶようにしてください。また、雨に濡れて困るものは濡れないようにビニール袋に入れた上でザックに入れるようにするのが無難です。 ## 食料関連 登山中の栄養補給と水分補給が必要です。 朝食は登山前に済ませておいて、昼食のみ登山中に取ることを前提にします。 水分は1日あたり1.5リットルくらいを目安に持っておくのが良いですが、行動時間や季節を踏まえて調節してください。荷物の重さにも直結します。 行動食というのは、歩きながら食べるか座らない小休止(休憩)の際に食べるものです。時々食べてエネルギーや栄養素の補給を行います。 - 水筒1リットル分(中身は水、お茶、スポーツドリンクなど何でもOK。ペットボトルでもOK) - 行動食(塩分を含むしょっぱい系と、糖分を含む甘い系のお菓子や軽食など) - 昼食(おにぎりやパンなど手軽に食べられるものがおすすめ。箸を使うものはやや手間。) ## ウェア関連 服装のところで説明したもの以外に、レインウェア(雨具)とヤッケ(風除け)があると安心です。 - レインウェア(長袖長ズボンでフード付きのもの。透湿素材のものが蒸れにくくおすすめ。ただし、高価) - ヤッケ(主に防風による保温を目的にした薄手のジャケット。レインウェアを風除けとして利用しても良い) ## 情報関連 持っておくべきものもしくは知っておくべき情報があります。 - 地図(登山口から下山口までと、公共交通機関から/までの道順がわかるもの) - 当日の天気予報 - 緊急連絡先(同行者に何かあった際の連絡先) - 登山計画書(登山ルート、同行者、緊急連絡先、持病などを記載し、管轄の都道府県警に提出したもの) ## 生活必需品 服薬中の薬やコンタクトレンズなど、なくてはならないものは場合によっては予備も必要です。 - 薬(持病がある場合など) - 眼鏡、コンタクトレンズ - お金(移動のためのSuicaやクレジットカードなども含む) ## 非常用装備 遭難時やケガに備えて持っておくべきものがあります。 - ヘッドライト(手ぶらで足元を照らして歩けるのであれば、ヘッドライトでなくても可) - 非常食(弱った状態でも簡単に食べられるもの。片手で食べられるもの) - 携帯電話 - 救急セット(ケガ、病気に対応するもの。何を持つべきかは別に説明予定) ___ # おわりに あると便利なものはほかにもたくさんありますが、荷物を増やすとそれだけ重くなり歩くのも大変になります。 重い荷物を背負うと体力を消耗する上に、バランスを崩しやすくなり転倒のリスクが上がります。 念のためと思って荷物を増やしたために遭難してしまうということもあります。 重要なのは、予定する登山コースの長さや天気に合わせて必要なものを選択する判断力です。 経験を積むと自分にとっての必要最小限の装備が何かというのが徐々にわかってきます。 最初のうちは装備のいくつかを経験者に頼ることもあるかもしれませんが、体力に余裕が出てきたら徐々に必要な荷物を自分ですべて持ち、徐々に無駄な装備を減らしていくと良いと思います。
Tag: Modprobe
Linux Kernelが対応していないUSBデバイスを使用する方法
ここで言うLinux Kernelが対応していないUSBデバイスというのは、デバイスのベンダーID(VID)とプロダクトID(PID)がカーネルのドライバが知らないために、ドライバはあるのにデバイスを認識しないということになってしまうデバイスのことを指します。 つまり、ドライバが知らないVID、PIDのUSBデバイスを使用する方法ということです。 以下の二つがあります。一つ目しか知らなかったのですが二つ目を知って便利になったのでここに書きます。
- ドライバをコンパイル
- ドライバに/sys のnew_idを使ってIDを伝える
ドライバをコンパイル
私の知る限り、USBデバイス用のドライバは通常、いくつかの(と言っても多数の)VIDとPIDの組み合わせを知っています。そしてその情報はソースコードに埋め込まれています。そのため新しいUSBデバイスに対応するためにはソースコードの修正を行って、コンパイルして利用する必要があります。 Linux Kernelに付属のドライバを使う場合には、以下の記事にあるような方法でコンパイルして利用する必要があります。しかし、Linux Kernelに付属のドライバはKernelバージョン毎にあるためKernelのアップデートをする度にドライバのコンパイルが必要になってしまいます。
Kernel アップデートの度にコンパイルするのはかなりの手間なのでこれを防ぐには、Kernelのアップストリームに取り込んでもらう手があります。修正内容としてはVIDとPIDが列挙されている個所に1つ追加するだけなので軽微ですが、Linux Kernelの修正の流儀がわかっておらず依頼していません。
ドライバに/sys のnew_idを使ってIDを伝える
ドライバに動的にVID PIDを伝えることでデバイスを使えるようにする方法があります。 /sys/bus/usb/drivers/の下にドライバ名のディレクトリがあればその下のnew_idにVID PIDを書き込みます。 するとドライバがそのデバイスを利用可能にしてくれます。 ドライバ名のディレクトリがない場合は該当のドライバが読み込まれていないのでmodprobeコマンドで読み込む必要があります。
echo "0411 014F" > /sys/bus/usb/drivers/rt2800usb/new_id
modprobeコマンドで読み込むのを自動で行うには/etc/modulesファイルにドライバ名を書きます。 また、/etc/modprobe.d/の下に拡張子を.confにしたファイルを置いて以下のように書くとOS起動時に上記コマンドまで実施してくれて便利です。
install rt2800usb /sbin/modprobe -i rt2800usb; echo "0411 014F" > /sys/bus/usb/drivers/rt2800usb/new_id
Tag: Nginx
Nginxでのレスポンスボディの書き換え
Nginxでのレスポンスボディの書き換え方法を調べていたら、HTTP Substitutions Filterというのがあったので、Nginx Plusで使うかモジュールコンパイルして使うしかないのかと思っていたら、sub_moduleというモジュールがsub_filterディレクティブを提供していてこれで実現可能でした。
ちなみにApache2の場合にはExtFilterというのがあって、ここで好きなプログラムを使って自由にレスポンスを書き換え可能です。 Nginxのsub_moduleの場合は変数は利用可能であるものの単純な文字列の置換しかできないようです。HTTP Substitutions Filterの場合は、正規表現も使えるようです。 外部コマンドを使った書き換えを簡単に定義するものはないのでしょうか。
Tag: Vagrant
vagrant failed with "`chmod': Operation not permitted @ chmod_internal - /home/user/.vagrant.d/insecure_private_key (Errno::EPERM)"
vagrant コマンドを実行すると以下のエラーが出て失敗しました。
/usr/lib/ruby/vendor_ruby/vagrant/environment.rb:858:in `chmod': Operation not permitted @ chmod_internal - /home/user/.vagrant.d/insecure_private_key (Errno::EPERM)
from /usr/lib/ruby/vendor_ruby/vagrant/environment.rb:858:in `chmod'
from /usr/lib/ruby/vendor_ruby/vagrant/environment.rb:858:in `copy_insecure_private_key'
from /usr/lib/ruby/vendor_ruby/vagrant/environment.rb:152:in `initialize'
from /usr/bin/vagrant:169:in `new'
from /usr/bin/vagrant:169:in `<main>'
environment.rbを見てみると、chmod で 0600 にしようとして失敗しているようです。 /home/user/.vagrant.d/insecure_private_key はvagrantコマンドを実行するユーザのオーナーになっていなかったために失敗していたので、オーナーを変更することでエラーなく実行できるようになりました。
PC上でのIaC環境の概要(GWアドベントカレンダー 4日目)
この記事はGWアドベントカレンダーの4日目の記事です。
自宅のPCにIaC環境を構築中ですが、その環境について少し説明します。
使用するツール
1台の物理Linuxサーバ上にすべての環境を構築します。 仮想マシンはVagrant + Virtual Boxで構築します。 コンテナはDockerで構築します。 構築ツールとしてAnsibleを使います。 CI/CDを実現するためのツールとしてGitlab、Gitlab Runnerを使います。
Gitlab、Gitlab Runnerの構築
GitlabとGitlab RunnerはAnsibleを使って、仮想マシンから作成します。 本番用とテスト用があり、テスト用の構築は本番用のGitlabのバックアップデータを使ってリストアすることで本番と同じデータを持つようにしています。
物理Linuxサーバの構築
OSインストール後の各種設定類はAnsibleにまとめようと思っていますが、まだできていません。
AnsibleとVagrantの連携
Ansibleのプレイブック(Gitlabのパイプラインからの呼び出しや手動実行)によって、Vagrant経由で仮想マシンを作成することがあります。 しかし、AnsibleのInventory PluginとしてはVagrant用のものが正式にはありません。そのため、作成した仮想マシンに対してプレイブックを実行するためには何らかの方法を考える必要があります。 一つはInventory PluginもしくはScriptを作ること、もう一つは作成する仮想マシン情報をあらかじめインベントリファイルに記載しておくことが考えられます。 どちらの方法でも実現できそうですが、どのようにするか検討中です。
今後の展望
- 物理Linuxサーバ構築用のパイプライン構築
- Kubernetesを動かす。 その上で、各種アプリケーションを動かす予定です。
vagrant up 失敗の原因究明 その2
というわけで、前回の続きです。
前回、原因究明はできたけれどもその報告ができていませんでした。 一日以上経って、ようやくForumにポストできました。
Can the failure message be improved? When VBoxManage.exe import failed with no disk space.
そして、Forum Postig Guideのデッドリンクについてもポストしておきました。
Dead link found in The Forum Posting Guide
誰か反応してくれると良いなぁ。。
vagrant up 失敗の原因究明
vagrant upがなぜか失敗するのでその原因究明をしたときの話です。
事象
PS E:\vagrant> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'hashicorp/precise64' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box 'hashicorp/precise64'
default: URL: https://vagrantcloud.com/hashicorp/precise64
==> default: Adding box 'hashicorp/precise64' (v1.1.0) for provider: virtualbox
default: Downloading: https://vagrantcloud.com/hashicorp/boxes/precise64/versions/1.1.0/providers/virtualbox.box
default: Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com
default:
==> default: Successfully added box 'hashicorp/precise64' (v1.1.0) for 'virtualbox'!
==> default: Importing base box 'hashicorp/precise64'...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.
Command: ["import", "\\\\?\\E:\\vagrant_home\\.vagrant.d\\boxes\\hashicorp-VAGRANTSLASH-precise64\\1.1.0\\virtualbox\\box.ovf", "--vsys", "0", "--vmname", "precise64_1571241203898_82313", "--vsys", "0", "--unit", "12", "--disk", "D:/VMimages/precise64_1571241203898_82313/box-disk1.vmdk"]
Stderr: 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interpreting \\?\E:\vagrant_home\.vagrant.d\boxes\hashicorp-VAGRANTSLASH-precise64\1.1.0\virtualbox\box.ovf...
OK.
0%...
Progress state: E_INVALIDARG
VBoxManage.exe: error: Appliance import failed
VBoxManage.exe: error: Code E_INVALIDARG (0x80070057) - One or more arguments are invalid (extended info not available)
VBoxManage.exe: error: Context: "enum RTEXITCODE __cdecl handleImportAppliance(struct HandlerArg *)" at line 957 of file VBoxManageAppliance.cpp
Tag: MovableType
cpanm Safeでインストールしようとするとテストでエラーとなって失敗する
cpanm Safeでインストールしようとするとテストでエラーとなって失敗しました。 対処法わからず。。。
Running Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Safe
Writing MYMETA.yml and MYMETA.json
-> OK
Checking dependencies from MYMETA.json ...
Checking if you have ExtUtils::MakeMaker 0 ... Yes (6.68)
Building and testing Safe-2.35
cp Safe.pm blib/lib/Safe.pm
Manifying blib/man3/Safe.3pm
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/safe1.t .......... ok
t/safe2.t .......... ok
t/safe3.t .......... ok
Possible unintended interpolation of @INC in string at /usr/lib64/perl5/DynaLoader.pm line 90.
# Failed test 'Can load version.pm in a Safe compartment'
# at t/safeload.t line 26.
# Unable to create sub named "*Safe::Root0::version::vxs::numify" at /usr/local/lib64/perl5/version.pm line 48.
# Compilation failed in require at (eval 11) line 1.
# BEGIN failed--compilation aborted at (eval 11) line 1.
# Looks like you failed 1 test of 3.
t/safeload.t .......
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/3 subtests
t/safenamedcap.t ... ok
t/safeops.t ........ skipped: PERL_CORE unset
t/saferegexp.t ..... ok
t/safesort.t ....... ok
t/safeuniversal.t .. ok
t/safeutf8.t ....... ok
t/safewrap.t ....... ok
Test Summary Report
-------------------
t/safeload.t (Wstat: 256 Tests: 3 Failed: 1)
Failed test: 1
Non-zero exit status: 1
Files=11, Tests=98, 1 wallclock secs ( 0.04 usr 0.02 sys + 0.53 cusr 0.08 csys = 0.67 CPU)
Result: FAIL
Failed 1/11 test programs. 1/98 subtests failed.
make: *** [test_dynamic] Error 255
-> FAIL Installing Safe failed. See /root/.cpanm/work/1592328454.16336/build.log for details. Retry with --force to force install it.
vim plugin mtdataapi の更新記録(ダウンロード機能追加)
mtdataapiに記事のダウンロード機能を設けました。
以下のコマンドでダウンロードできます。 ダウンロード先は、g:mt_basedir です。この配下にサイトIDのディレクトリが作られます。各エントリはエントリIDのファイル名になります。
let g:mt_basedir = $HOME/mtblog
:mtdataapi#downloadSiteToFile()
Movable Type Data API v4 の authenticationでBad Gateway
以下のマニュアルを参照してMovable Type 7のData API v4 の authentication を試したが、なかなかうまくいかなかった。 原因は clientId の I が小文字になっていたためだった。
マニュアルの例のところが小文字になっていたのでそれを参考にしていたのが間違い。
Tag: Safe
cpanm Safeでインストールしようとするとテストでエラーとなって失敗する
cpanm Safeでインストールしようとするとテストでエラーとなって失敗しました。 対処法わからず。。。
Running Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Safe
Writing MYMETA.yml and MYMETA.json
-> OK
Checking dependencies from MYMETA.json ...
Checking if you have ExtUtils::MakeMaker 0 ... Yes (6.68)
Building and testing Safe-2.35
cp Safe.pm blib/lib/Safe.pm
Manifying blib/man3/Safe.3pm
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/safe1.t .......... ok
t/safe2.t .......... ok
t/safe3.t .......... ok
Possible unintended interpolation of @INC in string at /usr/lib64/perl5/DynaLoader.pm line 90.
# Failed test 'Can load version.pm in a Safe compartment'
# at t/safeload.t line 26.
# Unable to create sub named "*Safe::Root0::version::vxs::numify" at /usr/local/lib64/perl5/version.pm line 48.
# Compilation failed in require at (eval 11) line 1.
# BEGIN failed--compilation aborted at (eval 11) line 1.
# Looks like you failed 1 test of 3.
t/safeload.t .......
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/3 subtests
t/safenamedcap.t ... ok
t/safeops.t ........ skipped: PERL_CORE unset
t/saferegexp.t ..... ok
t/safesort.t ....... ok
t/safeuniversal.t .. ok
t/safeutf8.t ....... ok
t/safewrap.t ....... ok
Test Summary Report
-------------------
t/safeload.t (Wstat: 256 Tests: 3 Failed: 1)
Failed test: 1
Non-zero exit status: 1
Files=11, Tests=98, 1 wallclock secs ( 0.04 usr 0.02 sys + 0.53 cusr 0.08 csys = 0.67 CPU)
Result: FAIL
Failed 1/11 test programs. 1/98 subtests failed.
make: *** [test_dynamic] Error 255
-> FAIL Installing Safe failed. See /root/.cpanm/work/1592328454.16336/build.log for details. Retry with --force to force install it.
Tag: Starman
cpanm Safeでインストールしようとするとテストでエラーとなって失敗する
cpanm Safeでインストールしようとするとテストでエラーとなって失敗しました。 対処法わからず。。。
Running Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Safe
Writing MYMETA.yml and MYMETA.json
-> OK
Checking dependencies from MYMETA.json ...
Checking if you have ExtUtils::MakeMaker 0 ... Yes (6.68)
Building and testing Safe-2.35
cp Safe.pm blib/lib/Safe.pm
Manifying blib/man3/Safe.3pm
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/safe1.t .......... ok
t/safe2.t .......... ok
t/safe3.t .......... ok
Possible unintended interpolation of @INC in string at /usr/lib64/perl5/DynaLoader.pm line 90.
# Failed test 'Can load version.pm in a Safe compartment'
# at t/safeload.t line 26.
# Unable to create sub named "*Safe::Root0::version::vxs::numify" at /usr/local/lib64/perl5/version.pm line 48.
# Compilation failed in require at (eval 11) line 1.
# BEGIN failed--compilation aborted at (eval 11) line 1.
# Looks like you failed 1 test of 3.
t/safeload.t .......
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/3 subtests
t/safenamedcap.t ... ok
t/safeops.t ........ skipped: PERL_CORE unset
t/saferegexp.t ..... ok
t/safesort.t ....... ok
t/safeuniversal.t .. ok
t/safeutf8.t ....... ok
t/safewrap.t ....... ok
Test Summary Report
-------------------
t/safeload.t (Wstat: 256 Tests: 3 Failed: 1)
Failed test: 1
Non-zero exit status: 1
Files=11, Tests=98, 1 wallclock secs ( 0.04 usr 0.02 sys + 0.53 cusr 0.08 csys = 0.67 CPU)
Result: FAIL
Failed 1/11 test programs. 1/98 subtests failed.
make: *** [test_dynamic] Error 255
-> FAIL Installing Safe failed. See /root/.cpanm/work/1592328454.16336/build.log for details. Retry with --force to force install it.
Tag: Docker
insecure registry of Docker(GWアドベントカレンダー 8日目)
この記事はGWアドベントカレンダーの8日目の記事です。
GitLabのパイプラインでdocker loginしようとすると以下のエラーで失敗しました。
docker -l debug login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} http://${CI_REGISTRY}
Error response from daemon: Get https://xxx.xxx.xxx.xxx:4567/v2/: http: server gave HTTP response to HTTPS client
以下にあるdaemon.jsonの設定をrunnerに追加することで解決しました。 registryをHTTPS化することも考えましたが、このregistryがリバースプロキシ配下になく、一旦HTTPのままで対処しました。
PC上でのIaC環境の概要(GWアドベントカレンダー 4日目)
この記事はGWアドベントカレンダーの4日目の記事です。
自宅のPCにIaC環境を構築中ですが、その環境について少し説明します。
使用するツール
1台の物理Linuxサーバ上にすべての環境を構築します。 仮想マシンはVagrant + Virtual Boxで構築します。 コンテナはDockerで構築します。 構築ツールとしてAnsibleを使います。 CI/CDを実現するためのツールとしてGitlab、Gitlab Runnerを使います。
Gitlab、Gitlab Runnerの構築
GitlabとGitlab RunnerはAnsibleを使って、仮想マシンから作成します。 本番用とテスト用があり、テスト用の構築は本番用のGitlabのバックアップデータを使ってリストアすることで本番と同じデータを持つようにしています。
物理Linuxサーバの構築
OSインストール後の各種設定類はAnsibleにまとめようと思っていますが、まだできていません。
AnsibleとVagrantの連携
Ansibleのプレイブック(Gitlabのパイプラインからの呼び出しや手動実行)によって、Vagrant経由で仮想マシンを作成することがあります。 しかし、AnsibleのInventory PluginとしてはVagrant用のものが正式にはありません。そのため、作成した仮想マシンに対してプレイブックを実行するためには何らかの方法を考える必要があります。 一つはInventory PluginもしくはScriptを作ること、もう一つは作成する仮想マシン情報をあらかじめインベントリファイルに記載しておくことが考えられます。 どちらの方法でも実現できそうですが、どのようにするか検討中です。
今後の展望
- 物理Linuxサーバ構築用のパイプライン構築
- Kubernetesを動かす。 その上で、各種アプリケーションを動かす予定です。
Docker Desktop for Windowsの導入
Docker Desktop for Windowsを導入してみました。
dockerコンテナを作って動かしたいのが目的です。 Windowsを使うのは、普段使っているOSがWindowsだからで、コンテナはLinuxのものを使います。 そうしたときに、docker Engineをどこで動かすかの選択肢があります。
- Windows (Docker Desktop for Windows)
- Windows上のLinux VM(Hyper-VやVirtual Box上のLinux VMでLinux用のDocker Engineを動かす)
開発用にLinux VMを動かしているのでそちらでDockerを使っても良いのですが、わざわざVMを起動して使うのも面倒そうなのでWindows上で動かすことにしました。 ただ、Windows上で動かすと言っても、実際にはDocker用のLinux VMがHyper-Vを使って起動します。 そのため、自分でLinux VMを用意して動かすのと仕組みはそれほど変わりません。
Docker Desktop for Windowsの場合、Docker ClientはWindows上で動きますが、Docker EngineはLinux VM上で動きます。 自分でLinux VMを用意して使う場合はDocker ClientもDocker EngineもLinux VM上で動きます。 コンテナそのものはどちらもLinux VM上で動きます。
Docker Desktop for Windowsを使う場合、DockerfileやコンテナにコピーするファイルをLinux VMから利用できるようにする必要があります。 どのドライブをアクセス可能にするかは、settingsから設定できます。 なお、コンテナからマウントして使うようなデータ領域としてはWindows上の領域は不向きで、data volumeやdata containerを使う方が良いようです。これには二つの理由があって、一つはWindows上の領域はLinux上からみて、rwxrwxrwxのモードで見えます。もう一つは、SMBを使ってLinux VMに領域を見せる際、NOBRLオプションが付いているため、ロックができない場合がある点です。 これらはDocker Desktop for Windowsのドキュメントの最初の方(Shared drives)に書いてあります。
と、ここまでやってから大事なことに気づきました。 開発用にLinux VMを動かしていますが、そちらはVirtual Boxを使っています。 Docker Desktop for WindowsはHyper-Vを使います。 これらの共存はできないので、どちらを使うか選ぶ必要があります。。つづく。。
kubenetes導入顛末記 その2
その1でとりあえず動作するところまで確認できたので、ここからはチュートリアルに沿ってやってみる。
https://kubernetes.io/docs/tutorials/hello-minikube/
nodeアプリケーション作成
server.jsというhello worldを作成。
node server.jsで動作確認して問題ないことを確認。
Docker Containerイメージ作成
Dockerfileを作成。
以下のコマンドで環境変数を設定。そしてビルド。
eval $(minikube docker-env)
docker build -t hello-node:v1 .
`
`Deployment作成
以下のコマンドでPodも作成されて動いているらしい。
でも、ローカルIPからしか接続できないらしい。試しにminikube sshでログインしてみたけども8080ポートで待ち受けているプロセスはなかった。。nodeコマンドは動作中だったので他のポートで待っているみたいだけど。どこで変換しているのか。。
kubectl run hello-node --image=hello-node:v1 --port=8080 --image-pull-policy=Never
Service作成
外からもアクセスできるようにServiceを作成する。
kubectl expose deployment hello-node --type=LoadBalancer
以下のコマンドで得られるURLにアクセスすると無事に表示される。どのポートで待っているのかの謎はこれで解ける。でも、ポートが8080ではないんだな。なんでだろ。
minikube service --url hello-node
アクセスログは以下で参照できた。pod-nameも補完してくれて良い感じ。
kubectl logs <POD-NAME>
アプリの更新
Docker Containerイメージを作成してDeploymentを更新。
docker build -t hello-node:v2 .
kubectl set image deployment/hello-node hello-node=hello-node:v2
これだけで新しいイメージが使われるようになった。Dashboardでも確認。
heapster addonの有効化
性能監視用のaddonらしい。以下で有効にするとdashboardのoverviewでCPUとメモリのグラフが表示されて、ほかのところにもそういった情報が追加される。
minikube addons enable heapster
Clean up
作成したものを削除する。
kubenetes導入顛末記 その1
前置き
コンテナに触れようと思い、kubenetesを導入することにしたので、その記録。
導入先はUbuntu 16.04の物理サーバ1台です。
導入方法の決定
kubenetesの導入方法はいろいろあるようですが、とりあえず動かしたいならminikubeがおすすめと記載があるのでそれに従う。
選び方はこちら。
選んだのは、Running Kubernetes Locally via Minikube。
Kubenetes導入の前にHypervisor導入
手順を見ていくと最初にHypervisorを入れろとある。ただ、VM上に構築しないという手もあるらしい。
記載順などからVirtual Boxが良さそうなのでVirtualBoxを採用。
ということで、まずはVirtualBoxの導入。以下のURLに従ってaptのsourceを指定してインストール。
https://www.virtualbox.org/wiki/Linux_Downloads
minikube導入の前にkubectl導入
以下の通り、こちらもaptのsourceを設定してinstall。
https://kubernetes.io/docs/tasks/tools/install-kubectl/
ちなみにこの状態で kubectl cluster-infoを実行すると以下の通り。
$ kubectl cluster-info
Kubernetes master is running at http://localhost:8080
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
The connection to the server localhost:8080 was refused - did you specify the right host or port?
kubectlのautocompletion設定
ここも前述のガイドにならって設定する。
echo "source <(kubectl completion bash)" >> ~/.bashrc
minikubeの導入
ここでようやくminikubeの導入。
Tag: IaC
insecure registry of Docker(GWアドベントカレンダー 8日目)
この記事はGWアドベントカレンダーの8日目の記事です。
GitLabのパイプラインでdocker loginしようとすると以下のエラーで失敗しました。
docker -l debug login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} http://${CI_REGISTRY}
Error response from daemon: Get https://xxx.xxx.xxx.xxx:4567/v2/: http: server gave HTTP response to HTTPS client
以下にあるdaemon.jsonの設定をrunnerに追加することで解決しました。 registryをHTTPS化することも考えましたが、このregistryがリバースプロキシ配下になく、一旦HTTPのままで対処しました。
Ansible実践ガイドを読んだ。(GWアドベントカレンダー 7日目)
この記事はGWアドベントカレンダーの7日目の記事です。
「Ansible 実践ガイド 第3版」を読みました。 この本は、これからAnsibleを始めようとする方や少し触ってみたものの、実際の環境にどのように適用すべきか検討し始めたくらいの方に最適と思います。 ただ、既に色々とAnsibleを適用しているものの構成が複雑で保守しづらくなってしまうというような方にも向いていると思います。 具体的なプレイブックの例がいくつも紹介されており、それぞれにプレイブックのノウハウがあります。
AnsibleやYAMLについての基本的な説明から始まっていて、その後具体的なプレイブックの紹介や保守性を考慮したディレクトリ構成等の実践的な内容へと移っていきます。 プレイブックのデバッグ方法についても様々な手法が説明されており、Ansibleを利用していく上で必要なことが一通り学べるようになっていると思います。
Infrastructure as Code関連の書籍紹介(GWアドベントカレンダー 6日目)
この記事はGWアドベントカレンダーの6日目の記事です。
IaCに関連する最近読んだ本の紹介です。 読んだ順に書いていますが、Ansible実践ガイドはまだ記事を書いていないのでここで簡単に紹介します。 Ansible を自由に利用できるようになるための基礎が幅広く記載されています。そのため、「インフラCI 実践ガイド」にもAnsibleが使われていますが、この内容を理解するのにも役立ちました。 また、これから新規にプレイブックを作るときの設計のポイントも記載されています。 Linuxサーバ向けだけでなく、Windowsやネットワーク機器向けの設定についても記載されており、これらを理解することでAnsibleのエコシステムや思想の理解が深まり様々な応用ができるようになります。
- 「Infrastructure as Code」
- 「しくみがわかるKubernetes」
- 「インフラCI 実践ガイド」
- Ansible 実践ガイド 第3版
sshのauthorized_keysの高速化(GWアドベントカレンダー 5日目)
この記事はGWアドベントカレンダーの5日目の記事です。
Gitlabのリポジトリにsshで接続するときはOSのgitユーザを使います。 このユーザはGitlabのユーザすべてで共用します。 そのため、全利用者の公開鍵情報をgitユーザに紐付けて管理する必要があります。
これを実現する方法として、gitユーザのauthorized_keysに全ユーザ分の公開鍵を書いておく方法がありますが、sshアクセスの度にファイルを上からスキャンし、確認する必要があり効率が悪いです。 そこでユーザ名に応じた公開鍵を返すコマンドを用意することで余計な確認を減らすことで高速化することができる仕組みがあります。
以下にGitlabでの設定の仕方が書いてありますが、OpenSSHの提供するAuthorizedKeysCommandという設定を使うことで実現できます。この設定に、公開鍵を返すコマンドを指定します。
Fast lookup of authorized SSH keys in the database
この仕組みを使うと、gitユーザのauthorized_keysに公開鍵を記載する必要がありません。
PC上でのIaC環境の概要(GWアドベントカレンダー 4日目)
この記事はGWアドベントカレンダーの4日目の記事です。
自宅のPCにIaC環境を構築中ですが、その環境について少し説明します。
使用するツール
1台の物理Linuxサーバ上にすべての環境を構築します。 仮想マシンはVagrant + Virtual Boxで構築します。 コンテナはDockerで構築します。 構築ツールとしてAnsibleを使います。 CI/CDを実現するためのツールとしてGitlab、Gitlab Runnerを使います。
Gitlab、Gitlab Runnerの構築
GitlabとGitlab RunnerはAnsibleを使って、仮想マシンから作成します。 本番用とテスト用があり、テスト用の構築は本番用のGitlabのバックアップデータを使ってリストアすることで本番と同じデータを持つようにしています。
物理Linuxサーバの構築
OSインストール後の各種設定類はAnsibleにまとめようと思っていますが、まだできていません。
AnsibleとVagrantの連携
Ansibleのプレイブック(Gitlabのパイプラインからの呼び出しや手動実行)によって、Vagrant経由で仮想マシンを作成することがあります。 しかし、AnsibleのInventory PluginとしてはVagrant用のものが正式にはありません。そのため、作成した仮想マシンに対してプレイブックを実行するためには何らかの方法を考える必要があります。 一つはInventory PluginもしくはScriptを作ること、もう一つは作成する仮想マシン情報をあらかじめインベントリファイルに記載しておくことが考えられます。 どちらの方法でも実現できそうですが、どのようにするか検討中です。
今後の展望
- 物理Linuxサーバ構築用のパイプライン構築
- Kubernetesを動かす。 その上で、各種アプリケーションを動かす予定です。
GitlabとGitlab Runnerのバージョン情報(GWアドベントカレンダー 3日目)
この記事はGWアドベントカレンダーの3日目の記事です。
GitlabとGitlab Runnerのバージョン情報がどこにあるのか書きます。 最新バージョンが出たかどうかを知るときや、アップデートするときのバージョンを指定したい場合に具体的なバージョンを知る必要があります。 実際には使用するリポジトリのバージョン名を知る必要がありますが、開発元のリリース情報は以下にあります。 なお、GitlabとGitlab Runnerのバージョンは対応していて、同じバージョンがリリースされるみたいです。
Gitlabのリリース情報
ここにあります。
Gitlab Runnerのリリース情報
ここにあります。
CIサーバのデプロイ方法(GWアドベントカレンダー 2日目)
この記事はGWアドベントカレンダーの2日目の記事です。
1日目の記事で、CDの対象にすべきではありませんと述べましたが、ではどのようにデプロイすべきでしょうか。 CIサーバのデプロイ方法と言っても、単なるインストール手順のことではありません。CIサーバのライフサイクルを考えた上でデプロイ手順全体を指します。 なお、本記事ではGitlabを対象に述べます。
本番用CIサーバのライフサイクル
まずは本番用のCIサーバのライフサイクルについて考えます。
- サーバデプロイ(OS構築)
- Gitlabインストール
- Gitlabアップデート
- Gitlabアップデート
- 以後、アップデートを繰り返す
上記のように、一度インストールした後はアップデートを繰り返します。 アップデートの際に新バージョンのインスタンスを用意すれば良いように思うかもしれませんが、GitlabはDBにデータを持っていて、異なるバージョン間でのリストアはサポートされていません。 Gitlabの場合、バックアップの仕組みを持っていますが、リストアできるバージョンは、 バックアップ取得時と同じバージョンのみがサポートされています。 そのため、アップデート済みの新インスタンスを用意してもそこへ旧バージョンのデータをリストアすることはできません。
テスト用CIサーバのライフサイクル
次にテスト用のCIサーバについて考えます。 テスト用のCIサーバは本番用と同じ操作を実施すべきなので、 テストの度に、本番用CIサーバと同じバージョンのものを再構築して動作を確認します。 ここで本番用CIサーバのバックアップデータを使ってテスト用CIサーバを構築するのがポイントです。 バックアップデータには各種プロジェクト情報やその設定値などが含まれています。これらのデータも本番用と同じものを使ってテストするのが理想的です。 したがって、テスト用CIサーバのライフサイクルは以下のようになります。
- サーバデプロイ(OS構築)
- Gitlabインストール
- 本番用Gitlabのバックアップデータをリストア
- Gitlabアップデート
- 以後、サーバデプロイから繰り返す
本番用CIサーバのデプロイ方法
前述のように本番用CIサーバを一度構築した後は、アップデートの適用のみを実施するようなケースを考えた場合には、その都度、アップデートを適用する方法が考えられます。 この方法の場合には、初期構築手順とアップデート手順の二つがあれば良いことになります。 これらの手順を自動化しておくことで効率的にデプロイが実現できます。 ただし、故障発生などにより最初から構築する必要があった場合に、正しく構築できるかどうか懸念が残ります。
これを解決するのがImmutable Serverです。1日目の記事でCDの対象外と述べましたが、パイプライン中でのデプロイを行わないのであれば、テスト用CIサーバを本番用CIサーバとして利用するように切り替えることも可能です。 こうすることでImmutable ServerとしてCIサーバを扱うことができます。 しかし、このような運用をする場合には注意点があります。本番用のDBバックアップを取得してから本番用CIサーバに対し何か変更があると(管理対象プロジェクトのコミット等)、それが失われる可能性があります。 つまり、利用を制限した上でバックアップから切り替えまでを完了できる必要があります。 これは多くの場合は難しいと思います。
結論
結局のところ、Immutable Serverとして扱うよりも、常にアップデートし続けるデプロイ方法の方が現実的ではないかと考えています。
明日はGitlabのバージョン情報について書く予定です。
CIサーバ自身のCI/CD(GWアドベントカレンダー 1日目)
この記事はGWアドベントカレンダーの1日目の記事です。
Infrastructure as Codeの考えでは、アプリケーションだけでなくインフラ部分(OSやミドルウェアなど)についてもCI/CDの対象として扱います。 この記事では、IaCに取り組もうと考えて最初に悩む(?)CIサーバ自身のCI/CDについて説明します。
CIサーバというのは、JenkinsやGitlabのようにコミットやプッシュを契機(trigger)に自動的にジョブを実行する機能を持つサーバのことです。 CIサーバ自身も様々な設定を持つ重要なサーバであり、管理対象です。
本記事では簡単のためにCIを自動構築と自動テストと定義します。また、CDを自動デプロイと定義します。 CI/CDのパイプラインとして自動にすべき部分や手動にすべき部分がありますが、本記事ではすべて自動で実施する場合としています。
前提
IaCの文脈で、各サーバをImmutable Serverとして扱う場合を想定しています。 環境としてテスト環境と本番環境があります。CIサーバはテスト環境と本番環境の両方にアクセスできるので、便宜上CI環境に配置されているとします。 CIとして、テスト環境の再構築とテストを実施し、CDとして本番環境の再構築とテストを実施するものとします。
CIサーバをCDの対象とすべきかどうか
CIサーバをCDの対象とするということは、CI環境のCIサーバを再構築(破棄、作成)することになります。 CIサーバをImmutable Serverとして扱うと、パイプラインの途中でCIサーバの再構築が行われるため、必ず途中で中断することになりCDの対象とすることはできません。 CIサーバをいくつものコンポーネントに分けて、一部の機能のみCDの対象とすることはできると思います。
CIサーバはImmutable Serverではない(Mutable Server)として扱うとCIサーバをCDの対象とすることができます。しかし、パイプラインを実行中のCIサーバを変更するというのは複雑で、避けるべきと思います。
したがって、CIサーバはCDの対象とすべきではないと考えます。
CIサーバをCIの対象とすべきかどうか
CIの対象(以下、CI管理対象)というのは理想的にはすべてのサーバです。したがってCIサーバもCI管理対象とすべきと考えられます。
CIサーバのテスト用インスタンスを作成し、テストを実施することは有効です。ただし、テスト用インスタンスを使って実際のパイプラインを実行してはいけません。 実際のパイプラインはテスト用のCIサーバインスタンスの再構築を含んでいたり、テスト環境や本番環境のサーバ再構築を含んでいます。実行して良いのは接続確認のような環境に変更を加えない内容のものだけです。
結論
CIサーバはCIの対象としますが、CDの対象外とします。 CIのパイプラインではテスト用インスタンスを作成し、自動テストを実行します。自動テストによってCIサーバの構築手順の妥当性を確認できます。
明日はCIサーバのデプロイ方法についての予定です。
「インフラCI 実践ガイド」を読んだ
インフラCI 実践ガイドを読みました。 以前読んだInfrastructure as Code(以下、IaC書籍)に対し、具体的な実装方法について説明しており今の自分に欲しい情報がたくさん得られて非常に満足しました。
本書はこれからインフラCIを始めようとする方向けの本です。インフラCIの具体的な実装の説明と、インフラCIの外側にある要素についても説明しています。 インフラCIの外側にある要素というのはシステムのデザインやリリースに関する制約やチームメンバのスキルなどです。インフラCIを導入し成功させるためにはインフラCIの外側にある要素も非常に重要です。
実際にインフラCIの環境を読者が実際に動かすことができるよう、演習環境としての構築方法とそれに必要な構成定義ファイルを提供しており、まさにこれから始める人にはうってつけの内容と思います。 また、インフラCIの技術的な側面だけでなく、インフラCIを実践するために必要な非技術的な要素についても随所で触れており、インフラCIをこれから導入しようとする場合のポイントについても理解ができるようになっています。 実際に最後の方の章では、技術的な観点というよりはインフラCIよりも広い範囲を考えた場合の導入方法についても述べられています。
IaC書籍は本書の中でも参照されており、より抽象的な概念の理解のためにIaC書籍を読んでおくと、本書の理解もより深まると思います。 実際に私もIaC書籍を読んでから本書を読みましたが、IaC書籍の内容ともリンクしてわかりやすかったです。
記述のスタイルとして、結果をまず述べてからその仕組みについて説明する形になっており、構成定義ファイルの中身についての説明が後回しになっていたり、省略されていたりします。そのため、具体的な構成定義ファイルの中身を見た方がイメージしやすい読者の場合には、ここに記載されている構成定義ファイルをPC上で見ながら本書を読むのも良いかと思います。
「しくみがわかるKubernetes」を読んだ。
「しくみがわかるKubernetes」を読みました。
ほんとに仕組みがわかった気になりました。 これまでminikubeでhello worldをやっただけの経験でしたが、kubernetesがどういう仕組みになっているかの全体像を掴むことができました。
この本ではDockerなどのコンテナそのものについての説明はほとんどありません。
コンテナそのものを知らないとそもそもkubernetesの良さもわからないかもしれませんが、
この本で説明しているのはコンテナの管理をするkubernetesの仕組みです。 コンテナがどのような仕組みのものなのか、コンテナイメージはどのように作るのかというようなことは知らなくても読み進めることができると思います。
しくみを説明する本ですので、kubernetsの全体像としてどのようなコンポーネントで構成されているのかや、それぞれのコンポーネントの役割が説明されています。
また、Infrastructure as Codeの観点から、すべての定義をファイルに残すべきということも随所で述べてあります。
本文中に登場する定義ファイルはダウンロードできるようになっており、実際に試すことも可能です。
読者自身が実機で試す際も、細かな定義はすべてファイルに記載されているので、実際に打つコマンドはそれを適用するためのコマンドばかりです。
Kubernetesの環境を自分で構築するのは大変ですが、Azureで提供されているAKS(Azure Kebernetes Service)を使うことで簡単に利用を開始できます。
提供されているサンプルコードもAKS向けのものとなっているので、手軽に動作確認ができるようになっています。
この本ではKubernetesの主要コンポーネントの紹介と構成検討のポイントなどが述べられています。
含まれていないのは構築手順やオプションのコンポーネント等です。
例えば、ネットワークやストレージのコンポーネントについてはあまり説明がありません。
そのため、この本だけを見て自分でKubernetesを構築したいという方には向きませんが、クラウド上のマネージドサービスとしてKubernetesを使いたいという人には向いていると思います。
自分で環境を構築したいという人でも、この本を読むことで全体像がイメージできるようになりますので、具体的な検討へのステップとしては有効と思います。
「Infrastructure as Code」を読んだ
「Infrastructure as Code」を読みました。
タイトル通り、システムのインフラ(アプリケーションの土台部分)をコードとして表現することについての本です。
アプリケーションはそもそもコードとして定義されているのが普通ですが、インフラは設計書や手順書によって表現されることが多くあります。
インフラをコードとして表現することで、様々な恩恵を得られるということを謳っています。
この本の中で繰り返し述べられていることは、以下のことです。
- 常に同じやり方をすること
- すべてコードに表現すること
- VCSを使ってコードを管理すること
- 繰り返しそのコードを使ってインフラを構築すること
- 人による判断が必要な個所以外は自動化すること
どんなツールを使うかやコードの管理や自動テストの行い方や管理単位の分割の仕方といった実現方法は、使う組織や運用に合わせて柔軟に変える必要があります。
この本では具体的なツールの使い方にはほとんど触れず、ツールの特徴の紹介と運用パターンの選び方(や選択肢)の紹介が多いです。
言い方を変えると特定のツールによらない普遍的な考え方を中心に述べており、Infrastructure as Codeの概念やメリットを理解したい人に向いています。
具体的なツールの使い方についての説明はありませんが、ツールの名前や特徴については簡単に触れられているので、ツールについて調べる取っ掛かりにもなります。
Infrastructure as Codeをこれから始めようと考えている人にとっては、良い参考書となると思います。
ゼロから仕組みを構築したいときには、考慮すべき観点のチェックリストにもなりますし、既に仕組みがある場合でもより効率化するためのヒントが得られるように思います。
Tag: Virtual Box
PC上でのIaC環境の概要(GWアドベントカレンダー 4日目)
この記事はGWアドベントカレンダーの4日目の記事です。
自宅のPCにIaC環境を構築中ですが、その環境について少し説明します。
使用するツール
1台の物理Linuxサーバ上にすべての環境を構築します。 仮想マシンはVagrant + Virtual Boxで構築します。 コンテナはDockerで構築します。 構築ツールとしてAnsibleを使います。 CI/CDを実現するためのツールとしてGitlab、Gitlab Runnerを使います。
Gitlab、Gitlab Runnerの構築
GitlabとGitlab RunnerはAnsibleを使って、仮想マシンから作成します。 本番用とテスト用があり、テスト用の構築は本番用のGitlabのバックアップデータを使ってリストアすることで本番と同じデータを持つようにしています。
物理Linuxサーバの構築
OSインストール後の各種設定類はAnsibleにまとめようと思っていますが、まだできていません。
AnsibleとVagrantの連携
Ansibleのプレイブック(Gitlabのパイプラインからの呼び出しや手動実行)によって、Vagrant経由で仮想マシンを作成することがあります。 しかし、AnsibleのInventory PluginとしてはVagrant用のものが正式にはありません。そのため、作成した仮想マシンに対してプレイブックを実行するためには何らかの方法を考える必要があります。 一つはInventory PluginもしくはScriptを作ること、もう一つは作成する仮想マシン情報をあらかじめインベントリファイルに記載しておくことが考えられます。 どちらの方法でも実現できそうですが、どのようにするか検討中です。
今後の展望
- 物理Linuxサーバ構築用のパイプライン構築
- Kubernetesを動かす。 その上で、各種アプリケーションを動かす予定です。
vagrant up 失敗の原因究明 その2
というわけで、前回の続きです。
前回、原因究明はできたけれどもその報告ができていませんでした。 一日以上経って、ようやくForumにポストできました。
Can the failure message be improved? When VBoxManage.exe import failed with no disk space.
そして、Forum Postig Guideのデッドリンクについてもポストしておきました。
Dead link found in The Forum Posting Guide
誰か反応してくれると良いなぁ。。
vagrant up 失敗の原因究明
vagrant upがなぜか失敗するのでその原因究明をしたときの話です。
事象
PS E:\vagrant> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'hashicorp/precise64' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box 'hashicorp/precise64'
default: URL: https://vagrantcloud.com/hashicorp/precise64
==> default: Adding box 'hashicorp/precise64' (v1.1.0) for provider: virtualbox
default: Downloading: https://vagrantcloud.com/hashicorp/boxes/precise64/versions/1.1.0/providers/virtualbox.box
default: Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com
default:
==> default: Successfully added box 'hashicorp/precise64' (v1.1.0) for 'virtualbox'!
==> default: Importing base box 'hashicorp/precise64'...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.
Command: ["import", "\\\\?\\E:\\vagrant_home\\.vagrant.d\\boxes\\hashicorp-VAGRANTSLASH-precise64\\1.1.0\\virtualbox\\box.ovf", "--vsys", "0", "--vmname", "precise64_1571241203898_82313", "--vsys", "0", "--unit", "12", "--disk", "D:/VMimages/precise64_1571241203898_82313/box-disk1.vmdk"]
Stderr: 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interpreting \\?\E:\vagrant_home\.vagrant.d\boxes\hashicorp-VAGRANTSLASH-precise64\1.1.0\virtualbox\box.ovf...
OK.
0%...
Progress state: E_INVALIDARG
VBoxManage.exe: error: Appliance import failed
VBoxManage.exe: error: Code E_INVALIDARG (0x80070057) - One or more arguments are invalid (extended info not available)
VBoxManage.exe: error: Context: "enum RTEXITCODE __cdecl handleImportAppliance(struct HandlerArg *)" at line 957 of file VBoxManageAppliance.cpp
Tag: OCI
Oracle CloudのCompute インスタンスが起動後すぐ停止する
Oracle CloudのCompute インスタンスが起動できなくなってしまいました。 正確にはインスタンスを開始させると、起動中というステータスになりますが、少し経つと今度は停止中となり、停止済みとなってしまいます。
以前は起動できたのにできなくなってしまいました。困った。。 しかもそれらしきログも出ずに原因究明ができません。 コマンドラインインタフェース(コマンドは後述)から起動してみても、開始要求は正常に行われるのでエラーになりません。
新しいインスタンスを作成用しようにも、以下のメッセージが出て作成もできません。
困った困った。。
可用性ドメインjRHI:AP-TOKYO-1-AD-1のシェイプVM.Standard.E2.1.Microの容量が不足しています。 後で再試行してください。
oci compute instance action --action=start --instance-id=
Tag: Net/Http
Goのnet/httpでWebサーバを作って確認したこと
Go のnet/httpパッケージを使うと簡単にWebサーバが構築できます。 実際に動作を確認した内容について備忘録としてメモしています。
並列処理可能
特に何も工夫せずにWebサーバとして動作させるだけで、goroutineによる並列処理が可能です。
動作確認のため、Apache Bench(ab)を使って確認しましたが、1000セッション同時に処理できていました。
動作確認の際は、リクエストの応答にsleepを1秒入れて1000セッションが10リクエストを発行しました。
すると、10秒くらいですべてのリクエストが処理されました。
動作確認に使ったコマンドは以下です。
実行すると約1秒毎に1000リクエストが処理されて、約10秒後に完了します。
結果のサマリを見ても、ほとんどのリクエストが約1秒で完了していました。
ab -c 1000 -n 10000 http://localhost:8080/
レスポンスのContent-Type自動設定
レスポンスをhtmlにすると、自動的にContent-Typeがtext/htmlになりました。
レスポンスをダブルクォートで囲んだ文字列にすると、中身がhtmlでもtext/plainになりました。
強制的に変更したいときは、以下のようにして指定できます。
w.Header().Set("Content-Type", "text/html; charset=utf-8")
コード
実際の動作確認の際は、不要なものを削除したりコメントアウトしたりしながら実施していますが、
上記の確認に必要なものはこれで足りると思います。
package main
import (
"fmt"
"html"
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/", uploader)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func uploader(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-type" , "text/html; charset=utf-8")
time.sleep(1 * time.Second)
fmt.Fprintf(w, "%s", html.EscapeString(r.URL.Path)
}
Tag: Box
Docker Desktop for Windowsの導入
Docker Desktop for Windowsを導入してみました。
dockerコンテナを作って動かしたいのが目的です。 Windowsを使うのは、普段使っているOSがWindowsだからで、コンテナはLinuxのものを使います。 そうしたときに、docker Engineをどこで動かすかの選択肢があります。
- Windows (Docker Desktop for Windows)
- Windows上のLinux VM(Hyper-VやVirtual Box上のLinux VMでLinux用のDocker Engineを動かす)
開発用にLinux VMを動かしているのでそちらでDockerを使っても良いのですが、わざわざVMを起動して使うのも面倒そうなのでWindows上で動かすことにしました。 ただ、Windows上で動かすと言っても、実際にはDocker用のLinux VMがHyper-Vを使って起動します。 そのため、自分でLinux VMを用意して動かすのと仕組みはそれほど変わりません。
Docker Desktop for Windowsの場合、Docker ClientはWindows上で動きますが、Docker EngineはLinux VM上で動きます。 自分でLinux VMを用意して使う場合はDocker ClientもDocker EngineもLinux VM上で動きます。 コンテナそのものはどちらもLinux VM上で動きます。
Docker Desktop for Windowsを使う場合、DockerfileやコンテナにコピーするファイルをLinux VMから利用できるようにする必要があります。 どのドライブをアクセス可能にするかは、settingsから設定できます。 なお、コンテナからマウントして使うようなデータ領域としてはWindows上の領域は不向きで、data volumeやdata containerを使う方が良いようです。これには二つの理由があって、一つはWindows上の領域はLinux上からみて、rwxrwxrwxのモードで見えます。もう一つは、SMBを使ってLinux VMに領域を見せる際、NOBRLオプションが付いているため、ロックができない場合がある点です。 これらはDocker Desktop for Windowsのドキュメントの最初の方(Shared drives)に書いてあります。
と、ここまでやってから大事なことに気づきました。 開発用にLinux VMを動かしていますが、そちらはVirtual Boxを使っています。 Docker Desktop for WindowsはHyper-Vを使います。 これらの共存はできないので、どちらを使うか選ぶ必要があります。。つづく。。
Tag: Virtual
Docker Desktop for Windowsの導入
Docker Desktop for Windowsを導入してみました。
dockerコンテナを作って動かしたいのが目的です。 Windowsを使うのは、普段使っているOSがWindowsだからで、コンテナはLinuxのものを使います。 そうしたときに、docker Engineをどこで動かすかの選択肢があります。
- Windows (Docker Desktop for Windows)
- Windows上のLinux VM(Hyper-VやVirtual Box上のLinux VMでLinux用のDocker Engineを動かす)
開発用にLinux VMを動かしているのでそちらでDockerを使っても良いのですが、わざわざVMを起動して使うのも面倒そうなのでWindows上で動かすことにしました。 ただ、Windows上で動かすと言っても、実際にはDocker用のLinux VMがHyper-Vを使って起動します。 そのため、自分でLinux VMを用意して動かすのと仕組みはそれほど変わりません。
Docker Desktop for Windowsの場合、Docker ClientはWindows上で動きますが、Docker EngineはLinux VM上で動きます。 自分でLinux VMを用意して使う場合はDocker ClientもDocker EngineもLinux VM上で動きます。 コンテナそのものはどちらもLinux VM上で動きます。
Docker Desktop for Windowsを使う場合、DockerfileやコンテナにコピーするファイルをLinux VMから利用できるようにする必要があります。 どのドライブをアクセス可能にするかは、settingsから設定できます。 なお、コンテナからマウントして使うようなデータ領域としてはWindows上の領域は不向きで、data volumeやdata containerを使う方が良いようです。これには二つの理由があって、一つはWindows上の領域はLinux上からみて、rwxrwxrwxのモードで見えます。もう一つは、SMBを使ってLinux VMに領域を見せる際、NOBRLオプションが付いているため、ロックができない場合がある点です。 これらはDocker Desktop for Windowsのドキュメントの最初の方(Shared drives)に書いてあります。
と、ここまでやってから大事なことに気づきました。 開発用にLinux VMを動かしていますが、そちらはVirtual Boxを使っています。 Docker Desktop for WindowsはHyper-Vを使います。 これらの共存はできないので、どちらを使うか選ぶ必要があります。。つづく。。
Tag: Windows
Docker Desktop for Windowsの導入
Docker Desktop for Windowsを導入してみました。
dockerコンテナを作って動かしたいのが目的です。 Windowsを使うのは、普段使っているOSがWindowsだからで、コンテナはLinuxのものを使います。 そうしたときに、docker Engineをどこで動かすかの選択肢があります。
- Windows (Docker Desktop for Windows)
- Windows上のLinux VM(Hyper-VやVirtual Box上のLinux VMでLinux用のDocker Engineを動かす)
開発用にLinux VMを動かしているのでそちらでDockerを使っても良いのですが、わざわざVMを起動して使うのも面倒そうなのでWindows上で動かすことにしました。 ただ、Windows上で動かすと言っても、実際にはDocker用のLinux VMがHyper-Vを使って起動します。 そのため、自分でLinux VMを用意して動かすのと仕組みはそれほど変わりません。
Docker Desktop for Windowsの場合、Docker ClientはWindows上で動きますが、Docker EngineはLinux VM上で動きます。 自分でLinux VMを用意して使う場合はDocker ClientもDocker EngineもLinux VM上で動きます。 コンテナそのものはどちらもLinux VM上で動きます。
Docker Desktop for Windowsを使う場合、DockerfileやコンテナにコピーするファイルをLinux VMから利用できるようにする必要があります。 どのドライブをアクセス可能にするかは、settingsから設定できます。 なお、コンテナからマウントして使うようなデータ領域としてはWindows上の領域は不向きで、data volumeやdata containerを使う方が良いようです。これには二つの理由があって、一つはWindows上の領域はLinux上からみて、rwxrwxrwxのモードで見えます。もう一つは、SMBを使ってLinux VMに領域を見せる際、NOBRLオプションが付いているため、ロックができない場合がある点です。 これらはDocker Desktop for Windowsのドキュメントの最初の方(Shared drives)に書いてあります。
と、ここまでやってから大事なことに気づきました。 開発用にLinux VMを動かしていますが、そちらはVirtual Boxを使っています。 Docker Desktop for WindowsはHyper-Vを使います。 これらの共存はできないので、どちらを使うか選ぶ必要があります。。つづく。。
vagrant up 失敗の原因究明 その2
というわけで、前回の続きです。
前回、原因究明はできたけれどもその報告ができていませんでした。 一日以上経って、ようやくForumにポストできました。
Can the failure message be improved? When VBoxManage.exe import failed with no disk space.
そして、Forum Postig Guideのデッドリンクについてもポストしておきました。
Dead link found in The Forum Posting Guide
誰か反応してくれると良いなぁ。。
vagrant up 失敗の原因究明
vagrant upがなぜか失敗するのでその原因究明をしたときの話です。
事象
PS E:\vagrant> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'hashicorp/precise64' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box 'hashicorp/precise64'
default: URL: https://vagrantcloud.com/hashicorp/precise64
==> default: Adding box 'hashicorp/precise64' (v1.1.0) for provider: virtualbox
default: Downloading: https://vagrantcloud.com/hashicorp/boxes/precise64/versions/1.1.0/providers/virtualbox.box
default: Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com
default:
==> default: Successfully added box 'hashicorp/precise64' (v1.1.0) for 'virtualbox'!
==> default: Importing base box 'hashicorp/precise64'...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.
Command: ["import", "\\\\?\\E:\\vagrant_home\\.vagrant.d\\boxes\\hashicorp-VAGRANTSLASH-precise64\\1.1.0\\virtualbox\\box.ovf", "--vsys", "0", "--vmname", "precise64_1571241203898_82313", "--vsys", "0", "--unit", "12", "--disk", "D:/VMimages/precise64_1571241203898_82313/box-disk1.vmdk"]
Stderr: 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interpreting \\?\E:\vagrant_home\.vagrant.d\boxes\hashicorp-VAGRANTSLASH-precise64\1.1.0\virtualbox\box.ovf...
OK.
0%...
Progress state: E_INVALIDARG
VBoxManage.exe: error: Appliance import failed
VBoxManage.exe: error: Code E_INVALIDARG (0x80070057) - One or more arguments are invalid (extended info not available)
VBoxManage.exe: error: Context: "enum RTEXITCODE __cdecl handleImportAppliance(struct HandlerArg *)" at line 957 of file VBoxManageAppliance.cpp
はじめてのWindows クラッシュダンプ解析
Windows 10のマシンがブルースクリーンになってしまって、再発すると困るので見てみました。 ググってみるとちょっと見てみるところまでは簡単にできそうだったのでやってみました。
結果はDPCウォッチドッグに引っかかっているみたい。(以下は、!analyze -vの抜粋)
DPC_WATCHDOG_VIOLATION (133)
The DPC watchdog detected a prolonged run time at an IRQL of DISPATCH_LEVEL
or above.
Arguments:
Arg1: 0000000000000000, A single DPC or ISR exceeded its time allotment. The offending
component can usually be identified with a stack trace.
Arg2: 0000000000000501, The DPC time count (in ticks).
Arg3: 0000000000000500, The DPC time allotment (in ticks).
Arg4: fffff8003376e350, cast to nt!DPC_WATCHDOG_GLOBAL_TRIAGE_BLOCK, which contains
additional information regarding this single DPC timeout
そしてkの結果には以下の文字列が。
Tag: コンテナ
Tag: Uml
「入門 UML 2.0」を読んだ
「入門 UML 2.0」を読んだ。 UMLってユースケースを表現するためのものでしょ?と思っていて、図を使ってユースケースを書く必要に迫られることも無かったのであまり勉強する気にもなっていなかったのですが、Plant UMLというテキストでUMLを既述できるものを知り、図を描くのにテキストで記述できるのは便利そうということで読んでみることにしました。
読んでみると、そもそもユースケース図を描くたものものという認識が誤りで、ユースケース図を表現することにも使えるが、それ以外の様々なものを表現するために使えるものであるということがわかりました。また、表現の仕方が定義されていて、UMLを知っている人であれば書き方を説明せずに記述できるということもよく分かりました。そのため、記述ルールについての凡例を書く必要もないのです。
UMLは既述したい目的毎に図の書き方がいくつも用意されています。そして、その目的や使い分けについて説明しています。しかし、その使い方は限定的ではありません。ある特定の種類の図ですべてを表現する必要はなく、その図で表現したい箇所だけをその図で表現し、そのほかの場所は異なる種類の図で表現しても良いとされています。結局は表現すべき重要な事柄を、それを表現するのに適切な図を使って表現すべきとしています。 つまり、何を表現すべきかを考えて使い分けるということです。
この本を読むことで、システム設計においてどのような情報を表現するべきかということがわかると思います。全体の概要を示したい場合や、特定部分の詳細について説明したい場合がありますが、それらがどのような種類の情報であるか、また混ぜるべきではない情報というのはどういうものかというのがなんとなくわかると思います。実際に書いて表現することを繰り返すことで、システムのどの部分をどのように表現するべきかというのがより直感的にわかるようになってくるのだと思います。
ところで、Plant UMLはテキストで記述したものをUML図に変換する仕組み(Webサービス、Javaプログラムとして提供されています)ですが、テキストをエディタで変更すると即座にその結果のUML図が変更されるという使い方ができます。
Vimでは、previmというpluginを使うことで実現できます。 previmはそもそもMarkdownに対してのプレビューを提供するものでしたが、PlantUMLにも対応したのです。
これを使いたかったという気持ちもあります。
そんなわけで、今後、図を記述する必要がある場合にはPlantUMLを積極的に使っていきたいと思っています。
Tag: Vim
「入門 UML 2.0」を読んだ
「入門 UML 2.0」を読んだ。 UMLってユースケースを表現するためのものでしょ?と思っていて、図を使ってユースケースを書く必要に迫られることも無かったのであまり勉強する気にもなっていなかったのですが、Plant UMLというテキストでUMLを既述できるものを知り、図を描くのにテキストで記述できるのは便利そうということで読んでみることにしました。
読んでみると、そもそもユースケース図を描くたものものという認識が誤りで、ユースケース図を表現することにも使えるが、それ以外の様々なものを表現するために使えるものであるということがわかりました。また、表現の仕方が定義されていて、UMLを知っている人であれば書き方を説明せずに記述できるということもよく分かりました。そのため、記述ルールについての凡例を書く必要もないのです。
UMLは既述したい目的毎に図の書き方がいくつも用意されています。そして、その目的や使い分けについて説明しています。しかし、その使い方は限定的ではありません。ある特定の種類の図ですべてを表現する必要はなく、その図で表現したい箇所だけをその図で表現し、そのほかの場所は異なる種類の図で表現しても良いとされています。結局は表現すべき重要な事柄を、それを表現するのに適切な図を使って表現すべきとしています。 つまり、何を表現すべきかを考えて使い分けるということです。
この本を読むことで、システム設計においてどのような情報を表現するべきかということがわかると思います。全体の概要を示したい場合や、特定部分の詳細について説明したい場合がありますが、それらがどのような種類の情報であるか、また混ぜるべきではない情報というのはどういうものかというのがなんとなくわかると思います。実際に書いて表現することを繰り返すことで、システムのどの部分をどのように表現するべきかというのがより直感的にわかるようになってくるのだと思います。
ところで、Plant UMLはテキストで記述したものをUML図に変換する仕組み(Webサービス、Javaプログラムとして提供されています)ですが、テキストをエディタで変更すると即座にその結果のUML図が変更されるという使い方ができます。
Vimでは、previmというpluginを使うことで実現できます。 previmはそもそもMarkdownに対してのプレビューを提供するものでしたが、PlantUMLにも対応したのです。
これを使いたかったという気持ちもあります。
そんなわけで、今後、図を記述する必要がある場合にはPlantUMLを積極的に使っていきたいと思っています。
mtdataapi.vimの開発状況
以前、このエントリで書いたプラグインがとりあえず使える感じになってきたので改めてここに書く。
このプラグインは、Movable TypeというCMSを利用する際の文字編集を簡単にするために開発しています。 Movable Type(以下、MT)は、エントリを編集するインタフェースとしてWeb UIを提供していますが、豊富なエディタの機能を利用することができないのが個人的な欠点でした。 Web UIのままでも、javascriptを書くことで様々な機能を追加することができますが、使い慣れたエディタを使える方が何かと便利です。 そこで、vimというエディタで編集したものがMTにすぐにアップロードできたり、MTのエントリをvimにダウンロードできたりすることを実現したいと思いました。
そこでmtdataapi.vimでは、MTのもつAPIであるData APIを使って、エントリ情報をやり取りすることでエントリ情報のアップロードやダウンロードを実現しました。 MtOpenコマンドの引数にエントリIDを与えると、MTから該当のエントリをダウンロードしてきてローカルファイルに保存します。そして、そのローカルファイルを開きます。 そのまま編集して:wで保存すると、MTにアップロードされて、エントリが更新されます。 ダウンロードしたエントリは、本文だけでなく公開、非公開(下書き)の状態やカテゴリ、タグなどの情報も含まれていて、それらも編集可能です。そのため、非公開のエントリを公開に変えて保存するだけで、エントリを公開状態にすることができます。
本文編集の際のフォーマットは、htmlだけでなくMarkdownも利用できます。 Markdownで表現できない部分(複雑なhtmlなど)は、htmlのままにしておいて、文章だけMarkdownで記載することも可能です。文章だけであればMarkdownで記載できれば十分なのですが、それができない場合はhtmlをMarkdownで扱おうとすると情報が失われてしまうケースがありました。そのため、両方を扱えるようにしています。 htmlの方が情報が多いので、基本的にはhtmlでローカルファイルには保存しておいてMTとやり取りします。文章を編集する際のみ、該当部分をMarkdownに変換する使い方を意図しています。
上記のhtmlとMarkdownを変換するために、MtHTMLtoMDとMtMDtoHTMLコマンドを用意しています。 ビジュアル選択した状態で上記コマンドを実行すると、選択部分が変換されます。 Markdownでの編集が終わったらhtmlに変換して、:wするという使い方を想定しています。 MtOpenした場合も、:wで保存した場合も、その後自動的にMTの情報でbufferが更新されます。このときはhtmlで更新されます。
MTでは画像のアップロード操作などもできます。 Web UIではマウスで簡単に画像の挿入ができますが、mtdataapi.vimではできません。そのため、Web UIでエントリを編集する場合もあると思います。 そうした場合、ローカルファイルの情報が古くなってしまいますが、MtOpenで開いた状態でを押すとMTから情報をダウンロードして最新の情報で更新されます。
自分でこのプラグインを作ってみて実際に使っていますが、文章を書くのが楽になってブログエントリを書くのも楽になりました。 ブログといえばWord Pressが有名でMovable Typeは利用者が少ないような気がしますが、利用者の方は使っていただけると嬉しいです。
vimのコマンドラインモードのマップ定義の仕方
vimではマップという機能で様々なことが実現できます。 簡単に言うとショートカットキーを作ることができます。 また、vimにはモードが複数あり、モード毎にキーの意味が異なるのでモード毎に同じキーに別の意味を割り当てることができます。
モードの一つとして、コマンドラインモードがあります。コマンドラインモードは、vimを終了するときに使用できる:qでも利用しています。 :qとキー入力する場合、キー入力前の状態はノーマルモードです。そこから:を入力した時点でコマンドラインモードに移ります。 qはコマンドラインモードのコマンド(の省略形)です。そのあと、実際にはエンターキーを入力しますがこれによりqコマンドが実行されます。
そこでこのqコマンドに別の意味を持たせることがmapでできるのですが、設定の仕方を誤ってなかなか期待通りにならなかったので失敗した点を示します。 なお、実際に失敗したキーはqではなく、w(保存コマンド)でしたので、以下の例ではwコマンドで示します。
失敗 その1
mapコマンド(実際にはcnoremapコマンドを使用)のlhs側(新しく登録するキー)にエンターキーを記載しない
cnoremap w w<CR>q<CR>
mapコマンドの引数は大きく二つあり、新しく登録するキー列とそのキー列を入力した場合の意味を示すキー列等です。 その二つをlhs、rhsとそれぞれ表現します。Left Hand SideとRight Hand Sideの略と思われます。
以下のように書くと、エンターを押さなくてもrhs側のキー列が入力されたのと同じことが起こります。 そのため、:w filename と打とうとしていた場合でも:wと入力した時点でrhs側が入力されてしまいやりたかったことができません。 実現したいこと次第で対処法は変わりますが(つまり複数の選択肢がありますが)、今回は以下のように記載することで対処可能でした。
cnoremap w<CR> w<CR>q<CR>
失敗 その2
lhs、rhsに:を余計に記載する
cnoremap :w<CR> :q<CR>
cnoremapコマンドはコマンドラインモードでのキー入力に対して機能するので、lhsにもrhsにも:は不要です。 以下のようにすると:wしようとすると:qで終了するようになるはずです。
cnoremap w<CR> q<CR>
vim plugin の ftdetectの効かせ方
vim plugin を作っていてなかなか解決できなかった課題のメモです。
vim ではファイルタイププラグインという種類のプラグインが作成できます。 ファイルタイププラグインはファイルタイプに合わせて挙動を変えることができるようにするためのプラグインです。 vim はファイルを開いた際に、そのファイルがどのファイルタイプか判別します。 ファイルタイプはC言語のようなプログラミング言語毎にあらかじめ定義されていますし、自分で作成することもできます。 自分で作成する場合には、ファイルタイプ名を決めて、そのファイルタイプの場合にどのような挙動にするかを定義したプラグインファイルを作成します。 例えば、ファイルタイプ毎に異なるマップを定義することができます。 その場合、プラグインファイルには定義したいマップコマンドを記述します。そうすることで、特定のファイルタイプの場合にのみそのマップコマンドが実行されるようになります。
ところで、ファイルを開くたびにそのファイルがどのファイルタイプかを判別する必要がありますが、自分で作成したファイルタイプのことはvimは知らないので、どのファイルが自作のファイルタイプに該当するかを定義する必要があります。 それには何らかの方法で以下のようにしてファイルタイプを指定する必要があります。これを実現する方法はいくつかありますが、その一つに ftdetect/*.vim というファイルを使う方法があります。
set filetype=aaaa
ftdetect/.vim というファイルは、ファイルを開いた際(厳密にはバッファを開いた際)に自動的に読み込まれて実行されるファイルの一つです。 runtimepath配下にあるftdetect/.vimを実行します。 このファイルは、以下の設定がされていないと読み込まれないようですが、これだけを設定していても読み込まれない場合がありました。
set runtimepath+=~/where/to/pluginpath/
filetype plugin on
読み込まれるようにするためには以下のように、runtimepathの設定の前に filetype offを設定する必要がありました。
filetype off
set runtimepath+=~/where/to/pluginpath/
filetype plugin on
blogの始め方その1
どこに書くか
blogを書き始めようとするときに、まずはどこに書くかを決める必要があります。 世界中で人気のWord Pressというソフトウェアを使う手もありますが、ややニッチ(?)なMovable Typeというソフトウェアもあります。 Movable TypeはSix Apartという会社が開発しているソフトウェアで、商用ブログサービスとしてType Padというものもあります。 私はMovable Typeに書くことにしているのでMovable Typeを使います。
何で書くか
Movable TypeはWebインタフェースがあるので、ブラウザで書くのが通常ですがブラウザのテキストフォームに書くような形になるので使いづらいです。使いやすくするにはjavascriptを書いて機能拡張するなどの工夫が必要です。しかし、世の中には文章を書くためのツールとしてエディタがいくつもあり、それらを使う方が文書を書くには都合が良いのです。当たり前ですね。Movable TypeにはWebのGUIインタフェース以外にWeb APIも提供しています。このWeb APIはData APIという名前で定義されていて、これを使うと記事の新規作成や編集なども行えます。
そういうわけで、エディタで書いた文章をData APIを使ってMovable Typeに投稿する仕組みが実現できそうです。 これができればエディタで気持ちよく文章を書いて、そのままMovable Typeのblogエントリとして投稿できるはずです。 欠点があるとすれば、写真などの画像を入れようとすると難しくて、WebのGUIインタフェースの方が直感的に配置できたり、アップロードもできるので操作性は上です。 ですので、画像の取り扱いはWeb GUI、文字はエディタと使い分けることにします。
さて、エディタで書いた文章をData APIを使ってMovable Typeに投稿しようと思いますが、どのような操作性が良いでしょうか。 気軽に編集できるようにするには、エディタでテキストファイルを保存するような操作でData APIを使って投稿できる、修正できるというのが良いでしょうか。 ローカルに編集したり、Data APIを使って編集を反映したりと使い分けられるようにするのも手です。 とりあえずはローカルにあるファイルを編集し、上書き保存すると、Data APIを使ってMovable Typeの記事も編集(変更)されるという仕組みを目指します。
足りない機能
エディタでファイルを保存すると自動的にData APIにアクセスする仕組みを実現する必要が出てきました。 自動で行うというのがポイントですが、そのためには以下のような方法が考えられます。
- ファイルの更新チェックをリアルタイムで行うようにカーネルフックモジュールを用意する
- ファイルの更新チェックを行うデーモンを用意する
- エディタの保存処理をフックする仕組みを用意する
カーネルフックモジュールで実装すると、色々と無駄で遅くなりそうです。 デーモンを用意するのも大げさな感じですし、無駄な感じです。 そこで今回はエディタの保存処理をフックする仕組みを用意することにします。
保存処理をフックできるようなエディタはいくつもありますが、筆者はvimが好きなのでvimを採用します。 vimはemacsと同じく拡張が用意で基本的になんでもできます。
vimの場合は、vim scriptという形で保存処理をフックする仕組みを記述すれば実現できます。 vim の設定ファイルはvimrcに記述しますが、この設定ファイルもvim script形式です。 そのため、vimrcに保存処理のフックすく仕組みを書けば解決できますが、その仕組みが巨大であったり、汎用的にできたり、公開したい場合にはプラグインとして作成することもできます。 今回はMovable Type利用者でかつ、vim利用者のためのプラグインを作成することにします。
足りない機能を補う
vim プラグインに必要な機能はData APIへのアクセスに関するものと、ローカルファイルの取り扱いに関するものに分けられます。 Data APIはHTTPアクセスなのでHTTPリクエストとレスポンスの取り扱いが必要です。 この部分はvital.vimを使います。 ローカルファイルの取り扱いは自分で用意します。
Data APIで取得したエントリはJSON形式で取得できますが、それをローカルファイルに保存する前にエディタで編集しやすい形に整形する必要があります。 また、その逆にローカルファイルの内容をData APIで投稿する際には逆の整形を行う必要があります。 こうした処理をちまちま書いていくといずれ出来上がります。 プラグインの処理の詳細は別の記事に書きますので、そちらを参照してください。
vim script の関数定義の際の引数リストのカンマの前にスペースは書けない
前回の記事に書いた件、以下のURLに知りたいことが書いてありました。 どうやらバグではなくて仕様ということらしいです。 help :todo を見ると、ドキュメントに書こうとしているようです。(以下に抜粋)
Space before comma in function definition not allowed: "function x(a , b)"
Give a more appropriate error message. Add a remark to the docs.
というわけで、 vim script の関数定義の際の引数リストのカンマの前にスペースは書けないということがわかりました。
vim plugin mtdataapi の更新記録(ダウンロード機能追加)
mtdataapiに記事のダウンロード機能を設けました。
以下のコマンドでダウンロードできます。 ダウンロード先は、g:mt_basedir です。この配下にサイトIDのディレクトリが作られます。各エントリはエントリIDのファイル名になります。
let g:mt_basedir = $HOME/mtblog
:mtdataapi#downloadSiteToFile()
実践Vimを読んだ。
実践Vimを読みました。 本書は初心者向けの内容ということですが、触ったこともないような初心者向けというよりは、vimtutorを終えて基本的な操作がわかった人向けという感触です。 タイトル通り、実践的な内容となっていて、実現したいことの実現方法をいくつも紹介しながらメリット、デメリットを紹介していて、それぞれで使用するオペレータやモーションの理解が深まるようになっています。そのため、どういう場合にどういうオペレータを使うべきかを理解できるようになっています。 なるべく繰り返し操作がしやすいような操作を求めていくと、実現したいことにぴったり一致するオペレータを知る必要が出てきますが、いろいろなオペレータを紹介することで、よくある操作を実行するのに必要なオペレータは既にあるということをうまく示せているように思います。繰り返しを基本とするように考えていくと、段々とどんなオペレータがあるのか調べる必要が出てくるので、今後の上達にもつながっていくと感じます。
印象に残った使い方としては、マークの使い方(vimgrepの実行前とかquickfix関連の実行前とかにマーク設定)とか、挿入モードやコマンドラインモードでのC-rを使った文字入力(C-r0とかC-rC-wとか)とか、globalコマンドの使い方(実行するexコマンドに、rangeを与えて範囲を広く指定するとか)です。でも、そもそも繰り返し可能にするためにどういうオペレータにすべきかとか、マクロの直列実行、並列実行とかそういう考え方が整理されて記述されているのがとても理解の助けになりました。
今後もvimの上達に向けて精進したいと思います。
msys2でrbenv
msys2を使ってみることにして、とりあえずvimのビルドしようと思ったらrubyがなかったので、rbenvを入れようとしたらなぜか動かない。
$ ~/.rbenv/bin/rbenv init
.rbenv/bin/rbenv: 行 1: ../libexec/rbenv: No such file or directory
ファイルは存在しているのに無いと言われてしまう。 同じ悩みを持つひとは、これをシンボリックリンクに変えて対処したようだ。こちら参照。 同じようにシンボリックリンクにしてみると確かに動く。 .rbenv/bin/rbenvの中身は確かに1行しかなくて、これを実行するだけなのでリンクに置き換えても問題なさそう。 問題は相対パスで書かれたものを実行できないということなのか。
切り分けのために、rbenvの中身を絶対パスに変更してみると。。
うん。動く。と思ったら引数が渡らない。 リンクのように振舞っているということか?相対パスの始まりが、コマンド実行時のカレントディレクトリになっているみたい。 試しに ~/.rbenv/bin に移動してから実行するとやはり動く。 相対パスの解釈の仕方が問題のようだ。 でも、この後の調べ方がわからない。相対パスを実行しようとするのは誰なのか。bashか? bash -xで見ても特に何も出ない。
pandocでフォーマット変換(vim-mtdataapi)
mtdataapiというvimのpluginからMovable Typeへの記事投稿の際、markdown形式で投稿できるようにしました。 変換にはpandocを使っています。
Movable Type 用 Vim Plugin を開発中
Movable Type というCMSを使ってブログを書いていますが、基本的にブラウザで入力するため文章入力が非効率に感じることが多々あったので、vimから投稿できるようにvim pluginを開発しています。
単純な更新ができるようになってきたので、一旦githubに公開しましたが、とても一般の方が使える状態ではありません。 需要があるようでしたら、issueやSNSなどで連絡もらえると嬉しいです。
vimのhelpを読んで新たに覚えた便利なコマンド(usr42)
前回の続きです。 usr42はGUIメニューについて。
あまりGUIにこだわりはないので情報少なめ。
:menu メニューの編集などが可能。mapコマンドのようにモード別のコマンドがある。 引数無しだと定義済みのメニューが表示される。
guioptions-=T ツールバーを非表示にする。 個人的に、メニューは使うこともあるがツールバー(アイコンのボタン)は使わないので、いらない。
vimのhelpを読んで新たに覚えた便利なコマンド(usr41)
前回の続きです。
この賞はVim scriptの記法について。
- let 変数定義に使います。 以下のようにs:を付けるとスクリプトローカルな変数を定義できます。 let s:count
使わなくなったら、unlet s:countで変数を削除してメモリを解放します。
exists() 変数の存在確認結果を返す。 引数は変数名の文字列を指定するため、以下のように実行します。 if exists(“s:count”)
$HOME $で始まるのは環境変数。
&ic &で始まるのはオプション。 &icはignorecaseオプションのこと。
@r @で始まるのはレジスタ。
. ピリオドを使って文字の連結ができます。 Perlと同じ。
a ? b : c aならばb、aでないならc。 よくある3項演算子。
a =~ b aがbパターンにマッチする。 =~ではなく、!
ならマッチしない。 Perlと同じ。ただし、大文字小文字を区別しない。 パターンは文字列として指定する。 “test” =“e”a =
# b aがbパターンにマッチする。大文字小文字を区別する。 Perlと同じ。 =?とすると大文字小文字を区別しない。continue.break while文のループ中で、次のループへ遷移したりループを終了する。
eval 文字列を評価した結果を返す。 executeコマンドは結果をコマンドとして実行するが、evalは評価のみで価を返す。
function 関数定義。 関数名は大文字で開始。 関数の中で引数を参照するときは、a:countという形でa:を付ける。 関数の中でletコマンドによって定義した変数は関数ローカルな価となる。 s:等を付けた場合はそれに従う。
function FunctionName() range rangeを付けると範囲指定を受け付ける。以下のように実行できる。 10,30call FunctionName 範囲は、a:firstline、a:lastlineで参照する。
rangeを付けなかった関数を10,30callで呼ぶと、同じ関数を21回呼ぶことになる。
function FunctionName(Start, …) …で可変長引数を指定。 a:0は可変長引数の数。a:000は可変長引数のリスト。 a:1は可変長引数の最初の値。
vimのhelpを読んで新たに覚えた便利なコマンド(usr40)
前回の続きです。
この賞は「新しいコマンドを作る」ということで、「map」、「command」、「autocmd」が説明されています。
map、unmap キーのマップを定義します。 をほかのキーに割り当てたりすることで、便利なキーとして登録できます。 unmapでマップを削除します。
command コマンドを定義します。 コマンド名は大文字で始める必要があります。
autocmd イベント発生時に自動的に実行するコマンドを指定します。 commandで作成したコマンドやcallコマンドを使って関数を実行できます。 executeコマンドを使うと実行するコマンドを動的に作成して実行することができます。
vimのhelpを読んで新たに覚えた便利なコマンド(usr29-usr32)
前回の続きです。
=a{ コードブロック(a{)を再インデント gg=Gとするとファイル全体の再インデント。
a{ コードブロック(a{)をインデント {}の行も含む。含まないときはi{を使う。
挿入モードでCtrl-D, Ctrl-T インデント削除(Ctrl-D)とインデント追加(Ctrl-T) カーソルの位置は関係なく、その行に対して適用
set expandtabと:%retab set expandtabでタブ文字を使用不可に設定。 retabコマンドで、バッファ中のタブ文字をスペースに置換
undo 2 2番の変更に戻る(アンドゥ)
g-、g+ g-で前の変更に戻る(アンドゥ) g+で次の変更に進む(リドゥ) ただし、アンドゥしてから変更した場合などもその順ですべての変更状態に遷移できる。
earlier 1f、later 10m earlier、laterで変更履歴を戻ったり進んだりする。 1fは最後に保存した状態。10mは10分など。 undolistで変更確認可能。
vimのhelpを読んで新たに覚えた便利なコマンド(usr26-usr28)
前回からの続きです。
:argdo %s/a/b/ge :args *.cというように指定して引数リストに関連ファイルを設定した上で、argdoコマンドで引数リストのファイルすべてに対してコマンドを実行。検索の場合、eが無いと文字列が見つからない場合にエラーで途中終了する。 ほかに:windo、bufdoコマンドもある。
ls | vim - vimのバッファを標準入力で埋める。
vim -w script file.txt scriptファイルにfile.txtの操作コマンド(ノーマルモードコマンド)の履歴を保存する。 後からvim -s script file.txtとすると同じ操作を適用できる。
set ignorecase smartcase 検索時の大文字小文字の違いを無視するが、パターンに大文字が含まれる場合は無視しない。
/\Cword \Cは大文字小文字の違いを無視しない。\cだと無視する。
/abc/2 abcが見つかった行の2行下に移動する オフセットという。
/abc/e+2 見つかった文字の最後(c)の二つ右に移動する bだと先頭を基準に移動する。 文字オフセットという。
set foldclose=all 折り畳みを自動的に閉じる
set foldmethod=indent インデントによって自動的に折り畳みを作る。 shiftwidthによって折り畳みを判断する
vimのhelpを読んで新たに覚えた便利なコマンド(usr23-usr25)
前回の続きです。
:%!xxd 16進ダンプとテキスト表示に変更(バッファを書き換える) 戻すときは以下。 編集は16進数部分のみ可能。それ以外は無視される。 これを使えばバイナリエディタとして使える。 :%!xxd -r
set showmatch 閉じ括弧の入力時に開き括弧にカーソルが移動する。
挿入モードでのCTRL-P、CTRL-N カーソル直前の文字列を使って補完入力 カレントバッファ等にある文字列から補完候補を選ぶ。
挿入モードでのCTRL-X CTRL-F ファイル名の補完。 /と打ってから補完すると/usrなどが候補として表示される。 さらに深い階層の補完候補を出すには再度CTRL-X CTRL-Fを入力。
挿入モードでのCTRL-A 前回と同じ文字を挿入する。 連続して同じ文字列を挿入する際に便利。 CTRL-@は挿入後挿入モードを抜けるらしいが、実際に試しても何も怒らなかった。なんでだろ。
挿入モードでのCTRL-YとCTRL-E CTRL-Yはカーソル位置の一行上の文字を挿入する。 CTRL-Eはカーソル位置の一行下の文字を挿入する。
gj、gk 表示行での移動。 折り返すほど長い行での移動を小刻みにする。
set virtualedit=all 行末より後ろなどの文字の無い場所にもカーソル移動ができ、文字の挿入や矩形選択が可能となる。 終了するときは以下。 set virtualedit=
gr、gR 画面上の表示幅が崩れないように文字を置換。 tabを置換する際に崩れない。
vimのhelpを読んで新たに覚えた便利なコマンド(usr20-usr22)
前回の続きです。
q: コマンドラインの履歴を編集して再実行できる。 過去実行したコマンドを編集(変更)して似たようなコマンドを実行したいときに便利。例えば、検索コマンドとか。
:oldfiles 最近開いたファイルの一覧を表示。
<2とすると2番目のファイルを指す。:e #<2という感じで使う。
- :mksession file.vim file.vimにセッション情報を保存する。 セッション情報を使うと開いていたファイルなどの情報を再現してvimを起動することができる。 vim -S file.vim または :source file.vim
vimのhelpを読んで新たに覚えた便利なコマンド(usr11-usr12)
前回の続きです。
K カーソルのある単語のmanを引く。 なんとびっくり。こんなことできるんですね。
:grep abc *.txt *.txtの中からabcをgrepして、該当箇所にカーソルを移動。ファイルも開く。
vimのhelpを読んで新たに覚えた便利なコマンド(usr10まで)
前回に引き続き、helpをみてそれまで知らなかったけれども使えそうと思ったコマンドを紹介。
qa レジスタaにマクロとして操作を保存。 実行は@a レジスタはヤンクで使われるものと同じなので、バッファの文字列をレジスタにヤンクしてマクロとして実行することも可能。 “ayyみたいに。
?pattern1?+1,/pattern2/-2s/foo/bar/g 上方向(後方)にpattern1を検索し見つかった行の次の行から、下方向(前方)にpattern2を検索し2行手前(上の行)までを対象に、fooをbarにすべて置換する。
!Gsort バッファの内容をsortコマンドの結果で置き換える。 一時ファイルを用意する必要ないので便利
:read !ls コマンドの実行結果をバッファに挿入。 以下だと現在位置を書き換え :.!ls
:wirte !wc ファイルの中身をコマンドに渡す。 結果が表示されるが、その後enterを押すと表示が消える。
vimのCTRL-^が動かない
vimのヘルプの、「07.3 他のファイルにジャンプする」にあるCTRL-^が期待通りに動かない。。なんでだろ。
:argsで現在ファイルを確認して、:nextや:previousでファイルを変更してからCTRL-^を入力しても何も変わらない。
vimのテキストをhtmlに変換
何がうれしいかって、blogにコードを張るときにhtmlコードをそのままコピペできる点。
でも、出来上がるhtmlファイルはそれ単体で完結している作りなので部分的にコピペが必要で勝手はいまいち。スタイルシートはblogに事前に設定しておけば変更不要なのでそこの手間は不要。
以下のコマンドで変換できる。
:TOhtml
以下が例。
1 if exists('g:loaded_helloworld')
2 finish
3 endif
4 let g:loaded_helloworld = 1
5 command! HWorld call helloworld#hello_world()
vimのhelpを読んで新たに覚えた便利なコマンド(usr_04.txtまで)
vimを使いこなせていない自信があったのでヘルプを見て勉強し直したら便利な使い方がたくさん載っていたのでここにメモ。 とりあえずusr_04.txtの範囲まで。
- カーソル位置の単語と一致する単語を検索
g* カーソル位置の単語を含むものを検索
H 画面上部にカーソル移動
M 画面中央にカーソル移動
-L 画面下部にカーソル移動
CTRL-O、CTRL-I(Tab) 前、後の位置にジャンプ(カーソル移動)
ma、
a maでマークして、aで移動。 CTRL-O、CTRL-Iでジャンプもできる`` 一つ前の位置にジャンプする(最初はCTRL-Oと同じ挙動)
~ 大文字小文字変換 ビジュアルモードでも利用可
(ビジュアルモード)o、O 選択範囲の変更のために、カーソルを反対側に移動 始点の変更ができる。矩形選択の場合はOも使って範囲変更可能。
“* yやpと合わせてクリップボードを使用
はじめてのvim plugin作成
vimconf2018 には参加できなかったけれども、発表資料を読んだりTwitterを眺めているとやっぱり何かしたくなったのと、もっとvimを使いこなしたくなったのでpluginを書く練習を始めようと決意した。
helpを読んで書いてみようと思ったが、サンプルで既に理解できないところがあったので、Alisueさんの発表資料にあるHello Worldを真似てみるところからスタート。
ファイル名やコマンド名は多少変えたけれども、そのまんま。すごく簡単。
plugin/helloworld.vim
1 if exists('g:loaded_helloworld')
2 finish
3 endif
4 let g:loaded_helloworld = 1
5 command! HWorld call helloworld#hello_world()
autoload/helloworld.vim
1 function! helloworld#hello_world() abort
2 echo "Hello, World"
3 endfunction
dein.vim使ったvimrcでのcolorscheme設定
icebergというcolorschemeを作った人の発表をvimconf2017で聞いたら、colorshcemeが大好きなちょっと?変わった人だったので、きっとこれは良いに違いないと導入を決めました。
dein.vimを使っているとどうもうまく反映されないので以下のページを参考にautocmdを使って設定したらうまくいきました。
au MyAutoCmd VimEnter * nested colorscheme iceberg
syntax enable
参考URL
vimconf2017へ行ってきた
11月4日にvimconf2017が開催されました。
vimの話はさておき、コーヒーは無料だし、お弁当は今半のすきやき弁当だし、懇親会は飲み放題だし、ホテルのビュッフェみたいなおいしい料理だしとても美味しかったです。
各席には電源コンセントもあるし、会場のWi-Fiもあるし、不自由なく過ごせました。
困った点といえば、vimのコマンドや機能を知らなくて理解が不十分だったり、懇親会で相談したり情報提供できるようなネタが無くて何を話すか悩んでしまったりしたことくらいでした。
発表内容はどれも興味深くて、色々と試してみたくなるような内容ばかりでした。
これから実際に試しながらvim力を高めていきたいと思います。
また来年も参加したいです!
以下、メモしたキーワードやURLです。
Tag: Vim Plugin
「入門 UML 2.0」を読んだ
「入門 UML 2.0」を読んだ。 UMLってユースケースを表現するためのものでしょ?と思っていて、図を使ってユースケースを書く必要に迫られることも無かったのであまり勉強する気にもなっていなかったのですが、Plant UMLというテキストでUMLを既述できるものを知り、図を描くのにテキストで記述できるのは便利そうということで読んでみることにしました。
読んでみると、そもそもユースケース図を描くたものものという認識が誤りで、ユースケース図を表現することにも使えるが、それ以外の様々なものを表現するために使えるものであるということがわかりました。また、表現の仕方が定義されていて、UMLを知っている人であれば書き方を説明せずに記述できるということもよく分かりました。そのため、記述ルールについての凡例を書く必要もないのです。
UMLは既述したい目的毎に図の書き方がいくつも用意されています。そして、その目的や使い分けについて説明しています。しかし、その使い方は限定的ではありません。ある特定の種類の図ですべてを表現する必要はなく、その図で表現したい箇所だけをその図で表現し、そのほかの場所は異なる種類の図で表現しても良いとされています。結局は表現すべき重要な事柄を、それを表現するのに適切な図を使って表現すべきとしています。 つまり、何を表現すべきかを考えて使い分けるということです。
この本を読むことで、システム設計においてどのような情報を表現するべきかということがわかると思います。全体の概要を示したい場合や、特定部分の詳細について説明したい場合がありますが、それらがどのような種類の情報であるか、また混ぜるべきではない情報というのはどういうものかというのがなんとなくわかると思います。実際に書いて表現することを繰り返すことで、システムのどの部分をどのように表現するべきかというのがより直感的にわかるようになってくるのだと思います。
ところで、Plant UMLはテキストで記述したものをUML図に変換する仕組み(Webサービス、Javaプログラムとして提供されています)ですが、テキストをエディタで変更すると即座にその結果のUML図が変更されるという使い方ができます。
Vimでは、previmというpluginを使うことで実現できます。 previmはそもそもMarkdownに対してのプレビューを提供するものでしたが、PlantUMLにも対応したのです。
これを使いたかったという気持ちもあります。
そんなわけで、今後、図を記述する必要がある場合にはPlantUMLを積極的に使っていきたいと思っています。
vim plugin の ftdetectの効かせ方
vim plugin を作っていてなかなか解決できなかった課題のメモです。
vim ではファイルタイププラグインという種類のプラグインが作成できます。 ファイルタイププラグインはファイルタイプに合わせて挙動を変えることができるようにするためのプラグインです。 vim はファイルを開いた際に、そのファイルがどのファイルタイプか判別します。 ファイルタイプはC言語のようなプログラミング言語毎にあらかじめ定義されていますし、自分で作成することもできます。 自分で作成する場合には、ファイルタイプ名を決めて、そのファイルタイプの場合にどのような挙動にするかを定義したプラグインファイルを作成します。 例えば、ファイルタイプ毎に異なるマップを定義することができます。 その場合、プラグインファイルには定義したいマップコマンドを記述します。そうすることで、特定のファイルタイプの場合にのみそのマップコマンドが実行されるようになります。
ところで、ファイルを開くたびにそのファイルがどのファイルタイプかを判別する必要がありますが、自分で作成したファイルタイプのことはvimは知らないので、どのファイルが自作のファイルタイプに該当するかを定義する必要があります。 それには何らかの方法で以下のようにしてファイルタイプを指定する必要があります。これを実現する方法はいくつかありますが、その一つに ftdetect/*.vim というファイルを使う方法があります。
set filetype=aaaa
ftdetect/.vim というファイルは、ファイルを開いた際(厳密にはバッファを開いた際)に自動的に読み込まれて実行されるファイルの一つです。 runtimepath配下にあるftdetect/.vimを実行します。 このファイルは、以下の設定がされていないと読み込まれないようですが、これだけを設定していても読み込まれない場合がありました。
set runtimepath+=~/where/to/pluginpath/
filetype plugin on
読み込まれるようにするためには以下のように、runtimepathの設定の前に filetype offを設定する必要がありました。
filetype off
set runtimepath+=~/where/to/pluginpath/
filetype plugin on
blogの始め方その1
どこに書くか
blogを書き始めようとするときに、まずはどこに書くかを決める必要があります。 世界中で人気のWord Pressというソフトウェアを使う手もありますが、ややニッチ(?)なMovable Typeというソフトウェアもあります。 Movable TypeはSix Apartという会社が開発しているソフトウェアで、商用ブログサービスとしてType Padというものもあります。 私はMovable Typeに書くことにしているのでMovable Typeを使います。
何で書くか
Movable TypeはWebインタフェースがあるので、ブラウザで書くのが通常ですがブラウザのテキストフォームに書くような形になるので使いづらいです。使いやすくするにはjavascriptを書いて機能拡張するなどの工夫が必要です。しかし、世の中には文章を書くためのツールとしてエディタがいくつもあり、それらを使う方が文書を書くには都合が良いのです。当たり前ですね。Movable TypeにはWebのGUIインタフェース以外にWeb APIも提供しています。このWeb APIはData APIという名前で定義されていて、これを使うと記事の新規作成や編集なども行えます。
そういうわけで、エディタで書いた文章をData APIを使ってMovable Typeに投稿する仕組みが実現できそうです。 これができればエディタで気持ちよく文章を書いて、そのままMovable Typeのblogエントリとして投稿できるはずです。 欠点があるとすれば、写真などの画像を入れようとすると難しくて、WebのGUIインタフェースの方が直感的に配置できたり、アップロードもできるので操作性は上です。 ですので、画像の取り扱いはWeb GUI、文字はエディタと使い分けることにします。
さて、エディタで書いた文章をData APIを使ってMovable Typeに投稿しようと思いますが、どのような操作性が良いでしょうか。 気軽に編集できるようにするには、エディタでテキストファイルを保存するような操作でData APIを使って投稿できる、修正できるというのが良いでしょうか。 ローカルに編集したり、Data APIを使って編集を反映したりと使い分けられるようにするのも手です。 とりあえずはローカルにあるファイルを編集し、上書き保存すると、Data APIを使ってMovable Typeの記事も編集(変更)されるという仕組みを目指します。
足りない機能
エディタでファイルを保存すると自動的にData APIにアクセスする仕組みを実現する必要が出てきました。 自動で行うというのがポイントですが、そのためには以下のような方法が考えられます。
- ファイルの更新チェックをリアルタイムで行うようにカーネルフックモジュールを用意する
- ファイルの更新チェックを行うデーモンを用意する
- エディタの保存処理をフックする仕組みを用意する
カーネルフックモジュールで実装すると、色々と無駄で遅くなりそうです。 デーモンを用意するのも大げさな感じですし、無駄な感じです。 そこで今回はエディタの保存処理をフックする仕組みを用意することにします。
保存処理をフックできるようなエディタはいくつもありますが、筆者はvimが好きなのでvimを採用します。 vimはemacsと同じく拡張が用意で基本的になんでもできます。
vimの場合は、vim scriptという形で保存処理をフックする仕組みを記述すれば実現できます。 vim の設定ファイルはvimrcに記述しますが、この設定ファイルもvim script形式です。 そのため、vimrcに保存処理のフックすく仕組みを書けば解決できますが、その仕組みが巨大であったり、汎用的にできたり、公開したい場合にはプラグインとして作成することもできます。 今回はMovable Type利用者でかつ、vim利用者のためのプラグインを作成することにします。
足りない機能を補う
vim プラグインに必要な機能はData APIへのアクセスに関するものと、ローカルファイルの取り扱いに関するものに分けられます。 Data APIはHTTPアクセスなのでHTTPリクエストとレスポンスの取り扱いが必要です。 この部分はvital.vimを使います。 ローカルファイルの取り扱いは自分で用意します。
Data APIで取得したエントリはJSON形式で取得できますが、それをローカルファイルに保存する前にエディタで編集しやすい形に整形する必要があります。 また、その逆にローカルファイルの内容をData APIで投稿する際には逆の整形を行う必要があります。 こうした処理をちまちま書いていくといずれ出来上がります。 プラグインの処理の詳細は別の記事に書きますので、そちらを参照してください。
vim script の関数定義の際の引数リストのカンマの前にスペースは書けない
前回の記事に書いた件、以下のURLに知りたいことが書いてありました。 どうやらバグではなくて仕様ということらしいです。 help :todo を見ると、ドキュメントに書こうとしているようです。(以下に抜粋)
Space before comma in function definition not allowed: "function x(a , b)"
Give a more appropriate error message. Add a remark to the docs.
というわけで、 vim script の関数定義の際の引数リストのカンマの前にスペースは書けないということがわかりました。
vim plugin mtdataapi の更新記録(ダウンロード機能追加)
mtdataapiに記事のダウンロード機能を設けました。
以下のコマンドでダウンロードできます。 ダウンロード先は、g:mt_basedir です。この配下にサイトIDのディレクトリが作られます。各エントリはエントリIDのファイル名になります。
let g:mt_basedir = $HOME/mtblog
:mtdataapi#downloadSiteToFile()
pandocでフォーマット変換(vim-mtdataapi)
mtdataapiというvimのpluginからMovable Typeへの記事投稿の際、markdown形式で投稿できるようにしました。 変換にはpandocを使っています。
Movable Type 用 Vim Plugin を開発中
Movable Type というCMSを使ってブログを書いていますが、基本的にブラウザで入力するため文章入力が非効率に感じることが多々あったので、vimから投稿できるようにvim pluginを開発しています。
単純な更新ができるようになってきたので、一旦githubに公開しましたが、とても一般の方が使える状態ではありません。 需要があるようでしたら、issueやSNSなどで連絡もらえると嬉しいです。
Tag: 奥穂高岳
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その3)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。 上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地 2019年8月16日(金)~8月18日(日)
この日は、涸沢カールのモルゲンロートを期待して早起きして写真撮ってから出発。下山のみなので特に急がずのんびり出発。快晴で気持ち良い!これが昨日だったらよかったのに!!!と思いながら後悔しても仕方ないのでしないようにしていた。・・・つもり。山々の眺めを堪能しながら下山しました。
あー、楽しかった!!!
以下は写真と簡単なコメント。3日目の分。
これは奥穂高岳方面のモルゲンロート。
これは前穂高岳のモルゲンロート。
これは奥穂高岳方面のモルゲンロート。
これは涸沢カールのモルゲンロート。
これは前穂高岳に日が差したところ。
これはヘリコプター。
これはヘリコプター。
これは・・・涸沢から北穂を向いて右手のところ。夏っぽい。
これは・・・なんだっけ。涸沢から横尾に向かう途中に見える山。
これは木の枝。陽が当たって水蒸気がもくもくしていた。
これはトンボ。
これは明神ヶ岳。これの向こう側に前穂高岳。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その2)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地
2019年8月16日(金)~8月18日(日)
ようやく穂高岳に登頂できました。穂高岳山荘の若女将さんとはキナバルのツアーで一緒になった縁があって、仲良く(?)させて頂いています。イベントの後の飲み会に混ぜてもらったり、飲んでて終電なくなったときに泊めて頂いたりもしました。ずうずうしくてすみません。そんな縁もあって登ってみたい気持ちも強く、以前に一度計画したことがありました。そのときはトラブルが発生したために登頂を断念。穂高岳山荘にお世話になりましたが登頂は叶いませんでした。そして今回、ようやく登頂することができました。北アルプスの最高峰。ガスが多くて最高の眺めとはいきませんでしたが、北アルプスっぽさを満喫できました。金曜を休みにしてすこしずらしたのがよかったのか、それほど混んでもいなかったので、久々の北アルプスを満喫できました♪今度は雲のない最高の眺めを見に行きたいです。
以下は写真と簡単なコメント。2日目の分。
岳沢小屋から登ってきたところ。
もっと上ったところ。ここは歩いている尾根の東側方面。
奥穂高岳山頂。ガスってる。。時々ちょっと薄くなるけど、近くが少し見える程度。。
これが噂のジャンダルム!!! 見えてないけど。。
これがちらっと見えるジャンダルム!!!かっこよかった!のと、思ってたより近かった!!!
常念岳!!まだ登れてない!!
涸沢カールを覗く。赤いのは涸沢ヒュッテの屋根。
前穂高岳。かっちょいい。やっと名前が分かった。これの右端が前穂高岳。
常念岳。
今話題の北アルプスのヘリコプター。
ワイン。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その1)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地
2019年8月16日(金)~8月18日(日)
最近はめっきり登山の頻度が少なくなってしまい体力的に心配でした。でも、それよりもっと心配していたのが休めるかどうか。結局前日の23時頃にやっと休めると同行者に連絡できるような状況でした。 金曜日の仕事を休んで土日の混雑を避ける作戦だったのです。 そんなことはさておき、無事に休みが取れたので金曜朝にいざ出発。みんな大好きな新島々のセブンイレブンに到着。仕事の状況確認してみるといろいろ対応しないといけない問題が。。ということで電話で仕事。1時間弱のロス。。 というわけで、仕事に振り回されながらもなんとか上高地に到着。時間は14時前。お昼くらいには到着していたかったのに。。計画を立てるときには遅くても15時には行動を終えるようにしているので、今日は出発時点で良くない状況です。 でも、今日は岳沢小屋までの長くない道のり。寝不足なのと久々で体力が不安ですが、なんとかなるでしょう。ということで出発!
以下は写真と簡単なコメント。1日目の分。
河童橋。雨で濁流に。午前中までは雨が降っていて、そのあとも降ったり止んだり。
岳沢名物の風穴。確かに冷たい風が吹き出ていて気持ち良い。ただ、出発が遅かったのでゆっくりせず先を急ぐ。
岳沢小屋到着。
一瞬、青空が!!! 晴れないかと期待するも時々青空が見える程度。。
小屋の正面を少し上から。赤い屋根は食堂や売店など。写真右の高くなったところが宿泊部屋。晴れていたらデッキからの眺めは素晴らしいんだろうなぁ。。デッキの下の方は上高地方面。
夕焼け。
アジフライがさくさくでとってもおいしかったし、トマトも地味にうまい。ってか、全部おいしかった!!!
Tag: 岳沢
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その3)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。 上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地 2019年8月16日(金)~8月18日(日)
この日は、涸沢カールのモルゲンロートを期待して早起きして写真撮ってから出発。下山のみなので特に急がずのんびり出発。快晴で気持ち良い!これが昨日だったらよかったのに!!!と思いながら後悔しても仕方ないのでしないようにしていた。・・・つもり。山々の眺めを堪能しながら下山しました。
あー、楽しかった!!!
以下は写真と簡単なコメント。3日目の分。
これは奥穂高岳方面のモルゲンロート。
これは前穂高岳のモルゲンロート。
これは奥穂高岳方面のモルゲンロート。
これは涸沢カールのモルゲンロート。
これは前穂高岳に日が差したところ。
これはヘリコプター。
これはヘリコプター。
これは・・・涸沢から北穂を向いて右手のところ。夏っぽい。
これは・・・なんだっけ。涸沢から横尾に向かう途中に見える山。
これは木の枝。陽が当たって水蒸気がもくもくしていた。
これはトンボ。
これは明神ヶ岳。これの向こう側に前穂高岳。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その2)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地
2019年8月16日(金)~8月18日(日)
ようやく穂高岳に登頂できました。穂高岳山荘の若女将さんとはキナバルのツアーで一緒になった縁があって、仲良く(?)させて頂いています。イベントの後の飲み会に混ぜてもらったり、飲んでて終電なくなったときに泊めて頂いたりもしました。ずうずうしくてすみません。そんな縁もあって登ってみたい気持ちも強く、以前に一度計画したことがありました。そのときはトラブルが発生したために登頂を断念。穂高岳山荘にお世話になりましたが登頂は叶いませんでした。そして今回、ようやく登頂することができました。北アルプスの最高峰。ガスが多くて最高の眺めとはいきませんでしたが、北アルプスっぽさを満喫できました。金曜を休みにしてすこしずらしたのがよかったのか、それほど混んでもいなかったので、久々の北アルプスを満喫できました♪今度は雲のない最高の眺めを見に行きたいです。
以下は写真と簡単なコメント。2日目の分。
岳沢小屋から登ってきたところ。
もっと上ったところ。ここは歩いている尾根の東側方面。
奥穂高岳山頂。ガスってる。。時々ちょっと薄くなるけど、近くが少し見える程度。。
これが噂のジャンダルム!!! 見えてないけど。。
これがちらっと見えるジャンダルム!!!かっこよかった!のと、思ってたより近かった!!!
常念岳!!まだ登れてない!!
涸沢カールを覗く。赤いのは涸沢ヒュッテの屋根。
前穂高岳。かっちょいい。やっと名前が分かった。これの右端が前穂高岳。
常念岳。
今話題の北アルプスのヘリコプター。
ワイン。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その1)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地
2019年8月16日(金)~8月18日(日)
最近はめっきり登山の頻度が少なくなってしまい体力的に心配でした。でも、それよりもっと心配していたのが休めるかどうか。結局前日の23時頃にやっと休めると同行者に連絡できるような状況でした。 金曜日の仕事を休んで土日の混雑を避ける作戦だったのです。 そんなことはさておき、無事に休みが取れたので金曜朝にいざ出発。みんな大好きな新島々のセブンイレブンに到着。仕事の状況確認してみるといろいろ対応しないといけない問題が。。ということで電話で仕事。1時間弱のロス。。 というわけで、仕事に振り回されながらもなんとか上高地に到着。時間は14時前。お昼くらいには到着していたかったのに。。計画を立てるときには遅くても15時には行動を終えるようにしているので、今日は出発時点で良くない状況です。 でも、今日は岳沢小屋までの長くない道のり。寝不足なのと久々で体力が不安ですが、なんとかなるでしょう。ということで出発!
以下は写真と簡単なコメント。1日目の分。
河童橋。雨で濁流に。午前中までは雨が降っていて、そのあとも降ったり止んだり。
岳沢名物の風穴。確かに冷たい風が吹き出ていて気持ち良い。ただ、出発が遅かったのでゆっくりせず先を急ぐ。
岳沢小屋到着。
一瞬、青空が!!! 晴れないかと期待するも時々青空が見える程度。。
小屋の正面を少し上から。赤い屋根は食堂や売店など。写真右の高くなったところが宿泊部屋。晴れていたらデッキからの眺めは素晴らしいんだろうなぁ。。デッキの下の方は上高地方面。
夕焼け。
アジフライがさくさくでとってもおいしかったし、トマトも地味にうまい。ってか、全部おいしかった!!!
Tag: 涸沢
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その3)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。 上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地 2019年8月16日(金)~8月18日(日)
この日は、涸沢カールのモルゲンロートを期待して早起きして写真撮ってから出発。下山のみなので特に急がずのんびり出発。快晴で気持ち良い!これが昨日だったらよかったのに!!!と思いながら後悔しても仕方ないのでしないようにしていた。・・・つもり。山々の眺めを堪能しながら下山しました。
あー、楽しかった!!!
以下は写真と簡単なコメント。3日目の分。
これは奥穂高岳方面のモルゲンロート。
これは前穂高岳のモルゲンロート。
これは奥穂高岳方面のモルゲンロート。
これは涸沢カールのモルゲンロート。
これは前穂高岳に日が差したところ。
これはヘリコプター。
これはヘリコプター。
これは・・・涸沢から北穂を向いて右手のところ。夏っぽい。
これは・・・なんだっけ。涸沢から横尾に向かう途中に見える山。
これは木の枝。陽が当たって水蒸気がもくもくしていた。
これはトンボ。
これは明神ヶ岳。これの向こう側に前穂高岳。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その2)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地
2019年8月16日(金)~8月18日(日)
ようやく穂高岳に登頂できました。穂高岳山荘の若女将さんとはキナバルのツアーで一緒になった縁があって、仲良く(?)させて頂いています。イベントの後の飲み会に混ぜてもらったり、飲んでて終電なくなったときに泊めて頂いたりもしました。ずうずうしくてすみません。そんな縁もあって登ってみたい気持ちも強く、以前に一度計画したことがありました。そのときはトラブルが発生したために登頂を断念。穂高岳山荘にお世話になりましたが登頂は叶いませんでした。そして今回、ようやく登頂することができました。北アルプスの最高峰。ガスが多くて最高の眺めとはいきませんでしたが、北アルプスっぽさを満喫できました。金曜を休みにしてすこしずらしたのがよかったのか、それほど混んでもいなかったので、久々の北アルプスを満喫できました♪今度は雲のない最高の眺めを見に行きたいです。
以下は写真と簡単なコメント。2日目の分。
岳沢小屋から登ってきたところ。
もっと上ったところ。ここは歩いている尾根の東側方面。
奥穂高岳山頂。ガスってる。。時々ちょっと薄くなるけど、近くが少し見える程度。。
これが噂のジャンダルム!!! 見えてないけど。。
これがちらっと見えるジャンダルム!!!かっこよかった!のと、思ってたより近かった!!!
常念岳!!まだ登れてない!!
涸沢カールを覗く。赤いのは涸沢ヒュッテの屋根。
前穂高岳。かっちょいい。やっと名前が分かった。これの右端が前穂高岳。
常念岳。
今話題の北アルプスのヘリコプター。
ワイン。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地(その1)
先日、久々に北アルプスに行ってきました。
行程は以下の通り。
上高地~岳沢小屋(泊)~奥穂高岳~涸沢小屋(泊)~上高地
2019年8月16日(金)~8月18日(日)
最近はめっきり登山の頻度が少なくなってしまい体力的に心配でした。でも、それよりもっと心配していたのが休めるかどうか。結局前日の23時頃にやっと休めると同行者に連絡できるような状況でした。 金曜日の仕事を休んで土日の混雑を避ける作戦だったのです。 そんなことはさておき、無事に休みが取れたので金曜朝にいざ出発。みんな大好きな新島々のセブンイレブンに到着。仕事の状況確認してみるといろいろ対応しないといけない問題が。。ということで電話で仕事。1時間弱のロス。。 というわけで、仕事に振り回されながらもなんとか上高地に到着。時間は14時前。お昼くらいには到着していたかったのに。。計画を立てるときには遅くても15時には行動を終えるようにしているので、今日は出発時点で良くない状況です。 でも、今日は岳沢小屋までの長くない道のり。寝不足なのと久々で体力が不安ですが、なんとかなるでしょう。ということで出発!
以下は写真と簡単なコメント。1日目の分。
河童橋。雨で濁流に。午前中までは雨が降っていて、そのあとも降ったり止んだり。
岳沢名物の風穴。確かに冷たい風が吹き出ていて気持ち良い。ただ、出発が遅かったのでゆっくりせず先を急ぐ。
岳沢小屋到着。
一瞬、青空が!!! 晴れないかと期待するも時々青空が見える程度。。
小屋の正面を少し上から。赤い屋根は食堂や売店など。写真右の高くなったところが宿泊部屋。晴れていたらデッキからの眺めは素晴らしいんだろうなぁ。。デッキの下の方は上高地方面。
夕焼け。
アジフライがさくさくでとってもおいしかったし、トマトも地味にうまい。ってか、全部おいしかった!!!
Tag: Movable Type
mtdataapi.vimの開発状況
以前、このエントリで書いたプラグインがとりあえず使える感じになってきたので改めてここに書く。
このプラグインは、Movable TypeというCMSを利用する際の文字編集を簡単にするために開発しています。 Movable Type(以下、MT)は、エントリを編集するインタフェースとしてWeb UIを提供していますが、豊富なエディタの機能を利用することができないのが個人的な欠点でした。 Web UIのままでも、javascriptを書くことで様々な機能を追加することができますが、使い慣れたエディタを使える方が何かと便利です。 そこで、vimというエディタで編集したものがMTにすぐにアップロードできたり、MTのエントリをvimにダウンロードできたりすることを実現したいと思いました。
そこでmtdataapi.vimでは、MTのもつAPIであるData APIを使って、エントリ情報をやり取りすることでエントリ情報のアップロードやダウンロードを実現しました。 MtOpenコマンドの引数にエントリIDを与えると、MTから該当のエントリをダウンロードしてきてローカルファイルに保存します。そして、そのローカルファイルを開きます。 そのまま編集して:wで保存すると、MTにアップロードされて、エントリが更新されます。 ダウンロードしたエントリは、本文だけでなく公開、非公開(下書き)の状態やカテゴリ、タグなどの情報も含まれていて、それらも編集可能です。そのため、非公開のエントリを公開に変えて保存するだけで、エントリを公開状態にすることができます。
本文編集の際のフォーマットは、htmlだけでなくMarkdownも利用できます。 Markdownで表現できない部分(複雑なhtmlなど)は、htmlのままにしておいて、文章だけMarkdownで記載することも可能です。文章だけであればMarkdownで記載できれば十分なのですが、それができない場合はhtmlをMarkdownで扱おうとすると情報が失われてしまうケースがありました。そのため、両方を扱えるようにしています。 htmlの方が情報が多いので、基本的にはhtmlでローカルファイルには保存しておいてMTとやり取りします。文章を編集する際のみ、該当部分をMarkdownに変換する使い方を意図しています。
上記のhtmlとMarkdownを変換するために、MtHTMLtoMDとMtMDtoHTMLコマンドを用意しています。 ビジュアル選択した状態で上記コマンドを実行すると、選択部分が変換されます。 Markdownでの編集が終わったらhtmlに変換して、:wするという使い方を想定しています。 MtOpenした場合も、:wで保存した場合も、その後自動的にMTの情報でbufferが更新されます。このときはhtmlで更新されます。
MTでは画像のアップロード操作などもできます。 Web UIではマウスで簡単に画像の挿入ができますが、mtdataapi.vimではできません。そのため、Web UIでエントリを編集する場合もあると思います。 そうした場合、ローカルファイルの情報が古くなってしまいますが、MtOpenで開いた状態でを押すとMTから情報をダウンロードして最新の情報で更新されます。
自分でこのプラグインを作ってみて実際に使っていますが、文章を書くのが楽になってブログエントリを書くのも楽になりました。 ブログといえばWord Pressが有名でMovable Typeは利用者が少ないような気がしますが、利用者の方は使っていただけると嬉しいです。
blogの始め方その1
どこに書くか
blogを書き始めようとするときに、まずはどこに書くかを決める必要があります。 世界中で人気のWord Pressというソフトウェアを使う手もありますが、ややニッチ(?)なMovable Typeというソフトウェアもあります。 Movable TypeはSix Apartという会社が開発しているソフトウェアで、商用ブログサービスとしてType Padというものもあります。 私はMovable Typeに書くことにしているのでMovable Typeを使います。
何で書くか
Movable TypeはWebインタフェースがあるので、ブラウザで書くのが通常ですがブラウザのテキストフォームに書くような形になるので使いづらいです。使いやすくするにはjavascriptを書いて機能拡張するなどの工夫が必要です。しかし、世の中には文章を書くためのツールとしてエディタがいくつもあり、それらを使う方が文書を書くには都合が良いのです。当たり前ですね。Movable TypeにはWebのGUIインタフェース以外にWeb APIも提供しています。このWeb APIはData APIという名前で定義されていて、これを使うと記事の新規作成や編集なども行えます。
そういうわけで、エディタで書いた文章をData APIを使ってMovable Typeに投稿する仕組みが実現できそうです。 これができればエディタで気持ちよく文章を書いて、そのままMovable Typeのblogエントリとして投稿できるはずです。 欠点があるとすれば、写真などの画像を入れようとすると難しくて、WebのGUIインタフェースの方が直感的に配置できたり、アップロードもできるので操作性は上です。 ですので、画像の取り扱いはWeb GUI、文字はエディタと使い分けることにします。
さて、エディタで書いた文章をData APIを使ってMovable Typeに投稿しようと思いますが、どのような操作性が良いでしょうか。 気軽に編集できるようにするには、エディタでテキストファイルを保存するような操作でData APIを使って投稿できる、修正できるというのが良いでしょうか。 ローカルに編集したり、Data APIを使って編集を反映したりと使い分けられるようにするのも手です。 とりあえずはローカルにあるファイルを編集し、上書き保存すると、Data APIを使ってMovable Typeの記事も編集(変更)されるという仕組みを目指します。
足りない機能
エディタでファイルを保存すると自動的にData APIにアクセスする仕組みを実現する必要が出てきました。 自動で行うというのがポイントですが、そのためには以下のような方法が考えられます。
- ファイルの更新チェックをリアルタイムで行うようにカーネルフックモジュールを用意する
- ファイルの更新チェックを行うデーモンを用意する
- エディタの保存処理をフックする仕組みを用意する
カーネルフックモジュールで実装すると、色々と無駄で遅くなりそうです。 デーモンを用意するのも大げさな感じですし、無駄な感じです。 そこで今回はエディタの保存処理をフックする仕組みを用意することにします。
保存処理をフックできるようなエディタはいくつもありますが、筆者はvimが好きなのでvimを採用します。 vimはemacsと同じく拡張が用意で基本的になんでもできます。
vimの場合は、vim scriptという形で保存処理をフックする仕組みを記述すれば実現できます。 vim の設定ファイルはvimrcに記述しますが、この設定ファイルもvim script形式です。 そのため、vimrcに保存処理のフックすく仕組みを書けば解決できますが、その仕組みが巨大であったり、汎用的にできたり、公開したい場合にはプラグインとして作成することもできます。 今回はMovable Type利用者でかつ、vim利用者のためのプラグインを作成することにします。
足りない機能を補う
vim プラグインに必要な機能はData APIへのアクセスに関するものと、ローカルファイルの取り扱いに関するものに分けられます。 Data APIはHTTPアクセスなのでHTTPリクエストとレスポンスの取り扱いが必要です。 この部分はvital.vimを使います。 ローカルファイルの取り扱いは自分で用意します。
Data APIで取得したエントリはJSON形式で取得できますが、それをローカルファイルに保存する前にエディタで編集しやすい形に整形する必要があります。 また、その逆にローカルファイルの内容をData APIで投稿する際には逆の整形を行う必要があります。 こうした処理をちまちま書いていくといずれ出来上がります。 プラグインの処理の詳細は別の記事に書きますので、そちらを参照してください。
pandocでフォーマット変換(vim-mtdataapi)
mtdataapiというvimのpluginからMovable Typeへの記事投稿の際、markdown形式で投稿できるようにしました。 変換にはpandocを使っています。
Movable Type へのフィードバック方法
先日の記事でMovable Typeのドキュメントのバグを見つけたのでフィードバックを行ったところ、すぐに対応して修正してもらえました。
https://movabletype.atlassian.net/browse/FEEDBACK-1309
フィードバック方法 以下のURLから内容を投稿するだけです。 ユーザ名やメールアドレスは公開情報となるので記入必須ではないようです。 メールアドレスを登録するとその後の対応が通知されます。
Movable Type 用 Vim Plugin を開発中
Movable Type というCMSを使ってブログを書いていますが、基本的にブラウザで入力するため文章入力が非効率に感じることが多々あったので、vimから投稿できるようにvim pluginを開発しています。
単純な更新ができるようになってきたので、一旦githubに公開しましたが、とても一般の方が使える状態ではありません。 需要があるようでしたら、issueやSNSなどで連絡もらえると嬉しいです。
Tag: Vim Plugi
mtdataapi.vimの開発状況
以前、このエントリで書いたプラグインがとりあえず使える感じになってきたので改めてここに書く。
このプラグインは、Movable TypeというCMSを利用する際の文字編集を簡単にするために開発しています。 Movable Type(以下、MT)は、エントリを編集するインタフェースとしてWeb UIを提供していますが、豊富なエディタの機能を利用することができないのが個人的な欠点でした。 Web UIのままでも、javascriptを書くことで様々な機能を追加することができますが、使い慣れたエディタを使える方が何かと便利です。 そこで、vimというエディタで編集したものがMTにすぐにアップロードできたり、MTのエントリをvimにダウンロードできたりすることを実現したいと思いました。
そこでmtdataapi.vimでは、MTのもつAPIであるData APIを使って、エントリ情報をやり取りすることでエントリ情報のアップロードやダウンロードを実現しました。 MtOpenコマンドの引数にエントリIDを与えると、MTから該当のエントリをダウンロードしてきてローカルファイルに保存します。そして、そのローカルファイルを開きます。 そのまま編集して:wで保存すると、MTにアップロードされて、エントリが更新されます。 ダウンロードしたエントリは、本文だけでなく公開、非公開(下書き)の状態やカテゴリ、タグなどの情報も含まれていて、それらも編集可能です。そのため、非公開のエントリを公開に変えて保存するだけで、エントリを公開状態にすることができます。
本文編集の際のフォーマットは、htmlだけでなくMarkdownも利用できます。 Markdownで表現できない部分(複雑なhtmlなど)は、htmlのままにしておいて、文章だけMarkdownで記載することも可能です。文章だけであればMarkdownで記載できれば十分なのですが、それができない場合はhtmlをMarkdownで扱おうとすると情報が失われてしまうケースがありました。そのため、両方を扱えるようにしています。 htmlの方が情報が多いので、基本的にはhtmlでローカルファイルには保存しておいてMTとやり取りします。文章を編集する際のみ、該当部分をMarkdownに変換する使い方を意図しています。
上記のhtmlとMarkdownを変換するために、MtHTMLtoMDとMtMDtoHTMLコマンドを用意しています。 ビジュアル選択した状態で上記コマンドを実行すると、選択部分が変換されます。 Markdownでの編集が終わったらhtmlに変換して、:wするという使い方を想定しています。 MtOpenした場合も、:wで保存した場合も、その後自動的にMTの情報でbufferが更新されます。このときはhtmlで更新されます。
MTでは画像のアップロード操作などもできます。 Web UIではマウスで簡単に画像の挿入ができますが、mtdataapi.vimではできません。そのため、Web UIでエントリを編集する場合もあると思います。 そうした場合、ローカルファイルの情報が古くなってしまいますが、MtOpenで開いた状態でを押すとMTから情報をダウンロードして最新の情報で更新されます。
自分でこのプラグインを作ってみて実際に使っていますが、文章を書くのが楽になってブログエントリを書くのも楽になりました。 ブログといえばWord Pressが有名でMovable Typeは利用者が少ないような気がしますが、利用者の方は使っていただけると嬉しいです。
Tag: Cmap
vimのコマンドラインモードのマップ定義の仕方
vimではマップという機能で様々なことが実現できます。 簡単に言うとショートカットキーを作ることができます。 また、vimにはモードが複数あり、モード毎にキーの意味が異なるのでモード毎に同じキーに別の意味を割り当てることができます。
モードの一つとして、コマンドラインモードがあります。コマンドラインモードは、vimを終了するときに使用できる:qでも利用しています。 :qとキー入力する場合、キー入力前の状態はノーマルモードです。そこから:を入力した時点でコマンドラインモードに移ります。 qはコマンドラインモードのコマンド(の省略形)です。そのあと、実際にはエンターキーを入力しますがこれによりqコマンドが実行されます。
そこでこのqコマンドに別の意味を持たせることがmapでできるのですが、設定の仕方を誤ってなかなか期待通りにならなかったので失敗した点を示します。 なお、実際に失敗したキーはqではなく、w(保存コマンド)でしたので、以下の例ではwコマンドで示します。
失敗 その1
mapコマンド(実際にはcnoremapコマンドを使用)のlhs側(新しく登録するキー)にエンターキーを記載しない
cnoremap w w<CR>q<CR>
mapコマンドの引数は大きく二つあり、新しく登録するキー列とそのキー列を入力した場合の意味を示すキー列等です。 その二つをlhs、rhsとそれぞれ表現します。Left Hand SideとRight Hand Sideの略と思われます。
以下のように書くと、エンターを押さなくてもrhs側のキー列が入力されたのと同じことが起こります。 そのため、:w filename と打とうとしていた場合でも:wと入力した時点でrhs側が入力されてしまいやりたかったことができません。 実現したいこと次第で対処法は変わりますが(つまり複数の選択肢がありますが)、今回は以下のように記載することで対処可能でした。
cnoremap w<CR> w<CR>q<CR>
失敗 その2
lhs、rhsに:を余計に記載する
cnoremap :w<CR> :q<CR>
cnoremapコマンドはコマンドラインモードでのキー入力に対して機能するので、lhsにもrhsにも:は不要です。 以下のようにすると:wしようとすると:qで終了するようになるはずです。
cnoremap w<CR> q<CR>
Tag: Cnoremap
vimのコマンドラインモードのマップ定義の仕方
vimではマップという機能で様々なことが実現できます。 簡単に言うとショートカットキーを作ることができます。 また、vimにはモードが複数あり、モード毎にキーの意味が異なるのでモード毎に同じキーに別の意味を割り当てることができます。
モードの一つとして、コマンドラインモードがあります。コマンドラインモードは、vimを終了するときに使用できる:qでも利用しています。 :qとキー入力する場合、キー入力前の状態はノーマルモードです。そこから:を入力した時点でコマンドラインモードに移ります。 qはコマンドラインモードのコマンド(の省略形)です。そのあと、実際にはエンターキーを入力しますがこれによりqコマンドが実行されます。
そこでこのqコマンドに別の意味を持たせることがmapでできるのですが、設定の仕方を誤ってなかなか期待通りにならなかったので失敗した点を示します。 なお、実際に失敗したキーはqではなく、w(保存コマンド)でしたので、以下の例ではwコマンドで示します。
失敗 その1
mapコマンド(実際にはcnoremapコマンドを使用)のlhs側(新しく登録するキー)にエンターキーを記載しない
cnoremap w w<CR>q<CR>
mapコマンドの引数は大きく二つあり、新しく登録するキー列とそのキー列を入力した場合の意味を示すキー列等です。 その二つをlhs、rhsとそれぞれ表現します。Left Hand SideとRight Hand Sideの略と思われます。
以下のように書くと、エンターを押さなくてもrhs側のキー列が入力されたのと同じことが起こります。 そのため、:w filename と打とうとしていた場合でも:wと入力した時点でrhs側が入力されてしまいやりたかったことができません。 実現したいこと次第で対処法は変わりますが(つまり複数の選択肢がありますが)、今回は以下のように記載することで対処可能でした。
cnoremap w<CR> w<CR>q<CR>
失敗 その2
lhs、rhsに:を余計に記載する
cnoremap :w<CR> :q<CR>
cnoremapコマンドはコマンドラインモードでのキー入力に対して機能するので、lhsにもrhsにも:は不要です。 以下のようにすると:wしようとすると:qで終了するようになるはずです。
cnoremap w<CR> q<CR>
Tag: Ftdetect
vim plugin の ftdetectの効かせ方
vim plugin を作っていてなかなか解決できなかった課題のメモです。
vim ではファイルタイププラグインという種類のプラグインが作成できます。 ファイルタイププラグインはファイルタイプに合わせて挙動を変えることができるようにするためのプラグインです。 vim はファイルを開いた際に、そのファイルがどのファイルタイプか判別します。 ファイルタイプはC言語のようなプログラミング言語毎にあらかじめ定義されていますし、自分で作成することもできます。 自分で作成する場合には、ファイルタイプ名を決めて、そのファイルタイプの場合にどのような挙動にするかを定義したプラグインファイルを作成します。 例えば、ファイルタイプ毎に異なるマップを定義することができます。 その場合、プラグインファイルには定義したいマップコマンドを記述します。そうすることで、特定のファイルタイプの場合にのみそのマップコマンドが実行されるようになります。
ところで、ファイルを開くたびにそのファイルがどのファイルタイプかを判別する必要がありますが、自分で作成したファイルタイプのことはvimは知らないので、どのファイルが自作のファイルタイプに該当するかを定義する必要があります。 それには何らかの方法で以下のようにしてファイルタイプを指定する必要があります。これを実現する方法はいくつかありますが、その一つに ftdetect/*.vim というファイルを使う方法があります。
set filetype=aaaa
ftdetect/.vim というファイルは、ファイルを開いた際(厳密にはバッファを開いた際)に自動的に読み込まれて実行されるファイルの一つです。 runtimepath配下にあるftdetect/.vimを実行します。 このファイルは、以下の設定がされていないと読み込まれないようですが、これだけを設定していても読み込まれない場合がありました。
set runtimepath+=~/where/to/pluginpath/
filetype plugin on
読み込まれるようにするためには以下のように、runtimepathの設定の前に filetype offを設定する必要がありました。
filetype off
set runtimepath+=~/where/to/pluginpath/
filetype plugin on
Tag: Blog
blogの始め方その1
どこに書くか
blogを書き始めようとするときに、まずはどこに書くかを決める必要があります。 世界中で人気のWord Pressというソフトウェアを使う手もありますが、ややニッチ(?)なMovable Typeというソフトウェアもあります。 Movable TypeはSix Apartという会社が開発しているソフトウェアで、商用ブログサービスとしてType Padというものもあります。 私はMovable Typeに書くことにしているのでMovable Typeを使います。
何で書くか
Movable TypeはWebインタフェースがあるので、ブラウザで書くのが通常ですがブラウザのテキストフォームに書くような形になるので使いづらいです。使いやすくするにはjavascriptを書いて機能拡張するなどの工夫が必要です。しかし、世の中には文章を書くためのツールとしてエディタがいくつもあり、それらを使う方が文書を書くには都合が良いのです。当たり前ですね。Movable TypeにはWebのGUIインタフェース以外にWeb APIも提供しています。このWeb APIはData APIという名前で定義されていて、これを使うと記事の新規作成や編集なども行えます。
そういうわけで、エディタで書いた文章をData APIを使ってMovable Typeに投稿する仕組みが実現できそうです。 これができればエディタで気持ちよく文章を書いて、そのままMovable Typeのblogエントリとして投稿できるはずです。 欠点があるとすれば、写真などの画像を入れようとすると難しくて、WebのGUIインタフェースの方が直感的に配置できたり、アップロードもできるので操作性は上です。 ですので、画像の取り扱いはWeb GUI、文字はエディタと使い分けることにします。
さて、エディタで書いた文章をData APIを使ってMovable Typeに投稿しようと思いますが、どのような操作性が良いでしょうか。 気軽に編集できるようにするには、エディタでテキストファイルを保存するような操作でData APIを使って投稿できる、修正できるというのが良いでしょうか。 ローカルに編集したり、Data APIを使って編集を反映したりと使い分けられるようにするのも手です。 とりあえずはローカルにあるファイルを編集し、上書き保存すると、Data APIを使ってMovable Typeの記事も編集(変更)されるという仕組みを目指します。
足りない機能
エディタでファイルを保存すると自動的にData APIにアクセスする仕組みを実現する必要が出てきました。 自動で行うというのがポイントですが、そのためには以下のような方法が考えられます。
- ファイルの更新チェックをリアルタイムで行うようにカーネルフックモジュールを用意する
- ファイルの更新チェックを行うデーモンを用意する
- エディタの保存処理をフックする仕組みを用意する
カーネルフックモジュールで実装すると、色々と無駄で遅くなりそうです。 デーモンを用意するのも大げさな感じですし、無駄な感じです。 そこで今回はエディタの保存処理をフックする仕組みを用意することにします。
保存処理をフックできるようなエディタはいくつもありますが、筆者はvimが好きなのでvimを採用します。 vimはemacsと同じく拡張が用意で基本的になんでもできます。
vimの場合は、vim scriptという形で保存処理をフックする仕組みを記述すれば実現できます。 vim の設定ファイルはvimrcに記述しますが、この設定ファイルもvim script形式です。 そのため、vimrcに保存処理のフックすく仕組みを書けば解決できますが、その仕組みが巨大であったり、汎用的にできたり、公開したい場合にはプラグインとして作成することもできます。 今回はMovable Type利用者でかつ、vim利用者のためのプラグインを作成することにします。
足りない機能を補う
vim プラグインに必要な機能はData APIへのアクセスに関するものと、ローカルファイルの取り扱いに関するものに分けられます。 Data APIはHTTPアクセスなのでHTTPリクエストとレスポンスの取り扱いが必要です。 この部分はvital.vimを使います。 ローカルファイルの取り扱いは自分で用意します。
Data APIで取得したエントリはJSON形式で取得できますが、それをローカルファイルに保存する前にエディタで編集しやすい形に整形する必要があります。 また、その逆にローカルファイルの内容をData APIで投稿する際には逆の整形を行う必要があります。 こうした処理をちまちま書いていくといずれ出来上がります。 プラグインの処理の詳細は別の記事に書きますので、そちらを参照してください。
Tag: Computer Science
「チューリングの計算理論入門」を読んだ
「チューリングの計算理論入門」を読んだ。 チューリングマシンってどんなだっけ?と思って、手に取った本。 シャノンの情報理論入門の著者と同じで、本の位置付けも入門で同じ。 チューリングについて語る前に、その頃の時代背景の説明や関係しそうなしなさそうな人物の紹介などについて述べて、その後チューリングの話に入るという展開。 チューリングマシンというものは、そもそも物理的な機械でなくて、数学的な理論の実装機械というものであり、その説明のために時代背景やチューリングが達成したかった数学的課題を説明している。そして、チューリングマシンは数学的な基礎だけでなく、現代のコンピュータの基礎としての位置付けとなった。
チューリングマシンとは、無限長のテープ(記憶装置)と状態を持った機械であり、状態遷移とテープの読み書きのルールを定義することであらゆるアルゴリズムを実行できるものです。
「シャノンの情報理論入門」を読んだ
「シャノンの情報理論入門」を読んだ。
学生時代の教科書として使っていたもっと堅い情報理論の本を読み返しているのだけれども、よく理解できないところがあったので、違う本も読んでみて理解を深めようと思って手にした本です。 情報理論というのは、情報というのをどのように伝達するのが効率良いのかとか意味のある情報とは何かとかそういうものを定義するものです。ある通信路を通して情報を一方から他方へ伝える場合の符号化の方法として何が最適かということを考える学問です。
堅い方の本で特によくわからなかったのは情報エントロピーでした。シャノンの情報理論入門では、エントロピーを期待値と説明していましたが、あぁ、なるほどと理解が深まりました。
本書はなるべく平易な表現で大まかに理解することを目指したものなので、タイトル通り、入門に良いと感じました。
Tag: 親子登山
鎌倉アルプス親子登山(背負子) 再び
前回(鎌倉アルプス親子登山(背負子))と同じコースで再び鎌倉アルプスに行ってきました。 子供を連れて電車で行くにはなかなかお手頃で、下山してからも公園があったり、神社があったりとなかなか楽しめます。 下山が観光地なので、街歩きを楽しんだりお土産買ったりと楽しめるのもまあ良いところかもしれません。今後も何度もお世話になると思います。
前回と同じく10時に北鎌倉駅集合。準備してスタートが10時過ぎ。 予報では神奈川県西部の山沿い(丹沢のあたり)ではにわか雨の可能性。空を見ると青空ではあるものの黒い雲が。。雨が降らないことを祈りながら出発。建長寺で拝観料を収めてからお参りしたら、石段登り。半僧坊までの階段は前回はとてもきつかったような記憶でしたが、今回はあっという間。なんでだろ?と考えてみると、前回は背中のベビーキャリーに乗せずに抱っこしながら歩いたので辛かったのでした。。降ろして歩かせたり抱っこして移動したりというのを頻繁にやった方が楽しいかなと思って抱っこしてみると、降りないと言う。なのでずっと抱っこする羽目にってのはよくあるパターン。。 今回は背中に乗っていてくれていたので、比較的楽。
今回は大人5人、子供3人の大所帯。だからか人見知りしたのか子供の口数が少ない。。あまり同世代の子供たちと遊ぶ機会が無いから、どうしてよいのかよくわからないのかなぁ。。親とか祖父母とかとばかり遊んでいるからねぇ。。
途中、リスやトンビを見ました。そのほかにも姿は見えなかったけれどウグイスのきれいな鳴き声を聞いたり、キツツキみたいに木をつつく鳥の音(姿も見た!)を聞いたり、天園ではトカゲを観察しながらランチを楽しみました♪
友人家族は子供と登山に行くのは初めてだったようですが、子供達も楽しんでいたようなので良かった。また一緒に行けると良いな♪
大山登山(親子登山)
本日、丹沢の大山に行ってきました。
オスプレイのポコ プラスを譲ってもらったので、その初使用として、近場の大山を選び登ってきました。
特に怪我等はありませんでしたが、この時期の大山を選んだのは子供にとっては寒すぎて失敗でした。
途中までは大丈夫そうでしたが、下山した時には手も足も冷たくなっていて寒かったようでした。
防寒対策が不十分だったというのと、下山が17時頃まで掛かってしまい太陽が沈み、寒くなってしまったのが原因と考えています。
防寒着としては綿の入った上下つなぎの服を普通の服の上に被せて着せました。
頭は帽子、手は手袋、足は普通の靴を履かせていましたが、途中で大人用の像足(ダウンシューズ)を履かせて足の保温、大人用のネックウォーマーで首回りの保温を追加しました。
途中で確認した時には手が温かく、問題なく保温できているかと考えていましたが、下山時には手も足も冷えていたことから、登りながら昼寝したときかその後くらいから徐々に冷えたものと推測しています。その頃から少し元気がなかったように記憶しています。
今日は人見知りした状態での登山だったので、それで大人しいのか寒いからなのかの判断がうまくできず、結果的に寒い思いをさせてしまいました。今後はもっと温かい山やコースを選ぶと共に、十分な保温を心がけたいと思います。
ところで、オスプレイのポコ プラス(ポコAG プラスではありません)の使い心地ですが、モンベルのベビーキャリアと比べて荷物がたくさん入ると聞いていましたが、メインの荷室のサイズはあまり変わりません。オスプレイの場合は追加のサブザックを付けられるので、そういったものを含めると大容量になるというもののようでした。しかも、キャリアのスタンド部分を閉じると荷室も狭くなってしまうので、その点はモンベルのベビーキャリアの方が使いやすいように思いました。ただ、オスプレイのものはひっかけにくいようにスタンド部分がやや上に上がっているようなので、考慮はされているようです。モンベルの場合は閉じるのを忘れるとひっかけやすい上に、閉じてあっても、今度は開くのを忘れるなどワンアクション余計に必要なのが難点です。今日使った範囲では、後ろをひっかけることはなかったので閉じ忘れや開き忘れが無い分、ストレスはありませんでした。
さて、本題の大山登山は10時くらいから歩き始めて、昼前に阿夫利神社着、1時頃から再度登り始めて15時山頂、17時下山という行程でした。早く出発するのも、休憩時間を短くするのもなかなか難しいので、コースタイムがもっと短いコースを選ぶのが正解でした。
今回は、寒い思いをさせてしまったのもあるし、下山時刻も遅いし、色々反省点の多い山行でした。次回に生かそうと思います。
以下はポコAG プラスのリンクです。
鎌倉アルプス親子登山(背負子)
鎌倉アルプスに行ってきました。 コース詳細はくにっとさんの記事に詳しいので省略します。 Facebookで親子登山のグループを作って最初の山行でしたが、以前から一緒に登山に行っていた仲間だったので特に問題なく無事に終了しました。 一緒に行った子供たちは2歳前後で自分でも少し歩けるので、本人が歩きたいと言うところは歩かせましたが、建長寺の境内だけ歩いて、あとは基本的に背中の上でした。 自分で歩かせるとなかなか進まないので時間にはかなり余裕を持たせておくのがポイントです。また、抱っこしたり歩いたりを繰り返すので手に抱いて歩いたりもしたので、腕力や体力にも余裕を持たせておくのがポイントです。体力無いときはずっと背負っておくのが一番楽かもしれません。 ちなみに集合時間が直前で変更になったりもしたので、親子登山の時はいろいろ柔軟に対応できるように時間にゆとりを持たせて計画することがとても大事ですね! 親子登山のためのFacebookグループ作って、これからいろいろ情報交換しながら山に行こうと思っているので興味ある方は連絡ください。 登山経験不問です!また、子供がいなくても、独身でも、子供と一緒に登山に行きたい方も一緒に山に行きましょう!お気軽に連絡ください!
小さな子供との登山で気を付けること 持ち物
小さな子供との登山に持っていくものをまとめました。 気を付けることの全体的なまとめはこちら 。 ###子供が使うもの * おむつ関連 * おむつ * おむつ替えシート(もしくは代わりになるマット) * おしり拭き * ごみ袋 * 飲食関連 * ストローマグ * 麦茶(ボトルに入れて1リットル弱程度) * お手拭きシート * スプーン、フォーク * 子供の食事 * おやつ * ごみ袋 * 服装関連 * くつ(歩かない場合でも防寒を兼ねて) * 帽子(日焼け防止、ケガ防止) * 防寒着(羽織るもの等) * 着替え(何らかの理由で濡れた場合、汚れがひどい場合に利用) * その他 * 日焼け止め * 虫除け * サンシェード(ベビーキャリアに取り付け可能な日除け) * レインカバー(ベビーキャリアに取り付け可能なもの) ###大人が使うもの * 荷物が入るサイズのベビーキャリア * ダブルストック(私はダブルストックが好きです) * ストックホルダー(ストックをしまえるように) * 地図、GPS(迷わないように) * カメラ(子供との楽しい思い出を写真に収めましょう) * 体力(子供の体重とその他の装備を背負って歩ける程度) * 通常の登山用の服装(詳細省略) * 通常の登山用の装備(詳細省略) * 登山計画書(家族や警察に届けましょう)
小さな子供との登山で気を付けることのまとめ
小さな子供との登山では、自分一人だけの時とは違って、子供の服装や体調にも気を付ける必要があるため、二人分の注意が必要です。 ここで言う小さな子供とは、自分で歩かず、ベビーキャリアに乗せて歩くような年齢の子供を想定しています。 ###服装 登山中は歩くと暑くなり、休憩すると寒くなるなど体感温度の変化が激しいです。そのため、こまめに温度調節が必要とはよく言われます。 ところがベビーキャリアに乗せられていて自分で歩かない子供の場合には、まったく歩かないために体温上昇は無く、冷える一方です。特に手足はよく冷えるので要注意です。 防寒対策としては、手袋や靴下などのほかに、ベビーキャリア用のレインカバーも使えるようです。防風効果があり保温が期待できます。 なお、ベビーキャリアに乗っている子供には背負っている人の体温による保温効果は期待できません。両者の間には空間があり、体温が伝わらないようになっているためです。 したがって子供の服は、じっとしていても冷えない程度の温かさの服を着せるのが良いです。 ###悪天対策 雨対策。濡れて体温が下がらないように全身を覆うタイプの雨具が望ましいです。ベビーキャリアには専用のレインカバーがあるのでそれを使うのが無難です。 フード付きのレインウェアなどは嫌がって取ってしまう可能性が高いので、自分で外せないタイプのものが良いと思います。 強風対策。大人と同じように風を通しにくい素材の服や、レインカバー等を使って防ぎます。 樹林帯コースを選ぶようにして、風が強くないルートを選択することも重要です。 ###おむつ 漏れないように、早めに交換しましょう。ある程度広くないと換えづらいので適当な場所があれば早めに交換しておくのが良いです。雨や風がある場合には体を冷やさないように小屋などで交換するのが良いですが、それができない場合でもなるべく風のない場所で交換するようにしましょう。 また、一人ですばやく交換するためのコツをつかんでおきましょう。動き回られると大変なので興味の引かせ方を習得しておきましょう。 ###食事 温めなくてもすぐに食べられるものが良いです。また、子供の食事の時にはつきっきりになってしまって、自分の食事は取れないので、子供の食事を済ませてから自分の食事をとるような時間配分を考えておきましょう。 ###関連記事 持ち物の一覧は小さな子供との登山で気を付けること 持ち物にまとめました。
浅間山、高麗山ハイキング(背負子)
久々に子供を背負って行ってきました浅間山。桁違いでした。 何が桁違いかっていうと、標高です。 標高181.3m 行程3km、2時間(往復) 累計高度400m コースは神奈川県平塚市。湘南平(高麗山公園)スタート。浅間山、高麗山(大堂)まで行って、往復です。 ちなみに、群馬の浅間山は2560mです。 アップダウンも少なく、子連れでも無理なく歩ける感じですが、雨の後だったからか滑りやすく見える箇所も多かったです。 山歩きに慣れた方であれば特に問題ない感じでしたが、不安な方は歩きづらいと感じそうなところもありました。 壊れかけのベンチも多数ありますが、要所要所にはしっかりしたベンチやテーブルがあり、人も多くなかったので休憩も取りやすい感じです。 湘南平の大駐車場に車を停めて、そこからピストンのコースです。 時間や脚力に余裕があれば、高麗山を越えて高来神社まで下りたり、地獄沢の方へ降りるのも良さそうでした。 湘南平公園 ハイキングコース案内
Tag: 小屋泊
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その3)
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。2日目の鳩待峠から。 個人的にはここの区間が今回一番楽しかった!晴れてたのもあるかも?
鹿の足跡。
晴れてきてとっても元気に!!
横田代という湿原エリア。気が少なく、風がやや強め。ここに先行パーティがいたけれど、昼ご飯を食べて戻ったようで、その後は会いませんでした。正面は燧ケ岳。
横田代の上部。雪が解けて地面が見えてます。
目的地(折り返し地点)としていたアヤメ平。誰もいなくて、風があって、ちょっと寒い。木道が一部出てました。
横田代の上部。正面に至仏山。雲の隙間から射す光が良い。風があったので雲も早く動いていて影も早い。
再び横田代からの燧ケ岳。
鳩待峠に戻ってきた。至仏山がすっかり晴れている。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その2)
前回のその1の続きです。
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。2日目の鳩待峠まで。
朝食。
尾瀬ヶ原は一面真っ白。友人たちはこの後ここを歩いていきました。
小屋のそばの解けたところ。水芭蕉が少し咲いていました。こんなに雪の多いときから咲くんですね。
鳩待峠に向かってすぐの橋。まだ雪がたっぷり。
晴れてきた!今日は晴予報!
陽が差してきれいに見えたところ。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その1)
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。1日目の分。
3人のザック。
久々の冬靴。
登山口の鳩待峠。
下に曲がった枝。
天気は曇り。
奥に至仏山。
燧ケ岳を背に登る。
右のなだらかな部分が至仏山の山頂。左のピークは小至仏山。
稜線に出たところ。少し手前から雨が降ってきたので防水装備に切り替え。稜線はガスの中でそこそこ濡れる。
植生を守ろう。
山頂到着。周りの山は白いフィルター越しに見えるが、肉眼ではきれいに映っていた。
山頂直下からの景色。まあまあきれいだったんですが写真だとなかなか。。。
尾瀬ヶ原方面に降りる大斜面。楽しく駆け下りた。
至仏山荘に到着。
談話室。きれいでこたつもある。
夕食。
Tag: 尾瀬
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その3)
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。2日目の鳩待峠から。 個人的にはここの区間が今回一番楽しかった!晴れてたのもあるかも?
鹿の足跡。
晴れてきてとっても元気に!!
横田代という湿原エリア。気が少なく、風がやや強め。ここに先行パーティがいたけれど、昼ご飯を食べて戻ったようで、その後は会いませんでした。正面は燧ケ岳。
横田代の上部。雪が解けて地面が見えてます。
目的地(折り返し地点)としていたアヤメ平。誰もいなくて、風があって、ちょっと寒い。木道が一部出てました。
横田代の上部。正面に至仏山。雲の隙間から射す光が良い。風があったので雲も早く動いていて影も早い。
再び横田代からの燧ケ岳。
鳩待峠に戻ってきた。至仏山がすっかり晴れている。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その2)
前回のその1の続きです。
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。2日目の鳩待峠まで。
朝食。
尾瀬ヶ原は一面真っ白。友人たちはこの後ここを歩いていきました。
小屋のそばの解けたところ。水芭蕉が少し咲いていました。こんなに雪の多いときから咲くんですね。
鳩待峠に向かってすぐの橋。まだ雪がたっぷり。
晴れてきた!今日は晴予報!
陽が差してきれいに見えたところ。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その1)
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。1日目の分。
3人のザック。
久々の冬靴。
登山口の鳩待峠。
下に曲がった枝。
天気は曇り。
奥に至仏山。
燧ケ岳を背に登る。
右のなだらかな部分が至仏山の山頂。左のピークは小至仏山。
稜線に出たところ。少し手前から雨が降ってきたので防水装備に切り替え。稜線はガスの中でそこそこ濡れる。
植生を守ろう。
山頂到着。周りの山は白いフィルター越しに見えるが、肉眼ではきれいに映っていた。
山頂直下からの景色。まあまあきれいだったんですが写真だとなかなか。。。
尾瀬ヶ原方面に降りる大斜面。楽しく駆け下りた。
至仏山荘に到着。
談話室。きれいでこたつもある。
夕食。
Tag: 残雪
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その3)
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。2日目の鳩待峠から。 個人的にはここの区間が今回一番楽しかった!晴れてたのもあるかも?
鹿の足跡。
晴れてきてとっても元気に!!
横田代という湿原エリア。気が少なく、風がやや強め。ここに先行パーティがいたけれど、昼ご飯を食べて戻ったようで、その後は会いませんでした。正面は燧ケ岳。
横田代の上部。雪が解けて地面が見えてます。
目的地(折り返し地点)としていたアヤメ平。誰もいなくて、風があって、ちょっと寒い。木道が一部出てました。
横田代の上部。正面に至仏山。雲の隙間から射す光が良い。風があったので雲も早く動いていて影も早い。
再び横田代からの燧ケ岳。
鳩待峠に戻ってきた。至仏山がすっかり晴れている。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その2)
前回のその1の続きです。
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。2日目の鳩待峠まで。
朝食。
尾瀬ヶ原は一面真っ白。友人たちはこの後ここを歩いていきました。
小屋のそばの解けたところ。水芭蕉が少し咲いていました。こんなに雪の多いときから咲くんですね。
鳩待峠に向かってすぐの橋。まだ雪がたっぷり。
晴れてきた!今日は晴予報!
陽が差してきれいに見えたところ。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その1)
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。1日目の分。
3人のザック。
久々の冬靴。
登山口の鳩待峠。
下に曲がった枝。
天気は曇り。
奥に至仏山。
燧ケ岳を背に登る。
右のなだらかな部分が至仏山の山頂。左のピークは小至仏山。
稜線に出たところ。少し手前から雨が降ってきたので防水装備に切り替え。稜線はガスの中でそこそこ濡れる。
植生を守ろう。
山頂到着。周りの山は白いフィルター越しに見えるが、肉眼ではきれいに映っていた。
山頂直下からの景色。まあまあきれいだったんですが写真だとなかなか。。。
尾瀬ヶ原方面に降りる大斜面。楽しく駆け下りた。
至仏山荘に到着。
談話室。きれいでこたつもある。
夕食。
Tag: 泊まり
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その3)
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。2日目の鳩待峠から。 個人的にはここの区間が今回一番楽しかった!晴れてたのもあるかも?
鹿の足跡。
晴れてきてとっても元気に!!
横田代という湿原エリア。気が少なく、風がやや強め。ここに先行パーティがいたけれど、昼ご飯を食べて戻ったようで、その後は会いませんでした。正面は燧ケ岳。
横田代の上部。雪が解けて地面が見えてます。
目的地(折り返し地点)としていたアヤメ平。誰もいなくて、風があって、ちょっと寒い。木道が一部出てました。
横田代の上部。正面に至仏山。雲の隙間から射す光が良い。風があったので雲も早く動いていて影も早い。
再び横田代からの燧ケ岳。
鳩待峠に戻ってきた。至仏山がすっかり晴れている。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その2)
前回のその1の続きです。
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。2日目の鳩待峠まで。
朝食。
尾瀬ヶ原は一面真っ白。友人たちはこの後ここを歩いていきました。
小屋のそばの解けたところ。水芭蕉が少し咲いていました。こんなに雪の多いときから咲くんですね。
鳩待峠に向かってすぐの橋。まだ雪がたっぷり。
晴れてきた!今日は晴予報!
陽が差してきれいに見えたところ。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠(その1)
令和になることは特に意識していなかったのですが、令和になってすぐに友人二人と至仏山に登山に行ってきました。 久しぶりの雪山でしたが、特に困ることもなく楽しめました。 友人と別れた後は一人で歩いたのですが、周りには人がほとんどおらず、1パーティとしかすれ違わないコースも歩けて満足できました。
行程は以下の通り。
鳩待峠~至仏山~山の鼻(泊)~鳩待峠~アヤメ平~鳩待峠
以下は写真と簡単なコメント。1日目の分。
3人のザック。
久々の冬靴。
登山口の鳩待峠。
下に曲がった枝。
天気は曇り。
奥に至仏山。
燧ケ岳を背に登る。
右のなだらかな部分が至仏山の山頂。左のピークは小至仏山。
稜線に出たところ。少し手前から雨が降ってきたので防水装備に切り替え。稜線はガスの中でそこそこ濡れる。
植生を守ろう。
山頂到着。周りの山は白いフィルター越しに見えるが、肉眼ではきれいに映っていた。
山頂直下からの景色。まあまあきれいだったんですが写真だとなかなか。。。
尾瀬ヶ原方面に降りる大斜面。楽しく駆け下りた。
至仏山荘に到着。
談話室。きれいでこたつもある。
夕食。
Tag: タンス
タンスの危険
子供がタンスによじ登っていたのを見ていたら、危ないと指摘を受けたので少し調べてみました。 その時の状況だけであれば危険度はそれほど高くなかったかもしれませんが、タンスで遊ぶことを許しているといずれ重大な事故を引き起こすかもしれません。 対策としては家具を壁に固定し、倒れないようにすることが基本です。地震対策だけでなく、子供の不注意などからの事故を防ぐためにも有効です。
消費者庁からは2017年11月10日に以下の注意喚起がなされました。 詳細はPDFにあります。
家具やテレビの転倒に気を付けましょう! -下敷きになった子どもが死亡する事故も-
また、独立行政法人製品評価技術基盤機構の平成29年度製品安全業務報告会でも取り上げられています。
今回指摘を受けたときは引き出しを開けずによじ登っていたので危険性は低いと判断して見ていましたが、今後引き出しを開けて遊ぶように発展する可能性も考えられるので、そういったことも意識していきたいと思いました。
Tag: 危険
タンスの危険
子供がタンスによじ登っていたのを見ていたら、危ないと指摘を受けたので少し調べてみました。 その時の状況だけであれば危険度はそれほど高くなかったかもしれませんが、タンスで遊ぶことを許しているといずれ重大な事故を引き起こすかもしれません。 対策としては家具を壁に固定し、倒れないようにすることが基本です。地震対策だけでなく、子供の不注意などからの事故を防ぐためにも有効です。
消費者庁からは2017年11月10日に以下の注意喚起がなされました。 詳細はPDFにあります。
家具やテレビの転倒に気を付けましょう! -下敷きになった子どもが死亡する事故も-
また、独立行政法人製品評価技術基盤機構の平成29年度製品安全業務報告会でも取り上げられています。
今回指摘を受けたときは引き出しを開けずによじ登っていたので危険性は低いと判断して見ていましたが、今後引き出しを開けて遊ぶように発展する可能性も考えられるので、そういったことも意識していきたいと思いました。
Tag: Hatchful
logo 作成サービス hatchful
logo 作成サービスのhatchfulというものを使ってみた。
faviconとブログのカバー画像をこれに変えてみた。 まだ変えられていないところも多いけれど、そもそもブログがたくさんあるのでそれの整理もした方が良いかなぁ。。。
Tag: Logo
logo 作成サービス hatchful
logo 作成サービスのhatchfulというものを使ってみた。
faviconとブログのカバー画像をこれに変えてみた。 まだ変えられていないところも多いけれど、そもそもブログがたくさんあるのでそれの整理もした方が良いかなぁ。。。
Tag: 誕生
Tag: Tweet Button
Tag: Twitter
Tag: Msys2
msys2にrbenv-buildでruby 2.6.3をインストール(失敗)
msys2にrbenv-buildでruby 2.6.3をインストールしようとして失敗してあきらめた話。 どうもmsys2でrubyをコンパイルしようとするとうまくいかないという話がちらほらあるらしいといくつか聞いたのであきらめることにした。 そもそもrbenvが動作しない。bin/rbenv を libexec/rbenv へのリンクにするととりあえず動作する。 rbenv install 2.6.3 すると、ダウンロードの途中で止まったようになり、Installing というメッセージが表示されない。 Ctrl-zで中断したときかfgで再開したときに以下のメッセージが出る。 何度か同じメッセージが出るのを確認して、ここで諦めた。
rbenv install 2.6.3
Installing ruby-2.6.3...
BUILD FAILED (MSYS_NT-10.0 3.0.6(0.338/5/3) using ruby-build 20190401-11-geee8a47)
Inspect or clean up the working tree at /tmp/ruby-build.20190423210704.9867
Results logged to /tmp/ruby-build.20190423210704.9867.log
Last 10 log lines:
/tmp/ruby-build.20190423210704.9867 ~
bzip2: I/O or other error, bailing out. Possible reason follows.
bzip2: No error
Input file = (stdin), output file = (stdout)
/where/to/path/.rbenv/plugins/ruby-build/bin/ruby-build: 353 行: 9912 Stopped tar $tar_args "$package_filename"
/tmp/ruby-build.20190423210704.9867/ruby-2.6.3 /tmp/ruby-build.20190423210704.9867 ~
/where/to/path/.rbenv/plugins/ruby-build/bin/ruby-build: 行 589: ./configure: No such file or directory
msys2でrbenv
msys2を使ってみることにして、とりあえずvimのビルドしようと思ったらrubyがなかったので、rbenvを入れようとしたらなぜか動かない。
$ ~/.rbenv/bin/rbenv init
.rbenv/bin/rbenv: 行 1: ../libexec/rbenv: No such file or directory
ファイルは存在しているのに無いと言われてしまう。 同じ悩みを持つひとは、これをシンボリックリンクに変えて対処したようだ。こちら参照。 同じようにシンボリックリンクにしてみると確かに動く。 .rbenv/bin/rbenvの中身は確かに1行しかなくて、これを実行するだけなのでリンクに置き換えても問題なさそう。 問題は相対パスで書かれたものを実行できないということなのか。
切り分けのために、rbenvの中身を絶対パスに変更してみると。。
うん。動く。と思ったら引数が渡らない。 リンクのように振舞っているということか?相対パスの始まりが、コマンド実行時のカレントディレクトリになっているみたい。 試しに ~/.rbenv/bin に移動してから実行するとやはり動く。 相対パスの解釈の仕方が問題のようだ。 でも、この後の調べ方がわからない。相対パスを実行しようとするのは誰なのか。bashか? bash -xで見ても特に何も出ない。
Tag: Rbenv
msys2にrbenv-buildでruby 2.6.3をインストール(失敗)
msys2にrbenv-buildでruby 2.6.3をインストールしようとして失敗してあきらめた話。 どうもmsys2でrubyをコンパイルしようとするとうまくいかないという話がちらほらあるらしいといくつか聞いたのであきらめることにした。 そもそもrbenvが動作しない。bin/rbenv を libexec/rbenv へのリンクにするととりあえず動作する。 rbenv install 2.6.3 すると、ダウンロードの途中で止まったようになり、Installing というメッセージが表示されない。 Ctrl-zで中断したときかfgで再開したときに以下のメッセージが出る。 何度か同じメッセージが出るのを確認して、ここで諦めた。
rbenv install 2.6.3
Installing ruby-2.6.3...
BUILD FAILED (MSYS_NT-10.0 3.0.6(0.338/5/3) using ruby-build 20190401-11-geee8a47)
Inspect or clean up the working tree at /tmp/ruby-build.20190423210704.9867
Results logged to /tmp/ruby-build.20190423210704.9867.log
Last 10 log lines:
/tmp/ruby-build.20190423210704.9867 ~
bzip2: I/O or other error, bailing out. Possible reason follows.
bzip2: No error
Input file = (stdin), output file = (stdout)
/where/to/path/.rbenv/plugins/ruby-build/bin/ruby-build: 353 行: 9912 Stopped tar $tar_args "$package_filename"
/tmp/ruby-build.20190423210704.9867/ruby-2.6.3 /tmp/ruby-build.20190423210704.9867 ~
/where/to/path/.rbenv/plugins/ruby-build/bin/ruby-build: 行 589: ./configure: No such file or directory
Tag: Ruby
msys2にrbenv-buildでruby 2.6.3をインストール(失敗)
msys2にrbenv-buildでruby 2.6.3をインストールしようとして失敗してあきらめた話。 どうもmsys2でrubyをコンパイルしようとするとうまくいかないという話がちらほらあるらしいといくつか聞いたのであきらめることにした。 そもそもrbenvが動作しない。bin/rbenv を libexec/rbenv へのリンクにするととりあえず動作する。 rbenv install 2.6.3 すると、ダウンロードの途中で止まったようになり、Installing というメッセージが表示されない。 Ctrl-zで中断したときかfgで再開したときに以下のメッセージが出る。 何度か同じメッセージが出るのを確認して、ここで諦めた。
rbenv install 2.6.3
Installing ruby-2.6.3...
BUILD FAILED (MSYS_NT-10.0 3.0.6(0.338/5/3) using ruby-build 20190401-11-geee8a47)
Inspect or clean up the working tree at /tmp/ruby-build.20190423210704.9867
Results logged to /tmp/ruby-build.20190423210704.9867.log
Last 10 log lines:
/tmp/ruby-build.20190423210704.9867 ~
bzip2: I/O or other error, bailing out. Possible reason follows.
bzip2: No error
Input file = (stdin), output file = (stdout)
/where/to/path/.rbenv/plugins/ruby-build/bin/ruby-build: 353 行: 9912 Stopped tar $tar_args "$package_filename"
/tmp/ruby-build.20190423210704.9867/ruby-2.6.3 /tmp/ruby-build.20190423210704.9867 ~
/where/to/path/.rbenv/plugins/ruby-build/bin/ruby-build: 行 589: ./configure: No such file or directory
msys2でrbenv
msys2を使ってみることにして、とりあえずvimのビルドしようと思ったらrubyがなかったので、rbenvを入れようとしたらなぜか動かない。
$ ~/.rbenv/bin/rbenv init
.rbenv/bin/rbenv: 行 1: ../libexec/rbenv: No such file or directory
ファイルは存在しているのに無いと言われてしまう。 同じ悩みを持つひとは、これをシンボリックリンクに変えて対処したようだ。こちら参照。 同じようにシンボリックリンクにしてみると確かに動く。 .rbenv/bin/rbenvの中身は確かに1行しかなくて、これを実行するだけなのでリンクに置き換えても問題なさそう。 問題は相対パスで書かれたものを実行できないということなのか。
切り分けのために、rbenvの中身を絶対パスに変更してみると。。
うん。動く。と思ったら引数が渡らない。 リンクのように振舞っているということか?相対パスの始まりが、コマンド実行時のカレントディレクトリになっているみたい。 試しに ~/.rbenv/bin に移動してから実行するとやはり動く。 相対パスの解釈の仕方が問題のようだ。 でも、この後の調べ方がわからない。相対パスを実行しようとするのは誰なのか。bashか? bash -xで見ても特に何も出ない。
Tag: Pandoc
pandoc's raw option
昨日まで使えていた pandoc の -parse-raw(-R) オプションが使えなくなって、代わりに+raw_htmlを使えというエラーが出て調べた。
無くなったのは2017年10月のpandc 2.0がリリースされたとき。最近変わったのかと思ったら結構前。 なんでかと思ったら、動いていた環境はWSLのUbuntu 16.04で古いのが入っていただけだった。バージョンは、1.16.0.2。 ちなみに動かなかったのはWindowsの2.7.3.こっちはだいぶ新しい。ちゃんと代わりのオプションを提示してくれたのが良い。
詳細はリリースノート参照。 –parse-rawで検索すると該当箇所がわかる。
pandocでフォーマット変換(vim-mtdataapi)
mtdataapiというvimのpluginからMovable Typeへの記事投稿の際、markdown形式で投稿できるようにしました。 変換にはpandocを使っています。
Tag: WSL
pandoc's raw option
昨日まで使えていた pandoc の -parse-raw(-R) オプションが使えなくなって、代わりに+raw_htmlを使えというエラーが出て調べた。
無くなったのは2017年10月のpandc 2.0がリリースされたとき。最近変わったのかと思ったら結構前。 なんでかと思ったら、動いていた環境はWSLのUbuntu 16.04で古いのが入っていただけだった。バージョンは、1.16.0.2。 ちなみに動かなかったのはWindowsの2.7.3.こっちはだいぶ新しい。ちゃんと代わりのオプションを提示してくれたのが良い。
詳細はリリースノート参照。 –parse-rawで検索すると該当箇所がわかる。
Tag: CS
「なっとく!アルゴリズム」を読んだ
「なっとく!アルゴリズム」を読んだ。
イラストを多く使って分かりやすくしているのがウリのアルゴリズム本とのこと。 しかし、読んでみるとなんとなくわかりづらかった。何がわかりづらいのか考えてみると、おそらく定義が無いか曖昧か後に出てくるのが原因だろうと思う。問題点の説明はできているので、問題の共有は読者との間にできていると思うが、アルゴリズムの定義がやや曖昧で、なるほどと納得するのに時間が掛かった。また、Pythonでアルゴリズムを表現しているが、全体のコードが後に出てくるため、全体を把握してから読み進めるというよりは、小さな部品から初めて完成させるというボトムアップ型の作りになっているのも関係しているかもしれない。
ただ内容については、「初めてのコンピュータサイエンス」に記載のなかったダイクストラ法等もあって幅広いアルゴリズムについて触れている。そこに惹かれたのが、本書を読んだ理由の一つでもある。
以下に、言及のあったアルゴリズムを挙げる。キーワードの紹介だけのものも含む。
二分探索
分割統治
クイックソート
幅優先探索(グラフ)
- ダイクストラ法 : 正の重みを考慮した重み付きグラフの最短経路に利用
- ベルマンフォード法 : 負の重みを考慮した重み付きグラフの最短経路に利用
貪欲法
動的計画法
k近傍法
B 木
赤黒木
スプレー木
転置インデックス
フーリエ変換
ブルームフィルタ
HyperLogLog
Simhash
「初めてのコンピュータサイエンス」を読んだ
「初めてのコンピュータサイエンス」を読んだ。 最近、Googleの入社エントリが話題になったが、やはりコンピュータサイエンスの基礎はきちんとしておかねばならないと再認識する良いきっかけになった。 大学の講義の教科書として使っていた本を読もうかと思ったが、手元になかったので図書館で何か良いものはないかと探して選んだのがこの本。 Pythonを使って説明する内容となっているためにPythonの説明から始まるが、アルゴリズムの説明などは多言語にも応用の利くように記載されていてPython以外の言語を書く人に対しても有効な記載ぶりである。 大学の講義を思い出すような内容であったが、プログラミングスタイルなどにも触れてられていて、大学の講義にはなかった内容もあって有意義であった。
今後しばらくはコンピュータサイエンス系の本を中心に読もうと思う。 次はアルゴリズム系として以下の本を読む予定。
Tag: Python
「実例で学ぶRaspberry Pi電子工作 作りながら応用力を身につける」を読んだ
「Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる」を読んだ。 図書館で何か面白い本は無いかなと探していて目に留まったのがこれ。 以前から気になっていたラズパイ。何かしてみたいもののこれといってやりたいことも見当たらなかったので、本を読んで具体化できたら何か思い浮かぶかと思って読んでみた。 買い方から始まってLEDの点灯に慣れたところで、スイッチの導入、カメラ画像の入力、サーボモーターを使った4足歩行など、一通り面白そうなことをやって示していて、非常に興味深く読むことができた。
電子回路は詳しくないが、色々と説明があるためにどういう課題に対して、この回路が役に立つのかということがわかりやすく記載されていて、自分で様々な電子回路部品を購入して使ってみようという気にさせる内容であった。 カメラ画像の扱いについても基本的な画像処理まで触れられており、実践的であった。この本を借りたのもそこが決めてであった。 まだ購入に至っていないが、カメラ画像を機械学習して何かを検知、通報するような用途に使うのが面白そうなので監視カメラとしての役割で何かできないか考えてみようと思う。
「初めてのコンピュータサイエンス」を読んだ
「初めてのコンピュータサイエンス」を読んだ。 最近、Googleの入社エントリが話題になったが、やはりコンピュータサイエンスの基礎はきちんとしておかねばならないと再認識する良いきっかけになった。 大学の講義の教科書として使っていた本を読もうかと思ったが、手元になかったので図書館で何か良いものはないかと探して選んだのがこの本。 Pythonを使って説明する内容となっているためにPythonの説明から始まるが、アルゴリズムの説明などは多言語にも応用の利くように記載されていてPython以外の言語を書く人に対しても有効な記載ぶりである。 大学の講義を思い出すような内容であったが、プログラミングスタイルなどにも触れてられていて、大学の講義にはなかった内容もあって有意義であった。
今後しばらくはコンピュータサイエンス系の本を中心に読もうと思う。 次はアルゴリズム系として以下の本を読む予定。
Tag: RasberryPi
「実例で学ぶRaspberry Pi電子工作 作りながら応用力を身につける」を読んだ
「Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる」を読んだ。 図書館で何か面白い本は無いかなと探していて目に留まったのがこれ。 以前から気になっていたラズパイ。何かしてみたいもののこれといってやりたいことも見当たらなかったので、本を読んで具体化できたら何か思い浮かぶかと思って読んでみた。 買い方から始まってLEDの点灯に慣れたところで、スイッチの導入、カメラ画像の入力、サーボモーターを使った4足歩行など、一通り面白そうなことをやって示していて、非常に興味深く読むことができた。
電子回路は詳しくないが、色々と説明があるためにどういう課題に対して、この回路が役に立つのかということがわかりやすく記載されていて、自分で様々な電子回路部品を購入して使ってみようという気にさせる内容であった。 カメラ画像の扱いについても基本的な画像処理まで触れられており、実践的であった。この本を借りたのもそこが決めてであった。 まだ購入に至っていないが、カメラ画像を機械学習して何かを検知、通報するような用途に使うのが面白そうなので監視カメラとしての役割で何かできないか考えてみようと思う。
Tag: Mtdataapi
pandocでフォーマット変換(vim-mtdataapi)
mtdataapiというvimのpluginからMovable Typeへの記事投稿の際、markdown形式で投稿できるようにしました。 変換にはpandocを使っています。
Tag: Data API
Movable Type Data API v4 の authenticationでBad Gateway
以下のマニュアルを参照してMovable Type 7のData API v4 の authentication を試したが、なかなかうまくいかなかった。 原因は clientId の I が小文字になっていたためだった。
マニュアルの例のところが小文字になっていたのでそれを参考にしていたのが間違い。
Tag: Cgroup
cgroupを使った負荷生成ツール
必要にせまられて(?)、指定したCPU使用率、メモリ使用率の負荷を掛けるツールを作りました。 cgroupを使ってツールのCPU使用率とメモリ使用率を制限します。 特別なツールを使わずに負荷を掛けられるのでstressパッケージをインストールしなくても負荷を掛けられるのがポイントです。と言いつつも、中でperlを使ってしまったのでこれも不要にする予定です。
stressパッケージを使わない方法はyesコマンドを使う方法やtmpfsをマウントする方法が検索すると見つかりますが、実行時間を指定できないために開始終了が煩雑(特に複数CPUコアの場合)だったり、メモリがbuff/cache扱いになって参照したい指標によってはメモリ使用率が高くないように見えてしまうために、変数領域として確保するようにしました。
使用率の指定はOS全体の使用率は指定できず、ツールの使用率しか指定できないので、注意が必要です。ここは今後改善したいと思っている部分です。
Tag: Cpu
cgroupを使った負荷生成ツール
必要にせまられて(?)、指定したCPU使用率、メモリ使用率の負荷を掛けるツールを作りました。 cgroupを使ってツールのCPU使用率とメモリ使用率を制限します。 特別なツールを使わずに負荷を掛けられるのでstressパッケージをインストールしなくても負荷を掛けられるのがポイントです。と言いつつも、中でperlを使ってしまったのでこれも不要にする予定です。
stressパッケージを使わない方法はyesコマンドを使う方法やtmpfsをマウントする方法が検索すると見つかりますが、実行時間を指定できないために開始終了が煩雑(特に複数CPUコアの場合)だったり、メモリがbuff/cache扱いになって参照したい指標によってはメモリ使用率が高くないように見えてしまうために、変数領域として確保するようにしました。
使用率の指定はOS全体の使用率は指定できず、ツールの使用率しか指定できないので、注意が必要です。ここは今後改善したいと思っている部分です。
Tag: Load
cgroupを使った負荷生成ツール
必要にせまられて(?)、指定したCPU使用率、メモリ使用率の負荷を掛けるツールを作りました。 cgroupを使ってツールのCPU使用率とメモリ使用率を制限します。 特別なツールを使わずに負荷を掛けられるのでstressパッケージをインストールしなくても負荷を掛けられるのがポイントです。と言いつつも、中でperlを使ってしまったのでこれも不要にする予定です。
stressパッケージを使わない方法はyesコマンドを使う方法やtmpfsをマウントする方法が検索すると見つかりますが、実行時間を指定できないために開始終了が煩雑(特に複数CPUコアの場合)だったり、メモリがbuff/cache扱いになって参照したい指標によってはメモリ使用率が高くないように見えてしまうために、変数領域として確保するようにしました。
使用率の指定はOS全体の使用率は指定できず、ツールの使用率しか指定できないので、注意が必要です。ここは今後改善したいと思っている部分です。
Tag: Memory
cgroupを使った負荷生成ツール
必要にせまられて(?)、指定したCPU使用率、メモリ使用率の負荷を掛けるツールを作りました。 cgroupを使ってツールのCPU使用率とメモリ使用率を制限します。 特別なツールを使わずに負荷を掛けられるのでstressパッケージをインストールしなくても負荷を掛けられるのがポイントです。と言いつつも、中でperlを使ってしまったのでこれも不要にする予定です。
stressパッケージを使わない方法はyesコマンドを使う方法やtmpfsをマウントする方法が検索すると見つかりますが、実行時間を指定できないために開始終了が煩雑(特に複数CPUコアの場合)だったり、メモリがbuff/cache扱いになって参照したい指標によってはメモリ使用率が高くないように見えてしまうために、変数領域として確保するようにしました。
使用率の指定はOS全体の使用率は指定できず、ツールの使用率しか指定できないので、注意が必要です。ここは今後改善したいと思っている部分です。
Tag: Stress
cgroupを使った負荷生成ツール
必要にせまられて(?)、指定したCPU使用率、メモリ使用率の負荷を掛けるツールを作りました。 cgroupを使ってツールのCPU使用率とメモリ使用率を制限します。 特別なツールを使わずに負荷を掛けられるのでstressパッケージをインストールしなくても負荷を掛けられるのがポイントです。と言いつつも、中でperlを使ってしまったのでこれも不要にする予定です。
stressパッケージを使わない方法はyesコマンドを使う方法やtmpfsをマウントする方法が検索すると見つかりますが、実行時間を指定できないために開始終了が煩雑(特に複数CPUコアの場合)だったり、メモリがbuff/cache扱いになって参照したい指標によってはメモリ使用率が高くないように見えてしまうために、変数領域として確保するようにしました。
使用率の指定はOS全体の使用率は指定できず、ツールの使用率しか指定できないので、注意が必要です。ここは今後改善したいと思っている部分です。
Tag: Google
Google Homeへの外部からの音声配信
自宅にいるのにスマホの着信に気づかない家族のために、外出先からGoogle Home(実際はmini)に通知をする仕組みが無いか調べたところ、Google Homeのブロードキャスト機能で実現できることがわかった。 Google Homeアプリのブロードキャストを選んで、配信したいことを声に出して言うだけ。 するとGoogle Homeからその音声が流れるという仕組み。
Alexaの場合は、リマインダーを使うということを書いた記事があったが、Google Homeなら音声配信がブロードキャストでできるので便利。ただ、リマインダーを使う場合は時間指定を行うので今すぐ伝えたいとき以外でも使えるのが便利。ブロードキャストはすぐに伝える用途向き。
Tag: Home
Google Homeへの外部からの音声配信
自宅にいるのにスマホの着信に気づかない家族のために、外出先からGoogle Home(実際はmini)に通知をする仕組みが無いか調べたところ、Google Homeのブロードキャスト機能で実現できることがわかった。 Google Homeアプリのブロードキャストを選んで、配信したいことを声に出して言うだけ。 するとGoogle Homeからその音声が流れるという仕組み。
Alexaの場合は、リマインダーを使うということを書いた記事があったが、Google Homeなら音声配信がブロードキャストでできるので便利。ただ、リマインダーを使う場合は時間指定を行うので今すぐ伝えたいとき以外でも使えるのが便利。ブロードキャストはすぐに伝える用途向き。
Tag: Jhead
Exif情報やファイルのタイムスタンプを元にファイル名を変更するjheadコマンド
背景
写真の整理をするのにファイル名を日付にしたかったので、便利なコマンドがないかと探して、jheadを使ってみました。 これまでは自作のスクリプトで対応していましたが、エラーハンドリングが中途半端だったので世の中の便利なツールを探しました。
ツールに求める条件
条件としては以下のもの。
- コマンド実行可能(GUI不要)
- Exif情報から撮影日で日付のファイル名に変更可能
- 重複時刻のファイルを別名で保存可能
jhead以外の選択肢
renamerというキーワードで色々見つかります。 pyrenamerが高機能そうでしたが、GUIが必要なようなので選択肢から外れました。
jheadの説明
jheadはExif情報の編集ツールですが、-nオプションでファイル名の変更ができます。 jheadコマンドの引数にオプションとファイル名を渡します。 ファイル名変更の場合は以下のように実行します。
jhead -n%Y%m%d-%H%M%S-%03i ファイル名
%iの指定は複数ファイルを指定した場合にそれらの通番となります。
Tag: Cookie
GDPRのためのCookie利用通知
GDPRへの対応としてCookieの利用通知を行うにはどうしたら良いのか気になっていましたが、調べてみると同じ悩みを持つ人はたくさんいるようで、手っ取り早く対処するにはCookie Consentを使うのが良さそう。 というわけで、さっそく使ってみた。 Wizardに従って出来上がったCodeをコピペするだけ。通知だけで、オプトインやオプトアウトしない場合は簡単。 プライバシーポリシーも作ってきちんとやった方が良いのだろうけど、とりあえずデフォルトのリンク先を採用して設定した。
Tag: GDPR
GDPRのためのCookie利用通知
GDPRへの対応としてCookieの利用通知を行うにはどうしたら良いのか気になっていましたが、調べてみると同じ悩みを持つ人はたくさんいるようで、手っ取り早く対処するにはCookie Consentを使うのが良さそう。 というわけで、さっそく使ってみた。 Wizardに従って出来上がったCodeをコピペするだけ。通知だけで、オプトインやオプトアウトしない場合は簡単。 プライバシーポリシーも作ってきちんとやった方が良いのだろうけど、とりあえずデフォルトのリンク先を採用して設定した。
Tag: 絵本
マツコの知らない絵本の世界
マツコの知らない世界で絵本の回があったので、まだうちで読んだことのない本をピックアップしてみた。 内容は読んだことがないのでまだ知らない。。紹介された本ではなくて、後ろに並んでいた本たち。
おすすめ絵本(あーそーぼー)
おすすめ絵本です。 お友達の家にあーそーぼーと言って訪ねるものの、あーとーでーと言われしまう絵本です。 友達がお取込み中の内容を一緒に手伝いながら、みんなで仲良く遊びます。 1歳半くらいから読み始めましたが、セリフを覚えるほど気に入ったみたいなので、図書館で何度も借りていましたが、とうとう購入しました。
おすすめ絵本(あーといってよあー)
おすすめ絵本の紹介です。 あー あー あーと子供と一緒に声を出しながら楽しむ本です。 1歳半くらいの時に初めて読みましたが、気に入ったようで何度も読んでいます。 単にあーと言うだけでなく、色々な声の出し方や、シチュエーションによって違う声のトーンなど様々なあーが紹介されています。 大人も子供と一緒にあーと声を出すので読んでいて楽しい本です。
Tag: 丹沢
大山登山(親子登山)
本日、丹沢の大山に行ってきました。
オスプレイのポコ プラスを譲ってもらったので、その初使用として、近場の大山を選び登ってきました。
特に怪我等はありませんでしたが、この時期の大山を選んだのは子供にとっては寒すぎて失敗でした。
途中までは大丈夫そうでしたが、下山した時には手も足も冷たくなっていて寒かったようでした。
防寒対策が不十分だったというのと、下山が17時頃まで掛かってしまい太陽が沈み、寒くなってしまったのが原因と考えています。
防寒着としては綿の入った上下つなぎの服を普通の服の上に被せて着せました。
頭は帽子、手は手袋、足は普通の靴を履かせていましたが、途中で大人用の像足(ダウンシューズ)を履かせて足の保温、大人用のネックウォーマーで首回りの保温を追加しました。
途中で確認した時には手が温かく、問題なく保温できているかと考えていましたが、下山時には手も足も冷えていたことから、登りながら昼寝したときかその後くらいから徐々に冷えたものと推測しています。その頃から少し元気がなかったように記憶しています。
今日は人見知りした状態での登山だったので、それで大人しいのか寒いからなのかの判断がうまくできず、結果的に寒い思いをさせてしまいました。今後はもっと温かい山やコースを選ぶと共に、十分な保温を心がけたいと思います。
ところで、オスプレイのポコ プラス(ポコAG プラスではありません)の使い心地ですが、モンベルのベビーキャリアと比べて荷物がたくさん入ると聞いていましたが、メインの荷室のサイズはあまり変わりません。オスプレイの場合は追加のサブザックを付けられるので、そういったものを含めると大容量になるというもののようでした。しかも、キャリアのスタンド部分を閉じると荷室も狭くなってしまうので、その点はモンベルのベビーキャリアの方が使いやすいように思いました。ただ、オスプレイのものはひっかけにくいようにスタンド部分がやや上に上がっているようなので、考慮はされているようです。モンベルの場合は閉じるのを忘れるとひっかけやすい上に、閉じてあっても、今度は開くのを忘れるなどワンアクション余計に必要なのが難点です。今日使った範囲では、後ろをひっかけることはなかったので閉じ忘れや開き忘れが無い分、ストレスはありませんでした。
さて、本題の大山登山は10時くらいから歩き始めて、昼前に阿夫利神社着、1時頃から再度登り始めて15時山頂、17時下山という行程でした。早く出発するのも、休憩時間を短くするのもなかなか難しいので、コースタイムがもっと短いコースを選ぶのが正解でした。
今回は、寒い思いをさせてしまったのもあるし、下山時刻も遅いし、色々反省点の多い山行でした。次回に生かそうと思います。
以下はポコAG プラスのリンクです。
Tag: Plugin
はじめてのvim plugin作成
vimconf2018 には参加できなかったけれども、発表資料を読んだりTwitterを眺めているとやっぱり何かしたくなったのと、もっとvimを使いこなしたくなったのでpluginを書く練習を始めようと決意した。
helpを読んで書いてみようと思ったが、サンプルで既に理解できないところがあったので、Alisueさんの発表資料にあるHello Worldを真似てみるところからスタート。
ファイル名やコマンド名は多少変えたけれども、そのまんま。すごく簡単。
plugin/helloworld.vim
1 if exists('g:loaded_helloworld')
2 finish
3 endif
4 let g:loaded_helloworld = 1
5 command! HWorld call helloworld#hello_world()
autoload/helloworld.vim
1 function! helloworld#hello_world() abort
2 echo "Hello, World"
3 endfunction
Tag: おすすめ絵本
おすすめ絵本(あーそーぼー)
おすすめ絵本です。 お友達の家にあーそーぼーと言って訪ねるものの、あーとーでーと言われしまう絵本です。 友達がお取込み中の内容を一緒に手伝いながら、みんなで仲良く遊びます。 1歳半くらいから読み始めましたが、セリフを覚えるほど気に入ったみたいなので、図書館で何度も借りていましたが、とうとう購入しました。
おすすめ絵本(あーといってよあー)
おすすめ絵本の紹介です。 あー あー あーと子供と一緒に声を出しながら楽しむ本です。 1歳半くらいの時に初めて読みましたが、気に入ったようで何度も読んでいます。 単にあーと言うだけでなく、色々な声の出し方や、シチュエーションによって違う声のトーンなど様々なあーが紹介されています。 大人も子供と一緒にあーと声を出すので読んでいて楽しい本です。
Tag: 1歳
おすすめ絵本(あーそーぼー)
おすすめ絵本です。 お友達の家にあーそーぼーと言って訪ねるものの、あーとーでーと言われしまう絵本です。 友達がお取込み中の内容を一緒に手伝いながら、みんなで仲良く遊びます。 1歳半くらいから読み始めましたが、セリフを覚えるほど気に入ったみたいなので、図書館で何度も借りていましたが、とうとう購入しました。
おすすめ絵本(あーといってよあー)
おすすめ絵本の紹介です。 あー あー あーと子供と一緒に声を出しながら楽しむ本です。 1歳半くらいの時に初めて読みましたが、気に入ったようで何度も読んでいます。 単にあーと言うだけでなく、色々な声の出し方や、シチュエーションによって違う声のトーンなど様々なあーが紹介されています。 大人も子供と一緒にあーと声を出すので読んでいて楽しい本です。
Tag: 子供
おすすめ絵本(あーそーぼー)
おすすめ絵本です。 お友達の家にあーそーぼーと言って訪ねるものの、あーとーでーと言われしまう絵本です。 友達がお取込み中の内容を一緒に手伝いながら、みんなで仲良く遊びます。 1歳半くらいから読み始めましたが、セリフを覚えるほど気に入ったみたいなので、図書館で何度も借りていましたが、とうとう購入しました。
おすすめ絵本(あーといってよあー)
おすすめ絵本の紹介です。 あー あー あーと子供と一緒に声を出しながら楽しむ本です。 1歳半くらいの時に初めて読みましたが、気に入ったようで何度も読んでいます。 単にあーと言うだけでなく、色々な声の出し方や、シチュエーションによって違う声のトーンなど様々なあーが紹介されています。 大人も子供と一緒にあーと声を出すので読んでいて楽しい本です。
Tag: ベビーキャリア
鎌倉アルプス親子登山(背負子)
鎌倉アルプスに行ってきました。 コース詳細はくにっとさんの記事に詳しいので省略します。 Facebookで親子登山のグループを作って最初の山行でしたが、以前から一緒に登山に行っていた仲間だったので特に問題なく無事に終了しました。 一緒に行った子供たちは2歳前後で自分でも少し歩けるので、本人が歩きたいと言うところは歩かせましたが、建長寺の境内だけ歩いて、あとは基本的に背中の上でした。 自分で歩かせるとなかなか進まないので時間にはかなり余裕を持たせておくのがポイントです。また、抱っこしたり歩いたりを繰り返すので手に抱いて歩いたりもしたので、腕力や体力にも余裕を持たせておくのがポイントです。体力無いときはずっと背負っておくのが一番楽かもしれません。 ちなみに集合時間が直前で変更になったりもしたので、親子登山の時はいろいろ柔軟に対応できるように時間にゆとりを持たせて計画することがとても大事ですね! 親子登山のためのFacebookグループ作って、これからいろいろ情報交換しながら山に行こうと思っているので興味ある方は連絡ください。 登山経験不問です!また、子供がいなくても、独身でも、子供と一緒に登山に行きたい方も一緒に山に行きましょう!お気軽に連絡ください!
小さな子供との登山で気を付けること 持ち物
小さな子供との登山に持っていくものをまとめました。 気を付けることの全体的なまとめはこちら 。 ###子供が使うもの * おむつ関連 * おむつ * おむつ替えシート(もしくは代わりになるマット) * おしり拭き * ごみ袋 * 飲食関連 * ストローマグ * 麦茶(ボトルに入れて1リットル弱程度) * お手拭きシート * スプーン、フォーク * 子供の食事 * おやつ * ごみ袋 * 服装関連 * くつ(歩かない場合でも防寒を兼ねて) * 帽子(日焼け防止、ケガ防止) * 防寒着(羽織るもの等) * 着替え(何らかの理由で濡れた場合、汚れがひどい場合に利用) * その他 * 日焼け止め * 虫除け * サンシェード(ベビーキャリアに取り付け可能な日除け) * レインカバー(ベビーキャリアに取り付け可能なもの) ###大人が使うもの * 荷物が入るサイズのベビーキャリア * ダブルストック(私はダブルストックが好きです) * ストックホルダー(ストックをしまえるように) * 地図、GPS(迷わないように) * カメラ(子供との楽しい思い出を写真に収めましょう) * 体力(子供の体重とその他の装備を背負って歩ける程度) * 通常の登山用の服装(詳細省略) * 通常の登山用の装備(詳細省略) * 登山計画書(家族や警察に届けましょう)
小さな子供との登山で気を付けることのまとめ
小さな子供との登山では、自分一人だけの時とは違って、子供の服装や体調にも気を付ける必要があるため、二人分の注意が必要です。 ここで言う小さな子供とは、自分で歩かず、ベビーキャリアに乗せて歩くような年齢の子供を想定しています。 ###服装 登山中は歩くと暑くなり、休憩すると寒くなるなど体感温度の変化が激しいです。そのため、こまめに温度調節が必要とはよく言われます。 ところがベビーキャリアに乗せられていて自分で歩かない子供の場合には、まったく歩かないために体温上昇は無く、冷える一方です。特に手足はよく冷えるので要注意です。 防寒対策としては、手袋や靴下などのほかに、ベビーキャリア用のレインカバーも使えるようです。防風効果があり保温が期待できます。 なお、ベビーキャリアに乗っている子供には背負っている人の体温による保温効果は期待できません。両者の間には空間があり、体温が伝わらないようになっているためです。 したがって子供の服は、じっとしていても冷えない程度の温かさの服を着せるのが良いです。 ###悪天対策 雨対策。濡れて体温が下がらないように全身を覆うタイプの雨具が望ましいです。ベビーキャリアには専用のレインカバーがあるのでそれを使うのが無難です。 フード付きのレインウェアなどは嫌がって取ってしまう可能性が高いので、自分で外せないタイプのものが良いと思います。 強風対策。大人と同じように風を通しにくい素材の服や、レインカバー等を使って防ぎます。 樹林帯コースを選ぶようにして、風が強くないルートを選択することも重要です。 ###おむつ 漏れないように、早めに交換しましょう。ある程度広くないと換えづらいので適当な場所があれば早めに交換しておくのが良いです。雨や風がある場合には体を冷やさないように小屋などで交換するのが良いですが、それができない場合でもなるべく風のない場所で交換するようにしましょう。 また、一人ですばやく交換するためのコツをつかんでおきましょう。動き回られると大変なので興味の引かせ方を習得しておきましょう。 ###食事 温めなくてもすぐに食べられるものが良いです。また、子供の食事の時にはつきっきりになってしまって、自分の食事は取れないので、子供の食事を済ませてから自分の食事をとるような時間配分を考えておきましょう。 ###関連記事 持ち物の一覧は小さな子供との登山で気を付けること 持ち物にまとめました。
浅間山、高麗山ハイキング(背負子)
久々に子供を背負って行ってきました浅間山。桁違いでした。 何が桁違いかっていうと、標高です。 標高181.3m 行程3km、2時間(往復) 累計高度400m コースは神奈川県平塚市。湘南平(高麗山公園)スタート。浅間山、高麗山(大堂)まで行って、往復です。 ちなみに、群馬の浅間山は2560mです。 アップダウンも少なく、子連れでも無理なく歩ける感じですが、雨の後だったからか滑りやすく見える箇所も多かったです。 山歩きに慣れた方であれば特に問題ない感じでしたが、不安な方は歩きづらいと感じそうなところもありました。 壊れかけのベンチも多数ありますが、要所要所にはしっかりしたベンチやテーブルがあり、人も多くなかったので休憩も取りやすい感じです。 湘南平の大駐車場に車を停めて、そこからピストンのコースです。 時間や脚力に余裕があれば、高麗山を越えて高来神社まで下りたり、地獄沢の方へ降りるのも良さそうでした。 湘南平公園 ハイキングコース案内
Tag: 鎌倉アルプス
鎌倉アルプス親子登山(背負子)
鎌倉アルプスに行ってきました。 コース詳細はくにっとさんの記事に詳しいので省略します。 Facebookで親子登山のグループを作って最初の山行でしたが、以前から一緒に登山に行っていた仲間だったので特に問題なく無事に終了しました。 一緒に行った子供たちは2歳前後で自分でも少し歩けるので、本人が歩きたいと言うところは歩かせましたが、建長寺の境内だけ歩いて、あとは基本的に背中の上でした。 自分で歩かせるとなかなか進まないので時間にはかなり余裕を持たせておくのがポイントです。また、抱っこしたり歩いたりを繰り返すので手に抱いて歩いたりもしたので、腕力や体力にも余裕を持たせておくのがポイントです。体力無いときはずっと背負っておくのが一番楽かもしれません。 ちなみに集合時間が直前で変更になったりもしたので、親子登山の時はいろいろ柔軟に対応できるように時間にゆとりを持たせて計画することがとても大事ですね! 親子登山のためのFacebookグループ作って、これからいろいろ情報交換しながら山に行こうと思っているので興味ある方は連絡ください。 登山経験不問です!また、子供がいなくても、独身でも、子供と一緒に登山に行きたい方も一緒に山に行きましょう!お気軽に連絡ください!
Tag: Kubenetes
kubenetes導入顛末記 その2
その1でとりあえず動作するところまで確認できたので、ここからはチュートリアルに沿ってやってみる。
https://kubernetes.io/docs/tutorials/hello-minikube/
nodeアプリケーション作成
server.jsというhello worldを作成。
node server.jsで動作確認して問題ないことを確認。
Docker Containerイメージ作成
Dockerfileを作成。
以下のコマンドで環境変数を設定。そしてビルド。
eval $(minikube docker-env)
docker build -t hello-node:v1 .
`
`Deployment作成
以下のコマンドでPodも作成されて動いているらしい。
でも、ローカルIPからしか接続できないらしい。試しにminikube sshでログインしてみたけども8080ポートで待ち受けているプロセスはなかった。。nodeコマンドは動作中だったので他のポートで待っているみたいだけど。どこで変換しているのか。。
kubectl run hello-node --image=hello-node:v1 --port=8080 --image-pull-policy=Never
Service作成
外からもアクセスできるようにServiceを作成する。
kubectl expose deployment hello-node --type=LoadBalancer
以下のコマンドで得られるURLにアクセスすると無事に表示される。どのポートで待っているのかの謎はこれで解ける。でも、ポートが8080ではないんだな。なんでだろ。
minikube service --url hello-node
アクセスログは以下で参照できた。pod-nameも補完してくれて良い感じ。
kubectl logs <POD-NAME>
アプリの更新
Docker Containerイメージを作成してDeploymentを更新。
docker build -t hello-node:v2 .
kubectl set image deployment/hello-node hello-node=hello-node:v2
これだけで新しいイメージが使われるようになった。Dashboardでも確認。
heapster addonの有効化
性能監視用のaddonらしい。以下で有効にするとdashboardのoverviewでCPUとメモリのグラフが表示されて、ほかのところにもそういった情報が追加される。
minikube addons enable heapster
Clean up
作成したものを削除する。
kubenetes導入顛末記 その1
前置き
コンテナに触れようと思い、kubenetesを導入することにしたので、その記録。
導入先はUbuntu 16.04の物理サーバ1台です。
導入方法の決定
kubenetesの導入方法はいろいろあるようですが、とりあえず動かしたいならminikubeがおすすめと記載があるのでそれに従う。
選び方はこちら。
選んだのは、Running Kubernetes Locally via Minikube。
Kubenetes導入の前にHypervisor導入
手順を見ていくと最初にHypervisorを入れろとある。ただ、VM上に構築しないという手もあるらしい。
記載順などからVirtual Boxが良さそうなのでVirtualBoxを採用。
ということで、まずはVirtualBoxの導入。以下のURLに従ってaptのsourceを指定してインストール。
https://www.virtualbox.org/wiki/Linux_Downloads
minikube導入の前にkubectl導入
以下の通り、こちらもaptのsourceを設定してinstall。
https://kubernetes.io/docs/tasks/tools/install-kubectl/
ちなみにこの状態で kubectl cluster-infoを実行すると以下の通り。
$ kubectl cluster-info
Kubernetes master is running at http://localhost:8080
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
The connection to the server localhost:8080 was refused - did you specify the right host or port?
kubectlのautocompletion設定
ここも前述のガイドにならって設定する。
echo "source <(kubectl completion bash)" >> ~/.bashrc
minikubeの導入
ここでようやくminikubeの導入。
Tag: Minikube
kubenetes導入顛末記 その2
その1でとりあえず動作するところまで確認できたので、ここからはチュートリアルに沿ってやってみる。
https://kubernetes.io/docs/tutorials/hello-minikube/
nodeアプリケーション作成
server.jsというhello worldを作成。
node server.jsで動作確認して問題ないことを確認。
Docker Containerイメージ作成
Dockerfileを作成。
以下のコマンドで環境変数を設定。そしてビルド。
eval $(minikube docker-env)
docker build -t hello-node:v1 .
`
`Deployment作成
以下のコマンドでPodも作成されて動いているらしい。
でも、ローカルIPからしか接続できないらしい。試しにminikube sshでログインしてみたけども8080ポートで待ち受けているプロセスはなかった。。nodeコマンドは動作中だったので他のポートで待っているみたいだけど。どこで変換しているのか。。
kubectl run hello-node --image=hello-node:v1 --port=8080 --image-pull-policy=Never
Service作成
外からもアクセスできるようにServiceを作成する。
kubectl expose deployment hello-node --type=LoadBalancer
以下のコマンドで得られるURLにアクセスすると無事に表示される。どのポートで待っているのかの謎はこれで解ける。でも、ポートが8080ではないんだな。なんでだろ。
minikube service --url hello-node
アクセスログは以下で参照できた。pod-nameも補完してくれて良い感じ。
kubectl logs <POD-NAME>
アプリの更新
Docker Containerイメージを作成してDeploymentを更新。
docker build -t hello-node:v2 .
kubectl set image deployment/hello-node hello-node=hello-node:v2
これだけで新しいイメージが使われるようになった。Dashboardでも確認。
heapster addonの有効化
性能監視用のaddonらしい。以下で有効にするとdashboardのoverviewでCPUとメモリのグラフが表示されて、ほかのところにもそういった情報が追加される。
minikube addons enable heapster
Clean up
作成したものを削除する。
kubenetes導入顛末記 その1
前置き
コンテナに触れようと思い、kubenetesを導入することにしたので、その記録。
導入先はUbuntu 16.04の物理サーバ1台です。
導入方法の決定
kubenetesの導入方法はいろいろあるようですが、とりあえず動かしたいならminikubeがおすすめと記載があるのでそれに従う。
選び方はこちら。
選んだのは、Running Kubernetes Locally via Minikube。
Kubenetes導入の前にHypervisor導入
手順を見ていくと最初にHypervisorを入れろとある。ただ、VM上に構築しないという手もあるらしい。
記載順などからVirtual Boxが良さそうなのでVirtualBoxを採用。
ということで、まずはVirtualBoxの導入。以下のURLに従ってaptのsourceを指定してインストール。
https://www.virtualbox.org/wiki/Linux_Downloads
minikube導入の前にkubectl導入
以下の通り、こちらもaptのsourceを設定してinstall。
https://kubernetes.io/docs/tasks/tools/install-kubectl/
ちなみにこの状態で kubectl cluster-infoを実行すると以下の通り。
$ kubectl cluster-info
Kubernetes master is running at http://localhost:8080
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
The connection to the server localhost:8080 was refused - did you specify the right host or port?
kubectlのautocompletion設定
ここも前述のガイドにならって設定する。
echo "source <(kubectl completion bash)" >> ~/.bashrc
minikubeの導入
ここでようやくminikubeの導入。
Tag: Vimrc
dein.vim使ったvimrcでのcolorscheme設定
icebergというcolorschemeを作った人の発表をvimconf2017で聞いたら、colorshcemeが大好きなちょっと?変わった人だったので、きっとこれは良いに違いないと導入を決めました。
dein.vimを使っているとどうもうまく反映されないので以下のページを参考にautocmdを使って設定したらうまくいきました。
au MyAutoCmd VimEnter * nested colorscheme iceberg
syntax enable
参考URL