ほりひログ

所属組織の製品 (Azure とか) に関連する内容が多めだけど、個人の見解であって、所属組織を代表する公式情報ではないです。

Text Blurrerを更新した

まずは近況。

訳あって5月いっぱいは暇してる予定。
面白そうなことがあれば出向くので、お誘いください。

本題

閑話休題

こちらのQiitaの記事に拡張機能を載せてもらった。

qiita.com

そのおかげで順調にユーザー数が増えている。
ありがたいことです。

Text Blurrer
Azure Portal Plus

そんなユーザーが増えている中、Text Blurrerのコードを割と大きく修正した。

きっかけはインライン要素のホワイトスペース処理の不具合。
これを直そうとしたらなかなか厄介で、今までの実装を修正する形では対応しきれなかったので、抜本的にコードを修正した。

ついでに正規表現の先読みアサーション(後読みアサーション)を使ったボカシもできるようにした。

正規表現アサーションについてはコチラ。 developer.mozilla.org

これまでのバージョンだと、設定のUIからアサーションを使った正規表現自体を入れることができなかった。
もっとも設定できたとしてもボカシの処理ロジックとして、アサーションに対応してなかった*1

今回バージョンアップでこのアサーションも処理できるようにした。
これを使うと、例えば下のスクショのように、"API_KEY="に続く文字列をボカすことができる。


以下、余談。

今更ながら、上のスクショのようにvscode.devgithub.devGitHub Codespacesでもこの拡張機能が動くことに気づいた。
これらもWebブラウザーで動いているので、当たり前と言えば当たり前なんだけど。
これでプロジェクトを開くとプロジェクト内の設定ファイルの中に見せたくない文字列があっても、それをボカすことができる。

ただGitHub Codespacesのターミナル内のテキスト、コマンドの出力結果はボカせないので、使う時は要注意*2

これらのサイトもVSCodeも同じMonacoベースのはずなので、VSCode拡張機能として仕立てられないか考えたけど、CSSのfilterをいじるAPIが見つからないので難しそう。


その他の追加

いくつか機能を追加したけど、正直なところ全部自分が開発/デバッグしている中であると欲しくなった機能。
なので自分以外の需要がないかもしれない。

除外URLパターンリスト

拡張機能を適用しないURLパターンを設定できるようにした。

コンテキストメニュー

Webページ内の選択キーワードを直接追加する。

ショートカットキー

Popupウィンドウにショートカットキーを付けてみた。
とりあえず2つ。

  1. Ctrl / + s: 「apply」ボタンを押すのと同じ。
  2. Shift + Alt + f: テキストエリアのフォーマッティング(空白行を消すだけ)

以上がText Blurrerの不具合修正/機能追加の詳細。

上に書いた通り、結構なコード変更があったので、今まで動いていたものが動かなくなる不具合が入った可能性もあるので、見つけたら issue あげてほしい。
https://github.com/horihiro/TextBlurrer-ChromeExtension/issues/new
その時に、うまく動かないサイトのURLとぼかしたいキーワードをセットでもらえると調査が捗る。

*1:そもそも根本的な問題は、自分がアサーション自体を全然わかってなかったこと

*2:ターミナル部分はxterm.js(https://github.com/xtermjs/xterm.js/)で作られていて、Canvasにテキストを描いているので、どういうテキストが書かれているのか外部からチェックするのが難しい

Azure Cloud Shellのシェルを決め打ちで起動するリンク

Azure Cloud Shellのシェル

Azure Cloud ShellではBashPowerShellがシェルとして使えて、シェルの切り替えはブラウザー内のUIからできる。

で、Xでこういうポストを見かけたので、どう切り替えているのか見てみた*1

BashPowerShell、どっちのシェルを起動するかはux.console.azure.comドメインのセッションストレージにあるconsoleShellTypeというものの値次第っぽい。
この値がpwshならPowerShellbashならBashが起動する。

リンクを開く時にセッションストレージの中を操作するのは無理だと思うので、他の方法としてクエリーパラメータからこいつをいじれないか調べてみた。
すると、feature.azureconsole.ostypeというクエリーパラメータを使って間接的にセッションストレージ内のconsoleShellTypeがいじれることがわかった。

それぞれのシェルでCloud Shellを起動するリンクがこちら。

Bashで起動するリンク

https://portal.azure.com/?feature.azureconsole.ostype=linux#cloudshell

PowerShellで起動するリンク

https://portal.azure.com/?feature.azureconsole.ostype=windows#cloudshell

ちなみに、これらのリンクは https://portal.azure.com になっていて、きっかけのポストにあったリンク https://shell.azure.com とはドメインが違う。

Cloud Shellの実体は https://poral.azure.com/#cloudshell の方で、https://shell.azure.com にアクセスした時は https://portal.azure.com/#cloudshell/ にリダイレクトされてCloud Shellが開いている。

shell.azure.comの方がURLがわずかに短いので、こっちでもクエリーパラメータが効かないか試してみた。

けど、ダメだった。
リダイレクトされるときのリクエスト/レスポンスを見てみると、レスポンスの Location ヘッダーにクエリーパラメータが引き継がれていないことがわかる。

なので無理っぽい。残念。

*1:Azure PortalJavascriptコードは難読化されてないので、こういうことがしやすい

Text Blurrerでタイトルバーの中も隠してみた

人知れず書いた一つ前のエントリーでText Blurrerではアドレスバーの中の文字はボカせないことを書いた。

uncaughtexception.hatenablog.com

だけど、よく考えたらタイトルバーの中もボカせてないことに後から気づいた。
不特定多数への画面共有の時とかは、いろいろ見ている目ざとい人がいるかもしれないので、タイトルバーから見られたくない文字列が漏れる、なんてこともあるかもしれない。

なので、念には念を入れる人向けに実験的に実装してみた。

使い方は、新しく設置した「Blur title of tabs」ボタンを有効にするだけ。

例えばタブのタイトル Example Domain が、

******* Domainみたいに、隠したいキーワードを * に置き換える。

なので厳密には blur せず mask するだけ。
<title> タグの中は装飾できなそうなので割り切った。

v0.1.9から使えるので、試したい方は手動更新を。

Microsoft Edgeでアドレスバーにホスト名だけ表示する

超小ネタを。

おかげさまで一部の方にはText Blurrerが好評の様で、自分が参加したイベントでも発表者に使ってもらえてた。
ありがたいことです。

chromewebstore.google.com

ただ所詮ブラウザー拡張なのでサイト内の文字列以外はボカせない。
そのイベントでも「アドレスバーに出る情報は隠せない」と指摘されてた。

例えばAzureポータルを開いてみると、アドレスバーに表示されるURLに割と見られたくない情報、テナント名とかサブスクリプションIDとかが含まれている。

Azureポータルに限らず他のサイトでも見られちゃまずい情報がURLに含まれているかもしれない。

なので、Microsoft Edgeでアドレスバーを非表示にする方法がないか調べてみたら、

  • 「F11を押して全画面表示にする」*1とか
  • 「起動オプションをいじってサイトを”アプリ”として起動する」*2

という方法は見つけられた。

他のウィンドウと頻繁に切り替える必要がなければ全画面表示でいいし、URLを隠したいサイトが決まっているなら"アプリ"として起動もいいと思う。

ただ会議中の画面共有とかだと他のウィンドウに切り替えたりすることがあるかもしれないし、見せる可能性があるサイトを全て事前にアプリ化することは難しいかもしれない。

そんな時に、たまたま見つけたのがMicrosoft Edgeの分割ウィンドウ機能。
元々は一つのタブを左右に分割して、それぞれで別のURLを開いておける機能だけど、タブ自体は一つなのでアドレスバーも一つしかない。
しかもそれぞれの分割領域で開いているサイトのURLが、ホスト名しか表示されないことに気づいた。

これを使って、上と同じAzureポータルを開いた状態がこちら。
左側でAzureポータルを開いて、右側は分割直後の初期画面状態で、左側を目一杯広く取るように分割している。

アドレスバーを比較してみると、分割後はホスト名しか表示されないので、分割前だとURLに含まれる見られたくない情報を見せずに済む。

右側の分割領域が活用できず、若干画面が狭くなるけど、URLを見せたくないことを優先するなら、まぁ我慢できるんじゃないだろうか。

そんな小ネタでした。

ALL Microsoft Applied Skills are earned!

タイトルの通り、公開されている1419個のMicrosoft Appied Skillsを全部獲った。

Earned 14 19 Applied Skills


(2024/01/30 追加分ここから)

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

(2024/01/30 追加分ここまで)


learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

learn.microsoft.com

Microsoft Applied Skills

シナリオベースの資格で、特定の製品/サービスの設定/運用に関するスキルを評価するもの。

techcommunity.microsoft.com

learn.microsoft.com

最初は8個だったらしいけど、2024年1月末現在は1419個。
Azure、Power Platform、データベースマイグレーション、セキュリティといろんなシナリオがある。

OpenAIやContainer Apps、Teamsアプリも追加された。

どのAppied Skillも同じ流れで、

  1. ブラウザー内で評価ラボを立ち上げて、
  2. 架空のCTOからのメール、
    「今は○○な状況。それを××な状況にしてほしい」
    みたいな実施内容を理解して、
  3. メールの通りにAzureポータル等から設定して
  4. 終わったら提出

とやると、その実施結果が適切かどうかを評価してくれる。

認定試験との違いはFAQを参照のこと。

learn.microsoft.com

最初は割と得意なエリアなWeb Appとかネットワークとかをやって、あとは放置気味だった。

けどその後「どうせ今ならタダだから&ドキュメント見放題だし」と馴染みのない分野もチャレンジ。
当然一発合格じゃないものもあるし、意外とPower Appsを知らないことを実感。

ただどのシナリオでも、メールに記載されたやらないといけないことをドキュメントから探し出せれば割とすんなりいける。

気になるところ

評価ラボが狭い。
ヘッダーとフッター(上下の赤枠部分)は完全にいらない。

この狭いエリアの中でブラウザーを使ってポータル等を開いて作業をする。

実はブラウザーでの作業自体は、ローカルPCのブラウザーで直接開いてもできる。
けどそれをやるとスコア付けされる保証がないっぽい。

learn.microsoft.com

仮想マシンではなく、お使いのマシンでポータルを開いた場合、作業内容をスコア付けすることはできません。

なので、「せめて評価ラボエリアを広く」と、それ用のUserstyleを作った。

userstyles.world

Stylusというスタイルシートをいじる拡張機能をから入れられるので興味があれば。

chromewebstore.google.com

結果はこの通り。すっきり。

上下のヘッダーとフッターを非表示(display: none)にしているだけど、評価ラボエリアが広くなる。
少しだけ作業が楽になる。

あと稀に評価ラボ自体が立ち上がっても、接続できていないことが多い。
その時は根気よくリロードを試すと復活することが多い。

自分はリロードよりも開きなおすことが多かった。
その為には元ページの「開始」ボタンをアクティブなままにしておけるよう、評価ラボのページを別タブで開いていた(CtrlかShiftを押しながら「開始」ボタンをクリック)。

これはもっと稀だけど、一回だけ課題のメールが文字化けしたことがあった。
これはもう運ゲー

一度落ちたApplied Skillで遭遇して、初回は文字化けしておらず内容はだいたいわかっていたので内容はわかっていたけど、それ以降、英語で表示するようにしている。

ちなみに、一度受かってもスコアに納得できない場合は72時間開ければ再チャレンジできる。

今ならタダなので、慣れ親しんだサービスの力試しでもいいし、馴染みのないサービスを触るチャンスとしてでも試してみては。

面倒なキャパシティ制限はAzure Policyで解決!Azure OpenAI Service #便利なAzure #キャパシティ制限

# タイトルはAIタイトルアシストに作ってもらったSNS向けなもの。

今年の〆は、だいぶ久しく触ってなかったAzure Policy。

Azure OpenAI Serviceでモデルをデプロイする時に、キャパシティの値が指定の値を超えていたらブロックする。

ポリシー定義

{
  "mode": "All",
  "policyRule": {
    "if": {
      "allOf": [
        {
          "field": "type",
          "equals": "Microsoft.CognitiveServices/accounts/deployments"
        },
        {
          "field": "Microsoft.CognitiveServices/accounts/deployments/model.format",
          "equals": "OpenAI"
        },
        {
          "anyOf": [
            {
              "field": "Microsoft.CognitiveServices/accounts/deployments/model.name",
              "in": "[parameters('modelNames')]"
            },
            {
              "value": "[length(parameters('modelNames'))]",
              "equals": 0
            }
          ]
        },
        {
          "field": "Microsoft.CognitiveServices/accounts/deployments/sku.capacity",
          "greater": "[parameters('capacityLimit')]"
        }
      ]
    },
    "then": {
      "effect": "deny"
    }
  },
  "parameters": {
    "capacityLimit": {
      "type": "Integer",
      "metadata": {
        "displayName": "Capacity Limit",
        "description": "The allowed capacity for the deployment."
      }
    },
    "modelNames": {
      "type": "Array",
      "metadata": {
        "displayName": "Model names",
        "description": "The target model names"
      },
      "defaultValue": []
    }
  }
}

モデルのデプロイメント Microsoft.CognitiveServices/accounts/deployments について、sku.capacityの値を指定の値(上限値)と比べているだけ。
あとmodel.formatでAOAIに限定している。

一応、指定したモデルのデプロイだけキャパシティ制限する、といった工夫は入れてみた。
パラメータmodelNames["gpt-4", "gpt-35-turbo"]みたいにモデルを指定すると、そのモデルのデプロイメント model.name が指定のモデルに含まれているかをチェックする。
限定しなければ(パラメータmodelNamesの長さが0なら)全デプロイメントのキャパシティをチェックする。

何に使うのか。

ハンズオンとかでAzure OpenAI Serviceをプロビジョニングできるサブスクリプションを複数の利用者にシェアする時に*1、各々の利用者が同じリージョンにキャパシティ好き放題でモデルをデプロイしてしまうと、他の人がデプロイできない、みたいな悪影響が出かねない。
そうすると利用者ごとにリージョンを振り分けたり、とかするけど、でも結局一人で全部使い切る輩がいるとまた別リージョンに、、、と面倒*2

そんな時にAzure Policy。
モデルデプロイ時のキャパシティに上限を設定してやることで、好き放題なモデルデプロイをブロックできる。
当然ながら、デプロイした後のキャパシティ変更でも、上限を超えていればブロックする。

Azure Policyのつらみ(愚痴)

便利だしやってても面白いんだけどさぁ。

30分、て。
試しに定義を作って、アサインして動作見て、アサイン取り消して定義を修正して、、、の作業が捗らない。

*1:それが多いシーンなのかはさておき。なくはない。

*2:まぁ1人1リージョンで割り当てればできるだろうけど、あまりやりたくはない。

Visual Studio CodeでChrome Extensionをデバッグする

俺的 Chrome Extension ブーム。

まだChrome Extensionが自分の中で熱いうちにもう一つ作って公開してみた。

といっても、新しいアイデアが思いついた訳ではなく、昔Userscriptとして作った以下二つの機能をがっちゃんこ()して、一つのChrome Extensionに焼きなおしたもの。

uncaughtexception.hatenablog.com

uncaughtexception.hatenablog.com

個人的には、Faviconを変えたり点滅させたりするのがお気に入りだけど、公開後の反応を見る限り、デスクトップ通知の方が人気の様子。

ただ、Userscriptからの移植で一番仕組みを変えたのがデスクトップ通知だったので、頑張った甲斐はあった。

という訳で、インストールしてください。星、待ってます。

chrome.google.com

と、ここまでが

Extension作りがひと段落した時に書いて公開し忘れてた内容。

完全にタイミングを逃したので、ネタを追加。

開発中の悩み

Chrome Extensionを作ってて思ったこと。

Chrome Extensionにはcontent script/popup/service workerの3種類のスクリプトが入ってて、VSCodeがない世界では開発者ツールだけ頑張るので、ブレイクポイントとか変数チェックしようとすると、見た目同じウィンドウがいくつか立ち上がる。

すると、いちいち

これは、、、どのスクリプトのウィンドウだ???

となって、割と大変だった。

せっかくVSCodeでコードを書いてたのだから、デバッグくらいできるに違いない、と調べた結果をまとめた。

前準備

まず.vscode/launch.jsonを作る。

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Debug on Chrome",
      "port": 9222,
      "runtimeArgs": [
        "--load-extension=${workspaceFolder}"
      ],
    }
  ]
}

内容はChromeの起動。
ほぼVSCodeが作るテンプレのまんま。

追加したのは、--load-extension オプションで manifest.json があるディレクトリを選ぶくらい。
プロジェクトルートに置いているなら --load-extension=${workspaceFolder} でよし。

いざデバッグ

デバッグの開始は通常通りF5キーで。

ここから、1つのVSCodeウィンドウで、content script/popup/service workerの3種類のスクリプトデバッグする。

content script/popupのデバッグ

といっても、content scriptとpopupのスクリプトは、特に何もすることなく、VSCodeからChromeのプロセスにアタッチできる。
ブレイクポイントを置けば、そこで処理はポーズしてくれるし、変数の確認も簡単。

ちなみにpopupを開くと勝手にpopup用の開発者ツールが立ち上がる。
けどpopupのデバッグだけなら閉じてもオーケー。

問題は次のservice worker。

service workerのデバッグ

service workerの場合、content scriptやpopupの時はできていた、コード内のブレイクポイントが有効化ができず、ポーズや変数確認ができない。

一方、chrome://extensions からservice worker用の開発者ツールを開けば、開発者ツール内で開いたソースに置いたブレイクポイントでポーズしたり変数確認はできるが、その場合、

の3つのウィンドウを見ることになる。

まぁ、3つくらいならましなのかもしれない。

それでも、、、!

「どうしてもデバッグVSCodeだけでやりたい!」という強い想いがあるなら、以下の手順をやると デバッグVSCodeにまとめられる。

このデバッグのやり方を見つけるのが難しかった。
それでも割と煩雑な方法。

  1. まずVSCodeF5キーでデバッグを開始
    この時点で、content script/popupのデバッグはできる

  2. Chromeが立ち上がったら、Ctrl + nとかで、もう1枚ウィンドウを作り chrome://extensions を開く。
    手順 1. のデバッグ開始で立ち上がった方を window1、ここで手動で作ったウィンドウを window2 としておく。

  3. window2 でservice workerが inactive(または無効) になっていることを確認する。

    なっていない場合、大抵は30秒ほど放置すると自動的に inactive になる(という、Chrome Extensionの仕様?バグ?)。

  4. window2拡張機能アイコンをクリックして、popupを表示する。
    この時、開発者ツールが勝手に立ち上がるが、この後使うのでまだ閉じない。

  5. 立ち上がった (popup用の) 開発者ツールの Application タブを開き、service workerについての情報が出ているか確認する。

  6. Status 欄にある start をクリックする。

    ここまで来たら、手順 4. で開いた開発者ツールは閉じていい。
    けど、popupは閉じちゃダメ。絶対に!

以上の手順でVSCodeがservice workerにアタッチして、デバッグができるようになる。

VSCodeCALL STACK には、popupの下にservice workerがぶら下がっているのがわかる。

こっちの方法でVSCodeChrome Extensionにアタッチすると、VSCodeデバッグを集約できるので、デバッグ作業中に操作するウィンドウは

の2つだけになって、割とスッキリしたんじゃないだろうか。

左下にpopup表示用Chrome(window2)もあるけど、こっちはデバッグ中は操作する必要ないのでノーカウント。

留意点として、手順 4. で window2 で開いたpopupをうかつに操作してpopupが閉じてしまう*1と、VSCodeとservice workerの接続が切れるので、デバッグ中は触らない方がいい。

他のウィンドウを操作する分にはpopupは閉じない。
上の手順では、手順 2. でpopup表示用と動作確認用の2つのウィンドウを分けたので、popupのスクリプトデバッグwindow1 でできる。
邪魔だと思うなら、他のウィンドウの裏に置いて隠せばいい。

もしpopupを閉じてしまい接続が切れてしまったら、手順 3. からやり直すと再接続ができる。

残る謎と課題

なぜservice workerを、popupの開発者ツールから起動することが、service workerへのアタッチにつながるのかは、実は全く理解してない。

あとpopupがないChrome Extensionだとこの方法が使えないかもしれない。
開発中はダミーのpopupが必要。

正直なところ、これが正規の方法かはわからないし、どちらも一長一短あるので、デバッグ準備とデバッグ作業中のどっちを楽にしたいか、選べばいいと思う。

あと、この知見が活かせる次のネタがまだないのが大きな課題。

*1:ウィンドウの最少化操作でもpopupが閉じちゃう