vim-markdownを入れた時にインサートモードが遅くなったときの回避法

随分前に rcmdnk/vim-markdown を入れて使ってたのですが、JekyllからHugoに乗り換えたのでアップデートしてfrontmatterの設定を追加したり、その他.vimrcをいじっていたら、インサートモードで入力してから文字が表示されるまでものすごく遅くなりました。

github.com

10秒以上遅延が発生するんでほんと困った。

ちなみに以下の設定は入れてありますが、遅い状況。

set synmaxcol=200
set lazyredraw
set ttyfast
set re=1

結論としては以下のような設定にすることでそれなりに早くなりました。

let g:vim_markdown_folding_disabled=1

let g:vim_markdown_liquid=1
let g:vim_markdown_math=0
let g:vim_markdown_frontmatter=1
let g:vim_markdown_toml_frontmatter=1
let g:vim_markdown_json_frontmatter=0

set nofoldenable

たぶんset nofoldenableがいけないのかなと思いましたがfoldしてほしくないので。。。
結局、vim_markdown_folding_disabled=1を組み合わせるとフォーマッタを効かせつつfolding無しでインサートモードでもそれなりのスピードで入力できるようになりました。

vim-markdown:TableFormat便利すぎるのでコレはすれられない。
素のtabularだけだと惜しい感じなんですよね。

なんか古い.vimrcみてたら整理したくなったけど今はやるべきではないと踏みとどまる理性はあったw

Jenkinsfile内で指定した複数nodeで同じジョブを流す

テストとかビルドではあんまりやらないんでしょうけど・・・
WindowsUpdateの自動実行続きです。

例えば、host1 host2 host3 と対象としたいSlaveがあって、host2が生きていなければスキップしたいです。
でもJenkinsはしつこく待つのでnodeが生きてるときだけジョブを走らせます。

  • ノードを定義してジョブをぐるぐる回す。
def targets = ["host1", "host2", "host3"]

targets.each {
    node(it) {
        echo it
    }
}

これで定義したノード3つで同じジョブが実行されます。
でも、これだとノードが止まっているとそこでジョブ全体が止まってしまいます。

  • ノードが生きてるかチェックする

Jenkinsのスクリプトコンソールで以下のスクリプトを流してみます。

println jenkins.model.Jenkins.instance.getComputer('host1').isOnline()
println jenkins.model.Jenkins.instance.getComputer('host2').isOnline()

結果

true
false

ノードがオンラインかどうか取れました!
getComputer()の引数にはホスト名ではなくノード名を渡します。
ちなみにノードが存在しないとヌルポが返ります。

  • Jenkinsfileの中で実行するノードを判定する

上の2つを組み合わせるとこんな感じ。

def targets = ["host1", "host2", "host3"]

targets.each {
    if (jenkins.model.Jenkins.instance.getComputer(it).isOnline()) {
        node(it) {
            echo it
        }
    }
}

これでうまくいくと思いきや以下のようなエラーが出ます。

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod jenkins.model.Jenkins getInstance
    at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectStaticMethod(StaticWhitelist.java:189)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor$12.reject(SandboxInterceptor.java:348)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:381)
    at org.kohsuke.groovy.sandbox.impl.Checker$6.call(Checker.java:282)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:286)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:29)
    at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
    at WorkflowScript.run(WorkflowScript:5)
    at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2030)
    at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2015)
    at com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:2056)
    at WorkflowScript.run(WorkflowScript:4)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:74)
    at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:66)
    at sun.reflect.GeneratedMethodAccessor303.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
    at com.cloudbees.groovy.cps.Next.step(Next.java:83)
    at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
    at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
    at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
    at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
    at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:19)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:35)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:32)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:32)
    at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:330)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:82)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:242)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:230)
    at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
    at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Finished: FAILURE

これはScript Security Pluginが許可されないメソッドを呼び出したときに出しているものだそうです。

qiita.com

なので、 Jenkinsの管理 > In-process Script Approval へ行き、エラーになっているメソッドを Approve します。
1つだけでなく繰り返し出るので何度か確認してください。

これで、実行できるようになるはずです。

次はいよいよPowerShellでWindowsUpdateを実行するジョブを記述します!

PowerShellでJenkinsのJNLP Slave起動のショートカットを作る

WindowsUpdateの自動実行が上手く動かないのに社内にWSUSが無いので手動やってたけど、いい加減バカバカしくなってきたのでJenkinsでなんとか出来ないか試行錯誤した過程でいろいろとノウハウを得たので忘れないようにメモしておく。

JenkinsのWindows Slaveを作る時に経験上Java Web Start(JNLP)でやるのが1番トラブルが少ないと思うのですが、いちいち設定するのが面倒なので多少楽にしようとあらかじめ作成した起動バッチのショートカットをAllUsersのスタートアップに作ります。

  • C:\jenkinsフォルダを作成
  • slave.jarをコピー
    • slave.jar は http://jenkins.example.com/jnlpJars/slave.jar にあります
  • 以下のJNLP起動バッチもコピーしてNODEとSECRETを自分のノードのものに書き換えます

NODEとSECRETは、Jenkinsの管理 > ノードの管理 > ノードを選択 > システム情報環境変数の所で見れます。
URLは、 http://jenkins.example.com/computer/${nodename}/systemInfo です。

@echo off

set NODE=win1
set SECRET=xxxxxxxxxxxxxx

cd C:\jenkins
start /min java -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -jar C:\jenkins\slave.jar -jnlpUrl http://jenkins.example.com/computer/%NODE%/slave-agent.jnlp -secret %SECRET%

C:\jenkinsにcdしているのはstartupから起動するとカレントディレクトリがC:\Windows\System32で起動するため想定しているのと違うjavaが起動してしまう事があったからです。
エンコーディングUTF-8にしているのはJenkinsのコンソールが文字化けしないようにしているためです。

  • 以下のショートカット作成PowerShellを流す
$WsShell = New-Object -ComObject WScript.Shell

$Shortcut = $WsShell.CreateShortcut($env:ALLUSERSPROFILE + "\Microsoft\Windows\Start Menu\Programs\Startup\jenkins-jnlp.lnk")
$Shortcut.TargetPath = "C:\jenkins\jenkins-jnlp.bat"
$Shortcut.IconLocation = "C:\jenkins\jenkins-jnlp.bat"
$Shortcut.Save()

念のために、デスクトップにも作りたければ以下のようにしておきます。

$Shortcut = $WsShell.CreateShortcut($env:PUBLIC + "\Desktop\jenkins-jnlp.lnk")
$Shortcut.TargetPath = "C:\jenkins\jenkins-jnlp.bat"
$Shortcut.IconLocation = "C:\jenkins\jenkins-jnlp.bat"
$Shortcut.Save()

全ユーザのデスクトップに出ます。

ちなみにWindows7より古いのは考慮してないです。
あとJREは入れてある想定・・・。

git submoduleを別のブランチに切り替える

submoduleのディレクトリに入ってブランチを切り替えてから、コミットするだけでした。

$ git submodule status
 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx foo (heads/master)
 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy bar (heads/master)

ってなってて、barの方をdevelopに変えたいとする。

$ cd bar
$ git checkout develop
Previous HEAD position was aaaaaaa... コメント
Branch develop set up to track remote branch develop from origin.
Switched to a new branch 'develop'

これでbar外に出てコミットするだけ。簡単でした。

  • 追記

developのままで最新化するのはgit pullするだけでした。

WindowsでIPv4をIPv6より優先させる

なんかWindowsクライアントからくるリクエストがIPv6の時があるので調べてみた。

  • 現状確認

デフォルトではIPv6IPv4ともに有効になっているが優先順位はどうなっているのか?

>netsh interface ipv6 show prefixpolicies
アクティブ状態を照会しています...

優先順位   ラベル  プレフィックス
----------  -----  --------------------------------
        50      0  ::1/128
        40      1  ::/0
        35      4  ::ffff:0:0/96
        30      2  2002::/16
         5      5  2001::/32
         3     13  fc00::/7
         1     11  fec0::/10
         1     12  3ffe::/16
         1      3  ::/96

優先順位35の::ffff:0:0/96IPv4マップということらしい。
こいつを最優先にしてみる。

  • 設定

ぐぐると優先順位50の::1/128と入れ替えろというのが見られるが面倒なので優先順位を50より高くしてみる。

>netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 60 4
OK


>netsh interface ipv6 show prefixpolicies
アクティブ状態を照会しています...

優先順位   ラベル  プレフィックス
----------  -----  --------------------------------
        60      4  ::ffff:0:0/96
        50      0  ::1/128
        40      1  ::/0
        30      2  2002::/16
         5      5  2001::/32
         3     13  fc00::/7
         1     11  fec0::/10
         1     12  3ffe::/16
         1      3  ::/96

どうやら、上手くいってるっぽい。

Macで共有フォルダに.DS_Storeを作らない

Windowsの人に嫌がられるし、共有ストレージ先だけに作成しないように出来ます。

ターミナルを起動して以下のようにするだけ。

$ defaults write com.apple.desktopservices DSDontWriteNetworkStores true

つーか、Thums.dbは・・・

VMWare ESXiのcoredumpを違うデータストアへ移動する

デフォルトで出来たダンプファイルを別のデータストアに移します。
ESXi 6.5でやってるけど5.x系でも多分いけると思う。

  • まず状態を確認
# esxcli system coredump file list
Path                                                                                                               Active  Configured       Size
-----------------------------------------------------------------------------------------------------------------  ------  ----------  ---------
/vmfs/volumes/52e6c5e2-eaf60c28-9344-6805ca1f75d3/vmkdump/3F7CF380-5BCB-11D9-BAC1-BCEE7B98EEB3-749731840.dumpfile    true        true  749731840
  • 次に別のデータストアに新しいダンプファイルを作成する。
# esxcli system coredump file add -d new_datastore
# esxcli system coredump file list
Path                                                                                                               Active  Configured       Size
-----------------------------------------------------------------------------------------------------------------  ------  ----------  ---------
/vmfs/volumes/52e6c5e2-eaf60c28-9344-6805ca1f75d3/vmkdump/3F7CF380-5BCB-11D9-BAC1-BCEE7B98EEB3-749731840.dumpfile    true        true  749731840
/vmfs/volumes/53461c2b-c63b7879-21a4-6805ca1f75d3/vmkdump/3F7CF380-5BCB-11D9-BAC1-BCEE7B98EEB3.dumpfile             false       false  749731840
  • 今作ったダンプファイルをActiveに設定
    • すると従来のダンプファイルはinactiveに変わります。
# esxcli system coredump file set -p /vmfs/volumes/53461c2b-c63b7879-21a4-6805ca1f75d3/vmkdump/3F7CF380-5BCB-11D9-BAC1-BCEE7B98EEB3.dumpfile
# esxcli system coredump file list
Path                                                                                                               Active  Configured       Size
-----------------------------------------------------------------------------------------------------------------  ------  ----------  ---------
/vmfs/volumes/52e6c5e2-eaf60c28-9344-6805ca1f75d3/vmkdump/3F7CF380-5BCB-11D9-BAC1-BCEE7B98EEB3-749731840.dumpfile   false       false  749731840
/vmfs/volumes/53461c2b-c63b7879-21a4-6805ca1f75d3/vmkdump/3F7CF380-5BCB-11D9-BAC1-BCEE7B98EEB3.dumpfile              true        true  749731840
  • 最後に従来のダンプファイルを削除
# rm 3F7CF380-5BCB-11D9-BAC1-BCEE7B98EEB3-749731840.dumpfile
# esxcli system coredump file list
Path                                                                                                     Active  Configured       Size
-------------------------------------------------------------------------------------------------------  ------  ----------  ---------
/vmfs/volumes/53461c2b-c63b7879-21a4-6805ca1f75d3/vmkdump/3F7CF380-5BCB-11D9-BAC1-BCEE7B98EEB3.dumpfile    true        true  749731840

これで切り替わった!