ubldrの起動パーティションの切り替え
やること
crochetでNanoBSDを作ると、/dev/mmcsd0s2aと/dev/mmcsd0s2bができる。
mmcsd0s2a: 今のバージョンのFreeBSD
mmcsd0s2b: 未使用
なので、mmcsd0s2bに新しいバージョンのFreeBSDをインストールしてみたメモ。
OSの準備
crochetを使って準備する。
u-bootからubldrを呼び出すスクリプトの準備
ubldrのソースを見ると環境変数loaderdevで起動パーティションを切り替えていた。boot.scrでloaderdevを設定するようにした。
boota.cmdとする。
setenv loaderdev mmc0:1.0;fatload ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} ubldr.bin && go ${kernel_addr_r} echo "Cannot load ubldr.bin"
bootb.cmdはmmc0:1.0
の部分をmmc0:1.1として作る。
それができたら、mkimageを使ってu-bootで読み込めるファイルを作る。
mkimage -A arm -O FreeBSD -T script -c none -d boota.cmd boota.scr mkimage -A arm -O FreeBSD -T script -c none -d bootb.cmd bootb.scr
SDカード書き込み
ここからRaspberry Piでの作業。 イメージをネットワーク経由で取得して書き込む。イメージのaをSDのbに書き込むのは注意。
mount_smbfs -I 192.168.1.13 //foo@192.168.1.13/public /mnt mdconfig -f /mnt/FreeBSD-armv6-12.0-RPI-B-344277P-RaspberryPi.img dd status=progress if=/dev/md0s2a of=/dev/mmcsd0s2b bs=1m mdconfig -d -u 0 # ついでにboot scriptも転送 cp /mnt/boota.scr /mnt/bootb.scr /tmp umount /mnt
ブートのスクリプトを変える
mount -tmsdosfs -o noatime /dev/mmcsd0s1 /mnt mv -i /mnt/boot.scr /mnt/boot.scr.original cp -ip /tmp/boota.scr /tmp/bootb.scr /mnt # bから起動したいのでbootbをコピーする。 cp -ip /tmp/bootb.scr /mnt/boot.scr sync umount /mnt
fstabの書き換え
/dev/mmcsd0s2aから起動しないようにfstabを書き換える。
mount -o noatime /dev/mmcsd0s2b /mnt cp -ip /mnt/etc/fstab /mnt/etc/fstab.original sed -i -e 's|mmcsd0s2a|ufs/rootfs|g' /mnt/etc/fstab sync umount /mnt tunefs -L '' /dev/mmcsd0s2a tunefs -L 'rootfs' /dev/mmcsd0s2b
最後に再起動。
reboot
起動したら新しいバージョンで起動しているのを確認する。
unman -a
前のバージョンに戻したくなったら、FATバーティションのboot.scrをboota.scrに戻せばOK。 aとbのパーティションに交互に使うことで、常に前のバージョンに戻せる状態を維持しながらアップデートできる。 あと、アップデートがRaspberry Pi単独でできる。
pingでDUP!って出る件
macからRaspberry PI(FreeBSD 12)にpingする。
$ ping -c4 192.168.1.9 PING 192.168.1.9 (192.168.1.9): 56 data bytes 64 bytes from 192.168.1.9: icmp_seq=0 ttl=64 time=7.090 ms 64 bytes from 192.168.1.9: icmp_seq=0 ttl=64 time=7.110 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=0 ttl=64 time=7.113 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=0 ttl=64 time=7.116 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=0 ttl=64 time=7.119 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=1 ttl=64 time=12.260 ms 64 bytes from 192.168.1.9: icmp_seq=1 ttl=64 time=12.514 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=1 ttl=64 time=12.521 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=1 ttl=64 time=12.523 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=1 ttl=64 time=12.525 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=2 ttl=64 time=7.955 ms 64 bytes from 192.168.1.9: icmp_seq=2 ttl=64 time=7.967 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=2 ttl=64 time=7.970 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=2 ttl=64 time=7.976 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=2 ttl=64 time=7.978 ms (DUP!) 64 bytes from 192.168.1.9: icmp_seq=3 ttl=64 time=5.988 ms --- 192.168.1.9 ping statistics --- 4 packets transmitted, 4 packets received, +12 duplicates, 0.0% packet loss round-trip min/avg/max/stddev = 5.988/8.983/12.525/2.404 ms
$ sudo tcpdump -i en0 -p -n icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on en0, link-type EN10MB (Ethernet), capture size 262144 bytes 22:18:20.565875 IP 192.168.1.12 > 192.168.1.9: ICMP echo request, id 17157, seq 0, length 64 22:18:20.572882 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64 22:18:20.572895 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64 22:18:20.572898 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64 22:18:20.572900 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64 22:18:20.572902 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64
Raspberry PIのtcmdump
# tcpdump -i ue0 -p -n icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on ue0, link-type EN10MB (Ethernet), capture size 262144 bytes 22:18:20.570596 IP 192.168.1.12 > 192.168.1.9: ICMP echo request, id 17157, seq 0, length 64 22:18:20.572422 IP 192.168.1.12 > 192.168.1.9: ICMP echo request, id 17157, seq 0, length 64 22:18:20.572991 IP 192.168.1.12 > 192.168.1.9: ICMP echo request, id 17157, seq 0, length 64 22:18:20.573462 IP 192.168.1.12 > 192.168.1.9: ICMP echo request, id 17157, seq 0, length 64 22:18:20.573923 IP 192.168.1.12 > 192.168.1.9: ICMP echo request, id 17157, seq 0, length 64 22:18:20.574099 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64 22:18:20.574122 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64 22:18:20.574133 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64 22:18:20.574141 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64 22:18:20.574149 IP 192.168.1.9 > 192.168.1.12: ICMP echo reply, id 17157, seq 0, length 64
NanoPi NEO2でFreeBSDを動かすメモ(NEO2用のu-bootを使う)
これまでの経緯とか
以前はu-bootを同じCPU(Allwinner H5)のボードのものをつかっていた。
u-bootにはNanoPi NEO2用の設定があるため、今回はそれを使うようにした。
まずはportsの準備
portsnap fetch portsnap extract
NanoPi NEO2用のu-boot
# インストール時間節約のためにpkgで入るやつはあらかじめinstallしておく。(依存関係はfreshportsとかで見ておいた。) pkg install -n gsed swig30 dtc u-boot-tools arm-none-eabi-gcc bison gmake python27 aarch64-none-elf-gcc cd /usr/ports/sysutils git clone https://github.com/rixwwd/u-boot-nanopi-neo2.git cd u-boot-nanopi-neo2 make clean install
NanoPi NEO2用のcrochet
githubからcloneしてくる。
cd git clone https://github.com/rixwwd/crochet.git git checkout -b nanopineo2 origin/nanopineo2
必要に応じでconfig.shなどで設定を変更した後に、
cd ~/crochet /bin/sh ./crochet.sh -c config.sh -v
他
設定はboard/NanoPi-NEO2/overlayに置いてもいいし、イメージができたあとなら、mdconfigでイメージをマウントして編集でもOK。 sshとか、DHCPとか忘れがち。 このやり方だとrootしかユーザがいないし、ssh有効になってないし、rootのパスワードは未設定。
Raspberry PiをRead onlyなSDカードで運用するためNanoBSDのめも
NanoBSDの仕組み
/etc/disklessが存在すると、/etc/rc.initdisklessが動く。 /conf/base, /conf/defaultは設定ファイルのデフォルトを置いておく。 rc.initdisklessは、/conf/base, /conf/defaultの順で上書きしていく。
特殊なファイル
- md_size
- そのディレクトリをtmpfsにすろときのサイズの指定。512バイトで1ブロックのときのブロック数で指定。
10240
なら5MB。
- そのディレクトリをtmpfsにすろときのサイズの指定。512バイトで1ブロックのときのブロック数で指定。
- remount
- そのディレクトリに別のファイシステムをマウントする。ファイルの中にマウントの指定をする。
mount -o ro /dev/mmcsd0s2d
みたいに。
- そのディレクトリに別のファイシステムをマウントする。ファイルの中にマウントの指定をする。
crochetのNanoBSD
- etcは5MBのtmpfs。内容はデフォルトにSDカードの設定用パーティションの内容で上書く。
- varは16MBのtmpfs。
- /conf/baseは、もとの/var, /etcのコピー。
実際の構成
- /conf/base/etc/md_size
- /etcのサイズ
- /conf/base/var/md_size
- /varのサイズ
- /conf/default/etc/remount
- /conf/default/etcに対し、設定用のパーティション
mmcsd0s2d
をマウントするときのmountコマンド。
- /conf/default/etcに対し、設定用のパーティション
動きは以下のようになる。
- /conf/default/etc/remoutにより、/conf/default/etcは/cfg(mmcsd0s2d)と同じ内容になる。
- rc.initdisklessにより/conf/default/etcは/etcにコピーされる。コピーといってもbaseに対する上書きになる。上書きではなく削除したいときは、.removeなファイル名にする。
- rc.initdisklassにより/conf/default/varは/varにコピーされる。コピーといってもbaseに対する上書きになる。上書きではなく削除したいときは、.removeなファイル名にする。
mmcsd0s2dの内容
- /etcのレイアウトそのまま。(コピーだからね。)
- etc/localは、/usr/local/etcの中身。crochetでビルド時に、/usr/local/etcは/etc/localにコピーして、/usr/local/etcは/etc/localへのリンボリックリンクにしている。
他
/etc/rc.conf - root_rw_mount=NO - /はRead Onlyでマウント - entropy_file=NO - 乱数のエントロピーのキャッシュは使わない
細かい動きは、/etc/rc.initdisklessを読む。NanoBSDって/etc/rc.initdisklessをうまく利用してるだけ。
Mattermostの統合機能、APIメモ
やったこと
mattermostで何ができるのか調べてみた。
できること
- 内向きのウェブフック
- POSTすると指定したチャンネルに投稿できる。
- 外向きのウェブフック
- 特定の単語にマッチするときに、指定したURLにHTTP POSTする。
- スラッシュコマンド
- スラッシュコマンドを入力すると、指定したURLにHTTP POST/GETする。
- API
- mattermostのWeb API。ユーザー、チーム、チャンネル等の新規作成、更新、削除等ができる。
誰が使えるの?
機能 | システム管理者 | チーム管理者 | メンバー |
---|---|---|---|
内向きのウェブフック | 可 | 可 | 設定次第で可 |
外向きのウェブフック | 可 | 可 | 設定次第で可 |
スラッシュコマンド | 可 | 可 | 設定次第で可 |
API | 可 | 可 | 可 |
「設定次第で可」は、「統合機能の管理を管理者のみに制限する」設定を無効にする。
APIの認証方法
他
ウェブフック、スラッシュコマンドを使うときは、config.jsonのAllowedUntrustedInternalConnections
にアクセスを許可するIPアドレスの範囲を指定する。192.168.56.0/24
みたいに。
JenkinsのビルドをDockerコンテナで実行する
やること
Spring Bootで作ったアプリケーションのビルド&テストを、Jenkinsを使ってDockerコンテナ内で実行する。
方法
- コンテナのイメージはopenjdk:8-jdk-alpineを使った。
- Jenkinsfileの書き方は、agentにanyを指定するか、dockerを指定するかでコンテナ内で実行するかしないかがかわる。
- mavenをコンテナに入れるの面倒なのでSpring Initlizr で作った時から入っている、mvnwを使う。
- Junitの結果のグラフがなぜか表示されなかったけど、Wikiのコメントに回避策が書いてあった。一応動いた。 https://wiki.jenkins.io/display/JENKINS/JUnit+graph
- maven-surefire-pluginのバージョンは2.20にしないとテストの実行が失敗する。
以下のようなJenkinsfileを作る。
pipeline { agent { docker { image 'openjdk:8-jdk-alpine' } } stages { stage('Checkout') { steps { checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'http://192.168.56.6:8081/gitbucket/git/root/dockertest.git']]]) } } stage('Build') { steps { sh './mvnw clean compile' } } stage('Test') { steps { sh './mvnw test' } } stage('Recoding Result') { steps { //junit '**/surefire-reports/*.xml' step([$class: 'JUnitResultArchiver', testResults: '**/surefire-reports/*.xml' ]) } } } }
実行結果
実行するとこんな感じ。
Started by user admin Obtained Jenkinsfile from git http://192.168.56.6:8081/gitbucket/git/root/dockertest.git Running in Durability level: MAX_SURVIVABILITY [Pipeline] node Running on Jenkins in /var/lib/jenkins/workspace/dockertest-docker [Pipeline] { [Pipeline] stage [Pipeline] { (Declarative: Checkout SCM) [Pipeline] checkout > git rev-parse --is-inside-work-tree # timeout=10 Fetching changes from the remote Git repository > git config remote.origin.url http://192.168.56.6:8081/gitbucket/git/root/dockertest.git # timeout=10 Fetching upstream changes from http://192.168.56.6:8081/gitbucket/git/root/dockertest.git > git --version # timeout=10 > git fetch --tags --progress http://192.168.56.6:8081/gitbucket/git/root/dockertest.git +refs/heads/*:refs/remotes/origin/* > git rev-parse refs/remotes/origin/master^{commit} # timeout=10 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10 Checking out Revision f97c7cff726cad83d24b041e4f44be49b479e536 (refs/remotes/origin/master) > git config core.sparsecheckout # timeout=10 > git checkout -f f97c7cff726cad83d24b041e4f44be49b479e536 Commit message: "Change stage name." > git rev-list --no-walk cbf8bf399f9563d46fe2cae73eba0ea99cd4457d # timeout=10 [Pipeline] } [Pipeline] // stage [Pipeline] withEnv [Pipeline] { [Pipeline] sh [dockertest-docker] Running shell script + docker inspect -f . openjdk:8-jdk-alpine . [Pipeline] withDockerContainer Jenkins does not seem to be running inside a container $ docker run -t -d -u 985:979 -w /var/lib/jenkins/workspace/dockertest-docker -v /var/lib/jenkins/workspace/dockertest-docker:/var/lib/jenkins/workspace/dockertest-docker:rw,z -v /var/lib/jenkins/workspace/dockertest-docker@tmp:/var/lib/jenkins/workspace/dockertest-docker@tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** openjdk:8-jdk-alpine cat $ docker top 364938fc3805b25ed0bc7097881d2a4fb592d7799e6afe694fec2d4b4481f74e -eo pid,comm [Pipeline] { [Pipeline] stage [Pipeline] { (Checkout) [Pipeline] checkout > git rev-parse --is-inside-work-tree # timeout=10 Fetching changes from the remote Git repository > git config remote.origin.url http://192.168.56.6:8081/gitbucket/git/root/dockertest.git # timeout=10 Fetching upstream changes from http://192.168.56.6:8081/gitbucket/git/root/dockertest.git > git --version # timeout=10 > git fetch --tags --progress http://192.168.56.6:8081/gitbucket/git/root/dockertest.git +refs/heads/*:refs/remotes/origin/* > git rev-parse refs/remotes/origin/master^{commit} # timeout=10 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10 Checking out Revision f97c7cff726cad83d24b041e4f44be49b479e536 (refs/remotes/origin/master) > git config core.sparsecheckout # timeout=10 > git checkout -f f97c7cff726cad83d24b041e4f44be49b479e536 Commit message: "Change stage name." [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Build) [Pipeline] sh [dockertest-docker] Running shell script + ./mvnw clean compile /var/lib/jenkins/workspace/dockertest-docker [INFO] Scanning for projects... [INFO] [INFO] -----------------------< com.example:dockertest >----------------------- [INFO] Building dockertest 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:3.0.0:clean (default-clean) @ dockertest --- [INFO] Deleting /var/lib/jenkins/workspace/dockertest-docker/target [INFO] [INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ dockertest --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ dockertest --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /var/lib/jenkins/workspace/dockertest-docker/target/classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.787 s [INFO] Finished at: 2018-08-26T11:35:58Z [INFO] ------------------------------------------------------------------------ [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Test) [Pipeline] sh [dockertest-docker] Running shell script + ./mvnw test /var/lib/jenkins/workspace/dockertest-docker [INFO] Scanning for projects... [INFO] [INFO] -----------------------< com.example:dockertest >----------------------- [INFO] Building dockertest 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ dockertest --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] Copying 0 resource [INFO] [INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ dockertest --- [INFO] Nothing to compile - all classes are up to date [INFO] [INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ dockertest --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /var/lib/jenkins/workspace/dockertest-docker/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ dockertest --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /var/lib/jenkins/workspace/dockertest-docker/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.20:test (default-test) @ dockertest --- [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.example.dockertest.web.HelloControllerTest 〜長いので省略〜 [INFO] [INFO] Results: [INFO] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9.830 s [INFO] Finished at: 2018-08-26T11:36:10Z [INFO] ------------------------------------------------------------------------ [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Recoding Result) [Pipeline] step Recording test results [Pipeline] } [Pipeline] // stage [Pipeline] } $ docker stop --time=1 364938fc3805b25ed0bc7097881d2a4fb592d7799e6afe694fec2d4b4481f74e $ docker rm -f 364938fc3805b25ed0bc7097881d2a4fb592d7799e6afe694fec2d4b4481f74e [Pipeline] // withDockerContainer [Pipeline] } [Pipeline] // withEnv [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline Finished: SUCCESS
FreeBSDのRaspbery PI用イメージを1GBのSDカード用に変換する
やること
FreeBSDのRaspbery PI用イメージを1GBのSDカード用に変換する。 配布されているイメージは1GBなのだが、手元にあったSDカードは953MBとちょっと足りない。 そのため、実際のSDカードのサイズに合わせる。
方法
SDカードと同じサイズのファイルを作成する。 それに公式イメージの内容をdump&restoreする。
macでイメージを作成する。
dd if=/dev/disk2 of=sd.img bs=1m
dump & restore
コピー先の準備
mdconfig -x 63 -y 255 -f sd.img gpart create -s MBR md0 gpart add -t '\!12' -a 63 -s 64m md0 gpart set -a active -i 1 md0 newfs_msdos -L MSDOSBOOT -F 16 /dev/md0s1 gpart add -t freebsd md0 gpart create -s BSD md0s2 gpart add -t freebsd-ufs md0s2 newfs -U md0s2a Tunefs -L roots /dev/md0s2a mount /dev/md0s2a /var/tmp/sd
コピー
mdconfig -f FreeBSD-11.2-RELEASE-arm-armv6-RPI-B.img echo '/dev/md1s2a /var/tmp/src ufs rw 1 0' >> /etc/fstab mount /var/tmp/src /dev/md1s2a dump -0 -h 0 -f - /media | restore -x -f - -v sync umount /var/tmp/src umount /var/tmp/sd
起動用パーティションもコピー
mount -t msdosfs /dev/md0s1 /var/tmp/sd mount -t msdosfs /dev/md1s1 /var/tmp/src cp -pRv /var/tmp/src/* /var/tmp/sd/. sync umount /var/tmp/src umount /var/tmp/sd mdconfig -d -u 0 mdconfig -d -u 1