PlantUMLのdocker イメージを試す

みんな大好きPlantUMLのdockerイメージがdocker hubに登録されていました!!!

plantuml/plantuml

「いや、前からあるじゃん」って思うかもしれませんが、PlantUML-Serverではなくて、PlantUMLのdocker イメージです。

このブログを書いている時点(2022.12.1)で確認できる一番古いtagが1.2022.8になっているので、今年の8月にこっそり作られたようです。

ただ、このPlantUMLのイメージはPlantUML Serverのイメージと違って使い方が書いていないので、自分が試した方法をメモしておきます。

環境

以下の環境で試しました。

  • MacBook Pro M1 macOS バージョン12.6

  • docker: Docker version 20.10.21, build baeda1f

とりあえず docker run

実行結果

% docker run --rm plantuml/plantuml
Unable to find image 'plantuml/plantuml:latest' locally
latest: Pulling from plantuml/plantuml
5843afab3874: Pull complete 
53c9466125e4: Pull complete 
d8d715783b80: Pull complete 
ce3d08f559fd: Pull complete 
aae4759eae07: Pull complete 
4f0c6d3bb110: Pull complete 
Digest: sha256:fb7780724913edb6fde211983e1b8ca83f7a426391c597731938a4c2c94c0448
Status: Downloaded newer image for plantuml/plantuml:latest
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
PlantUML version 1.2022.13 (Sat Nov 19 13:22:17 GMT 2022)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Default Encoding: UTF-8
Language: en
Country: US
 
PLANTUML_LIMIT_SIZE: 4096

Dot version: dot - graphviz version 2.47.1 (20210515.0534)
Installation seems OK. File generation OK

M1 で試したせいでワーニングが出ていますが、今手持ちがこれしかないので、このままやります。

githubに登録されているDockerfileを確認すると、以下のようになっていたので、デフォルトではバージョンを表示するようになっているようです。

ENTRYPOINT ["java", "-jar", "/opt/plantuml.jar"]
CMD ["-version"]

pngを生成する

PlantUMLのクイックスタートでお馴染みの以下のファイルを任意のところに作成します。(ファイル名は"sequenceDiagram.pu"としておきます)

@startuml
Alice -> Bob: test
@enduml

そして以下のコマンドを実行します。

% docker run -v "sequenceDiagram.puがあるディレクトリの絶対パス":/data --rm plantuml/plantuml sequenceDiagram.pu

上記を実行すると、sequenceDiagram.puと同じディレクトリにsequenceDiagram.pngが生成されていると思います。

はい。簡単ですね。

まとめ

  • PlantUMLのdocker イメージがいつの間にかdocker hubに登録されていました

  • これを使えば、自分のPCにわざわざ環境を構築しなくても済むので手軽に試すにはありかと思います

  • たぶんCIとかで使うことを想定しているんだろうなと思いました

  • もっと公式が宣伝してほしい

おまけ

大量のpuファイルを一度に実行したい場合は、以下のコマンドでできます。

% docker run --rm -v "puファイルがあるディレクトリの絶対パス:/data --entrypoint="" plantuml/plantuml sh -c 'find -name "*.pu" | xargs java -jar /opt/plantuml.jar'

entrypointを無効化して、パイプでxargsを使うために"sh -c"で実行しています1

年単位で考えたらまだ安い

1年1ヶ月ぶりについてに来てしまった。。。

デレステお知らせ
デレステお知らせ

そう、大槻唯ちゃんのガチャが!!!!

アイコンは杏だけど、大槻唯ちゃんを観測したその時から、大槻唯Pとして細く長く活動しておりました。 (総選挙で投票したりくらいですが)

昨年の正月に来たガチャで今まで貯めていた石を使い果たし、人生初の課金して天井までいってなんとかゲット。 今回も約1年間貯めた石で160連するも撃沈。。。

160連後のスクショ
160連後

残り140連で天井なわけですが、どうするか一晩考えた結果・・・

課金後のスクショ
課金後

課金しました。(34700円)

そして、290連目!!!!

大槻唯ちゃんを引いた時のスクショ
大槻唯ちゃんキター!!!

尊い画像
大槻唯ちゃん!!!

ガチャ結果画面のスクショ
ガチャ結果画面

天井1歩手前で引きました!!!! よかった。おまけで仁奈ちゃんもついてきました。

尊い画像2
今回の大槻唯ちゃん

あと10連すれば天井でSSRが1人手に入るけど、次回の大槻唯ちゃんガチャのために取っておこうか、どうするべきか悩む。。。

これでデレステには約45000円課金したことになるけど、 シンデレラガールズは10周年だから、年換算したら、約4500円。 PS4やSwitchのゲームを買うよりまだ安い。。。

2021年まとめ

思い立った時や残しておきたい時に書くブログですが、今年も1年のまとめを残しておきたいと思います。

1月

コロナのせいで実家に帰れず、初めての関西で年越しを経験。 あと、今年は車を買おうと思っており、1月の中旬から色々と車屋さんに行ってどの車が良いか考えていた。 車屋さんは大体車が必要な場所にあるので、車初心者には優しくないと思う。

2月

1月に続いて車探し。初めは新車を購入しようと思っていたけど、見積もりをしてもらうと想定よりも高いので、中古車で良いのを探していた。 あと、1台目だからか、あまり新車のディーラーさんは相手にしてくれず、中古車のディーラーさんの方が親切だったというのもあるかもしれない。 色々と見た結果社用車あがりのほぼ新品のような車で気に入ったものが見つかったため、それを購入することになった。

3月

車を買ったのは良いが、免許を取得してから約8年間全く運転していなかったので、運転の練習に教習所行ったり、個別指導してくれるサービスを使ってみたりして、運転の練習をぼちぼちやっていた。3月下旬に納車されて、それからは週末に運転して少しづつ慣れようとしている。 ただ、仕事も3月はめちゃくちゃ忙しかった記憶がある。。。

4月

メインで使用していたDELLのノートPCが壊れた。電源ボタンが光るけど、それ以上の反応はなくお亡くなりになった。 そこで、次のPCとして前々から買おうか悩んでいたM1 MacBook Proを購入。車買ったばかりなのに、またそこそこの買い物をしてしまったけど、今もブログ書くのに使用しているし、ゼロからのOS自作入門もこの環境で今のところ問題なくできているので、すごく満足している。ただ、キー配列だけがなかなか慣れず苦労している。

5月

4月から業務内容が変わったこともあり、その勉強をしたり、新人の研修を担当したりといろいろ仕事が忙しい月だった。

6月

あまり覚えていない。。。

7月

スケボーを買った。小さい頃に欲しかったけど、買ってもらえずふと思い立って購入。その後、オリンピックでスケボーが金メダルを取って注目されて なんかオリンピックに影響受けて買っちゃったおじさんみたいになってしまった。。。家の近所でなかなかできるところがないので、今も滑れるところをずっと探している。 あと、初めての長距離ドライブも体験。

8月

夏休みも実家には帰らず家でゆっくりと過ごす。 ゼルダの伝説 スカイウォードソードを少しずつ進める。12月の現在でも、ポケモンをやっいるせいでまでクリアしていない。

9月

iPhone13に機種変しようかずっと悩んでいた。でもなかなか在庫がなくて結局機種変せず。 あと、コロナワクチン1回目の接種。病院の人がすごく丁寧で無事に接種は終わったけど、1回目から副反応はなかなかしんどかった。。。

10月

コロナワクチン2回目の接種。1回目よりもキツくて4日間くらいはへばっていたと思う。 あと、デジモンの映画をamzon primeで見てからデジモン熱が再発して、デジモンの主題歌CDを買い漁っていた。2021年でもデジモンのCDがamazonで普通に買えてビックした。今でも需要は結構あるのかもしれない。

11月

色々考えた末にiPhone13ではなく、iPad Airを買った。初めてのタブレットだけど、スマフォゲームが大画面でできたり、マンガも読みやすくて大変満足している。ただ、意外と重かったのが誤算で、iPad miniでもよかったかもしれない。

12月

今年も実家には帰らず家で年越しをする予定。今年はスタットレスタイヤに交換する予定はなかったけど、思いのほか雪が降っているので来年はスタットレスタイヤに履き替えないといけないかもしれない。 仕事は無理矢理終わらせてきたので、来年はそのツケを払わないといけないと思いつつ、今年も家でゆっくり年越しをしようと思う。来年は地元に帰れるといいなー。

以上

ゼロからのOS自作入門 環境構築~第1章

はじめに

OS自作したくなったので、内田先生の「ゼロからのOS自作入門」をやっていこうと思います。 メインPC(ubuntu)が壊れてしまい、M1 MacBook Proで環境構築しましたが、慣れないDockerを使ったりと大変だったので、備忘録的に記載していきます。 (本にはWindowsでの環境構築方法が丁寧に記載されているので、環境構築に悩みたくない人は素直にWindowsを使う方が良いと思います。M1での環境構築についてもここに先人の方々のすばらしいやり方が載っているので、M1しかなくて環境構築に困りたくない人はそっちを参照した方が良いと思います。)

手順

今回はDockerの勉強も兼ねているので、Dockerを使ってubuntu環境を構築してその上で開発していきます。

1. sudoユーザ&GUI操作可能なubuntuコンテナを作成

最終的にはqemuで動かしてGUIも表示させるようなので、以下のサイトを参考に環境を構築します。

上記方法で環境構築するとrootで操作することになってしまうので、以下のサイトを参考にDockerコンテナ内にsudoユーザを作りました。

コンテナの起動とかはDocker DesktopでGUI操作するのが一番楽だと気が付きました。(いちいちコンテナID覚えるの面倒。。。)

f:id:nitomo71:20210831172851p:plain
DockerDesktop

ユーザにログインするには、

  1. Docker Desktopからコンテナを起動

  2. Docker DesktopでCLIを開く

  3. 以下コマンド実行してユーザ名とパスワードを入力

sudo login

でログインできます。

2. 公式の手順をなぞる

mikanos-buildを上から順番に実行していきます。

ansible-playbook -K -i ansible_inventory ansible_provision.yml

を実行すると、以下のようなエラーがでますが、今のところとりあえず問題なさそうです。

TASK [check whether qemu-system-gui exists] ************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["dpkg-query", "--show", "qemu-system-gui"], "delta": "0:00:00.012730", "end": "2021-08-14 20:36:49.313362", "msg": "non-zero return code", "rc": 1, "start": "2021-08-14 20:36:49.300632", "stderr": "dpkg-query: qemu-system-gui に一致するパッケージが見つかりません", "stderr_lines": ["dpkg-query: qemu-system-gui に一致するパッケージが見つかりません"], "stdout": "", "stdout_lines": []}
...ignoring

手順を進めていくと、edk2のビルドでエラーになります。

In file included from /usr/lib/llvm-7/lib/clang/7.0.0/include/stdint.h:61:
/usr/include/stdint.h:26:10: fatal error: 'bits/libc-header-start.h' file not found
#include <bits/libc-header-start.h>
         ^~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
GNUmakefile:331: recipe for target '/home/osdev/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/MikanLoaderPkg/Loader/OUTPUT/Main.obj' failed
make: *** [/home/osdev/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/MikanLoaderPkg/Loader/OUTPUT/Main.obj] Error 1


build.py...
 : error 7000: Failed to execute command
    make tbuild [/home/osdev/edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64/MikanLoaderPkg/Loader]


build.py...
 : error F002: Failed to build module
    /home/osdev/edk2/MikanLoaderPkg/Loader.inf [X64, CLANG38, DEBUG]

- Failed -
Build end time: 00:10:43, Aug.15 2021
Build total time: 00:00:05

調べてみると、以下のサイトでも同様のエラーが報告されていました。

fatal error: 'bits/libc-header-start.h' file not found【mikanos】

上記のサイトを確認すると内田先生が以下のようにコメントしているらしいですが、

通常は $HOME/osbook/devenv/x86_64-elf以下に置いてあるはず。

自分の環境ではそもそもそのファイルはありませんでした。

osdev:~/osbook/devenv$ find -name libc-header-start.h
osdev:~/osbook/devenv$

再度、内田先生のコメントをよく読んでみると、"x86_64-elf以下"とあり、もしかしてと思い"uname -a"してみると

osdev:~/osbook/devenv$ uname -a
Linux 77cc22babb26 5.10.25-linuxkit #1 SMP PREEMPT Tue Mar 23 09:24:45 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux

となっており、mikanosの環境構築の前提としてアーキテクチャx86_64なのではという仮説が生まれました。

なので、以下のサイトを参考にビルドし、手順1からやり直しました。

Dockerの「マルチCPUアーキテクチャ」に対応したイメージをビルドする

上記のサイトでは、オプションを有効にしないとbuildxkコマンドは使用できないような記載がありますが、最新のDockerをインストールしてあれば、"buildx"コマンドは使用できました。

ちゃんとx86_64のイメージで起動できていると、以下のように表示できると思います。

$ uname -a
Linux bedb80ac310c 5.10.25-linuxkit #1 SMP PREEMPT Tue Mar 23 09:24:45 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

気を取り直して再度手順を進めていくと、最後の最後で失敗しました。

osdev:~/mikanos$ ./build.sh 
/* 省略 */
+ /home/osdev/osbook/devenv/mount_image.sh ./disk.img ./mnt
+ [ 2 -lt 2 ]
+ dirname /home/osdev/osbook/devenv/mount_image.sh
+ DEVENV_DIR=/home/osdev/osbook/devenv
+ DISK_IMG=./disk.img
+ MOUNT_POINT=./mnt
+ [ ! -f ./disk.img ]
+ mkdir -p ./mnt
+ sudo mount -o loop ./disk.img ./mnt
mount: ./mnt: mount failed: 許可されていない操作です.

以下のサイトをみると、オプションをつけないとマウントできないようです。

Dockerコンテナ上でイメージファイルをマウントする

ってことで、最終的にビルトと起動にはそれぞれ以下のコマンドを使用しました。

  • ビルド

    $ docker buildx build --platform linux/amd64 -t ubuntu:osdev -f Dockerfile .

  • 起動

    $ docker run --privileged -it -e DISPLAY="xxx.xxx.xxx.xxx:0" --platform linux/amd64 ubuntu:osdev

以下の画面が表示されたので、いったん環境構築は完了です。

f:id:nitomo71:20210831185322p:plain
mikanos

1章

hexeditというバイナリエディタを使用してみました。 このエディタ、新規ファイルが作成できないので、事前にtouchコマンドとかで空ファイルを作成してから編集する必要がありました。 (最初emacsで書いてて、途中からhexeditを使うような編集方法にしたら起動できるファイルは作れましたが、CRCの計算が合わなくて、いろいろ調査したけどよくわからず最終的にtouchコマンドで空ファイル生成、hexeditで編集でちゃんとしたやつが作れました)

f:id:nitomo71:20210831190306p:plain
mikanos hello world

これから

とりあえず時間を見つけて今後も少しずつでも進めていきたいと思います。 また、ある程度進んだらブログ書こうと思いますが、特に躓くことがなければ完成報告のブログになるかも。

コマンドライン引数で自作のオプションを指定する

プログラム実行時に自作のオプションで動作を変更したい時があると思います。
そういうときに便利なgetopt_long()を使用してみたので、備忘録的にメモしておきます。

とりあえずサンプルコード

#include <stdio.h>
#include <getopt.h>

int main(int argc, char **argv)
{
  int opt1 = 0;
  int opt2 = 0;
  int opt3 = 0;
  struct option longopts[] = {
    {"option1", required_argument, NULL, 1},
    {"option2", required_argument, NULL, 2},
    {"option3", no_argument, NULL, 3},
    {0, 0, 0, 0},
  };
  int opt;
  int longindex;
  
  while((opt = getopt_long(argc, argv, "option1:option2:otption3", longopts, &longindex)) != -1) {
    switch (opt) {
    case 1:
      opt1 = atoi(optarg);
      printf("opt1 = %d\n", opt1);
      break;
    case 2:
      opt2 = atoi(optarg);
      printf("opt2 = %d\n", opt2);
      break;
    case 3:
      opt3 = 3;
      printf("opt3 = %d\n", opt3);
      break;
    default:
      printf("?? getopt_long returned character 0%o ??\n", opt);
    }
  }

  return 0;
}

コンパイルして実行すると以下のような感じです。

$ ./a.out --option1=1 --option2=2 --option3
opt1 = 1
opt2 = 2
opt3 = 3

オプションは全部指定しなくても大丈夫です

$ ./a.out --option1=1 --option3
opt1 = 1
opt3 = 3

今わかっているレベルでの説明を以下に記載します。
(間違っている可能性あります。)

  struct option longopts[] = {
    {"option1", required_argument, NULL, 1},
    {"option2", required_argument, NULL, 2},
    {"option3", no_argument, NULL, 3},
    {0, 0, 0, 0},
  };

option構造体は以下のような定義になっています。

struct option {
    const char *name;
    int         has_arg;
    int        *flag;
    int         val;
};

"name"には使用したいオプション名を設定します。
"has_arg"は引数の設定をするようです。
引数をつけたい(--option1=1とかやりたい)時は"required_argument"、別に引数いらないときは時は"no_argument"と指定します。どっちでもよくする場合は、"optional_argument"と指定します。
"flag"はよく理解できていませんが、"NULL"指定するとgetopt_longが成功した時の戻りとして"val"の値を返すような設定になります。
つまり、今回の場合、"--option1=1"みたいな指定があるとgetopt_longは戻り値として"1"を返すようになるようです。
"val"は前記のように、getopt_long()の戻り値を設定します。

getopt_longの引数は5つです。
"argc"と"argv"はmain関数の引数をそのままわたしています。
"option1:option2:otption3"はオプション文字列するようです。
":"があると引数があるオプションで、ないと引数がないオプションとなるようです。
("::"だと、引数があってもなくてもよい設定になるようです。)
でもoption構造体でも同様の設定しているでの、ここで設定する意味がわかりませんでした。
(仮に""だけでも動作しましたし、別の適当な文字列でも動作しているようでした。。。。)

"longopts"はoption構造体を指定して、"longindex"指定されたオプションが定義してあるオプション構造体のインデックスを指しています。

while文以下はオプションによって処理を分けているだけなので説明は省略します。


以下は参考にさせてもらったサイトです。
getopt_long関数の利用 - コマンドラインオプションの処理 - 碧色工房
C言語でコマンドライン引数を取り扱う方法
getopt_long(3) — manpages-ja-dev — Debian testing — Debian Manpages
getoptを使う - Qiita

2020年まとめ

1年以上ぶりのはてなブログです。
実は今の1月1日から毎日日記(のようなもの)をevernoteにひっそりと書いていて、
7月からその内容をnoteに転記していました。つまり日記は久しぶりではないです。

昨年は毎日家計簿をつけて、今年は毎日日記をつけるという活動を行っていいましたが、
この流れで来年も何かしようと思っているのですが、何が良いか未だ考え中・・・・

そんなこんなではてなブログにも自分の1年間をざっくり残していこうと思います。

1月
・人生初めての海外旅行(そして多分人生最後だと思う)でハワイに行く
・高校の部活の友達とバスケの大会に出た(ボロボロだった)

2月
・コロナのせいで飲み会中止に(結局今年は一回も飲み会なかった)
・アニメの影響で虚構推理(小説)を読み終える
・探偵AIシリーズも読み終える

3月
ポケモンソードで殿堂入り?をする
TOEICが延期に
・人生初の現金書留を送る

4月
在宅ワークが始まる
どうぶつの森をはじめる

5月
在宅ワーク継続
・風呂の蛇口が壊れて水が止まらなくなる
ゼノブレイドDEを始める

6月
在宅ワークが終わる(悲しい)
・Ubuntu20.04にアップグレード

7月
・noteを始める
・初めの和歌山、とれとれ市場

8月
・ちょくちょく在宅勤務をする
・仕事がなくてモチベーションが下がる
膳所西武百貨店が閉店した

9月
・美容院の担当の人が変わった
・炎上プロジェクトにアサインされる
在宅ワーク終了

10月
TOEIC受験
iPadが欲しくて買いかけた(買っていない)
ゼノブレイドDEクリアする

11月
・ライザのアトリエを始める
・フルアヘッドココを読み始める
・ロストフラグ1周年めでたい

12月
在宅ワーク再開
・りゅうおうのおしごと13巻まで読み終える

以上