それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

php でクラスが呼び出す関数をスタブにしたいとき require を工夫すればいいが、laravelでは面倒が起きる

php でクラスが呼び出す関数をスタブにしたいとき

コードテストを書いていて、クラスが呼び出すクラスのメソッドをダミー化してたいとき、スタブを使う。

スタブを作るには、クラスが呼び出すクラスのメソッドを書き換える必要がある。phpでは動的なクラス定義変更ができない。

結論 require_once を弄くればいい。

require_once されているファイルを動的に差し替えればテストが可能。

当たり前なのだけど、気づかないときは気づかない。ちょっと盲点かもしれない。

mockery でやる

また、その実現のために、Mockery が使える。

<?php
// モックでスタブを作る
$mock = Mockery::mock('alias:'.MyChecker::class);
$mock->shouldReceive('is_src_exists')->andReturn(faklse);

たとえば、次のようなクラスがあって。クラスが例外を吐くことをテストしたい。とする

MyChecker::is_src_exists というメソッドを定義して。

<?php
class MyChecker {
  public static function is_src_exists( $path ) {
    return realpath($path) && is_readable($path);
  }
}

MyFileClassクラスの例外送出テストしたいとする。

<?php
class MyFileClass {
  public static function move($src,$dst){
    if (false == MyChecker::is_src_exists($src) ){
      throw new RuntimeException("src not found");
    }
    rename($src,$dst);
  }
}

テスト対象はMyFileClass である。MyChecker::is_src_exists を呼び出すMyFileClassがテスト対象である。

上記のクラスをテストして、例外が起きることをテストしたい

<?php 
class MyFileClassTest extends TestCase{
  public function test_file_move_function_raise_exception(){
    $this->expectException(RuntimeException::class);
    MyFileClass::move('/no_exists','/tmp');
  }
}

php では、動的に関数を上書きできない。runkitを使えばできなくもないが、環境整備も面倒だ。

動的に上書きできないし、フラグや引数やENVをソースコードに書くのも避けたい。 環境変数の切り分けコードをテストのために追記すると、コード全体の見通しが著しく悪化する。

だったら、かわりに、require_once をうまく使えばいい。

<?php 
require_once 'mock_is_src_exists.php';
class MyFileClassTest extends TestCase{ // 以下略

mock_is_src_exists.php

<?php 
// スタブとして代用するクラス定義
class MyChecker {
  
  public static function is_src_exists( $path ) {
    return false;
  }
}

テストしたいモックオブジェクトを作るのではなく、モックオブジェクトの定義を本来の名前でファイルに書き出して、それをrequire してしまえば、解決するのである。

require_onceを使った解決

// mock としてのロードをできるファイルを作る
function create_mock() {
  $temp = tempnam();
  file_put_contents($temp, <<<'EOS'
    <?php 
    class MyChecker{
      publick static function is_src_exists($path){ 
        return false;
      }
    }
  EOS);
  require_once $temp;
  register_shutdown_function(fn()=>@unlink($temp);
}
// テスト前に実行する。
create_mock();

ただ、どうしても煩雑になる。

どうやら、これを快適にやってくれるのが、Mockey 関連であるようで、 phpunit が使っているものらしい。

*1

Mockery を使ったショートカット

require をもっと便利に動的に作れたら便利だろう。それがMockeyらしい。

冒頭で出てきた、mockey のサンプルコードがそれに当たる。

<?php
// モックでスタブを作る
$mock = Mockery::mock('alias:'.MyChecker::class);
$mock->shouldReceive('is_src_exists')->andReturn(faklse);

Mockery で alias:MyClassoverload:MyClass などしたらrequire を変えていい感じにスタブができる。

ただし、php はrequireされたクラスをアンロードできないので。別の箇所でロード済みだと名前が被ってエラーになる。

Could not load mock MyChecker::class, class already exists

そこで、phpunit をprocessIsolation で動かして、テストごとにファイルロードをリセットしてから実行するようにする。

アノテーションを使ってphpunit に指示を出す。

@runTestsInSeparateProcesses@preserveGlobalState disabled を使えばいい。

<?php
use PHPUnit\Framework\TestCase
class MyFileClassTest extends TestCase {
  /**
  * @runTestsInSeparateProcesses
  * @preserveGlobalState disabled
  */
  public function test_file_move_function_raise_exception() {
    // 例外が起きることをテストする
    $this->expectException(RuntimeException::class);
    // モックでスタブを作る
    $mock = Mockery::mock('alias:'.MyChecker::class);
    $mock->shouldReceive('is_src_exists')->andReturn(faklse);
    // メソッドを呼び出すクラスをテストして、例外を送出させる。
    MyFileClass::move('/no_exists', '/tmp');
  }
}

これで無事にモック(スタブ)を使って、クラスが使ってる関数やクラスのメソッドを上書きして、テストコードを実行することができるわけだ。

phpでクラスが呼び出しているクラスの中にある関数やメソッドにダミー値を返却(スタブ)して、作ったクラスの条件判定をすべて網羅してテストしたい。

ネットワークや外部依存が増えた

現代では、プログラミングがオフラインの自己環境で解決しない時代。ネットワークや外部リソースにほぼ必ず依存する。

例えば、DNSHTTPSなど外部のコンテンツを取得する関数に固定値を返却させてテストコードが現実世界に依存しないように記述したい。たとえばDNSのAレコードを変更するツールを作っているとして、コードのテストのために、実際のDNSレコードを書き換えに行くなどは、非現実的である。別の手段として、テスト用にDNSコンテンツサーバーとDNSゾルバを組み込んだDocker環境を作り管理するとか変態的な手間がかかる。どれも正気なテスト実現方法とは言えない。考えるだけでおぞましい。だからモック(スタブ)が必要である。

動的変更は、型付や高速化と相反する

そこで、ある程度メソッドが「固定値」を返すようにスタブを作れば、テストコードのプログラミングが圧倒的に楽になるわけです。

Pythonrubyなど「ゆるい」言語は何でも書き換えられるので、メソッドを上書きしてしまえばいいわけですが。ある程度の「型付」言語はそれを許してくれないし、厳密なコードから離れてしまう。PHPでやろうとすると、クラスを動的に書き換える必要がある。しかし、PHPはそれを許してくれない。高速化の足かせになるだろうし型チェックがききづらくなる。runkitという手もあるがそれもちょっとと思える。緩さと厳密さの板挟みの痛し痒しである。

laravel の場合

laravel の場合、サービスプロバイダでインスタンスを作るという役割を上手に活用することで、モックを作ることができるのだが。

<?php

namespace Tests\Feature\Rules;

use Mockery;
use Tests\TestCase;
use Mockery\MockInterface;

class CheckSrcRuleSeperateTest extends TestCase {
  
  public function test_check_src_rule_has_enough_space(){
    $this->instance(
      MyChecker::class,
      Mockery::mock(MyChecker::class, function (MockInterface $mock) {
        $mock->shouldReceive('is_src_exists')->andReturn(true);
        $mock->shouldReceive('storage_has_enough_space')->andReturn(false);
      })
    );
    // テストコード
    $rule = ['path' => new CheckSrcFile()];
    $v = $this->app['validator']->make(['path' =>test_data('60min.mp4') ], $rule);
  }
}

ただし、「サービスプロバイダ」でインスタンスなので、staticなものをスタブすることはできない。

また、use Tests\TestCase;でテストで使ってるIlluminate\Foundation\Testing\TestCaseuse CreatesApplication している箇所があり、app()でたくさん登録している。

そういう経緯からかphpunit の processIsolation が動かない。

つまり、laravel でh static なものは、スタブ作成が不能

laravel では、static メソッドをスタブにしたテスト不可能

まとめるとこういうことになる。

スタブ作成にはMockery をつかう
-> Mockery は require を使う
-> Mockery は require のために、processIsolation が必要
-> laravel では artisan test から app()を使ってる
-> laravel では app()を使うので、processIsolation はサポート不可能
-> laravel では mock はオブジェクトに限ってサポートされている
-> mockオブジェクトは、サービスプロバイダを経由する必要がある。
-> static::method() はスタブできない。

なので、static::method()をスタブ化したテストはlaravelではかけない。

とくに、laravel 公式で「processIsolationは動かない」と書いてあって絶望するなど。

まぁめんどくさいですよね。phpの限界だろうね。

*1:mockey を使っているとrequire関連のエラーが出まくるので、requireを動的にやっていると想像した。コードは見ていません。

lua の配列のループに関するメモ

配列の定義とループ

local t = {}
table.insert(t, "a")
table.insert(t, "b")
print(t[1])
for key,entry in pairs(t) do
    print(string.format("%s=>%s", key, entry ))
end

実行結果

a
1=>a
2=>b

ポイント

  • local xで変数定義
  • 配列はテーブルで{}で定義。php の配列が近い
  • 添字は[1]から
  • for ループと pairs を一緒に使う
  • printf のかわりに、string.format

配列の添字は1から始まります。[0]ではありません。t[1] です。大事なので2回言いました。

lua しばらく使わないといつもここで詰まる。

joplinを完全にアンインストールする

OLD バージョンに戻したいとき

MacOSなら、次のフォルダを削除すれば良い。

rm -rf  ~/.config/joplin-desktop/

macOS Theme というスッキリしたテーマが動かないので、 joplin 2.3 以降ではちょっと困った。

どこのバージョンで動かなくなったか、バージョンを一つずつダウングレードを考えて、調査してたときに消せずに困った。

プラグインを使ってる系はアップデートで動かなくなるのでフリーなソフトウェアの罠ですね。

まぁAppleもアップデートでよく動かなくなるけど。

プラグインやテーマを考えると、いまのところ、v2.12.19が安定して動いてる。

apt-cacher で httpsなレポジトリ をプロキシ・キャッシュする。

apt-cacher 便利で使ってる。

以前導入したapt-cacher が便利である。

膨れ上がった複数台のRaspi4や、膨れ上がったLXCや、Dockerfileからのdocker build時に時短のために大活躍中である。

apt-cacher の問題点/HTTPS

apt-cacher は HTTPSに未対応である。TLSはProxy Connectしてしまうとキャッシュできないので。流石にこれどうしようもない問題である。

APTのレポジトリなどはAPT専用のキーで署名されてるのでHTTPSは無用だと思うのですが、chromeがHTTPを絶滅させに掛かってるので、早晩HTTPSになってしまうのであろう。

そこで、なんとかHTTPSのレポジトリ(docker や nodejs のレポジトリ)をキャッシュできないかと考えていた。

解決方法:強引にHTTPでアクセスする。

調べていると解決方法があって、そうかその手があったか。という感じだったのでメモとして残します。

apt-cacher 側でhttpsするー>クライアントにhttpsさせない

設定を確認すると、次のようになっている。

つまり、HTTPならすべて、プロキシするわけである。

cat /etc/apt-cacher-ng/acng.conf  | grep PassThroughPattern
# PassThroughPattern: private-ppa\.launchpad\.net:443$
PassThroughPattern: .* #
# PassThroughPattern: ^(bugs\.debian\.org|changelogs\.ubuntu\.com):443$

apt-cacher を通すクライアントのDebianから、httpsなレポジトリへアクセスすると、次のようになる。証明書検証エラーになってしまう。

Err:1 https://download.docker.com/linux/debian bookworm InRelease
  Invalid response from proxy: HTTP/1.1 400 Bad Request  Server: nginx/1.18.0 (Ubuntu)  Date: Tue, 10 Oct 2023 08:16:25 GMT  Content-Type: text/html  Content-Length: 166  Connection: close     [IP: 192.168.2.21 443]
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
W: Failed to fetch https://download.docker.com/linux/debian/dists/bookworm/InRelease  Invalid response from proxy: HTTP/1.1 400 Bad Request  Server: nginx/1.18.0 (Ubuntu)  Date: Tue, 10 Oct 2023 08:16:25 GMT  Content-Type: text/html  Content-Length: 166  Connection: close     [IP: 192.168.2.21 443]
W: Some index files failed to download. They have been ignored, or old ones used instead.

https -> http にダウングレードする

そこで、apt レポジトリの設定をいじってあげる。

## http にする場合(Apt-Cacherを使うとき)
sudo sed -e 's|https:|http:|' -i /etc/apt/sources.list.d/docker.list
## https にする場合
sudo sed -e 's|http:|https:|' -i /etc/apt/sources.list.d/docker.list

その結果、次のような soueces.list が出来上がる。

/etc/apt/sources.list.d/docker.list

deb [arch=arm64 signed-by=/etc/apt/keyrings/docker.gpg] http://download.docker.com/linux/ubuntu   jammy stable

この状態で、Apt-Cacherを通すと・・・

無事にキャッシュされる。

takuya@raspi-ubuntu:~$ sudo apt update
[sudo] password for takuya:
Get:1 http://download.docker.com/linux/ubuntu jammy InRelease [48.8 kB]
Hit:2 http://ports.ubuntu.com/ubuntu-ports jammy InRelease
Get:3 http://ports.ubuntu.com/ubuntu-ports jammy-updates InRelease [119 kB]
Hit:4 http://ports.ubuntu.com/ubuntu-ports jammy-backports InRelease
Get:5 http://ports.ubuntu.com/ubuntu-ports jammy-security InRelease [110 kB]

インストールも問題なく行える。

sudo apt reinstall docker-ce-cli

apt-cacher-ng へhttp でプロキシに繋いで、apt-cacher-ng プロキシ側がhttpsでデータとを取りに行って返してくれる。

debian でも試してみた.

takuya@:~$ cat /etc/apt/sources.list.d/php.list
deb [signed-by=/etc/apt/keyrings/php.gpg]  http://packages.sury.org/php/ bookworm main
takuya@:~$ cat /etc/apt/sources.list.d/nodesource.list
deb [signed-by=/etc/apt/keyrings/nodesource.gpg] http://deb.nodesource.com/node_18.x nodistro main

アップデートとインストール

takuya@:~$ sudo apt update
取得:1 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
ヒット:2 http://debian-mirror.sakura.ne.jp/debian bookworm InRelease
ヒット:3 http://deb.nodesource.com/node_18.x nodistro InRelease
ヒット:4 http://debian-mirror.sakura.ne.jp/debian bookworm-updates InRelease
ヒット:5 http://download.docker.com/linux/debian bookworm InRelease
ヒット:6 http://packages.sury.org/php bookworm InRelease
ヒット:7 http://packages.gitlab.com/gitlab/gitlab-ce/debian bookworm InRelease
ヒット:8 http://www.deb-multimedia.org bookworm InRelease
48.0 kB を 4秒 で取得しました (12.6 kB/s)
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了

特に問題なく行える。

結論

HTTP->HTTPSにリダイレクトがかかるサイトは、HTTPでアクセスすればいい。

参考資料

USBメモリブートしたRaspiは USBエラーで巻き込み死亡する

IO ERROR ですべてが喪失する。

Raspberry Pi をUSBディスクで運用している。

USBの挿し方があまいのか、USBがうまく拾えなくて、USB自体にエラーが出た。するとRaspberry自体がまともに動かなくなった。

USBディスクで運用するときの罠。

Raspberry Pi をUSBブートで起動する人は多いと思う。

microSDはすぐ壊れるし、あまり書き込み速度も望めない。

USBエラーでディスクも拾えなくなる。

USB関連にエラーがでた場合(USBデバイスの取り外し時になんか変な刺さり方したときや、壊れたディスクを試したとき)

このときに、USB-HDDにアクセス不能になり、巻き込まれて死亡する

非常にまずいと思います。

かといってmicroSDを使うのはしんどいし、NFSを使うのがベターかと思うんですが。速度がねぇ

今回、壊れたSSDをつないだからなのか。 それとも普通に駄目なのか。

このあたりの切り分けが必要だと思うんです。

もうRaspi4をすてて作業用に、PCを買った方が安いかもしれないね。

raspi4 の予備のmicroSDを用意しよう

容量を大きくしたらいいか。でも遅いんだよなぁ

microSDに戻したいが速度が違いすぎる。

SSDと速度比較したら2倍以上違うわ。

こっちが、microSD(32G / high endurance / UHS-II )

takuya@pi4-ubuntu:~$ dd if=/dev/zero of=out bs=1k count=10k conv=sync
10240+0 records in
10240+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.491372 s, 21.3 MB/s

こっちがSSD(USB nvme converter NG-2242A / TS120GMTS420S )

takuya@raspi-ubuntu:~$ dd if=/dev/zero of=out bs=1M count=1000 status=progress
915406848 bytes (915 MB, 873 MiB) copied, 5 s, 182 MB/s
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 5.89569 s, 178 MB/s

透過暗号化や、透過圧縮してこれだからなぁ

SSDはキャッシュするから、早いんですよね。

USBで運用するときは気をつけよう

RaspberryをUSB運用するときは、USBの抜き差しは細心の注意を払おう。

gitlab mattermost で急にGitlabログインできなくなった。

Bad Response from Token Request An Error has occured

gitlab mattermost で急にGitlabログインできなくなった。

シークレットキーを変えてみたけど?だめだった。 scope を追加したら行けた

なぜ、Scopeが変わったのか、ちょっとわからないけど、どこかのタイミングで要求するOAuthとOpenIDで、OpenIDの仕様に合わせて変更が入ったようだ。

いつの間にか。以下の設定が消えていた。

# before
## mattermost['gitlab_scope'] = ""
# after
mattermost['gitlab_scope'] = "read_user"

クライアント側でなく、Gitlab側のスコープが足りないだけだった。

ubuntu の ip コマンドで、v6アドレスをdhcp取得する

ubuntu の ip コマンドで、v6アドレスを取得する

v4 と同じ感じに、dhclient を使おうとすると

sudo dhclient -6 -d eth1

リンクローカルアドレス( no link local addr )がないと言われる。

Internet Systems Consortium DHCP Client 4.4.1
Copyright 2004-2018 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

no link-local IPv6 address for eth1

If you think you have received this message due to a bug rather
than a configuration issue please read the section on submitting
bugs on either our web page at www.isc.org or in the README file
before submitting a bug.  These pages explain the proper
process and the information we find helpful for debugging.

exiting.

そりゃそーだ、、って無くてもなんとかなるはずなんだけど。やってくれないようです。

いちどリセットしておいて

sudo ip  link set eth1 down   
sudo ip addr flush dev eth1
sudo ip  link set eth1 up

v6 アドレスを取得に行く

sudo ip link set eth1 down
sudo ip link set eth1 up

もしかしたら -6 をつけたほうが良かった?

sudo ip -6 link set eth1 up

うーん、よくわからない。Router探索が走るタイミングはどこのコマンドだ。

laravel (jetstream + livewire) を 9->10 に手動でアプグレ・アップデート

laravel (jetstream + livewire) を 9->10 にアップデート

componser.json の書き換え

     "require": {
-        "php": "^8.0.2",
+        "php": "^8.1",
         "guzzlehttp/guzzle": "^7.2",
-        "laravel/framework": "^9.19",
-        "laravel/jetstream": "^2.12",
-        "laravel/sanctum": "^3.0",
-        "laravel/tinker": "^2.7",
-        "livewire/livewire": "^2.5",
+        "laravel/framework": "^10",
+        "laravel/jetstream": "^4.0",
+        "laravel/sanctum": "^3.3",
+        "laravel/tinker": "^2.8",
+        "livewire/livewire": "^3.0",
         "socialiteproviders/gitlab": "^4.1"
     },
     "require-dev": {
         "barryvdh/laravel-ide-helper": "^2.12",
         "fakerphp/faker": "^1.9.1",
         "laravel/pint": "^1.0",
-        "laravel/sail": "^1.0.1",
+        "laravel/sail": "^1.25",
         "mockery/mockery": "^1.4.4",
-        "nunomaduro/collision": "^6.1",
-        "phpunit/phpunit": "^9.5.10",
-        "spatie/laravel-ignition": "^1.0"
+        "nunomaduro/collision": "^7.9",
+        "phpunit/phpunit": "^10.4",
+        "spatie/laravel-ignition": "^2.3"
     },     },

書き換え方法としては、一旦、要求されるバージョンを調べて、そのメジャー・バージョンにしておいて。適当な数字をはめてこんでいく。

"require": {
    "php": "^8.1",
    "guzzlehttp/guzzle": "^7",
    "laravel/framework": "^10",
    "laravel/jetstream": "^4.0",
    "laravel/sanctum": "^3",
    "laravel/tinker": "^2",
    "livewire/livewire": "^3",
    "socialiteproviders/gitlab": "^4"
},

インストールしてみて。

composer update

メインとなる、"laravel/framework" を追加して

composer require "laravel/framework"

パッケージを追加していく。

composer require "livewire/livewire" "laravel/tinker"

すると、具体的なマイナーバージョンが決まってくれる。

"livewire/livewire": "^3.0",
"laravel/tinker": "^2.8",

resource の書き換え <x-jet-label><x-larbel>に変わってた。プレフィックスが変更になっていた。 もしかしたら、明示的にプリフィクスを追加するオプションが追加されたのかもしれない。

sed -s 's|x-jet-|x-|g' -i resources/view/*.php
sed -s 's|x-jet-|x-|g' -i resources/view/*/*.php
sed -s 's|x-jet-|x-|g' -i resources/view/*/*/*.php

livewireのアプリケーションの配置を変更

livewire がapp/Livewire/に変わってた。こちらももしかしたらインストール時にオプションで変更できたかもしれない。

- app/Http/Livewire/MyApp/myEdit.php 
+ app/Livewire/MyApp/myEdit.php 

このあたりは、まとめて変更できる。

php artisan livewire:upgrade

問題点

jetstream の SAVE ボタンなど (x-button) の挙動がおかしくなった。

wireguard の起動と削除

wireguard の起動と削除

wireguardを指定して起動したい

wg quick のようなスクリプトが提供されてない環境では、明示的にリンクをUp/Downする必要がある

wg は起動スクリプトでしかなく、Wiregudardはカーネルモジュールであり、リンクとして動作してる。そのため、リンクのアップダウンで対応する。

設定と起動

WG_IF=wg0
WG_LOCAL_IPv4=172.16.1.1/24
WG_LOCAL_IPv6=fc02:1234:e801:b00b::1/64
ip link add dev $WG_IF type wireguard
ip addr add $WG_LOCAL_IPv4 dev $WG_IF
ip addr add $WG_LOCAL_IPv6 dev $WG_IF
ip link set mtu 1420 up dev $WG_IF

起動と終了

ip link set wg0 down
ip link set wg0 up

削除

ip link set wg0 down
ip link delete dev wg0

Windowsで文字コード表を出す

文字コード表から文字を選びたい。

Windowsでも「文字の一覧」から「文字を探し」、Unicode文字コードを確認したり、探した文字を入力したい。文字の一覧辛さがしてみたい。

いい方法が分からなかったので、プログラムから検索して出す方法を使うことにした。

いまはGoogle検索で出てくるので、本当に必要かと訊かれると、多分要らない。でも無いと困る。

参考URL

https://paso-kake.com/it/windows10/7521/

chromeからwindows でアプリが開かれるときの設定を追いかけてみる。

Chromeからwindows でアプリが開かれるとき

ChromeからWindowsのアプリが起動するが、アレってどうなってんだろう。

リクエストとレスポンスを追いかけてみる。

Fb Messenger が開かれるときは次のようになっていた。

要は、プロトコルハンドラーっぽい。

だったら、プロトコル・ハンドラーを調べ見てみる。

どうやら、プロトコルハンドラをレジストリに登録すれば、ChromeからWindowsアプリを開くリンクを作れることがわかる。

vlc をハンドラ登録してみて試す。

VLCをハンドラとして登録するには、次の参考URLがあった。

https://gist.github.com/aykxt/1aff15ba794061b8b4dc47e5aa1175e6

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\vlc]
@="URL:VLC Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\vlc\DefaultIcon]
@="C:\\Program Files\\VideoLAN\\VLC\\vlc.exe,0"

[HKEY_CLASSES_ROOT\vlc\shell]

[HKEY_CLASSES_ROOT\vlc\shell\open]

[HKEY_CLASSES_ROOT\vlc\shell\open\command]
@="cmd /V:ON /c set url=%1 && call set url=%%url:~6%% && start \"\" \"C:\\Program Files\\VideoLAN\\VLC\\vlc.exe\" --open !url!"

なるほど、WindowsでもiOSみたいにアプリを立ち上げて続きはアプリって出来るんだね。

windows で mplayer を使う

windowsmplayer を使う

C:/Users/takuya/AppData/Roaming/PulseAudio/bin/pulseaudio.exe
mplayer  -vo x11 -ao pulse sample.m4a

https://forums.fedoraforum.org/showthread.php?255217-MPlayer-interrupted-by-signal-11-in-module-decode_video

STDOUTでつなぐだけでいいのだから

y◯-dlp 'https://radiko.jp/#!/live/ABC' -o - | ffplay -nodisp -loglevel quiet -

拍子抜けするくらい簡単になってる。

これならCATT使う必要がないと思う

CATTでこんな感じに指定こそ出来るが。残念ながらm3u8に認証が挟まる場合は使えない。

pipenv shell
pipenv install catt
catt -d 'Office Speaker' cast 'https://radiko.jp/#!/live/JOBK'    

mplayer やCATTでRadikoを垂れ流せないかと思ったけど、意外とめんどくさそうだ。

debian multimedia を有効にする

debian multimedia を有効にする

mp4tagsをインストールしようとおもったら、見当たらなかったので。multimediaから拾うことにした。 マルチメディア関連だし、https://www.deb-multimedia.org を使えばいいと思ったので。

apt-keyを入れて

wget https://www.deb-multimedia.org/pool/main/d/deb-multimedia-keyring/deb-multimedia-keyring_2016.8.1_all.deb
sudo dpkg -i deb-multimedia-keyring_2016.8.1_all.deb

apt source を有効にして

echo deb https://www.deb-multimedia.org $(lsb_release -sc) main non-free \
| tee /etc/apt/sources.list.d/debian-mutltimedia.list

更新して

apt update 

インストール

apt install mp4v2-utils

OPNSense のCronジョブを定義する

OPNSense のジョブを定義する

Cron で選択できるジョブを定義したい。

以下の記事を参考にした。

ポイント

ポイントはactions.dフォルダを使う。

/usr/local/opnsense/service/conf/actions.d/

ただし、この内部はOSアップデートやディスクのSync前に再起動で消える可能性がある。

プラグインの場合

プラグインで提供されているdamonなら、次のコマンドを登録すればいい。

pluginctl -s snmpd restart
pluginctl -s dhcpd restart

スクリプトを作って登録。

実行するスクリプトを作る /home/takuya/scripts/radiko-area.sh

#!/usr/bin/env bash

## PPPoE接続後に、 radiko エリアを修正する
## 2021-01-26

DEBUG=0

function radiko_area_kansai(){

  [[ $DEBUG == 1 ]] &&  >&2 echo '--------- check radiko ---'
  if curl -s  https://radiko.jp/area | grep -oE 'JP2[6-9]' ; then
     echo kansai
     [[ $DEBUG == 1 ]] &&  >&2 echo kansai
    return 0
  else
   [[ $DEBUG == 1 ]] &&  >&2 echo not kansai
   [[ $DEBUG == 1 ]] &&  >&2 curl -s  https://radiko.jp/area
   request_radiko_area_correction
   return 1
  fi
}
function request_radiko_area_correction(){

  [[ $DEBUG == 1 ]] && >&2 echo radikoエリア変更リクエスト
  curl -s 'https://radiko.jp/contact3' \
    -X POST \
    --data-raw \
     'confirm=1&email=dummy%40dummy.com&area_judge_result=福岡県&prefecture=兵庫県&area_id=JP28+HYOGO+JAPAN' > /dev/null

}

## main
function main(){
    radiko_area_kansai 2>&1 1> /dev/null;
}


main

スクリプトを動作テスト

chmod +x /home/takuya/scripts/radiko-area.sh
/home/takuya/scripts/radiko-area.sh

スクリプトを登録する

ファイル名には規則がある。

/usr/local/opnsense/service/conf/actions.d/actions_${NAME}.conf

スクリプトの名前の規則はあるんだけど、直接書き込むと消される事がある。正確には仮想マシンの再起時にSyncされる前だったり。このへんは正しい対応法がわからない。

今回は次のようにした。

mkdir /home/takuya/scripts/service/
cd  /home/takuya/scripts/service/
touch actions_radiko-area.conf
ln -sr /home/takuya/scripts/service/actions_radiko-area.conf \
  /usr/local/opnsense/service/conf/actions.d/actions_radiko-area.conf

ジョブの定義

/usr/local/opnsense/service/conf/actions.d/actions_radiko-area.conf

[reload]
command:/usr/local/bin/flock -n -E 0 -o /tmp/radiko_updater.lock /home/takuya/scripts/radiko-area.sh
parameter:
type:script_output
message:Radiko Area Update
description: Radiko area corrention request

作った登録を有効にする。

sudo service configd restart

起動テストする

configctl radiko-area reload

ジョブにでてくる

追記

数週間後に、ファームウェアのアップデートで消えてしまう

ファームウェアのアップデートで消えてしまう事があるので、リモートでAPIで叩いたほうが良いかもしれない。

OPNSense の SNMP がよく止まる。

OPNSense の SNMP がよく止まる。

OPNSense のSNMPがなぜか止まって、Zabbixがエラーログを履きまくるんで、定期的に再起動することにする。

サービスの再起動の方法

SSH からなら

ssh opnsense.local 'pluginctl -s snmpd restart'

API からなら

  key=xxxxxxxmM8IEUv
  secret=xxxxxxxSv16
  OPNSenseAddr=192.168.x.x
  URL="https://${OPNSenseAddr}/api/core/service/start/snmpd"
  curl \
    --silent \
    --basic \
    --user "$key:$secret" \
    --insecure \
    $URL

内部のCronで自動再起動

外部から接続して再起動もなんだかんだ面倒なので。OPNSense自身のcronで再起動させることにする。

sudo touch /usr/local/opnsense/service/conf/actions.d/actions_snmp-service.conf
sudo vim /usr/local/opnsense/service/conf/actions.d/actions_snmp-service.conf

/usr/local/opnsense/service/conf/actions.d/actions_snmp-service.conf

[reload]
command:/usr/local/sbin/pluginctl -s snmpd restart
parameter:
type:script_output
message:SNMP restart
description: SNMP restart.

作った登録を有効にする。

sudo service configd restart

起動テストする

sudo configctl actions_snmp-service reload