RaspbianにLXDを導入する

Raspberry Pi 3 Model B
OS: Raspbian Stretch lite March 2018

RaspbianではaptコマンドでLXDパッケージを導入することができないようであるからSnappyというパッケージマネージャで以ってインストールするのがよいようである。先んじてaptコマンドでlxcとsnapdパッケージをインストールしておく。

$ sudo apt install lxc snapd
$ sudo snap install lxd

$ snap list
Name  Version    Rev   Tracking  Developer  Notes
lxd   3.0.0      6661  stable    canonical  devmode

lxdコマンドは/snap/binへ配置されるようであるからパスを通すぞと息巻いていたらすでに開通済みであり拍子抜けしたものである。どうやら/etc/profile.d/apps-bin-path.shがこの役割を担っているようであった。

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/snap/bin

$ cat /etc/profile.d/apps-bin-path.sh
# Expand the $PATH to include /snap/bin which is what snappy applications
# use
PATH=$PATH:/snap/bin

然し乍らsudoで実行する際には/etc/sudoersにあるsecure_pathの影響が及ぶからこのままでは「sudo: lxd: コマンドが見つかりません」と出て終いである。そうであるからsecure_pathにも/snap/binを追加する。

$ sudo visudo
#Defaults       secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

そうしたらsudo lxd initで初期設定をおこなう。クラスタリングモードで実行するか否かやストレージなどに関する様々な問いかけがあるけれどもひとまずはすべてデフォルトのまま通した。

$ sudo lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
(snip)

なんらかコンテナの操作をしようとするとこうである。パーミッションの設定がソケットファイルへの接続を許してくれない模様である。パーミッションを確認するとrootユーザとlxdグループにだけ読み書きを許すような情勢である。

$ lxc list
If this is your first time running LXD on this machine, you should also run: lxd init
To start your first container, try: lxc launch ubuntu:16.04
Error: Get http://unix.socket/1.0: dial unix /var/snap/lxd/common/lxd/unix.socket: connect: permission denied

$ sudo ls -l /var/snap/lxd/common/lxd/unix.socket
srw-rw---- 1 root lxd 0  4月 11 21:50 /var/snap/lxd/common/lxd/unix.socket

このままではユーザpiがたいへん困るのでlxdグループに追加するとよい。なお続けざまにコンテナを操作しようとしても同じエラーメッセージを頂戴したので一旦ログアウトして再度ログインするとよさそうである。

$ sudo gpasswd -a pi lxd
ユーザ pi をグループ lxd に追加

これでコンテナの操作がほしいままになった。

参考:
Linux Containers – LXD – オンラインでの試用

Raspberry Pi 3 Model Bの本体に付いているLEDの点滅を自在に操作する

Raspberry Pi 3 Model B
OS: Raspbian Stretch lite March 2018

緑のLEDを司るファイルは /sys/class/leds/led0/、オレンジのLEDを司るファイルは /sys/class/leds/led1/ 以下に配置されているようである。何をきっかけにLEDを点滅させるかはtriggerファイルの内容を確認すればよろしい。デフォルトでは緑のLEDがmmc0、オレンジのLEDがinputである。

$ cat /sys/class/leds/led0/trigger
none (snip) panic mmc1 [mmc0] rfkill-any rfkill0 rfkill1

$ cat /sys/class/leds/led1/trigger
none (snip) default-on [input] panic mmc1 mmc0 rfkill-any rfkill0 rfkill1

mmc0はSDカードにアクセスがあった時に点滅する。inputはなんだかよくわからないが何しろinputであるからなんらかの入力であろうと思う。heartbeatやtimerを選択すると規則的に点滅させることができる。じっと眺めているとまばゆさで目が潰れてしまう。

heartbeatを選択したときのLEDのようす

点滅の制御はbrightnessでおこなう。0から255までの値を取り0で消灯、1~255で点灯する。数値の大小で輝度が変えられるように見えるけれどもどうやら一様な明るさである。なおbrightnessの数値を0に変更するとtriggerは勝手にnoneへ変更された。

$ sudo su -c "echo 0 > /sys/class/leds/led0/brightness"
$ sudo su -c "echo 1 > /sys/class/leds/led0/brightness"

一秒ごとに緑のLEDを明滅させる拙いシェルスクリプトled.shは概ねこんな具合である。あとはsudo bash led.shとすれば緑LEDが毎秒明滅するようになった。

#!/bin/bash

if [ $(id -u) != '0' ]; then
  echo 'Run as root.'
  exit 1
fi

GREEN='/sys/class/leds/led0'
trap 'echo mmc0 > ${GREEN}/trigger; exit 1' 1 2 9 15
echo none > ${GREEN}/trigger

while true
do
  echo 0 > ${GREEN}/brightness
  sleep 1
  echo 1 > ${GREEN}/brightness
  sleep 1
done

参考:
Can we control the on-board leds
How do I control the system LEDs using my software?
Are there other act_led_trigger options besides “mmc” and “heartbeat”?

カスタマイズしたRaspbianが入ったmicroSDのディスクイメージを能う限りコンパクトに取得する

OS: Ubuntu Server 12.04

大規模な変更や無謀な試みを施す直前にRaspbianのバックアップを取っておきたいけれども64GBの容量を謳うmicroSDのイメージファイルをそのままddコマンドで吐き出すと時間とストレージがいくらあっても足りないものである。容量いっぱいまで拡げられたルートパーティションを縮める手続きが必要である。

$ lsblk -i
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
(snip)
sdf      8:80   1  60.1G  0 disk
|-sdf1   8:81   1  41.8M  0 part
`-sdf2   8:82   1    60G  0 part

作業の大雑把な流れはファイルシステムのサイズを縮小→パーティションサイズを縮小、という具合である。また

 パーティションサイズ >= ファイルシステムサイズ

という掟もあるようであるから計算を誤るとKernel PanicでOSが起動しないイメージファイルが生まれるおそれがあり心を砕いて取り組む繊細な仕事である。利用できる環境であればGPartedでシュッとやるのが早くて確かでよりコンパクトになるからもう絶対GPartedがよかろうとおもう。

仕事をするGPartedのようす

ファイルシステムを縮小

/dev/sdfとして認識されたmicroSDのパーティション構成を具に確認するとこうである。ブートパーティションが/dev/sdf1、ルートパーティションが/dev/sdf2のようである。ルートパーティションのサイズは概ね60GiBであった。此れをresize2fsコマンドで以って縮めることを目当てにする。

$ sudo fdisk -l /dev/sdf
(snip)
   Device Boot      Start         End      Blocks   Id  System
/dev/sdf1            8192       93802       42805+   c  W95 FAT32 (LBA)
/dev/sdf2           98304   125958143    62929920   83  Linux

$ echo 'scale = 3; (125958143 - 98304 + 1) * 512 / 1024 ^ 3' | bc
60.014

ひとまずe2fsckコマンドを前もって実施しておかないと「Please run ‘e2fsck -f /dev/sdf2’ first.」などと言われて終いであった。

$ sudo e2fsck -f -y -v -C 0 /dev/sdf2

無闇に縮小する訳にはいけないからどれだけの容量が実際に使用されているかを前もって把握せねばならない。tune2fsで以って使用済みのブロック数から値を割り出すとだいたい2.01GiBを使用中というふうに観察できる。

$ sudo tune2fs -l /dev/sdf2
(snip)
Block count:              15732480
Free blocks:              15204597
Block size:               4096

$ echo 'scale = 3; (15732480 - 15204597) * 4096 / 1024 ^ 3' | bc
2.013

まったく隙間なく縮めてしまうとOS起動後に容量不足で禄な操作が許されないので、少しゆとりをもたせて2.1GiBに定めた。これをresize2fsコマンドに渡すと「resize2fs: Invalid new size: 2.1G」というエラーになるからどうも自然数しか受け付けてもらえない情勢である。さりとて3GiBでは目当ての値より一寸隔たりが大きいのでMiB単位で考えるのがよさそうである。2.1GiBは2.1 * 1024 = 2150.4MiBであるから2150Mとすれば概ねよかろうと思う。

$ sudo resize2fs -p /dev/sdf2 2150M

パーティションサイズを縮小

fdiskでルートパーティションのサイズを縮めるには現在のルートパーティションを一旦削除して新たに作り直せばよかった。終了セクタはファイルシステムのサイズより大きくなるよう取らねば都合が悪いようだから2200MiBとした。

$ sudo fdisk /dev/sdf
Command (m for help): p
(snip)
   Device Boot      Start         End      Blocks   Id  System
/dev/sdf1            8192       93802       42805+   c  W95 FAT32 (LBA)
/dev/sdf2           98304   125958143    62929920   83  Linux

Command (m for help): d
Partition number (1-4): 2

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (2048-125958143, default 2048): 98304
Last sector, +sectors or +size{K,M,G} (98304-125958143, default 125958143): +2200M

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

このあとサイズを指定せずにresize2fsを実行することでファイルシステムのサイズをパーティションサイズに一致するよううまい具合に膨らませてくれるようである。

$ sudo resize2fs -p /dev/sdf2
$ sudo fdisk -l /dev/sdf
(snip)
   Device Boot      Start         End      Blocks   Id  System
/dev/sdf1            8192       93802       42805+   c  W95 FAT32 (LBA)
/dev/sdf2           98304     4603903     2252800   83  Linux

これで漸くルートパーティションのサイズがコンパクトにまとまった。あとは512byte * (4603903 + 1)sectorだけddコマンドで以ってディスクイメージをファイルに書き出せば終いである。GPartedの仕事にくらぶればやや肥大気味ではあるけれども1bitをシビアに争う要請ではないから良しとしたいところである。

$ sudo dd if=/dev/sdf of=raspbian.img bs=512 count=4603904

なおresize2fsのマニュアルを読み進めているとKiBやGiBに対して風当たりの強い様が見られて大変興味深かった。

Note: when kilobytes is used above, I mean real, power-of-2 kilobytes, (i.e., 1024 bytes), which some politically correct folks insist should be the stupid-sounding “kibibytes”. The same holds true for megabytes, also sometimes known as “mebibytes”, or gigabytes, as the amazingly silly “gibibytes”. Makes you want to gibber, doesn’t it?

参考:
Raspberry Piで最小限に切り詰めたSDカードのイメージをバックアップする手順メモ.md
Linuxファイルシステムのサイズ変更とデフラグ
Raspberry Pi Visual identity guidelines

Raspberry Pi 3 Model BにBluetoothキーボードを接続する

Raspberry Pi 3 Model B
OS: Raspbian Stretch lite March 2018

すっかり一線から退いていたEC TechnologyのBluetoothキーボードに出番がやってきたのである。接続までの大まかな流れはデバイスのスキャン→ペアリング→接続というものであった。まずはbluetoothctlという対話型コマンドを実行する。

$ sudo bluetoothctl
[NEW] Controller 00:00:5E:00:53:00 raspberrypi [default]

キーボードのFnキーを押下しつつCキーを押し込むとペアリングモードに移行する。

そうしたらscan onでデバイスのスキャンをおこなう。しばらく待ち構えていると目当てのBluetooth Keyboardが見つかった。このデバイスのBluetooth Device Address(BD_ADDR)である00:00:5E:00:53:FFを控えておく。

[bluetooth]# scan on
Discovery started
[CHG] Controller 00:00:5E:00:53:00 Discovering: yes
[NEW] Device 00:00:5E:00:53:FF Bluetooth Keyboard

控えておいたBD_ADDRで以ってペアリングを開始する。ひとたびペアリングに成功すればRaspberry Piを再起動したとてペアのままであった。それでは都合が悪いという場合はremoveコマンドにBD_ADDRを渡してまったく削除することもできる。

[bluetooth]# pair 00:00:5E:00:53:FF
Attempting to pair with 00:00:5E:00:53:FF
(snip)
[CHG] Device 00:00:5E:00:53:FF Paired: yes
Pairing successful

[bluetooth]# paired-devices
Device 00:00:5E:00:53:FF Bluetooth Keyboard

あとはconnectコマンドで接続を実施すればよい。これでBluetoothキーボードから自在にキー入力がおこなえた。接続していると都合が悪いならdisconnectコマンドにBD_ADDRを渡すことで切断できる。

[bluetooth]# connect 00:00:5E:00:53:FF
Attempting to connect to 00:00:5E:00:53:FF
[CHG] Device 00:00:5E:00:53:FF Connected: yes
Connection successful

しばらくキーボードに触れずにいたりRaspberry Piを再起動するなどして接続が失われてしまっても、何かキーを押すことでひとりでに再度接続を可能にするためにはtrustコマンドでBD_ADDRを登録するのが良いようである。キー押下から入力が可能になるまではおおむね3秒程度を要するようである。なお登録を取り消すならuntrustコマンドであった。

[bluetooth]# trust 00:00:5E:00:53:FF
[CHG] Device 00:00:5E:00:53:FF Trusted: yes
Changing 00:00:5E:00:53:FF trust succeeded

デバイスの詳らかな様子を確認するときはinfoコマンドである。

[bluetooth]# info 00:00:5E:00:53:FF
Device 00:00:5E:00:53:FF
        Name: Bluetooth Keyboard
        Alias: Bluetooth Keyboard
        Class: 0x000540
        Icon: input-keyboard
        Paired: yes
        Trusted: yes
        Blocked: no
        Connected: no
        LegacyPairing: yes
(snip)

bluetoothctlから抜け出すにはこういう具合である。

[Bluetooth Keyboard]# quit
[DEL] Controller 00:00:5E:00:53:00 raspberrypi [default]

参考:
2.1 Bluetoothctl
Pairing processes
bluetoothctl – What is a bluetooth agent?

コンソール画面に画像を表示する

Raspberry Pi 3 Model B
OS: Raspbian stretch lite November 2017

連邦捜査局みたような名前のコマンドを使えば実現可能であった。

$ sudo apt install fbi
$ sudo fbi -T 1 -a keshiki.JPG
using "DejaVu Sans Mono-16", pixelsize=16.67 file=/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf

sshで接続している際に連続してfbiコマンドを実行してしまうとkillallでfbiプロセスを仕留めてももはやコンソール画面から画像が消えることはなかった。よそのターミナルへコマンドを送る大変便利なユーティリティを拝借してqキー押下をコンソールへ送信し事なきを得たがこれには閉口した。

参考:
Utility to Send Commands or Data to Other Terminals (tty/pts)