Xbox Wireless Headset を強制的に再起動させる方法
普段使っている Xbox Wireless Headset がうんともすんとも言わなくなったので、対処した時の方法を備忘録に残します。
ハードウェア
- Xbox Wireless Headset - Starfield Limited Edition
どんな症状が発生したのか
- 電源が入らない
- 充電ケーブルを指してもランプが点灯しない
試したこと
- 適当な充電器に接続してみる(Anker の充電器をいくつか)
- Xbox Series X 本体に接続する
解決策
- ヘッドセット本体に USB ケーブルを接続する(この時、反対側はなにも繋がない)
- 電源ボタンとマイクボタンを同時押しする
- 同時押ししながら、USB ケーブルのもう片方を充電器に接続する
これで、ヘッドセットが強制的にリブートします
まとめ
コントローラといいヘッドセットといい、高い割にすぐ調子悪くなるのは何故なのか
Azure Functions の Http Trigger でモデルバインディングに失敗するとレスポンスが返ってこない問題
Azure Functions Isolted Worker で、ASP.NET Core Integration を設定していると、コード内で例外が発生した場合にレスポンスが返ってこないことがあったので、備忘録を残します。
何が起きるのか
- コード内で未処理の例外が発生すると、レスポンスが返ってこず、クライアントがタイムアウトするまで待たされ続ける動きをする
内部的には、ASP.NET パイプラインがハングアップすることで、にっちもさっちもいかなくなるのが原因でした。
条件
- .NET の Function App
- ASP.NET Core Integration を設定している
- Funcrions.Worker.Extensions.Http.AspNetCore が 1.3.1 以下
修正方法
Funcrions.Worker.Extensions.Http.AspNetCore を 1.3.2 以上にアップデートします。
対応する Pull Request
まとめ
結構致命的なので、お悩みの方は早いところアップデートしましょう。
コンテナ内の SQL Server に対して Docker.DotNet を使ってデータベースをリストアする方法
コンテナ内の SQL Server でテスト用 DB を作る際、.bak ファイルからデータベースを復元したかったのでやってみました
手順
次のステップでやっていきます
- データベースを .bak でバックアップする
- bak を .tar に変換
- .tar を埋め込みリソースに設定 → ここまで割愛
- .tar ファイルをコンテナに転送して .bak に展開
- .bak を使って DB をリストア
埋め込みリソースを設定する
Visual Studio のプロパティ設定で埋め込みリソースを設定しても良いのですが、ファイルが増えてくると都度埋め込みリソースに設定するのはめんどくさいので、.csproj でまとめて埋め込みリソースに設定する記述を追加します。
<ItemGroup> <EmbeddedResource Include="{リソースフォルダのパス}\*.tar" /> </ItemGroup>
埋め込みリソースを読み込む
埋め込みリソースとして持っておけば、いろいろ取り回しが楽なので埋め込みリソースを使用します
埋め込みリソースを Stream に読み込むコードは以下のような感じです。
ファイルパスは、名前空間.フォルダ名.ファイル名 です
フォルダ名に - が入っている場合、- は使えないので、_ に置換します。(例)test-resources フォルダの場合、test_resources にする)
var resourceFullName = $"{プロジェクトの名前空間}.{フォルダ名}.{ファイル名}"; var assembly = Assembly.GetExecutingAssembly(); using (var stream = assembly.GetManifestResourceStream(resourceFullName)) { if (stream is null) throw new FileNotFoundException(resourceName); }
.tar をコンテナに転送
コンテナに .tar を転送します。
埋め込みリソースを読み込むコードを下記のように変更します。
はじめに、転送先のディレクトリをコンテナ内に作成します。
CreateContainerParameters の設定に Cmd を設定します。
var containerConfig = new CreateContainerParameters { Image = imageFullName, Env = environmentVairbales, ExposedPorts = exposedPorts, HostConfig = hostConfig, Cmd = new[] { "bash", "-c", "mkdir -p {ディレクトリパス}" } };
var resourceFullName = $"{プロジェクトの名前空間}.{フォルダ名}.{ファイル名}"; var assembly = Assembly.GetExecutingAssembly(); using (var stream = assembly.GetManifestResourceStream(resourceFullName)) { if (stream is null) throw new FileNotFoundException({ファイル名}); await _dockerClient.Containers.ExtractArchiveToContainerAsync( _containerId, new ContainerPathStatParameters { Path = "コンテナの転送先ディレクトリ" }, stream ); }
ExtractArchiveToContainerAsync を使うと、転送後に .tar を展開してくれるので、リストアは .bak を指定します。
DB をリストアする
SqlCommand でリストア用のクエリを流します
var restoreCommand = $@" RESTORE DATABASE [{データベース名}] FROM DISK = N'{.bak の転送先ディレクトリ}/{.bak ファイル名}' WITH REPLACE, MOVE '{データベース名}_Data' TO '{.mdf ファイルの展開先}', MOVE '{データベース名}_Log' TO '{.ldf ファイルの展開先}', RECOVERY; "; using(var command = new SqlCommand(restoreCommand, connection)) { await command.ExecuteNonQueryAsync(); }
まとめ
.bak から展開 DB の復元が出来ました。
これで、ユニットテスト毎にきれいなテストデータでテストを回すことが出来るようになりました。
C# だけでコンテナを立ち上げて SQL Server を動かす
表題の通り、ユニットテストとかでコンテナ化した DB を使いたかったんですけど、Dockerfile も docker-compose.yml も書きたくなかったので、 C# でのやり方をまとめます。
必要なパッケージ
今回は、以下のパッケージを使います
コードの全文
コードの解説
NUnit の StartDockerContainer を指定したメソッドでコンテナの初期化をします。
また、最後に OneTimeTearDown を指定したメソッドでコンテナを削除します。
削除をしないと、次回テスト実行時にややこしいので、必ずここで削除します。
StartDockerContainer の最初の方で、既存のコンテナが存在していないかの確認と、存在する場合は削除するコードを書いています。 これは、デバッグ実行などで中途半端に動かして、最後にコンテナを削除し忘れていると、次回実行時にややこしいことになるので、 一度チェックを入れています。
StartDockerContainer の最後でちょっと Delay を入れていますが、これはコンテナの立ち上がりを待つための措置です。(後述の SQL Server の設定でリトライを入れているので、無くても大丈夫な気もします)
InitializeDatabaseAsync で SQL Server の初期設定を行っています。 ここで重要な点は、下記のコードです。
var retryOptions = new SqlRetryLogicOption { NumberOfTries = 5, DeltaTime = TimeSpan.FromSeconds(1), MaxTimeInterval = TimeSpan.FromSeconds(20), AuthorizedSqlCondition = delegate (string query) { if (Regex.IsMatch(query, "(SELECT)")) { return true; } else { return false; } }, // 10054 : SQL Server とのコネクション確立に失敗した場合に発生するのでリトライする(SQL Server が完全に立ち上がる前にコネクションを開こうとすると発生する) // 18456 : SQL Server のログインに失敗した場合に発生するのでリトライ(10054 と同じく、立ち上がれば解消するはず) TransientErrors = new[] { 10054, 18456 } }; var retryLogicProvider = SqlConfigurableRetryFactory.CreateExponentialRetryProvider(retryOptions); retryLogicProvider.Retrying += (object? s, SqlRetryingEventArgs e) => { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} : Retrying for {e.RetryCount} times for {e.Delay.TotalMilliseconds / 1000.0:0.00} sec - Error code: {(e.Exceptions[0] as SqlException).Number} - Error msg: {e.Exceptions[0].Message}"); };
コンテナの初期化時に少しディレイを入れていますが、立ち上がり時間は毎回まちまちなので、タイミングによっては立ち上がりが間に合わずエラーになる場合があります。 なので、特定のエラーコードに対してリトライ設定を入れます。
今回は、エラーコード 10054 と 18456 に対してリトライを設定します。
10054 は、SQL Server とのコネクション確立に失敗した場合に出るエラーです。
18456 は、SQL Server のログインに失敗した場合のエラーです。
SQL Server が立ち上がる前に接続を開く → 10054 が発生
SQL Server が立ち上がったが、ログイン出来る状態になっていない → 18456 が発生
となるので、この二つをリトライすることで実行時のストレスがぐっと下がります。
まとめ
C# だけでコンテナの立ち上げからの SQL Server の接続が出来ました。
Visual Studio + C# だと、普通にコマンドを流すよりもデバッグがやりやすくて良いですね。
fatal: not a git repository のエラーでローカルリポジトリがぶっ壊れたので頑張って直した話
表題の通りです
また発生した時の為に備忘録で残します。
何が起きたのか
めちゃくちゃ乖離しているブランチにチェックアウトしたら、突然 fatal: not a git repository: sub-modules/~ のエラーで何もできなくなった
環境
やったこと
sub-module を初期化しました
- submodule を削除
git submodule deinit -f --all
- submodule のフォルダの中身を削除
.git/modules/ 以下を空にする
- submodule を再取得
git submodule deinit -f --all
- 解決
まとめ
App Service の Key Vault reference を User Assigned MSI で使う
App Service の Key Vault reference を使う際の備忘録です
何をするのか
- App Service の Key Vault reference を User Assigned Managed Id で繋ぐ
既定の動作
Key Vault reference の規定動作は、System Assigned Managed Id になります。
なので、少し手を加えないと User Assigned Managed Id が使えません。
因みに 2024年7月現在、この設定は実質ポータルから操作できません。
必要なもの
App Service に Managed Id を設定したり、Managed Id に Key Vault の権限を設定する部分は、今回は割愛します。
- Azure CLI or Azure PowerShell
今回は、Azure CLI を使用します
やってみる
早速やってみましょう
User Assigned Managed Id のリソース Id を取得する
まず、使いたい Managed Id のリソース Id を知りたいので、次のコマンドを流して取得します
az identity show -n {Your Managed Id name} -g {Your resource group name} --query id
ポータルから取得しても ok です
App Service と紐づける
az webapp update -g {Your resource group name} -n {Your Web App name} --set keyVaultReferenceIdentity={Managed Id resource id}
function app の場合は、
az functionapp update -g {Your resource group name} -n {Your Web App name} --set keyVaultReferenceIdentity={Managed Id resource id}
Bicep で紐づけたい場合は、SiteProperties > keyVaultReferenceIdentity に Managed Id のリソース Id を指定します
既定の動作に戻したい
戻す場合は次のようにします
az webapp update -g {Your resource group name} -n {Your Web App name} --set keyVaultReferenceIdentity=SystemAssigned
function app の場合は、
az functionapp update -g {Your resource group name} -n {Your Web App name} --set keyVaultReferenceIdentity=SystemAssigned
余談
ポータルの Key Vault reference のブレードを開くと、User assigned でも System Assigned でも、System assigned managed identity と表示されて分かりづらいですが、 指定した Managed Id で繋がっているはずです
まとめ
ポータルからポチポチ出来ないのでちょっとした検証には不便ですが、これにて一件落着
Microsoft MVP for Microsoft Azure を受賞しました。
今年も Microsoft MVP を受賞させていただきました
2016年から足掛け9年になりました(審査スキップが入っているので受賞は8回)
昨年は、子供が生まれてバタバタしていたこともあり大した事が出来ませんでしたが、 今年はまた細々と活動していければと思います
子供がまだ小さいので、リアル勉強会はあと数年お預けですが、 どこかで見かけたらよろしくお願いします
今年も一年よろしくお願いします