• redmineのwikiでTOC(目次)の位置を固定する

    経緯

    redmineのwikiで、ページ内のh1.h2.等見出しをまとめたページ内リンクを作ってくれる{{toc}}マクロがある。
    ※大体、右肩に表示したいことが多く{{>toc}}を用いている

    しかし、長いページをスクロールさせると目次がスクロールアウトして見えなくなり、ページ内リンクをクリックできなくて不便だと思っていた。 例えば何かの手順を流れに沿って並べてあるような場合に説明(セクション)を行ったり来たりしたい。
    見出しでセクション分けしていた内容を独立した別ページにするなどしてみたものの、数が多いと面倒だしリンク集部分を自前でメンテするのも大変。

    ということで、tocマクロによる目次をページがスクロールしても画面内に留めるredmine_wiki_fix_tocプラグイン。 https://github.com/tckz/redmine_wiki_fix_toc

    Feature

    • ページ内に右寄せのTOC{{>toc}}がある場合に、同TOCが元々表示されていた位置よりも下にスクロールしたとき、表示位置を固定(position: fixed)する。
      • 左寄せのTOCを画面内にfixすると文章にかぶってしまうので右寄せ限定
    スクロール前
    ↓↓↓ スクロールさせる ↓↓↓
    スクロール後

    補足

    • すべてのページにプラグイン独自のhtmlを差し込むためにview_layouts_base_body_bottomフックを用いる

      class ViewListener < Redmine::Hook::ViewListener
        def view_layouts_base_body_bottom(context)
          context[:controller].send(:render_to_string,
            :template => 'wiki_fix_toc/body_bottom',
            :layout => false,
            :locals => {:context => context})
        end
      end
      
    • 後はplugins/redmine_wiki_fix_toc/app/views/wiki_fix_toc/body_bottom.html.erbでTOCを見つけてイベントを貼り付けるコードを書く。

    環境

    • CentOS 7.1 x64
      • ruby 2.2.0p0 x64
        • redmine 3.1.1
    • Windows 10 Enterprise x64
      • Firefox Developer Edition 43.0a2 x64
  • HugoでLiveReloadされない

    • 出力されたhtmlに</body>がないと、jsコードが差し込まれずLiveReloadされない。

    MTからJekyllを介してHugoに移行」に書いたように、 編集中serverにファイル更新をwatchさせるLiveReloadが便利。

    hugo server --watch --port=3000
    

    </body>の前に以下のようなjsコードが差し込まれ、hugo server側の再生成に連動して開いているページがreloadされる。

    <script data-no-instant>document.write('<script src="http://'
            + (location.host || 'localhost').split(':')[0]
            + ':3000/livereload.js?mindelay=10"></'
            + 'script>')</script>
    

    </body>がないと、jsコードが差し込まれずLiveReloadも行われない。

    利用したテンプレートが先進的でhtml/head/bodyタグがなかったことから、LiveReloadが有効にならず悩んだ。

    環境

    • CentOS 6.6 x64
      • hugo v0.15-DEV
      • ruby 2.2.0p0 x64
        • jekyll-import 0.7.1
  • MTからJekyllを介してHugoに移行

    Googleウェブマスターツールから、サイトのモバイルユーザビリティに問題あるぞという通知が来ていて、デザインを変えたいなーと思っていた。

    • イチから作るのは面倒、モバイルデバイスにも対応している既存デザインを使いたい。
    • サイトは静的ファイル公開で完結したい。
    • MTのテンプレートにちょうどいいのが見つからない(かつ「再構築」待ちがなんだかおっくうになってた)
    • Octopressのテーマにいいのがある
      3rd Party Octopress Themes
    • OctopressはコアがJekyllらしい。
    • Movable TypeからJekyllへのimporterがある

    といことでまずはJekyllに移行。

    Movable Type » Octopress/Jekyll

    やはり移行ツールがあると、ちょっと試してみるかという気になる。
    以下のページを参考にMTのDB(MySQL)接続設定を書いて実行するだけで簡単に MTの記事をjekyll形式のファイルにエクスポートできた。
    http://import.jekyllrb.com/docs/mt/

    テーマを適用しようとしてちょいちょいいじり始めたけどなんだか生成が遅い。 ちょっと修正して確認するのに、130エントリでwatch状態からの生成時間が18secほどかかるのはなかなかつらい。

    Jekyll » Hugo

    調べてみるとHugoというのが速くてよいらしい。

    記事ソースファイルに完全な互換はないけどちょいスクリプト加工でなんとかなりそう。 レスポンシブ対応してるテーマもあるし。
    https://github.com/spf13/hugoThemes/

    記事ソースファイル

    • Jekyll-importでインポートした状態。

      ---
      layout: post
      title: GAEアプリケーションを HRDに移行
      date: '2012-10-14 15:37:05 +0900'
      mt_id: 131
      blog_id: 2
      post_id: 131
      basename: gae_hrd
      categories:
      - gae
      ---
      (本文)
      
    • awkを使って日付の書式と、slug部分を加工。
      *_idは不要だけどなんとなく残した。
      typeはなくてもいい感じがしたけど、テーマの方で生成条件付けに使えるので適当に設定

      ---
      title: GAEアプリケーションを HRDに移行
      date: '2012-10-14T15:37:05+09:00'
      mt_id: 131
      blog_id: 2
      post_id: 131
      categories:
      - gae
      slug: gae-hrd
      type: post
      ---
      (本文)
      

    ディレクトリ構成(抜粋)

    • 元々のURLを変更しない前提で
      • uglyurlsをtrueに
      • publishdirをpublicから一段掘り下げ(MTのときは記事のpathが/mt/archives/YYYY/MM/xxxx.htmlという感じだった)
    • content/下については年単位ぐらいでディレクトリわけたい+年月日でソートできるようにしたいのでこんな感じに。実際の出力先pathはfront matterのslugとconfig.ymlで調整
    config.yml
    content/
      archives/
        2012/
          2012-10-14-gae-hrd.html
          ...
    public/
      index.html <- 手書き
      mt/ <- ここから下がhugoでの生成
        index.html
        archives/
          2012/
            10/
              gae-hrd.html
    static/
      css/
        custom.css <- テーマのcss上書き分
    themes/
      テーマ/
    

    config.yml(抜粋)

    ---
    baseurl: "http://passing.breeze.cc/mt/"
    publishdir: "public/mt/"
    languageCode: "ja"
    title: "あぁ そうだった"
    canonifyurls: true
    builddrafts: false
    uglyurls: true
    pluralizeListTitles: false
    permalinks:
      archives: /archives/:year/:month/:slug.html
      verbose: true
      theme: "beg-modified"
      MetadataFormat: "yaml"
    

    生成

    • あとはディレクトリ構成のトップでhugoコマンドを叩くだけ。生成時間0.5secほど。速い。

    感想など

    • 速い。
    • 編集中LiveReloadがすごく便利。ファイル更新を検知して再生成、ブラウザで生成ページを開いていれば再生成に連動してreloadされる。
      http://gohugo.io/extras/livereload/

      • hugoを仮想マシンlinux内で動かしつつ手元のWindowsからterminalでloginしてviで編集、手元のWindows機でブラウザ実行しているので下記のようなコマンドラインを使っている。

        hugo server -w --baseUrl=http://local-env.local:3000/mt/ --bind=0.0.0.0 --port=3000
        
    • 移行を始めたときはv0.14だったのだけど、テンプレートプロパティのdeprecate予告がありテンプレート修正した。これからも変化しそう。

      • .Site.BaseUrl -> .Site.BaseURL
      • .Site.Recent -> .Site.Pages
      • .Url -> .URL

    環境

    • CentOS 6.6 x64
      • hugo v0.15-DEV
      • ruby 2.2.0p0 x64
        • jekyll-import 0.7.1
  • WSUSでmovecontent完了後、sqlserverがCPU 100%に貼りついて何もできなくなった話

    結論

    WSUSサーバのディスク容量が逼迫してきたので、HDDを増設しContentを移動したが、 (この環境では)movecontentしないでアンインストール& 再インストール時にWsusContentのpathを変更した方がよかった。

    経緯

    HDD増設後NTFSフォーマットして、新ドライブ下フォルダにWsusContentを移動

    > cd "C:\Program Files\Update Services\Tools" 
    > wsusutil.exe movecontent F:\WSUS F:\move.log
    

    wsustil.exeが完了、コマンドプロンプトに戻ってきた。 上記move.logの内容は下記のとおりで正常に終わったぽい。

    2015-05-08T11:58:50 Successfully stopped WsusService.
    2015-05-08T11:58:50 Beginning content file location change to F:\WSUS
    2015-05-08T13:11:16 Successfully copied content files.
    2015-05-08T13:11:16 Successfully copied application files.
    2015-05-08T13:11:30 Successfully changed WUS configuration.
    2015-05-08T13:11:31 Successfully changed IIS virtual directory path.
    2015-05-08T13:11:31 Successfully removed existing local content network shares.
    2015-05-08T13:11:31 Successfully created local content network shares.
    2015-05-08T13:11:31 Successfully changed registry value for content store directory.
    2015-05-08T13:11:31 Successfully changed content file location.
    2015-05-08T13:11:33 Successfully started WsusService.
    2015-05-08T13:11:33 Content integrity check and repair...
    2015-05-08T13:11:37 Initiated content integrity check and repair.
    

    で、WSUS管理コンソールを開いたら応答がなく、 タスクマネージャーで確認したら、sqlserver(Windows Internal Databaseを使用)が CPUを食い尽くしていた。(4コア機なので実際は25%)

    WSUSのログ"C:\Program Files\Update Services\LogFiles\SoftwareDistribution.log"を確認すると、SQLserverへの接続がタイムアウトしたというエラーが出ている。 上記move.logの最後にあるように、wsusutil.exeの実行は終了しても その後wsusservice実行の中で整合性チェック&repairが呼出されるらしい。

    この処理に要する時間は、更新の数に依存するらしいが目安は不明。 以下のURLによれば「in some cases several days」もあり得るという。

    https://social.technet.microsoft.com/Forums/en-US/99df985b-f88b-471b-9b66-fd92203de323/wsus-not-working-after-movecontent?forum=winserverwsus

    開発の都合で、多数の製品を同期しており更新の数は多かった。 (管理コンソールが開かなくなったので確認できていない。 WsusContent下のファイル数でいえば3万ぐらいだったと思う)

    結局、1週間たってもCPU貼りつき状態のままだったのでアンインストール&再インストールした。 ネットワーク環境の問題もあるので一般化できないが、メタデータ同期+コンテンツDLしなおしで3日必要だった。

    環境

    • Windows Server 2008 R2 SP1
      • Windows Internal Database
      • WSUS 3.0 SP2
  • GAEアプリケーションを HRDに移行

    移行といっても「GAEに移行した」のとおり、static contentをservletで公開しているだけなのでdashboardのdeprecate警告を消したかっただけ。

    Master/Slave から HRD への移行にあるようにM/Sなアプリケーションを複製し、HRDなアプリケーションを作成。
    DataStoreを使ってないのでMigration Toolを実行することもなし。
    ついでにApp Engine SDKを最新化したら、appengine-web.xmlに<threadsafe>指定が必須になってたらしく追記。

    参考:appengine-web.xml does not contain a <threadsafe> element

    独自ドメインで公開しているアプリケーションをどうやって設定するのか忘れてしまっていた。

    GAEアプリケーションは、http://some-appid.appspot.comという感じのURLで公開される。
    (2年前の話なので今も同じかわからないが)独自ドメインで公開する場合は、そのドメインでGoogle Appsを利用できるようにしておいて、Google Appsから利用するサービスとして登録する。

    このサイトの場合、

    1. breeze.ccドメインのDNSに、ghs.google.comを指すCNAMEレコードとしてpassing.breeze.ccを登録する(ここの場合、既に登録済)
    2. GAEのダッシュボードから、移行後アプリケーションのApplication Settings→Domain Setup→Add Domainでドメイン名追加(ここならbreeze.cc)
    3. Google Appsのダッシュボードから、設定→「(移行前アプリケーション) の設定」で、http://passing.breeze.cc/を削除
    4. 同様に「(移行後アプリケーション)の設定」で、http://passing.breeze.cc/を追加

    という感じ。