Skip to main content

常にいまいち

Hugoのsitemap.xmlがlocを相対パスで出力してた

問題 表題の通り。 相対パスで出力されてたのでsitemap.xmlとして不正な状態だった。 結論 baseURLが”/“になってた これを修正すればsitemap.xmlにも反映された 説明 まず疑ったのはsitemap.xmlのテンプレートがおかしいのでは? という線。 sitemap.xmlは特にテンプレートを設定せずにおいても出力されるが、 これを自分で明示的に設定した。 配置場所は layout/_default/sitemap.xml で内容はデフォルトのものをコピペした。 詳細は https://gohugo.io/templates/sitemap-template/#sitemap-templates こちらを参照。 これでは改善しなかったので、absURLを使って <loc>{{ .Permalink | absURL }}</loc> こんな感じで明示的に修正してみた。 使い方の詳細は https://gohugo.io/functions/absurl/#readout こちらを参照。 これでも直らなかったのでそもそもbaseURLおかしいのでは? と思い、config.tomlを参照したら "/" こうなってしまっていたので、これを修正するとlocが絶対パスになった。 設定の詳細は https://gohugo.io/getting-started/configuration/#all-configuration-settings この辺参照。

(調査中) connect() to XXXX:80 failed (99: Cannot assign requested address) while connecting to upstream

状況 dockerで動かしてるnginxでこんな感じのエラーが出た。 connect() to XXXX:80 failed (99: Cannot assign requested address) while connecting to upstream 調査進捗 エラー自体はポートの枯渇が原因っぽい。 https://stackoverflow.com/questions/14144396/nginx-proxy-connect-to-ip80-failed-99-cannot-assign-requested-address カーネルパラメータは母艦と共有するのでVMとかで動かしてるならそっちをチューニングしても良さそう。以下参考。 https://blog.stormcat.io/post/entry/docker-tcp-kernel/ https://qiita.com/ozota/items/728f0e838817d4ed7399 https://tetsuyai.hatenablog.com/entry/20111220/1324466655 今回エラー吐いたところは無茶な負荷かけたのが原因なので、今後パフォーマンスが必要になったら改めて調べる予定。

CircleCIでジョブがタイムアウトした話

はじめに この記事に詳細が書かれている まとめ CircleCIのrunはデフォルトで最後の出力から10分後タイムアウトする no_output_timeoutに任意の値を設定できる 説明 こんな感じでタイムアウトが発生して Too long with no output (exceeded 10m0s): context deadline exceeded と出力されていた。 - run: command: . ./ourlongscript.sh no_output_timeout: 30m こんな感じでtimeoutを設定することで回避できる。

goenvを2.0にしたらビルドできなくなった話

結論 この記事を読めばいい 解決策 環境変数にGOENV_DISABLE_GOPATH=1をセットする 2系を使うのを諦める 起きてたこと goenvの2系ではGOPATHがgoのバージョンごとに管理されていた。 goの環境構築をよくある形で行なうとGOPATHは ${HOME}/go になっていると思うが、 2系では $({HOME}/go/<使用しているバージョン> となる。 1.14.0を使っているなら ${HOME}/go/1.14.0 になる。 解決策としては1系を使うか GOENV_DISABLE_GOPATH=1 すればいい。

GitHub Actionsで改行含むテキストをステップのアウトプットに指定する

はじめに 英文読める人はこちらをどうぞ。 以下の内容はこの記事の内容をまとめたものとなっている。 背景 GitHub Actionsでは以下のように設定することでstepsで実行した処理の出力を他から参照できる。 steps: - run: | description="description here" echo "::set-output name=description::$description" id: set_description この例では他のstepから ${{ steps.set_description.outputs.description }} のように値を参照する。 しかし、ここで1つ問題があり、descriptionに複数行が含まれると最初の行だけしかセットされない。 対処方法 以下のように改行文字をエスケープすることでoutputに複数行の文字列をセット可能。 description="${description//'%'/'%25'}" description="${description//$'\n'/'%0A'}" description="${description//$'\r'/'%0D'}" 前述の例だとこの様になる。 steps: - run: | description="description here" description="${description//'%'/'%25'}" description="${description//$'\n'/'%0A'}" description="${description//$'\r'/'%0D'}" echo "::set-output name=description::$description" id: set_description エスケープされたテキストのデコードは処理系で行われるため、ユーザーコードでこれを意識する必要はない。 参考 https://github.community/t5/GitHub-Actions/set-output-Truncates-Multiline-Strings/td-p/37870

[Kubernetes]HPA使用時のreplicasの設定

DeploymentとHorizontalPodAutoscaler(HPA)の組み合わせでハマった箇所があったため、検証結果と検証用の資料をまとめた。 検証環境 Kubernetes version: 1.14.10-gke.27 検証資料: https://github.com/ques0942/k8s-hpa-sample 結論 HPA使用時はDeploymentにreplicasを設定しないほうが良い replicasありのDeploymentに後からHPAを適用したい場合 replicas無しのDeploymentをapplyすると一時的にPodは1つになる kubectl apply edit-last-applied deployment ${target} でDeploymentからreplicasを削除できる HPAでスケールアウトした後HPAを削除してもPod数はそのまま 最後にapplyしたDeploymentがreplicasを持たない場合、kubectl editでreplicasを書き換えたとしてもその後replicas無しのDeploymentをapplyしてもPod数は1にならない 詳細は後述するがkubectl applyの差分計算ロジックによる挙動 説明 Deploymentに紐づくPodの数は replicas に設定された数字と等しくなるが replicas が未設定の場合は1になる。 一方でHorizontal Pod Autoscaler(HPA)を使用すると、Deploymentの replicas は負荷状況に合わせて自動で変更される。では以下のようなユースケースの場合どのような挙動となるだろうか? 手順 replicas = 3としてDeploymentを適用する HPAを有効化する HPAでreplicasが10に増加した 1で適用したDeploymentを修正して適用したが、その時replicasは3のままだった 問題 この手順を踏むと4の実施後にreplicasは3に戻ってしまう。 規模が大きくなってくるとデプロイ時に縮退することになるため望ましくない挙動だろう。 対策 最後にapplyされたDeploymentを開いてreplicasを削除する kubectl apply edit-last-applied deployment ${target} を使う 以降applyするDeploymentにはreplicasを含めない 単純にreplicasを含まないDeploymentをapplyすると、一時的にPod数は1になるため注意。

IssueのトリガーでGithub Actionsを動かしてみる

具体的にはIssueに特定のラベルが付いていたらそれを元にGithub Pagesに記事を追加したい。 試しに このブランチ でテストを行ったがうまく行かなかった。 ブランチ に含まれるworkflowはpushでは起動するがissuesで動かない。 masterじゃないと動かないという制限があるかも? ということで 新規レポジトリ作ってmasterにactionsを登録したら動いた。 https://github.com/ques0942/github-actions-sample/commit/ee6bf81ebec027eda315d135aacd744def3e8ca8/checks?check_suite_id=393358382 こちらのレポジトリでもPRの段階ではissuesからのイベントでは起動されなかった。 やはり何かしら制限がありそう。 トリガーされるイベントが多すぎるので制限されるのもわからないではないが、masterでしかテストできないのはなかなか不便。 結論 この資料に記載があったが、masterかデフォルトブランチに設定がないと起動しない模様。 memo runnerにインストールされているソフト こちら 特定のラベルが含まれているか調べるには https://github.community/t5/GitHub-Actions/Do-something-if-a-particular-label-is-set/td-p/40712# コンテキストの中身を確認する 以下のようにechoを使うことで中身をダンプできる。 name: pullrequest from issue on: issues jobs: display: runs-on: ubuntu-18.04 steps: - name: display run: echo '${{ toJson(github.event) }}' if節関連 if節の中ではenvは使えない。${VAR}でもenv.VARでも駄目だった。 if節の中では文字列はシングルクォーテーションのみ。ダブルクォーテーションでは駄目。 バックスラッシュで改行することはできない。 env関連 envの中で定義済みの変数を展開することはできないっぽい envで変数を定義するときに以下のように定義しても展開されない模様。 VAR: 1 VAR2: ${VAR}-2 envを複数定義することもできないのでこれに関しては諦めるしかなさそう。 actionのwithで環境変数を使う stepsでactionを使用する場合withで引数を渡すが、ここにenvで定義した環境変数を渡したい場合は $VAR とするのではなく、 env.VAR とする必要がある。 git関連 git pushをrun内で実行するとうまく行かなかったのでaction使ったほうが良さそう。 github関連 前述のpush actionも良いが、このaction を使用すると、gitへのcommit及びpull requestの作成をやってくれるのでかなり楽に実現できる。 steps内でファイルの追加、削除、更新してこのactionを実行するとそれらをまとめてcommitしてpull requestを作成してくれる。 ただし変更差分は全てcommitされるので不要なファイルを無視するか削除する必要がある。

plantumlのメモ

plantuml使うにあたって知っていると便利なことをまとめておく。 マクロ !define arrow(arg1, arg2) arg1 --> arg2 arrow(node1, node2) このように記述するとこれは以下のように展開されて評価される。 node1 --> node2 ネットワーク図を書くときに以下のように定義しておくと整理が楽になる。 !define http(a, b) a --[#magenta]--> b : http !define grpc(a, b) a --[#blue]--> b : grpc 使用できる色の定義はここ skinparam 以下のようにskinparamを設定しておくと、同じグループのノードをまとめてスタイリングできる。 skinparam node { backgroundColor<<QA>> PaleGreen backgroundColor<<DEVELOP>> LightSkyBlue } cloud gcp { node "node1" as nd1 <<QA>> node "node2" as nd2 <<DEVELOP>> } 図の向き top to bottom direction 、 left to right direction のように図の先頭に書いておくと、 図の向きを上から下、左から右のように制御することができる。 レイアウト 基本的にレイアウトは全て自動で設定されるが、見えないエッジを定義することで多少の制御は可能。あくまでも多少なのできれいにレイアウトすることは諦めたほうが良い。どうしても線が重なって見づらいときなどの緊急避難用。

go-sqlmockのTips

まとめ 動作確認したのは v1.3.3 database/sqlのテストはgo-sqlmockを使うと比較的楽に行える クエリのmatcherには正規表現が使える Rowsからエラーを受け取りたい場合は、エラーが発生する行のデータを作る必要がある 不要なエラーのチェックだけならsqlmock.ExpectationsWereMetは呼び出さなくてもよい まえがき golangでSQLを使うコードを書く場合、database/sql を使うことになるが、golangの標準ライブラリだけでこれのテストを書くことは非常に辛い。 おそらくDBを実際に用意してテストするしか無いが、様々なエラーケースのテストが必要な場合それだけではテストしきれない。 この記事ではDATADOG/go-sqlmockを使ってテストした際のTipsをまとめておく。 はじめに 基礎的な部分はREADME.mdやexamples、godocを読めば事足りるが、以下に忘れがちな内容を記載する。 Query matcher クエリが実行されたかどうかをチェックするにあたって、呼び出された回数だけをチェックしたいケースが有る。 このような場合は、正規表現を使うことで対処できる。 mock.ExpectQuery(".*").WillReturnRows(rows) 雑だがgomockのAny()相当のことがしたい場合はこれで実現可能である。 また、QueryMatcher自体を自分でカスタマイズすることも可能だがこちらは試していない。 refs: https://godoc.org/github.com/DATA-DOG/go-sqlmock#QueryMatcher Rowsからエラーを受け取る クエリの結果エラーを受け取りたい場合、 ExpectedQuery.WillReturnRows にエラーを含む sqlmock.Rows を登録することになるが、このとき以下のようにしてしまうとエラーが発生せずにハマることになる。 sqlmock.NewRows([]string{"ID"}).RowError(0, commonErr) パッと見は最初の行でエラーが出そうであるが、これではエラーは出ない。 多分この辺のせい。 以下のようにエラーが発生する行数になるまでAddRowを実行する必要がある。 sqlmock.NewRows([]string{"ID"}).AddRow(1).RowError(0, commonErr) 不要な呼び出しのチェック READMEのサンプルではmock.ExpectationsWereMet を実行してmockが呼び出されているか検証しているが、 SQLが実行されなかったことを保証するだけであれば このメソッドを呼び出さずとも良い。 例えばvalidationの結果、SQLが実行されないようなケースのテストでそのようなテストが必要になる。 ExpectXXX系のメソッドが呼ばれなかった場合に db.QueryContext のようなメソッドを実行すると、sqlmockがエラーを返すためそれを検証すれば良い。

Hugoで生成したコードをgithub pagesへデプロイするたびにカスタムドメインが初期化される

github actionsを使ってgithub pagesをデプロイしていると、デプロイのたびにカスタムドメインの設定が消えてしまっていたため原因を調べた。 まとめ カスタムドメインを使用する場合はリポジトリルートの CNAME ファイルに指定したいドメインを記載する必要がある Hugoでは static/CNAME を作成すれば良い 起きていたこと github pagesでカスタムドメインを使用する場合、 settings タブからカスタムドメインの設定を行うが、これは公開中のブランチ( master もしくは gh-page)の CNAME ファイルを作成、更新する形で設定される。 このため、Hugoなどで生成したコードをそれらのブランチに対してデプロイするような構成にしていた場合は、生成されたコードに CNAME ファイルが含まれていないとデプロイのたびにカスタムドメインの設定が無効になってしまう。 refs: https://help.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site#configuring-a-subdomain Hugoでの解決策 static/CNAME に指定したいドメインを記載する。 refs: https://gohugo.io/hosting-and-deployment/hosting-on-github/#use-a-custom-domain