2021年2月25日木曜日

cppcheck html report

 久しぶりに cppcheck を使ってみたら HTML レポートができるようになっていたのでメモ。

環境セットアップ

HTML レポートを作成するには python 環境が必要です。
https://github.com/danmar/cppcheck/tree/main/htmlreport
バージョンは 2.7 以上であれば大丈夫なようです。
また pygments に依存してるので pip install pygments もしておきましょう。

Cppcheck を実行

HTML レポートは cppcheck の結果 xml から作成するので、まずは cppcheck をかけて xml を出力します。

e.g.
cppcheck --enable=all --xml myproject 2> result.xml

Cppcheck 自体の使い方は(かなり昔に書いた記事ですが)こちら「ブログズミ: Cppcheck を使ってみた」、もしくは公式ドキュメントを参照してください。

HTML レポート

xml ができたらいよいよ html にします。

cppcheck-htmlreport --file=result.xml --title=iutest --report-dir=./html

--file で cppcheck で出力した xml を指定します。(複数指定可能)
その他のオプションは下記のヘルプを参考にしてください。

Usage: cppcheck-htmlreport [options]

Options:
  -h, --help            show this help message and exit
  --title=TITLE         The title of the project.
  --file=FILE           The cppcheck xml output file to read defects from. You
                        can combine results from several xml reports i.e. "--
                        file file1.xml --file file2.xml ..". Default is
                        reading from stdin.
  --report-dir=REPORT_DIR
                        The directory where the HTML report content is
                        written.
  --source-dir=SOURCE_DIR
                        Base directory where source code files can be found.
  --source-encoding=SOURCE_ENCODING
                        Encoding of source code.

結果

iutest の結果を gh-pages に入れておいたのでそちらを参考にしてみてください。
https://srz-zumix.github.io/iutest/test/cppcheck/



ソースコードも HTML ページ上で確認できます。

今回はこれで以上です。



2021年2月17日水曜日

Wekan サーバーの引っ越しで mongoDB のバックアップ・リストアした(docker-compose 編)

 とある事情で Wekan サーバーを引っ越ししました。
docker-compose で立てていたのですが、データベースのバックアップ・リストアをしたときの手順を備忘録として残しておきます。

手順はこちらを参考しました。
Dockerで起動しているMongoDBにリストアする - Qiita

環境

docker-compose はこんな感じです。

元サーバー

version: '2'
services:
  wekan:
    image: mquandalle/wekan
    restart: always
    links:
      - wekandb
    environment:
      - MONGO_URL=mongodb://wekandb/wekan
      - ROOT_URL=http://hogehoge:8088
    ports:
      - 8088:8080
    networks:
       - app_net

  wekandb:
    image: mongo:3.2.11
    volumes:
      - /mnt/sda1/docker/wekan/data:/data/db
      - /mnt/sda1/docker/wekan/configdb:/data/configdb
    restart: always
    networks:
       - app_net

networks:
  app_net:
    ipam:
      config:
        - subnet: 172.XX.XX.X/24
  

network 指定あり、db はホストにマウント済み。

移動先サーバー

version: '2'
services:

  wekan:
    image: mquandalle/wekan
    restart: always
    links:
      - wekandb
    environment:
      - MONGO_URL=mongodb://wekandb/wekan
      - ROOT_URL=http://fugafuga:8088
    ports:
      - 8088:8080

  wekandb:
    image: mongo:3.2.11
    volumes:
      - db_data:/data/db
      - db_config:/data/configdb
    restart: always

volumes:
  db_data:
    external: true
  db_config:
    external: true
  

network はなし。Windows マシンなのでホストにマウントするのがうまくいかないのでボリュームを作ってそこに永続化。

バックアップ

Qiita 記事のリストアコマンドをバックアップコマンドに変更して実行します。
元サーバーはホストに db をマウントしてるのでそこからやってもいいのかもしれませんが、mongodump しました。

また、ネットワーク作ってるのでそれを指定してます。

docker run --rm --link wekan_wekandb_1:mongo -it -v ~/wekan/backup:/backup --network wekan_app_net -w /backup mongo:3.2.11 bash -c "mongodump --host mongo"

backup ディレクトリに出力されてるはずなのでそれを引越し先サーバーにコピー。

リストア

リストアもバックアップ同様に行いました。
こちらはネットワークを指定しませんが docker-compose up すると wekan_default のようにデフォのネットワークが作られるのでそちらを指定します。
(細かいですが Windows 上なのでルートパスの / を2重化してます。この件は「ブログズミ: Docker Toolbox でホストのカレントディレクトリをマウントするときの備忘録」を参照してください。)

docker run --rm --link wekan_wekandb_1:mongo -it -v "/$(pwd)/backup/dump":/backup --network wekan_default -w //backup mongo:3.2.11 bash -c "mongorestore --host mongo /backup"


2021-01-14T08:18:03.435+0000    building a list of dbs and collections to restore from /backup dir
2021-01-14T08:18:03.484+0000    reading metadata for wekan.cfs_gridfs.attachments.chunks from /backup/wekan/cfs_gridfs.attachments.chunks.metadata.json
2021-01-14T08:18:03.484+0000    reading metadata for wekan.cfs_gridfs._tempstore.chunks from /backup/wekan/cfs_gridfs._tempstore.chunks.metadata.json
・・・
2021-01-14T08:18:04.035+0000    finished restoring wekan.customFields (0 documents)
2021-01-14T08:18:05.581+0000    restoring indexes for collection wekan.cfs_gridfs.attachments.chunks from metadata      
2021-01-14T08:18:05.665+0000    finished restoring wekan.cfs_gridfs.attachments.chunks (189 documents)
2021-01-14T08:18:05.666+0000    done

のようにできたら完了です。
移行先の Wekan にアクセスして確認しましょう。

最後に

Wekan は OSS の Trello っぽいやつです。
かなり進化していて WIP 制限とかスイムレーンとかあるので Trello よりも仕事で使えると思います。

便利なんでぜひ使ってみてください。

今回は以上です。


2021年2月12日金曜日

[CodeShip][Drone.io] DockerHub pull rate limit に対応する

DockerHub の pull rate limit への対応方法メモです。
基本的には DockerHub にログインした状態で pull することになると思います。
ログイン情報のパスワードには DockerHub の設定から API トークンを発行しそれを設定します。


ただ、このユーザー/パスワードを各 CI サービスに適用する方法はサービスによって違います。今回は CodeShip と Drone.io の設定を紹介したいと思います。

CodeShip の場合

CodeShip Pro の場合です。 Basic の場合はコマンドの中で docker login コマンドを実行する方法になると思います。

Using Docker Image Registries | CloudBees Docs
上記リンク先のドキュメントに設定方法が記載されています。

手順としては大きく分けて2つで、Dockerconfig.json の用意とリポジトリ/ YAML の設定になります。

Dockerconfig.json の用意

まず DockerHub にログインするための config.json を生成します。

{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "your_auth_string",
            "email": "your_email"
        }
    }
}  

json ファイルの中身は上記のようなものになります。
この json ファイルは docker login したら $HOME/.docker/config.json に保存されるものを使えばよいのですが、macOS の場合保存場所が keychain になっているため、下記方法で取得します。公式ドキュメントでは「Docker Credentials On Mac OSX」のあたりです。

まずは以下のような credentials.evn ファイルを作成します。
USERNAME/PASSWORD は適宜埋めてください(PASSWORD には API TOKEN)

DOCKER_USERNAME=...
DOCKER_PASSWORD=...
DOCKER_REGISTRY=https://index.docker.io/v1/
  

続いて、以下のコマンドを実行します。

mkdir ./dockercfg
docker run -it --rm \
    --env-file=credentials.env \
    -v "$(pwd):/opt/data/" \
    -v "/var/run/docker.sock:/var/run/docker.sock" \
    codeship/dockercfg-generator /opt/data/dockercfg

すると、カレントディレクトリ/dockercfg/ に config.json が出来上がります。

リポジトリ / YAML の設定

config.json が出来上がったらそれをシークレットファイルにして、CI 環境が読み込むように YAML に設定をします。

シークレットファイルの作成のためにプロジェクトの設定ページから codeship.aes をダウンロードしてください。リポジトリのルートに配置したら不用意に commit してしまわないように .gitignore に追加しておきましょう。

aes を配置したら以下のコマンドを実行します。パスは適宜変更してください。

jet encrypt dockercfg/config.json dockercfg.encrypted

出来上がった .encrypted ファイルは git add/commit します。

続いて YAML の設定をします。
追記するのは codeship-steps.yml ファイルの方です。
以下のように encrypted_dockercfg_path を追加してください。

- name: spec
  service: gcc
  command: /work/build.sh
  encrypted_dockercfg_path: ./dockercfg.encrypted
動作確認

これで設定は以上です。変更を commit/push して動作確認してみましょう。
うまく設定できていれば DockerHub の Token 一覧画面で最終アクセス日時が更新されるはずです。

Drone.io の場合

Images | Drone
Drone の公式ドキュメントはこちらです。

CodeShip と同じように Dockerconfig.json ファイルを作成し、それを drone のシークレットファイルとして CLI から登録します。
iutest で生成用に用意した Makefile があるので参考にしてください。
https://github.com/srz-zumix/iutest/tree/master/.ci/drone

json ファイルを作成したら以下のコマンドで登録できます。

	drone secret add --repository srz-zumix/iutest \
		--name dockerconfig \
		--data @dockerconfig.json

シークレットファイルをアップデートする場合は update サブコマンドを使います。

	drone secret update --repository srz-zumix/iutest \
		--name dockerconfig \
		--data @dockerconfig.json

PR でもこのシークレットファイルを利用可能にする場合は --allow-pull-request オプションを追加してください。
シークレットファイルを登録したら以下のように、このファイルを使用するように YAML の設定をします。

kind: pipeline
name: test

image_pull_secrets:
  - dockerconfig

steps:
...


image_pull_secrets に指定するのは secret add/update したときに指定した --name オプションの名前です。

動作確認

設定は以上です。
CodeShip と同様にトークンが利用されたかどうかを確認しましょう。

まとめ

今回対応した CodeShip/Drone どちらも Dockerconfig.json ファイルをシークレットに用意してそれを環境に読ませる方法でした。

最初 Drone の方は

echo -n '<ユーザ名>:<アクセストークン>' | base64

の結果を auth に設定していて、それではうまくいかなくて手こずっていたのですが、CodeShip のやり方を知って助かりました。
(Mac 環境で base64 してるのが原因?)

ともあれ、CodeShip や Drone と同様に Docker の config.json を使った login をする CI サービスではこの方法が使えそうです。

今回は以上です。

2021年2月1日月曜日

古い gcc が欲しくて CentOS 5 の docker image を作った話

はじめに
なぜ古い GCC が必要になったのか?
個人開発している iutest では古の環境でもなるべく使えるように頑張りたいなーという気持ちがあります。(なんかこう制約をかいくぐってなんとかするの楽しいし)
Google Test の最新版で C++11 が要求されるようになったこともあり、今後昔の言語バージョンをサポートするライブラリは減っていくのかなーと思います。
当然、新しい言語バージョンを使っているのなら、そのバージョンをターゲットとしたライブラリのほうが効率が良いと思います。
iutest でももちろんなるべく新しい言語バージョンの機能を取り込んでいくつもりです。

ここで問題になってくるのはテストです。
今までは古の環境を想定して、iutest 側で言語機能がないと Config をセットしてテストしていました。
ライブラリ内部での undefined とかシンタックスエラーはこれでも検出できるのですが、やはり「ないと仮定」しても「実際にはある」ので、実は対応してなかったってのがいくらでも出てきちゃいます。

そんな感じで、一応サポートする気持ちはあるけどテストはできる限りという状態だったため、テストのカバー範囲を広げるために日々 OS やコンパイラのテスト環境を増やしている次第です。

なぜ CentOS 5 なのか?
はじめに、古い GCC が欲しいと思ったときに Ubuntu のパッケージからできるだけ古いものをインストールしようとしました。
しかし、そこまで古いものは取ってこれませんでした。

つぎに、ソースコードからビルド・インストールすることを試しました。
こちらはなかなかビルドが通らない、あと古い環境だと認証通らなくて(GPG key とか)必要な依存物が取ってくるのも大変でした。
(H8 クロスコンパイラはネット上の情報から作ることはできましたが)

で、CentOS の古いバージョンなら取ってこれるんじゃないとアドバイスもらったところ、本家のパッケージは EoL で取ってこれなかったのですが、アーカイブがあってそこからすんなりインストールすることができました。

と、いうわけで以下。そのときの手順をまとめます。

完成形 Dockerfile
その前に先に完成した Dockerfile を載せておきます。
以下、説明の参考にしてください。



CentOS 5 で gcc 3.4.6 と pyenv を使う
Python 3 系も使いたかったので pyenv のインストールまでしました。
GCC のインストールよりもこっちが大変だった。
では、見ていきましょう。

COPY CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
まず、CentOS 5 は既に EoL なのでリポジトリファイルを編集して、アーカイブされたパッケージを参照するように変更します。

ネットの力を借りて、それっぽく動くようにはなりましたが、「libselinux」でエラーになってしまいました。
↑の変更に加えて「libselinux」の変更も必要みたいだったので、↓を参考に設定。
無事に yum update できるようになりました。
gcc 3.4.6 のインストール
RUN yum update -y && \
    yum -y install epel-release && \
    yum install -y make gcc g++ nkf wget perl gettext libffi-devel \
        compat-gcc-34-3.4.6-4.1.x86_64 compat-gcc-34-c++-3.4.6-4.1.x86_64
gcc 3.4.6 のインストールはこのレイヤーで終わりです。
ポイントは↑のレイヤーで対応した、パッケージ参照先の変更だけです。

アーカイブされたパッケージ群から gcc と g++ をインストールしています。
pyenv のインストール
↑の方法では Python 3 系をインストールできなかったので pyenv 使って 3 系を使えるようにしました。
というわけで、pyenv のためにいろいろソースビルドしました。
以下の記事を参考にして、ソースビルド・インストールができました!ありがとうございます。

最後に
過去のものをビルドして使うのは大変だなと学びました。
そして、そういったものを Docker image にしておくことで少しでも苦労から開放されるなーと思いました。
Docker 素晴らしい。

今回作ったイメージは DockerHub にアップしてあります。
では。