こんにちは。サイオステクノロジーの塙です。 今回はKubernetes をベースとしたプラットフォームでGPUを扱っていくための手法について解説してみます。 概要 直近では特にAIや機械学習(ML)に関する話題が増え、これらの分野を活用したソリューションの実現を図る組織も多いのではないでしょうか。 これらの分野の計算リソースのためには、GPUが必要となってきます。 そして、GPUリソースを効率的に使用するために、Kubernetes と組み合わせてGPUを管理し、コストの削減と効率化が期待出来ます。 コンテナ環境を利用することで、機械学習(ML)のための複雑な環境を何度も同じようにセットアップすることができる kubernets のスケジューリングにより、リソースの利用率の効率化をすることができる では、KubernetesでGPUを扱うためにはどんな準備が必要となるのかを説明していきます。 KubernetesでのGPUの使用 Kubernetes でのGPUスケジューリング*1 を有効にするためには、デバイスプラグインを使用します。 デバイスプラグインは、特定のハードウェアのリソースを管理するためのgRPCサービスとなります。Kubelet がデバイスプラグインと連携することでGPUをコンテナに割り当てることが可能になります。 デバイスプラグインについての詳細は以下をご参考下さい。 参考 Device Plugins *1 GPU スケジューリング: 複数のプロセスが同時に実行されるGPUのリソースを効率的に管理するためのプロセスです。 これは、タスクの優先順位付けや、タスクのリソース割り当てなどを行い、GPUリソースの使用率を高め全体的なパフォーマンスを向上させることに繋がります。 GPUスケジューリングは、特に並列計算が求められるAIや機械学習(ML)向けアプリケーションで重要な機能となっている。 具体的にKubernetesでGPUを使用するために以下の対応が必要です。(ここでは、NVIDIAを例にしてます) 対応するベンダーのGPUドライバーをノードにインストールする 前提として、gcc と 正しいカーネルバージョンのインストールが必要です 詳細は、 NVIDIA CUDA Installation Guide for Linux を参照 Kubernetes でデバイスプラグインをインストールする Kubernetes からyamlファイルでデプロイします 詳細は、 https://github.com/NVIDIA/k8s-device-plugin?tab=readme-ov-file#example-for-debian-based-systems- with-docker-and-containerd を参照 ■ Kubernetes のオブジェクトからの使用方法 デバイスプラグインまでインストールを行った後、従来のCPU/メモリをリクエストするのと同様に、カスタムGPUリソースをリクエストすることで、Pod から GPUを使用することが可能になります。 apiVersion: v1 kind: Pod metadata: name: test-gpu-pod spec: restartPolicy: OnFailure containers: - name: test-gpu-container image: registry.example/example/example:v10.2 resources: limits: nvidia.com/gpu: 1 # requesting 1 GPU Kubernetesでのデバイスプラグインの制限について Kubernetes の Schedule GPUs 、 Device Plugins を参照すると、以下のような制限が記載されています。 コンテナ間でGPUを共有することは出来ない 拡張リソースはオーバーコミットすることは出来ない マニフェスト定義でresources.limits を指定する形式である resources.request を指定する時は、resources.limits と同じにする必要がある GPUリソースを指定する時には上記の制限に注意したいところですが、特に気になったものは コンテナ間でGPUを共有することは出来ない という制限です。 Kubernetes上のコンテナとして扱うからには、AIや機械学習(ML)向けアプリケーションのワークロードを分割して実行したいと思います。ただし、この制限があるとその分GPUを搭載する必要が出てきてしまいます。 単体だけでもコストのかかるGPUを、コンテナ数分用意するとなると非常に高価になってしまいます。 そのため、NVIDIAや他のベンダーが、Kubernetesのコードをベースとしたソリューションを実装して、GPUリソースの共有を提供できる形にしています。 GPUへの共有アクセス NVIDIA のデバイスプラグインを例に、GPUへの共有アクセスを提供している機能を記載します。 下記、Time-Slicing と MPS は相互に排他的となります。 ■ Time-Slicing タイムスライシングスケジューラを活用して、複数のCUDAプロセスを同時に実行します。 GPUは一定間隔でCUDAプロセスを切り替えることによって複数プロセスの共有が可能となります。 GPUのレプリカセットを定義することができ、各レプリカをPodにリソースとして提供することが出来ます。 version: v1 sharing: timeSlicing: resources: - name: nvidia.com/gpu replicas: 4 # 単一のGPUを4つのレプリカとして提供する 設定した後は、GPUリソースに.sharedが付与されるので、それをGPUリソースとして利用します。 apiVersion: v1 kind: Pod metadata: name: test-gpu-pod spec: restartPolicy: OnFailure containers: - name: test-gpu-container image: registry.example/example/example:v10.2 resources: limits: nvidia.com/gpu.shared: 1 # requesting 1 GPU 注意点としては以下があります。 複数のGPUをリクエストしても、比例して計算能力が向上することが保証されない プロセス間の切り替え時にオーバーヘッドが発生する メモリ制限は考慮されていない。1つのプロセスが異常終了すると、他のプロセスも影響して終了する GPUを共有して使用しているため ■ MPS (Multi Process Service) こちらも、複数のCUDAプロセスが単一のGPUを共有出来るようにする機能です。制御を行うdaemon を使用して、アクセスを管理します。 Time-Slicing のデメリットであるオーバーヘッドを排除しています。 各プロセスに独自のメモリアドレス空間を提供することにより、プロセスにメモリの制限を適用することが出来ます。 注意点としては以下があります。 プロセスを完全分離させているわけではないため、メモリの保護の提供はされていない あるプロセスが異常終了した場合に、他のプロセスに影響を与える可能性があります 参考 https://docs.nvidia.com/deploy/mps/index.html ■ MIG (Multi Instance GPU) 単一の物理的なGPUを複数の独立したGPUインスタンスに分割することが出来る機能です。 利用可能なGPUとしては、 Ampere , Hpper などがあります。 注意点としては以下があります。 各GPUのモデルによって、特定のMIGプロファイルをサポートするため、柔軟なカスタムを行うことは出来ない 参考 Supported MIG Profiles まとめ 今回は、Kubernetes でGPUを扱っていくための手法についてまとめてみました。 今やクラウドベースでGPU搭載のインスタンスを使用してKubernetes を構築出来るようですが、その前提となっている技術等について改めて簡単に整理してみると面白いです。 次回は、実際の構築例を試してみて所感を記載していこうと思います。 本書の記載が読者のお役に立てれば幸いです。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post KubernetesでGPUを使用する first appeared on SIOS Tech. Lab .
こんにちは、サイオステクノロジーの佐藤 陽です。 今回はオブジェクト指向プログラミングの強力な武器の一つである、 ポリモーフィズムを利用した依存関係の制御 について書きたいと思います。 「依存関係性の制御」や、「依存関係性の逆転(DIP)」などは既に色々なところで解説されていますが 自分の知識定着と、どこかの誰かの役に立つことを期待して書いていきたいと思います。 良ければ最後までご覧ください! はじめに 先日、今更ながら「 Clean Architecture 達人に学ぶソフトウェアの構造と設計 」を読んだのですが その中で個人的に刺さる一文がありました。 それが以下のものです。 OO とは「ポリモーフィズムを使用することで、システムにあるすべてのソースコードの依存関係を絶対的に成業する能力」である。 ※OO=オブジェクト指向 この一文に感銘を受け、この気持ちをアウトプットせざるを得なかったため、今回の記事を書くに至っています。 オブジェクト指向プログラミングのメリット よくオブジェクト指向のプログラミングのメリットとして 現実世界に近い形でプログラミングが可能 カプセル化 継承 といったものが挙げられますが、Clean Architectureの書籍の中では 「これらはオブジェクト指向の大きなメリットではない」とバッサリと切り捨てられていました。 (本記事ではこの点には触れないため、気になる方はぜひ 4 章「オブジェクト指向プログラミング」を読んでみてください。) ではオブジェクト指向の一番の強みとは何かというと、先ほども書いた 「ポリモーフィズムを利用した依存関係の制御」 と述べています。 この点に関して自分なりに整理していきたいと思います。 ポリモーフィズムとは はじめにポリモーフィズムについて簡単に説明します。 こちらも色々なところで記事にされているので、ここではサクっとだけ。 ポリモーフィズムは「同じ関数であっても、別の動作をするような処理」を実現します。 よく挙げられる例として動物の鳴き声があります。 「鳴く」という動作注目した場合 犬であれば「ワンワン!」、猫であれば「にゃー!」、馬であれば「ヒヒーン!」と鳴きます。 「同じ動物」の同じ「鳴く」という動作であっても、発せられる声は異なってきます。 これを実現するのがポリモーフィズムです。 今回はこれを以下のような形で実施します。 動物( IAnimal )というインターフェイスを定義し、鳴く( MakeSound )というメソッドを定義します。 そしてこの Interface を実装するDog、Cat、Horseのクラスを実装します。 そして、この Interface のインスタンスとして生成した変数( animal )から MakeSound() を呼び出すと 変数として代入した動物の鳴き声が生成されます。 今回、 animal 変数の生成を自前で書いているのであまり恩恵を感じられていませんが DI コンテナなどの組み合わせることによってポリモーフィズムは非常に強力な真価を発揮します。 現時点では、「同じ関数でも動作を切り替えられるんだなぁ」くらいに思っていただいて OK です。 これを元に、実際に依存関係の制御についてお話していきます。 依存関係の制御 真価を発揮するケース ではこの「 ポリモーフィズムを利用した依存関係の制御 」というのが、どういったケースで協力な武器となるか見ていきます。 まずはじめに以下のようなユースケースを想定し、依存関係の制御をする場合と、しない場合について比較を行います。 ユースケース とあるECサイトを作成するものとします。 そのEC サイトにおいては、以下のような会員ランクの制度があるそうです。 この時、ユーザーが自身の会員ランクを問い合わせる機能を実装します。 具体的な実装の流れとしては以下のような感じになりそうです。 ControllerがBusinessRuleに対して会員情報を渡してランクを問い合わせる DB からユーザー情報に紐づく購入履歴を参照する 購入数や購入金額の情報を受け取る 購入数や購入金額から会員ランクを算出 Controllerへ会員ランク情報を返す 依存関係の制御を行わない場合 構成としては以下のようになりそうです。 (※厳密な UML 図ではないです。) それぞれのクラスの役割は以下の通りです。 Controller リクエストを受けてユーザー情報を BusinessRule へと渡す Business Rule 購入履歴から会員ランクを判定する Database Access DB へのアクセッサーを担う この時の「制御」と「依存」の関係性を図に加えたいと思います。 なお、この時の制御と依存の定義としては以下の通りです。 制御 メソッドを呼び出して実際に利用する関係 依存 呼び出す関数を含むモジュールに言及している関係 C#でいえば using, Java でいえば import を使っていれば依存関係といえます。 Business Rule が Database Access に対して 制御 も行っていますし、 依存 もしている関係性であることが分かります。 ただ、別にこれでも実装自体は行えますし、動作に特段支障も出ないかと思います。 依存関係の制御を行う場合 では先ほどのケースに 依存関係の制御 を行いたいと思います。 Database Access クラス用に Interface を追加し、それを実装する形にします。 そして、Business Rule のクラスからは Interface を参照するようにします。 図としては以下のような形ですね。 この時、改めて制御と依存の関係性を見てみたいと思います。 ここでポイントなのが、 Business Rule と Interfaceを一つの塊 として見ることです。 Interface を挟み込み、依存関係の制御を行うことで 依存関係が Database Access –> [Business Rule + IDatabase Access] という方向に逆転していることが分かります。 これこそが「 ポリモーフィズムを利用した依存関係の制御 」になります。 Interface を挟み込むことによって、開発者が自由自在に依存関係の制御を行えることができるようになるのです。 メリット 依存関係を制御できることによって、何が嬉しいのでしょうか? 一番のメリットとしては、 依存関係を反転することで「購入履歴から会員ランクを判断する」という ビジネスにとって重要なルールが実装されている Business Rule クラス が何者にも依存しなくなること です。 このルールはビジネスにとって非常に大切なものであり、Databaseの切り替えや、ルールを使う側の都合によって、修正が入ることは望ましくありません。 依存方向を変更することで、Business Rule クラス が Database Access クラス の存在を知る必要がなくなり、Database Access クラスの修正や差し替えが非常に容易になります。 例えば 元々はMySQL を使っていたけど Oracle に切り替えたい テスト用にダミーデータに差し替えたい といった事も Business Rule クラスの修正なしに、簡単に行えるようになります。 なぜなら、Business Rule クラス が依存しているのはIDatabase Accessというインターフェイスであり 実際にDatabaseにアクセスするためのクエリが書かれているのは、それを実装しているクラス(Oracle Database Access, MySQL Databas Access etc.)であるためです。 Business Rule クラス からしたら、インターフェイスを実装したクラスがどのような実装になっているか知らないですし、知る必要がありません。 そのため、Database Access クラス の実装がどう変化しようと、 Business Rule クラス の実装に影響は受けないのです。 なおこのように、 依存する先をインターフェイスのような安定した抽象にすることを「 依存関係逆転の原則(Dependency inversion principle) 」と呼びます。 この「安定した抽象」という表現についてですが、 「抽象」に関しては、Interface を指しています。(今回であれば IDatabaseAccess) 対極にある言葉としては「具象」であり、これは Interface を実装したクラスを指します。(今回であれば MySQLDatabaseAccess など) 「安定した」については、書籍には以下のような記載がありました。 優れたソフトウェア設計者やアーキテクトは、インターフェイスの変動制をできるだけ抑えようとする。新しい機能を実装するときにも、できる限りインターフェイスの変更なしで済ませられるようにする。 安定したソフトウェアアーキテクチャは、変化しやすい具象への依存を避け、安定した抽象インターフェイスに依存するべきである。 つまり、インターフェイスは極力修正の必要がない( =安定している状態) ように設計を行うべきということが分かります。 また、このような実装をすることで、インターフェイスに依存するBusiness Ruleのコードの修正も必要なくなることが分かりました。 このように、 コードを修正する際に不要な影響を及ぼさない依存関係性にすることを「 オープン・クローズドの原則(Open Closed Principle) 」と呼びます。 以上のことから、ポリモーフィズムを利用して依存関係を制御し、関係性を逆転させて安定した抽象への依存とすることで Business Rule の周りがどのようにに変更されようとも、Business Rule に修正を加える必要がなくなり、システムの改修が容易になるのです。 インスタンスの生成 これまで述べてきたような事を実現するためには、 IDataAccess dataAccess = new MySQLDataAccess(); といったような実装をどこかに加えなければいけません。 ただ、これを Business Rule の中に入れてしまっては、結局 MySQLDatabaseAccess に依存する形となってしまい、元も子もありません。 これを解決する実装方法に関しての詳細は今回触れませんが DI コンテナーを利用する Abstract Factory パターンを利用する といった対応をすることで、依存関係を保ったままインスタンスの生成を行うことができます。 まとめ 今回は、オブジェクト指向プログラミングの強力な強みである「 ポリモーフィズムを利用した依存関係の制御 」について説明しました。 「 抽象であるインターフェースに依存するように、ポリモーフィズムを使って依存関係を制御しよう 」ということでした。 是非このあたり意識して設計の方を行っていきたいですね。 ではまた! 参考文献 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post オブジェクト指向の強力な武器 ~依存関係の制御~ first appeared on SIOS Tech. Lab .
こんにちは! 今月も「OSSのサポートエンジニアが気になった!OSSの最新ニュース」をお届けします。 BMW に搭載される最新の OS が Linux ベースから Android へ変更されました。 LinuxからAndroidへ「BMW」車載OSの劇的変化 https://toyokeizai.net/articles/-/743299/ 4/18、バッファロー製のルータで脆弱性が確認されました。 現在ご利用中の方はファームウェアのアップデートを実施ください。 バッファロー製Wi-Fiルーターに脆弱性 IPAなどが注意呼び掛け 「最新版ファームウェアへ更新を」 https://www.itmedia.co.jp/news/articles/2404/18/news143.html 4/18、さくらインターネットは IaaS 型パブリッククラウドである「さくらのクラウド」で Red Hat Enterprise Linux の提供を開始しました。 さくらのクラウドで「Red Hat Enterprise Linux Server」を提供開始 https://news.mynavi.jp/techplus/article/20240418-2929655/ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 【2024年4月】OSSサポートエンジニアが気になった!OSS最新ニュース first appeared on SIOS Tech. Lab .
今号では、curl コマンドのオプションについてちょっと詳しくご紹介します! 2022年 7月 27日にご紹介した「 知っておくとちょっと便利!curl コマンドの使い方をご紹介 」 では、よく使用されると考えられるオプションの意味や使い方について簡単にご説明しましたが、 今回は表示される内容を、ちょっと掘り下げて見ていきます。 -o オプション (コンテンツをファイル出力する) 取得したコンテンツをファイル出力します。 各項目の意味について、それぞれ確認していきます。 $ curl http://example.com -o examplefile % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 27 100 27 0 0 3879 0 --:--:-- --:--:-- --:--:-- 4500 $ cat examplefile This is example index page ※ Time という項目が 3つあるため、それぞれ色を変更して表示しています。 ・ % Total: 全データ量に対する、ダウンロード済みデータ量の割合 ・ % Received: 受信した全データ量に対する、ダウンロード済みデータ量の割合 ・ % Xferd: 送信する全データ量に対する、送信済みデータ量の割合 ・ Average Speed: ダウンロードもしくはアップロードの平均速度 (1秒あたり) ・ Time : これまでにかかった時間 ・ Time : 全体のダウンロードもしくはアップロード時間 ・ Time : 残りのダウンロードもしくははアップロード時間 ・ Current: 現在のダウンロードもしくはアップロード速度 (1秒あたり) -v オプション (コンテンツ取得時の詳細なログを表示する) コンテンツを取得した際の詳細なログ (レスポンスヘッダの内容や HTTP ステータスコード等) を表示します。 各項目の意味について、それぞれ確認していきます。 $ curl -v http://example.com 1 * About to connect() to example.com port 80 (#0) 2 * Trying 127.0.0.1... 3 * Connected to example.com (127.0.0.1) port 80 (#0) 4 > GET / HTTP/1.1 5 > User-Agent: curl/7.29.0 6 > Host: example.com 7 > Accept: */* 8 > 9 < HTTP/1.1 200 OK 10 < Date: Wed, 20 Jul 2022 20:12:42 GMT 11 < Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips 12 < Last-Modified: Wed, 20 Jul 2022 19:15:01 GMT 13 < ETag: "1b-5e4416af2a4ab" 14 < Accept-Ranges: bytes 15 < Content-Length: 27 16 < Content-Type: text/html; charset=UTF-8 17 < 18 This is example index page 19 * Connection #0 to host example.com left intact ※各項目についての説明をするため、左に番号を記載しています。 ・ 1 行目: 接続しようとしている URL (example.com) およびポート (80) ・ 2 行目: 接続しようとしている IP アドレス (127.0.0.1) ・ 3 行目: 記載の URL (example.com)、IP (127.0.0.1) に接続完了 ・ 4 ~ 8 行目: リクエストヘッダの内容 4 行目: HTTP メソッド (GET)、HTTPバージョン (1.1) 5 行目: curl のバージョン (7.29.0) 6 行目: リクエスト先のホスト名 7 行目: レスポンスを受け取る際に、受け入れを許可するコンテンツタイプ (この場合、すべてのコンテンツタイプを許可) ・ 9 ~ 17 行目: レスポンスヘッダの内容 9 行目: HTTPバージョン (1.1)、ステータスコード (200)、ステータスメッセージ (OK) 10 行目: レスポンスヘッダが作成された日時 11 行目: Web サーバ (この場合は Apache)、および OpenSSL のバージョン 12 行目: コンテンツの最終更新日時 13 行目: エンティティタグ (コンテンツの識別子) 14 行目: Range に対応している (コンテンツの特定部分のみをリクエストできる) 旨を示す 15 行目: レスポンスボディのサイズ (単位:byte) 16 行目: レスポンスボディの種類 (この場合は HTML 形式)、および文字エンコード (この場合は UTF-8) ・ 18 行目: コンテンツの内容 なお、 -I オプション を指定した際に出力される内容と、上記 9 ~ 17 行目 で表示される 内容は同じものになっています。 $ curl -I http://example.com HTTP/1.1 200 OK Date: Wed, 20 Jul 2022 20:14:49 GMT Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips Last-Modified: Wed, 20 Jul 2022 19:15:01 GMT ETag: "1b-5e4416af2a4ab" Accept-Ranges: bytes Content-Length: 27 Content-Type: text/html; charset=UTF-8 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 知っておくとちょっと便利!curl コマンドのオプションをちょっと詳しくご紹介 first appeared on SIOS Tech. Lab .
こんにちは。サイオステクノロジーの橋本です。 今回は RHEL 8、9 において /etc/pam.d/ 配下のファイルや /etc/nsswitch.conf といった認証周りの設定変更方法について実例を挙げつつ説明していきます。 ※今回はそれぞれのファイルの説明は行いません。 ファイルを直接編集しているワイルドな方は今一度手順を見直してください。 時間がない人向けに 大体の場合 root ユーザで /etc/authselect/ 配下の設定を変更し authselect apply-changes コマンドを実行すれば設定は反映されます。 前提 /etc/pam.d/ 配下のファイルや /etc/nsswitch.conf を直接編集することは推奨されていません。 設定ファイルを間接的に編集し、authselect コマンドを用いて設定を反映させる必要があります。 ※似た考え方をするコマンドに GRUB2 の grub2-mkconfig コマンドなどがあります。 サーバの根幹に関わる設定なので安全な設定変更方法を実現しているわけです。 nsswitch.conf の以下の項目を編集したい場合は、新しくプロファイルを作成する必要があります。 passwd、 group netgroup automount services 今回は passwd も変更したいので新しいプロファイルを作成します。 よく使うコマンド RHEL 8、9 では認証周りの設定をプロファイルという形で複数保持することが 可能です。複数ある中から任意のプロファイルを一つ選んで利用するわけです。 まずは利用可能なプロファイル一覧を確認し、 現在選択されているプロファイルとその設定内容を確認しましょう。 ・利用な可能なプロファイル一覧を表示 # authselect list - minimal Local users only for minimal installations - sssd Enable SSSD for system authentication (also for local users only) - winbind Enable winbind for system authentication # ・現在選択されているプロファイルを確認 # authselect current プロファイル ID: sssd 有効な機能: なし # ・プロファイルの内容を確認 # authselect test sssd ファイル /etc/nsswitch.conf: # If you want to make changes to nsswitch.conf please modify # /etc/authselect/user-nsswitch.conf and run 'authselect apply-changes'. # # Note that your changes may not be applied as they may be # overwritten by selected profile. Maps set in the authselect ~後略~ 設定の変更 まずは新しいプロファイルを作成しましょう。 # authselect create-profile newprofile --base-on sssd /etc/authselect/custom/newprofile で新規のプロファイルが作成されました # 上記コマンドでプロファイル sssd をベースとした新しいプロファイルが作成されました。 この段階では「sssd」と「newprofile」の間に設定差はありません。 newprofile の設定内容は /etc/authselect/custom/newprofile 配下にあります。 # ls -la /etc/authselect/custom/newprofile 合計 52 drwxr-xr-x. 2 root root 4096 4月 22 14:36 . drwxr-xr-x. 3 root root 24 4月 22 14:36 .. -rw-r--r--. 1 root root 4633 4月 22 14:36 README -rw-r--r--. 1 root root 3248 4月 22 14:36 REQUIREMENTS -rw-r--r--. 1 root root 540 4月 22 14:36 dconf-db -rw-r--r--. 1 root root 279 4月 22 14:36 dconf-locks -rw-r--r--. 1 root root 2461 4月 22 14:36 fingerprint-auth -rw-r--r--. 1 root root 505 4月 22 14:36 nsswitch.conf -rw-r--r--. 1 root root 3732 4月 22 14:36 password-auth -rw-r--r--. 1 root root 340 4月 22 14:36 postlogin -rw-r--r--. 1 root root 2355 4月 22 14:36 smartcard-auth -rw-r--r--. 1 root root 4778 4月 22 14:36 system-auth # pam 配下のファイル、例えば system-auth の設定を変更したい場合は、 /etc/authselect/custom/newprofile 配下の system-auth を編集した上で、 プロファイル「newprofile」を適用すればいいわけです。 ・変更前 password sufficient pam_unix.so sha512 shadow {if not "without-nullok":nullok} use_authtok ・変更後 password sufficient pam_unix.so sha512 shadow {if not "without-nullok":nullok} use_authtok remember=5 nsswitch.conf の設定の変更 さて問題は一部の nsswitch.conf の設定です。 項目によって設定変更方法が異なります。 以下の項目は /etc/authselect/custom/newprofile/nsswitch.conf で 設定を編集する必要があります。 passwd group netgroup automount services ・変更前 passwd: {if "with-files-domain":sss files|files sss} systemd {exclude if "with-custom-passwd"} ・変更後 passwd: files ldap 設定の内容を確認してみると意図した内容となっているみたいです。 # authselect test custom/newprofile | egrep "password sufficient|passwd: files ldap" passwd: files ldap password sufficient pam_unix.so sha512 shadow nullok use_authtok remember=5 password sufficient pam_sss.so use_authtok password sufficient pam_unix.so sha512 shadow nullok use_authtok password sufficient pam_sss.so use_authtok # プロファイルの変更 この段階でプロファイルを変更してみましょう # authselect select custom/newprofile プロファイル "custom/newprofile" が設定されました。 以下の nsswitch マップはプロファイルで上書きされます: - passwd - group - netgroup - automount - services Make sure that SSSD service is configured and enabled. See SSSD documentation for more information. # 前述の 5 項目 (passwd など) 以外の shadow などは /etc/authselect/user-nsswitch.conf で行う必要があります。 ・編集前 passwd: sss files systemd shadow: files ・編集後 passwd: sss files systemd shadow: files ldap passwd や group などは /etc/authselect/user-nsswitch.conf を編集しても設定は反映されません。 /etc/authselect/custom/newprofile/nsswitch.conf を編集しましょう。 ※設定するファイルがいろいろ分かれているのはちょっと分かりにくいですね。。。。 設定の変更反映 この後、authselect apply-changes で変更した設定を変更させます。 # authselect apply-changes 変更は正常に適用されました。 # 今回は authselect について説明しました。 私が調べた限り事例などは少なく手探りで調べる必要があるコマンドだったので、 どなたかのお役に立てればと思います。 PAM や nsswitch.conf はサーバの認証周りの根幹に関わるので、 慎重に設定してください。 補足 authselect は RHEL 8 以降のコマンドとなります。 RHEL 7 以前は authconfig でした。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post OS の認証周りの設定を変更してみよう ~authselect について~ first appeared on SIOS Tech. Lab .
こんにちは。サイオステクノロジー OSS サポート担当 山本 です。 今回は Apache Solr (Solr) というやつを試そうとしてみたので、それについてのお話です。 非常に尖った用途を持つ OSS で、(私のように) 使う機会がなければ恐らく馴染みのないものかと思いますが、だからこそ必要になりそうな時に存在を知っていると選択肢が増えそうだなぁ、と思えるものなので、そのあたりを頑張って伝えていきたいと思います。 ■Solr って何? Solr は、 全文検索 というものを行うための OSS です。 全文検索……ってつまりどういうことをするの?というのをものすごくざっくり言うと 「 データを登録 しておいて」後に「 登録済みのデータから検索 を行う」もの です。 リレーショナルデータベース ( RDB ) をご存じであれば、それに近いことをやるのかな、とイメージするとわかりやすいかもしれません。 大まかな流れを先に確認してみましょう。 Solr では基本的に、まず登録するデータに合わせて スキーマ と呼ばれる型 を作成します。 スキーマは 複数の フィールド から成り、それぞれのフィールドには “フィールド名” や “型 (文字列、数値など)” などを設定します。 例えば、”料理” のスキーマならフィールドは “名前”、”材料”、”調理時間目安”、”調理手順”……など、”本” のスキーマならばフィールドは “タイトル”、”著者”、”発表年”、”冒頭文”、”概要”……などが考えられます。(実際には登録するデータに合わせて考える必要があります。) スキーマを作成したら、決められた書式に合わせて 用意しておいたデータを登録 します。 (こうして Solr に登録したデータは、 ドキュメント と呼ばれます。) ここまでが前準備です。 そうしたら、Solr に対して問い合わせ ( クエリ ) を発行すると、該当する ドキュメント を結果として返してくれる……というわけです。 Solr でやること・やれることは、極めて大まかにですが大枠としては以上です。 用語こそ違えど、概要を見る感じは RDB と似たようなもの ですね。 では改めて Solr の、というか全文検索の特色は何かと言うと…… 文字列検索に特化している ことです。 例えば、先に挙げたスキーマ例で言えば 「”名前” “材料” “調理手順” の いずれか に『蒸し』を 含む ドキュメント」 のような検索を、solr は 極めて高速に 行うことができます。 RDB でも “LIKE 句” によって同じようなことはできますが、原則として RDB はこのような「特定の文字列を含む」という検索は得意とはしておらず、検索対象の DB サイズが大きくなるほど極端に遅くなりがちです。 また Solr は、例えば「いちご」で検索することで「イチゴ」「苺」「ストロベリー」を含むドキュメントも検索できるようにするような 同義語・類義語検索や、あいまい検索などを実現 できる仕組みなど、 我々が「検索」と聞いたときにイメージするような機能を実現 できるものになっています。 逆に Solr は、集計や結合処理などの RDB の得意とするような処理には適しているとは言えません。 ところで、Apache のソフトウェアの中には Solr と同じく全文検索のための OSS である Lucene というものが存在しています。 Solr の話を見ていると稀に名前の出てくるこの Lucene についても簡単に触れておくと、 Lucene は Java (および Python) 向けの組み込みライブラリの OSS であるのに対して、 Solr は Lucene をベースにしている派生の OSS であり、 Web API や Web UI などを備えるサーバ向けアプリケーション です。 Solr では Lucene でできることは概ねできる、とされており、単体で動かせるアプリケーションであることからも、とりあえず「全文検索」がどんなものか体感したいのであれば Solr を試してみるのがよいかと思います。 ■Solr をほんの少しだけ試してみる さて、ざっくり概要についてお話ししてみましたが、話だけではわかりにくいと思うので少し試してみましょう。 Solr を試すなら、 公式の配布しているコンテナイメージ を使うのが恐らく最も手軽でしょう。 今回は Red Hat Enterprise Linux 9 環境で Podman を使って試してみます。 コンテナイメージが現在どこで配布されているかやコンテナ以外での導入方法については、公式の ダウンロードページ から確認してください。 さて、Podman を導入済みであれば、以下のようなコマンドを実行すれば デモ用データ付きの Solr を立ち上げることができます。簡単ですね。 $ podman run -dt --name test-solr -p 8984:8983 solr solr-demo 実行したら、まずは管理用の Web UI に接続してみましょう。 任意の Web ブラウザを立ち上げ、(上記の例で立ち上げた場合は) 以下のような URL にアクセスしてみましょう。 http://(IPアドレス or ホスト名):8984/solr すると、このようなページが表示されるはずです。 表示された管理用画面ではいろいろなことができますが、とりあえず今回はデモ用データの確認できるクエリのページだけ確認しておきましょう。 この画面の画面下部にある “ Execute Query ” ボタンを押下すると、登録されているデモ用データの一覧が表示されるはずです。 (UI で条件を指定してやれば、条件に合致したものだけが表示されます。) 一方、 既定の URL へのアクセス によって直接検索結果を取得することもできます。 例えば、デモ用データの中から “name” フィールド に「drive」を含むものを取得したいなら、デモ用データのある コア ( ドキュメント を入れる大枠のようなもの) は “demo” という名前になっていますが、この場合は以下のようなアドレスにアクセスすれば OK です。 http://(IPアドレス or ホスト名):8984/solr/demo/select?q=name%3Adrive ※ “%3A” = “: (コロン)” を URL エンコードしたもの 例として、Podman で Solr を実行したホスト上から curl を使って先述のアドレスへアクセスすると、以下のようにデフォルトの JSON フォーマットでの結果が返ってくるはずです。 $ curl 'http://localhost:8984/solr/demo/select?q=name%3Adrive' { "responseHeader":{ "status":0, "QTime":41, "params":{ "q":"name:drive" } }, "response":{ "numFound":2, "start":0, "numFoundExact":true, "docs":[{ "id":"6H500F0", "name":["Maxtor DiamondMax 11 - hard drive - 500 GB - SATA-300"], "manu":["Maxtor Corp."], "manu_id_s":"maxtor", "cat":["electronics","hard drive"], "features":["SATA 3.0Gb/s, NCQ","8.5ms seek","16MB cache"], "price":[350.0], "popularity":[6], "inStock":[true], "store":["45.17614,-93.87341"], "manufacturedate_dt":"2006-02-13T15:26:37Z", "_version_":1796378465704869888 },{ "id":"SP2514N", "name":["Samsung SpinPoint P120 SP2514N - hard drive - 250 GB - ATA-133"], "manu":["Samsung Electronics Co. Ltd."], "manu_id_s":"samsung", "cat":["electronics","hard drive"], "features":["7200RPM, 8MB cache, IDE Ultra ATA-133","NoiseGuard, SilentSeek technology, Fluid Dynamic Bearing (FDB) motor"], "price":[92.0], "popularity":[6], "inStock":[true], "manufacturedate_dt":"2006-02-13T15:26:37Z", "store":["35.0752,-97.032"], "_version_":1796378465692286976 }] } } ■最後に 今回はそもそも Solr とはどんなものか、ということを中心にお話ししてみました。 検索機能を作りたい時に使うのかなぁ、となんとなく伝わったでしょうか?多数のページで構成された、公開するためのサイト……例えばマニュアル・ヘルプだったり、EC などを作る場合には利便性を確保するための選択肢として強力に働いてくれるハズです。 なお、今回の話の中で出てきた RDB や Podman ってのは何なんだ、という方は以下の別記事も見ていただけたら幸いです。 わからないなりに理解したいデータベース①:RDB編:MySQL① わからないなりに理解したい Podman ① ~ 何をするもの? ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Solr って何者?①:Solr って何?? first appeared on SIOS Tech. Lab .
PSの米谷俊輔です。 今回はWeb3.0における デジタルアイデンティティ を管理する技術、DIDsについて調べてみましたので解説します。 DIDsとは DIDs (分散型識別子: Decentralized Identifiers) は、分散型台帳技術 (主にブロックチェーン) を使った識別子 (IDを識別するための情報) です。 Web2.0までのように認証サービスを提供する IDプロバイダー (IdP) に依存せず、利用するユーザが自身の デジタルアイデンティティ ※1 を管理し ※2 、国や事業者等に掲示する情報をユーザー自身が制御することができます。 DIDsは SSI (自己主権型アイデンティティ: Self-Sovereign Identity) ※3 を実現する手段として注目されています。 ※1: デジタル化した個人などに関連した属性情報 (例: ID、パスワード、メールアドレス) の集合 ※2: 実際の運用において学歴や資格等の情報は有効かつ信頼性のある方法で検証が必要であり、信頼できる認証機関やデータ提供者が関与することが求められます。 ※3: 国や事業者等の認証機関や管理者に依存することなく、自身の個人情報を自身で管理・保管を行い、あらゆる決定権を持つべきであるとする考え方。 以降の説明の理解を深めるためにDIDsとDIDの違いについて最初に説明します。 DIDとDIDsの違い Web3.0においてDecentralized IdentifiersはDIDまたはDIDsと表記されます。この表記はDIDを理解する上で障害になることがあります。 DIDは「分散型アイデンティティ: Decentralized Identity」、「分散型識別子: Decentralized Identifier(s)」と異なる意味の複数の言葉を示す略語として使用され、いずれの意味であるかは文脈から理解する必要があります。一方DIDsは「分散型識別子: Decentralized Identifiers」を示す略語であり、意味を明確にしたい場合に利用する傾向があります。 この記事では Decentralized IdentifiersはDIDs で統一して表記します。 次からDIDsについて解説を始めます。最初にDIDsの特徴です。 DIDsの 特徴 DIDsは SSIを実現する手段であることは前述しましたが、 SSIでは以下の「SSIの10原則」 ※4 が提唱されております。 ※4: 2016年にSSL/TLSの専門家であるクリストファー・アレン氏が「The Path to Self-Sovereign Identity」の記事中で提唱した原則 No. 原則 説明 1 実在 (Existence) ユーザーは独立した存在である。 2 コントロール (Control) ユーザは自身のIDを管理することができる。他のユーザがIDを管理する存在であってはならない。 3 アクセス (Access) ユーザーは自身のIDに紐づくすべてのデータにアクセスすることができ、ユーザーに隠されたデータや制限がない。 4 透明性 (Transparency) IDを管理・更新するシステムおよびアルゴリズムは透明性が担保されている。 5 持続性 (Persistence) IDは永久に、少なくともユーザーが望む限り存続する。これは「忘れられる権利」と矛盾しない。 6 携帯性 (Portability) IDに紐づくすべてのデータはサービス間で利用可能である。またユーザが自身のIDを管理し続けられることを保証する。 7 相互運用性 (Interoperability) IDは可能な限り広く利用できる。 8 同意 (Consent) IDに紐づくすべてのデータは共有される際にはユーザの同意が必要である。 9 最小化 (Minimalization) IDに紐づくすべてのデータは開示範囲を最小限とする。 10 保護 (Protection) ユーザの権利は保護されなければならない。ID ネットワークのニーズよりも個人の自由と権利が優先される。 出典: https://www.w3.org/TR/did-core/#design-goals 「SSIの10原則」を私的にまとめるとSSIは、「特定の国やシステムに依存しない独立した存在である。」、「ユーザーは自身のIDに紐づくすべてのデータを把握し、管理することができる。 」、「様々なサービス間で相互運用が可能で、ユーザーが望む限り存続する。」、「SSIに紐づいたデータの提示はユーザの同意が必要、且つ最小限の範囲に限られる。」 、「これらを実現するSSIを管理するシステムおよびアルゴリズムは堅牢かつ透明性を担保されている。」といった特徴があると考えます。 SSIを実現する手段である DIDsはこの原則に準じた特徴を持つと考えられます。 またDIDsは 国際技術標準化団体のW3C (World Wide Web Consortium) により2022年7月19日に「Decentralized Identifiers (DIDs) v1.0」として標準規格が公表されました。W3Cが定めた標準規格はDIDsを理解・利用する上で重要な基準となると考えます。 「Decentralized Identifiers (DIDs) v1.0」の要旨(全文は こちら ) では 「SSIの10原則」の他に 「 DIDsは検証可能な分散型デジタルIDを可能にする新しいタイプの識別子である。 」、「DIDsは、DID subjectと DID documentを関連付けるURIであり、その表題に関連する信頼できるやり取りを可能にする。」の特徴が追加されています。 「DIDsは検証可能な分散型デジタルIDを可能にする」という特徴からDIDsには、検証可能なID、検証不可能なID、検証可能だが検証しないIDがあるということが分かります。検証可能なIDとは氏名、住所、血液型、生年月日、写真、認証番号、資格、学歴、職歴、病歴などパーソナリティに結びつくIDのうち、行政や信頼できる機関より検証に必要なデータが発行されるものが対象となります。 検証可能な 分散型デジタル IDを実現するために必要とされている技術が VC (検証可能な資格情報: Verifiable Credentials) です。 VCとは VCは 行政 や信頼できる機関より発行されたデータを使い安全にIDの真正を検証する技術およびフォーマットであり情報そのものとは異なります。 VCもDIDsと同様にW3Cの「 Verifiable Credentials Data Model v2.0 」により標準規格が公表されています。 「Verifiable Credentials Data Model v2.0」におけるVCの仕組みについて解説します。 VCの仕組み 「Verifiable Credentials Data Model v2.0」ではVCの仕組みの一例を以下の図のように表しています。 図1. The roles and information flows forming the basis for this specification. 出典: Verifiable Credentials Data Model v2.0 | W3C 図1には3人の人物「Issuer」 (発行者)、「Holder」 (保有者)、「Verifier」 (検証者) および1つのデータベース「Verifiable Data Registry」 (検証可能なデータの保管データベース) が登場します。VCの仕組みにおけるそれぞれの役割は以下の通りです。 Holder (保有者) DIDの利用ユーザ―を想定 Verifiable Data Registryにスキーマを利用してID情報を登録します。Issuerに対しID情報に対するVCs ( VCで検証されるデジタル証明書 ) の発行を依頼します。 Issuerが発行したVCsを保管し、Verifierに対しID情報およびVCsを提示します。 Issuer (発行者) 行政や信頼できる機関等の検証に必要なデータの発行元を想定 Holderの依頼を受けてVerifiable Data Registryに登録されたID情報を検証し、VCsを発行します。 Verifier (検証者) 認証システム等、HolderのID情報を要求元を想定 Holderが提示したID情報に対しVerifiable Data Registryに登録されたスキーマおよびID情報を検証します。 Holderが提示したVCsを検証します。 Verifiable Data Registry (検証可能なデータの保管データベース) スキーマおよびID情報を保持します。 VCの仕組みによりVerifierはIssuer問い合わせることなく、Holderが提示したID情報の検証を行うことができます。 まとめ DIDsの解説をまとめると以下となります。 DIDsは、分散型台帳技術を使った識別子です。 DIDsは 「SSIの10原則」 に準じた特徴を持つと考えられる。 「Decentralized Identifiers (DIDs) v1.0」はW3Cにより公表されたDIDsの標準規格である。 DIDsの 検証可能な 分散型デジタル IDを実現する技術が VC である。 VCとDIDsを組み合わせることでID情報の真正が保証される。 いかがでしたでしょうか。今回はDIDsから関連すSSIやVCの簡単な解説を行いました。DIDsやVCについてはこれからもさらに技術的な解説を行う予定です。 Web3.0時代のID であるDIDsが社会に普及することによりID情報の主導権はユーザー自身の手に取り戻されることが期待されます。また今までID情報を管理してきたIdPは個人情報流出のリスクから解放されることが考えられます。今後もDIDsをはじめとしたブロックチェーン技術について注目していきたいと思います。 参考URL Decentralized Identifiers (DIDs) v1.0 The Path to Self-Sovereign Identity Verifiable Credentials Data Model v2.0 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Web3.0時代のID、DIDsについて調べてみたので解説してみた first appeared on SIOS Tech. Lab .
こんにちは、サイオステクノロジー武井です。今回は、今ナウくてあつい「プロンプトエンジニアリング」について一筆したためました。 プロンプトエンジニアリングとは? 「プロンプトエンジニアリング」という言葉を聞いたこといらっしゃる方いると思います。米国では「プロンプトエンジニア」という職種は数千万の年収をもらえるという噂も聞きます。 OpenAIが提供するChatGPTや、マイクロソフトのBing Chatはプロンプトの与え方が良い回答を引き出すための成否を分けると言っても過言ではありません。正確な回答を引き出すためのプロンプトを上手に作成出来る技術を「プロンプトエンジニアリング」と呼び、そのためのテクニックはいくつかありまして、代表的なものを以下に記載します。 Few-shot Learning 少数の例文から新しいタスクに対して高精度な回答を出力する技術です。例えば、ChatGPTでは、少数の例文から新しい文章を生成することができます。 Zero-shot Learning 事前学習されたモデルに対して、新しいタスクに対する指示を与えることで回答を出力する技術です。例えば、「英語で書かれた小説を日本語に翻訳してください」という指示を与えることで、モデルは自動的に翻訳を行います。 ReAct 言語モデルでさまざまな言語推論や意思決定を遂行する手法です。行動理由の「推論」と「行動」の組み合わせにより、より高度なタスクを処理することができます。 この他にもたくさんあります。 牛タンゲームでプロンプトエンジニアリングを学ぶ 上記の中でよく利用するものの1つである「Few-Shot Learning」を例に、プロンプトエンジニアリングについてさらに詳しく説明します。 これは何よりも実例をあげるのが一番です。そこで、伝説のアイドル「広末涼子」さんが流行らせたという「牛タンゲーム」を題材にしてFew-shot Learningを解説します。 「牛タンゲーム」は、合コンや宴会などで行われる余興の1つです。牛タンゲームのルールをご存じの方は、この後の牛タンゲームの説明は読み飛ばしていただいて構いません。そうでない方はちょっとお付き合いください。 で、牛タンゲームの説明ですが、まず最初の人が「牛(ぎゅう)」と発言し、次の人間は「タン」と手をたたきます(このとき「タン」とはいいません)。次の人は再び「牛」といい、次の人は「タン」と手をたたきます。 そして、また次の人は「牛」といって、次の人、次の次の人も「タン」と手を叩きます。 ここまでで、「牛・タン・牛・タン・牛・タン・タン」となり、1ターン目が終了します。 その後は、3回目の「タン」をターンごとに増やしていきます。 例えば、Aさん、Bさん、Cさん、Dさんの4人がこの順番で牛タンゲームを始めた場合、その役割分担は以下のとおりになります。 おわかり頂けましたでしょうか?ぜひ皆さんもご家族・ご友人同士で試してみてください。 今回、ChatGPTに以下の質問をしてみます。 牛タンゲームをAさん、Bさん、Cさん、Dさんの4人でこの順番で始めたときに、3ターン目で最後に手を叩くのは誰ですか? 以下の図のとおり、期待するべき回答はDさんです。 では、ChatGPTに聞いてみましょう。 さすがに人類の叡智を極めたChatGPTでも、牛タンゲームの内容は知らなかったようです。回答も誤っていますし、なんだかさも涼しい顔をして、謎の独自ルールを解説しています。僕たちの知っている牛タンゲームはこんなんじゃないはずです。 そこで、Few-shot Learningの出番です。 ChatGPTがうまく答えられないことについては、事前知識と模範的な回答例をいくつか与えて学習させることで、正確な回答をすることが出来るようになります。これがFew-shot Learningと言われるものです。 早速実践してみます。以下の質問をChatGPTにしてみます。 最初の「#ルール」で、牛タンゲームのルールという事前知識を与えた上で、「#サンプル」で牛タンゲームの模範的な実践例をさらに与えています。これでChatGPTに学習をさせているわけです。先の質問に対する回答は以下のようになります。 ずばり、正解です!! このような学習をモデルにさせるためには従来は「ファインチューニング」という手法が取られていました。しかしながら、ファインチューニングにはいくつかの問題点があります。新しいタスクに適応させるためのモデルの訓練には、そのタスクに関連する大量のデータが必要でした。データの収集、整理、前処理は時間とリソースを大きく消費するプロセスでした。また、データが不足している場合、モデルは学習データに過度に適応してしまうオーバーフィッティングのリスクが高まり、これが実際の適用時に性能の低下を引き起こすことがありました。さらに、新しいタスクに対してモデルを再訓練するための計算リソースも必要とされ、これが追加のコストと時間を必要としました。 一方で、Few-shot Learningの登場により、これらの問題点が大きく緩和されました。この手法の魅力は、非常に限られたデータセットでも新しいタスクを効果的に学習できる点にあります。事前に大規模なデータセットで訓練されたモデルの知識を利活用することで、新しいタスクにも迅速に適応することが可能となりました。この方法は、新しいタスクのデータ収集の手間や、再訓練に伴う計算リソースのコストを大幅に削減する利点があります。 Few-shot Learning素晴らしいですね。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post 牛タンゲームでプロンプトエンジニアリングを学ぶ first appeared on SIOS Tech. Lab .
はじめに こんにちは、サイオステクノロジーのあさりです。今回は、django-admin-rangefilterというパッケージを使って、DjangoAdminのモデル一覧画面でカレンダー形式での日付の範囲指定を行えるフィルターを実装する方法を紹介します。 環境 Python3 Django4.2 django-admin-rangefilter 0.10.0 DjangoAdminのフィルター機能について DjangoAdminでは、以下のようにlist_filterでフィールドを指定するとそのフィールドに基づいた絞り込みが可能になります。今回は、例として こちら の記事で作成したAccessLogモデルを使用します。 # accesslog/admin.py from django.contrib import admin from .models import AccessLog class AccessLogAdmin(admin.ModelAdmin): list_display = ('access_date_time', 'request_url', 'request_method',) list_filter = ('access_date_time',) #フィルター機能を利用するフィールドの指定 admin.site.register(AccessLog, AccessLogAdmin) list_filterの設定完了後に次のコマンドでサーバーを立ち上げて、どのようなフィルターが実装されているか確認してみましょう。 python3 manage.py runserver アクセスログの一覧画面を確認すると以下のようなフィルターが実装されていると思います。 list_filterに指定したaccess_date_timeフィールドはDateTimeFieldで定義されており、DateTimeFieldに対しては画像のような5つの選択肢を持つフィルターが実装されるようです。しかし、このデフォルトのフィルターでは先月や昨年のデータの絞り込みを行いたいときに不便だなと感じます。 そこでdjango-admin-rangefilterというパッケージを導入して、日付を範囲指定して絞り込みを行えるフィルターを実装したいと思います。 django-admin-rangefilterによるフィルターの実装 パッケージのインストール まずは、パッケージをインストールしましょう。 pip install django-admin-rangefilter 設定ファイルに追加 次に、インストールしたパッケージをプロジェクト内で有効化するために設定ファイルのINSTALLED_APPSにrangefilterを追加します。 # settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'accesslog', 'rangefilter', ] フィルターの実装 rangefilterを使って、access_date_timeについてカレンダー形式で日付の範囲指定を行えるフィルターを実装するには、admin.pyを次のように編集してください。 # accesslog/admin.py from django.contrib import admin from rangefilter.filters import DateRangeFilter from .models import AccessLog class AccessLogAdmin(admin.ModelAdmin): list_display = ('access_date_time', 'request_url', 'request_method',) list_filter = (('access_date_time', DateRangeFilter),) #フィルター機能を利用するフィールドの指定 admin.site.register(AccessLog, AccessLogAdmin) 実装はこれで完了です。 動作確認 サーバーを立ち上げて、フィルターが実装できているか確かめてみましょう。 カレンダーアイコンから開始日と終了日の指定ができ、検索ボタンとリセットボタンも実装されていると思います。 おわりに 今回は、django-admin-rangefilterを使って、カレンダー形式で日付の範囲指定を行えるフィルターを実装しました。デフォルトのフィルターに比べて便利で導入も簡単なのでぜひ試してみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DjangoAdmin モデル一覧画面で日付の範囲指定を行えるフィルターを実装してみた first appeared on SIOS Tech. Lab .
こんにちは、サイオステクノロジーの佐藤 陽です。 今回は、ASP.NET Core入門シリーズ第三弾として、 ミドルウェア と リクエストパイプライン について書いていきたいと思います。 コントローラーじゃないところでリクエストに共通処理を追加したい! ミドルウェアって何? リクエストパイプラインって何? という方はぜひ最後までご覧ください。 また前回の記事から繰り返しになりますが まだ自分も勉強中の身なので、記事の内容に誤りなどありましたらコメントにて指摘いただけると幸いです。 はじめに 今回のテーマは ミドルウェア と リクエストパイプライン です。 「コントローラー等のアプリケーションコードはガシガシ書くけど、パイプライン周りは触ったことない」という方も多いのではないでしょうか? 前回の記事の中にもMiddlewarePipelineというワードが何回か出てきました。 リクエストを処理するにあたって非常に重要な仕組みであるため、このあたりもしっかり追っていきたいと思います。 ミドルウェアとリクエストパイプラインとは ミドルウェア とは、ソフトウェアコンポーネントです。 そして、それらのミドルウェアを連ねたものが リクエストパイプライン と呼ばれています。 前回の記事 でも紹介したインプロセスホスティングの場合のASP.NET Coreの動作の図を例にみると ASP.NET Core のアプリケーションに対するリクエストは、 コントローラ(Application Code) で処理される前に、 リクエストパイプライン(Middleware Pipeline) にて順々に処理されます。 ※表記揺れがあって申し訳ないですが、コントローラとApplicationCode, リクエストパイプラインとMiddleware Pipelineは同義として扱います。 リクエストパイプラインの内部をもう少し詳細に見てみると、以下のような形となります。 このリクエストパイプラインの仕組みを利用することで、 コントローラでの処理の前処理および、後処理を実装することが可能となります。 パイプラインの構築方法 ではこのリクエストパイプラインが、どのように実装されているかを見ていきたいと思います。 扱うプロジェクトとしては、 前回の記事 でも作成したMVCのプロジェクトとしたいと思います。 リクエストパイプラインを構成するソースコードとしては、Program.csファイルの中に書かれています。 ( 汎用なホスト を利用している場合は、Startup.cs の Configureメソッド内に書かれます) プロジェクトのProgram.cs の中身を抜粋します。 var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); この時、 app 変数は WebApplication クラスのインスタンスです。 前回の記事の復習になりますが、このWebApplicationクラスの役割としては以下2つのものがあります。 リクエストパイプラインの構築 ホストの開始 このWebApplicationのインスタンスと、Use, Run, Mapといったような拡張メソッドを利用してパイプラインを構築していきます。 なお、ミドルウェアの定義に関しては①インラインで定義する方法と、②再利用可能なクラスとして定義する方法の2種類があるため、それぞれについて見ていきたいと思います。 インライン定義での追加 まずはインラインで定義したミドルウェアの追加方法を紹介します。 拡張メソッドである UseExtensions.Use を利用して以下のように書きます。 await next.Invoke() を境として、前処理なのか後処理なのかを区別することができます。 app.Use(async (context, next) => { //ここにコントローラで処理される前に行う処理を書く //次のミドルウェアへと遷移する await next.Invoke(); //ここにコントローラでの処理が行われた後に行う処理を書く }); 余談ですが、Use拡張メソッドの引数はIApplicationBuilder型となっています。 public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, RequestDelegate, Task> middleware) 「Program.csにおいてappはWebApplicationクラスだから型が違うのでは?」 と思われる方もいるかもしれませんが、 WebApplication はIApplicationBuilderのInterfaceを実装しているので、ここは問題なしです。 再利用可能なクラスによる追加 インライン定義での追加はサクッとできてお手軽なのですが やはり可読性や再利用性などを考えた場合、事前に再利用な可能なクラスにまとめて使いまわす方が得策とされています。 本章では事前に定義したミドルウェアを追加していく方法を見ていきたいと思います。 なお事前に定義したミドルウェアとしては「 組み込みミドルウェア 」と「 カスタムミドルウェア 」があるため、それぞれについて見ていきます。 組み込みミドルウェア ASP.NET Coreにおいては 組み込みミドルウェア コンポーネント が豊富に提供されています。 先ほど見たProgram.csにおいて書かれているミドルウェア群も、組み込みミドルウェアの一例になります。 ここでは実際に UseHttpsRedirection のメソッドを例にしてソースコードを見てみたいと思います。 UseHttpsRedirectionの ソースコード を見ると、Summaryとして Adds middleware for redirecting HTTP Requests to HTTPS. と記載されていることから、ミドルウェアに追加するためのメソッドであることがわかります。 またこちらのソースコードの中身を見てみると、Useメソッドと同じような形で拡張メソッドとして定義されていることがわかります。 public static IApplicationBuilder UseHttpsRedirection(this IApplicationBuilder app) { ArgumentNullException.ThrowIfNull(app); var serverAddressFeature = app.ServerFeatures.Get<IServerAddressesFeature>(); if (serverAddressFeature != null) { app.UseMiddleware<HttpsRedirectionMiddleware>(serverAddressFeature); } else { app.UseMiddleware<HttpsRedirectionMiddleware>(); } return app; } この時、コード内において app.UseMiddleware<HttpsRedirectionMiddleware>(serverAddressFeature); と実行している場所があります。 ここで書かれている HTTPsRedirectionMiddleware というのが 事前定義されたミドルウェア本体 であり、 UseMiddlware<TMiddleware> メソッドを利用して追加していることが分かります。 他の UseStaticsFiles() メソッドなども同様の形で拡張メソッドとして定義されており これらのメソッドを通して、組み込みミドルウェアをリクエストパイプラインへと追加しています。 カスタムミドルウェア 先ほどはASP.NET Core側で用意されている組み込みミドルウェアに言及しましたが もちろん自分でミドルウェアを作成したいようなケースも往々にしてあります。 その際、先ほどのHTTPsRedirectionMiddlewareのようなクラスを自分で定義することが可能です。 ただし、どんなものでもいいわけではなく、作成に当たっていくつかルールが存在します。 公式ドキュメント によると、ミドルウェアは以下のようなものを持つ必要があるとのことです。 RequestDelegate 型のパラメーターを持つパブリック コンストラクター。 Invoke または InvokeAsync という名前のパブリック メソッド。 このメソッドでは次のことが必要です。 Task を返します。 HttpContext 型の最初のパラメーターを受け取ります。 先ほどの HTTPsRedirectionMiddleware のソースコードを見ても、これらが含まれていることが確認できます。 また必須ではないようですが、組み込みミドルウェアのように拡張メソッドを定義してあげることも一般的のようです。 定義してもしなくても性能的な部分では変わりませんが、可読性の向上を目的としているようです。 その際、組み込みミドルウェアと同様の形として ***Extensitons という名称のstaticクラスで定義する Use*** という名称の拡張メソッドを定義する といった形にするかとよいかと思われます。 追加する順番について これまでリクエストパイプラインにミドルウェアを追加する方法について説明してきましたが この ミドルウェアを追加する順番というのが、実はとても重要です!! これに関しては 公式ドキュメント にも以下のように言及されています。 Program.cs ファイルでミドルウェア コンポーネントを追加する順序は、要求でミドルウェア コンポーネントが呼び出される順序および応答での逆の順序を定義します。 この順序は、セキュリティ、パフォーマンス、および機能にとって重要です。 つまりUseメソッドを呼び出した順にミドルウェアが追加され、その順番に処理も行われます。 上記のProgram.csのコードでリクエストパイプラインの構築を行う場合 ExceptionHandlerのミドルウェアでの前処理を行う ↓ HstsのMidlewareでの前処理を行う ↓ EndpointRoutingミドルウェアでの前処理を行う ↓ ... (略) コントローラでの処理が行われる (略) ... ↓ EndpointRoutingミドルウェアでの後処理を行う ↓ HstsのMidlewareでの後処理を行う ↓ ExceptionHandlerのミドルウェアでの後処理を行う といった順番で処理が行われます。 順番が大切な理由 「順番を誤ると何かまずい事が起こるの?」という問いに対する例を一つ挙げたいと思います。 例えば一番最初に呼ばれているExceptionHandlerのミドルウェアを、リクエストパイプラインの後半で実行するよう変更するとします。 この ExceptionHandler のミドルウェアの役割としては 例外をキャッチし、それらをログに記録し、代替パイプラインで要求を再実行するミドルウェアをパイプラインに追加します。 との記載があります。 つまり、この ミドルウェアがあるからこそ例外がキャッチされログが記録される わけです。 逆に言えば、このミドルウェアが実行される前のソースコードにおいて例外が発生しても、それはログに残りません。 そうするとエラーの解析も難しくなり、障害が起きた時の復旧が困難になってしまいます。 このため、このExceptionHandlerのミドルウェアは一番最初に持ってくる事が大切となります。 他のミドルウェアに関しても同様に、追加する順番には理由があるものが多いです。 そのため 既存のリクエストパイプラインの順番はむやみに変えない 新規にミドルウェアを追加する場合は順番に気を付ける といった心がけが重要になるかと思います。 ターミナルミドルウェア 先ほどまでは Use メソッドを使ってミドルウェアにパイプラインを追加しました。 もう一つ、追加する方法として Run メソッドを利用する方法があります。 注意点として、 Program.csファイルの最後で利用されている app.Run() とは別モノです。 Program.csの最後で利用されているのはApplicationをスタートさせるための Run() であり、 今回紹介するのはMiddlewareを追加するための Runメソッド (拡張メソッド)です。 詳細はリンク先の定義を確認してみてください。 このRunメソッドで追加したミドルウェアは ターミナルミドルウェア(もしくは終端ミドルウェア) と呼ばれるものであり、ターミナルミドルウェアが呼ばれた時点でリクエストパイプラインは終了する形となります。 実際にやってみましょう。 以下のようにターミナルミドルウェアを2つ追加します。 app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); //1つ目のターミナルミドルウェアの追加 app.Run(async context => { await context.Response.WriteAsync("1st Hello world."); }); //2つ目のターミナルミドルウェアの追加 app.Run(async context => { await context.Response.WriteAsync("2nd Hello world."); }); app.Run(); この状態でアプリを起動し、以下のURLに遷移します。 Http://localhost:{port}/Home/Index すると、”1st Hello world.”という文字が表示されました。 1つ目のターミナルミドルウェアによってレスポンスが返されていることがわかります。 ただここでふと思ったのですが 今回のサンプルプロジェクトにはControllerコンポーネントに、HomeControllerクラスとIndexメソッドは定義されています。 ターミナルミドルウェアより先にMapControllerRouteによってルーティングが定義されているため リクエストはControllerへとルーティングされ、以下のようなViewが返されるかと思ったのですが、ターミナルミドルウェアの処理が優先されました。 ここの処理がいまいち納得がいっておらず、少し考察してみたいと思います。 考察 ※ここからの記載は真偽の定かではない独自の考察になります まず、上記のProgram.csにおいてMapControllerRouteメソッドによってルーティングが設定されています。 ターミナルミドルウェアである Run() が存在しない場合、このメソッド自体は正しく機能していることは確認できました。 そのため、ルーティングの設定自体は正しく行えているものとします。 ここで、 公式ドキュメント のルーティングに関する記載に以下のような文章がありました。 (翻訳がわかりづらかったので原文で載せます。) Note: Routes added directly to the WebApplication execute at the end of the pipeline. 「WebApplicationインスタンスで直接加えられたルートはPipelineの最後に追加されます」と書かれています。 今回は、この「WebApplicationインスタンスで直接加えられたルート」のケースに該当すると考えます。 また、Runに関する 公式ドキュメント には以下のような記載があります。 Run デリゲートでは、next パラメーターは受け取られません。 最初の Run デリゲートが常に終点となり、パイプラインが終了されます。 そのため、以下の2点から ルーティングはPipelineの最後に追加される Runが呼ばれた時点でPipelineが終了してしまう ルーティングのMiddlewareに到達する前に、RunによってPipelineが終了してしまったのではないかなと考察しました。 回避策 ちなみに以下のような実装をすると、 ルートが存在する場合はControllerの処理が走る ルートが存在しない場合はRunの処理が実行される といった処理を実現できました。 app.UseRouting(); app.UseAuthorization(); //UseEndpointsのミドルウェアを追加 app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); }); //ターミナルミドルウェアの追加 app.Run(async context => { await context.Response.WriteAsync("Hello world."); }); app.Run(); ちなみに、これは少し前のASP.NET Coreのバージョンでの書き方であり ASP.NET Core 8.0では、 UseEndpoints および UseRouting をわざわざ書かなくていいとされています。(明示的に書く必要がある場合を除き) 実際、UseEndpointsの部分に ASP0014 の警告文も表示されます。 参考: ASP.NET Core でのコントローラー アクションへのルーティング なお、UseEndpointsを利用するとルーティングが正しく行われる理由としては UseEndpointsの 仕様 として、以下の通りであるためです。 一致が見つかると、UseEndpoints ミドルウェアはターミナルです。 ターミナル ミドルウェアについては、この記事で後ほど定義します。 UseEndpoints の後のミドルウェアは、一致が検出されなかった場合にのみ実行されます。 これにより、 UseEndpointsにおいてルートが見つかった場合は、そこでパイプラインが終了しRun()が実行されない UseEndpointsにおいてルートが見つからなった場合は、後続のMiddleware の処理が行われRun()が実行される という処理となると考えられます。 ということで一応回避策はありましたが、MSが推奨する方法ではないですし、あまり納得もいっていないです。 ASP.NET Core2.2時代などはUseMVCの拡張メソッドを利用してミドルウェアを追加した場合 パイプラインの構造が変更され、ターミナルミドルウェアが定義されていても、ルートが一致した場合は無視される動きがありました。 このあたりがASP.NET Core 8.0のMapControllerRouteでは挙動が違うのかなとも予想されます。 MapControllerRouteの挙動などはRoutingの調査の時に改めて行いたいと思います。 今後ASP.NET CoreのRoutingを題材とした記事を書こうと思っているので、その時まで少々お待ちください。 このあたり詳しいよ!わかるよ!という方はぜひぜひコメントお待ちしています。 パイプラインの分岐 RunとUseのほかに Map という拡張メソッドも存在します。 こちらは何かというと、パイプラインの処理をパスによって分岐することが可能となります。 実際にソースコードを修正してみましょう。 app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); //分岐1 app.Map("/sios1", HandleMapTest1); //分岐2 app.Map("/sios2", HandleMapTest2); //分岐3(パスに該当しなかった場合) app.Run(async context => { await context.Response.WriteAsync("Hello I am non-Map sios."); }); app.Run(); //分岐1用の処理 static void HandleMapTest1(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Hi, I am sios1"); }); } //分岐2用の処理 static void HandleMapTest2(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Hello, I am sios2"); }); } こちら実行すると、それぞれ分岐した結果のレスポンスが得られました。 分岐なし Http://localhost:{port} 分岐1 Http://localhost:{port}/sios1 分岐2 Http://localhost:{port}/sios2 ただ個人的に「Program.csの可読性が一気に落ちるなぁ」という印象を持ちました。 このMapの拡張メソッドを使用しないと実現できないユースケースを除いては、あまり利用しない方がよいのかなと感じました。 ただ、使いこなせてないだけかもしれないので、気にはかけていこうとは思います。 まとめ 今回はミドルウェアとリクエストパイプラインの概要を説明しました。 ミドルウェアを定義し、それをリクエストパイプラインに追加することでコントローラでの処理の前処理・後処理を実現できることがわかりました。 その際、ミドルウェアを追加する順序も非常に重要であることも気を付けたいポイントです。 ルーティングのところで宿題事項が残ってしまいましたし、パイプラインもまだまだ奥が深いような気がするので、新たな発見があれば追加で記事にしていきたいと思います! ではまた! 参考文献 ASP.NET Core のミドルウェア カスタム ASP.NET Core ミドルウェアを記述する ASP.NET Coreのカスタムミドルウェア ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post ASP.NET Core入門 – ミドルウェアとパイプライン 解説【.NET 8】 first appeared on SIOS Tech. Lab .
PS/SLの佐々木です。 2024/4/13, 14でWEB3/AI SUMMIT2024というイベントがあり参加してきました。 こちらはよくあるカンファレンス形式でテーマは表題通りWeb3関係がメインで、Web3の中でAIをどのように利用していくかというパネルディスカッションが多い印象でした。 こちらのイベントに今回参加してきたので内容を紹介したいと思います。 パネルディスカッションのテーマ 多かったパネルディスカッションのテーマは以下の通りです。 国内のWeb3の取り組み 海外のVCのトレンド Web3とAIの可能性 ステーブルコイン Web3のマスアダプションに向けて必要なもの うまくいっている事例 全体を通して 国内のWeb3の取り組み 日本政府は暗号資産の税率の変化やDAOの法人格化、また会計での課題について現在の進捗と課題を話していました。 先日自民党議員の平さんがWeb3ホワイトペーパーにも出していましたが、2024年に暗号資産の課税方式が期末時価評価課税の対象から除外され、シンガポールやスイスに出て行ってしまった企業家が日本に戻ってきてくれることを期待するといっていました。 またDAOの法人化では現在の合同会社と同等の扱いができるように提言を出すとのことでした。 一方でキャピタルゲインの課税についての議論や暗号資産を寄付した場合などどのような控除が必要なのかといった議論はこれからだとおっしゃられていました。 日本は最初に規制を強め徐々に整備を進めていて、これからな部分は多いものの世界でも進んだ市場を提供していくという力強いメッセージがありました。 日本企業の取り組みとしては大手IT企業では独自でウォレットを開発していたり、NFTを用いたスタンプラリーのようなプロダクトの開発を行っています。 また今後考えていることとしてはIPとコラボした取り組みやコミュニティへの貢献に関するプロダクト、フィールセーフのような仕組み作りを考えているという話がありました。 海外のVCのトレンド 海外のVCトレンドとしてはインフラレイヤーのプロジェクトへの投資が多い印象でした。 様々なL1, L2レイヤーのパブリックチェーンのプロジェクトがありますが、それぞれの相互運用性であったり、Dappsが開発されるにあたってのツールやDeveloperフレンドリーな開発体験を提供するための機能がまだまだ足りておらずこの問題には関心があるようでした。 ブースに出店していた海外のプロジェクトもこれらの問題を解決するためにチェーンから開発してより上位のレイヤーで起きている問題を解決しに行くといったアプローチをとっていることが多い印象でした。 またRWA(Real World Asset)によりコレクションやアンティークの流動性を高めたり、AI関連のプロダクトに関心があるようでした。 Web3とAIの可能性 AIの問題点からそれをWeb3で解決できるというのがセッション全体を通しての流れでした。 AIの問題点は以下の通りです。 データが巨大企業に集まってしまっている 使用されているデータの信憑性 アルゴリズムの不透明さ 結果に対しての検証が困難 企業のさじ加減でAIを使用できなくなる可能性も これらの問題に対してWeb3ではデータやロジックには透明性があり、安全に使用できるのではないかとの見方がされています。 また方法の詳細は分かりませんが、出力の正しさを検証する際にゼロ知識証明を使用することができるのではないかとの意見がありました。 またP2Pの上で構築することで持続可能性も高く、だれもが安価にAIを使用できる未来を示唆している人もいました。 また現在はマシンパワーとデータ量で勝負する(物理で殴るという表現もされますが、、、)世界になってしまっていますが、アルゴリズムとデータがパブリックなものになってくれば誰もがAIを作れる世界線もありえ知恵やアイディアで勝負できるようになるかもしれません。 ステーブルコイン 異なるコイン間のインターオペーラビリティに関する問題と既存のPaymentサービスの差別化(少額決済がやりやすいとか)に関する議論や可能背について語られていましたが、いまひとつステーブルコインが便利な点がわかりませんでした。 国際送金に関しては手数料が安くなる理屈は理解できるのですが、例えばUSDCとJPYCに交換する手順の簡略化など今後行っていかないといけないんだろうと思いました。 Web3マスアダプションに向けて必要なもの まず1点目がWalletについてです。 現在の見立てではユーザーがノンカストディアルウォレットを管理してアプリケーションにアクセスすることは考えにくいとされています。 ウォレットの必要性により現在ユーザーがWeb3アプリケーションに参画しにくくなっている(実際にEmailでログインとWalletログイン両方を備えたサービスでWalletログインを使用したユーザーはいなかった)というのは私自身も感じています。 しかしカストディアルウォレットを使用すると署名用のキーを握られてしまうことになるのでWeb3の理念的には微妙なのかなと思ってたり。 この問題に関しては問題提起のみで解決に関する議論やアイディアはなかったのでチャンスのある領域です。 2点目はチェーン間のインタオペーラビリティです。 現在非常に多くのチェーンがローンチされています。 しかしチェーン間でのデータやトークンのやり取りが非常に難しいという問題があります。 そのためユーザーや開発者はDappsが使用しているチェーンごとにWallet(複数チェーンをサポートしているWalletはありますが、ローンチされているすべてのチェーンに対応することは非常に難しい)を持ち、それぞれのトークンを管理するという煩雑さはユーザーのみならず開発者もやりずらいポイントになっています。 同一チェーンでDappを開発する場合にはチェーン内でのインタオペーラビリティは非常に強みになってくるのですが、様々なチェーンがローンチされている現在はそのメリットが薄まってしまっています。 ここに関しては規格を整備していくのかBridgeするアプリケーションを開発するのか様々なアプローチが考えられるところです。 これらによりユーザーはWeb3に参入しやすくなり、開発者は技術選定がしやすくなったり、Dappの開発が活発になるのではないかと考えられます。 うまくいっている事例 うまくいっている事例ではナイジェリアやアフリカ方面の話があり、自国の政治状態が不安定で自国通貨のボラリティがビットコインのボラリティよりも下回っている場合は資産を暗号資産に移している人が多いようでした。 またアフリカのほうでは銀行口座を持っている人の割合が少なく、また人口も増加しているためマスアダプションに向けてはかなり導入しやすい地域だといわれています。 このようにDefiの分野では導入が進んでいる場所もあるようです。 またチェーンがものすごいTVLをつけているといった話もありましたが、TVLを支えている技術や優位性が今一つまだ理解できておらず、今後個人的な調査課題とさせていただければと思います。 全体を通して 今後の展望や課題は上記で述べた通りで、様々なセッションがありましたが、議題の違いとアプローチの違いはあれどマスアダプションに向けてのボトルネックになっている場所の認識は大方同じように感じました。 個人的にもローンチされているチェーンが多すぎてキャッチアップは追いつかないし、チェーンを変えたくなった場合にどうすればよいかあまりわかっていないので新しいプロダクトの開発状況は今後もウォッチして何か動きがあればこちらで発信していきます。 イベント全体について 今回teamz様か主催しているイベントだったのですが、全体の雰囲気としては日本人と外国人が半分半分ぐらいな印象でした。 また登壇者に関しては2/3ぐらい外国人でほとんどのセッションも英語で行われていました。 しかしたくさんのリアルタイム自動翻訳機があり、精度もそこそこなので英語を聞きながら自動翻訳機を眺めていれば内容は大方問題なく理解できるレベルかと思いました。 またロビーでは朝からお酒やお菓子の提供がされていてDJが爆音で音楽をかけているという日本のイベントではあまり見ない光景で新鮮で非常に楽しかったです。 また私はいろんなブースを回るのが好きなのですが、今回の出展企業やプロジェクトは海外のものが多く(日本人のほうが少なかった)なぜ規制の厳しい日本に来ているのか質問したりプロダクトの説明を受けたりしました。 どうやら規制は厳しいがそれだけ参入障壁が高く、また個人ID(マイナンバー)が普及しきっていないのでチャンスはあると考えているようでした。 またIPが豊富に存在し、日本の規制当局も規制緩和に向けてかなり前向きにとらえていることが非常に好印象のようで、数年前に日本のWeb3企業がシンガポールやスイス拠点でやっているのを横目で見ていたので非常に新鮮な意見でした。 またビットコインの抽選会やハッカソン、VIP専用のエリアやセッションなども新鮮で2日間を通して非常に刺激を受けました。 来年度以降もイベントを開催するようなのでまた是非参加したいと思いました。 イベントロビー 登壇ステージ 協賛企業一覧(日本企業ほとんどない笑) 参考 自民党議員 平将明議員のHPに乗っているWeb3ホワイトペーパーのリンクを張っておきますので興味のある方は読んでみてください! web3ホワイトペーパー2024要旨.pdf web3ホワイトペーパー2024.pdf ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post TEAMZ WEB3 / AI SUMMIT 2024イベントレポート first appeared on SIOS Tech. Lab .
はじめに こんにちは、サイオステクノロジーの藤井です。経産省が策定した「 ソフトウェア管理に向けたSBOMの導入に関する手引 」という資料の中で紹介されているFOSSologyというSBOMツールについて調査したので、この記事では、その使い方や特徴について解説しています。 SBOMとは SBOMとは、ソフトウェア部品表(Software Bill of Materials)、つまり、ソフトウェアコンポーネントやそれらの依存関係の情報などの一覧のことです。 詳しくは、 SBOM解説記事 を参考にしてみてください。 FOSSologyとは SBOM解説記事内でも紹介した、経産省の「ソフトウェア管理に向けたSBOMの導入に関する手引」の中では、以下の様に紹介されています。 開発元:Linux Foundation OSS の名称やバージョンの特定はできないものの、対象ソフトウェアに含まれるコンポーネントのライセンス及び著作権を検出し、管理することが可能 Web UI を用いたインポートや解析が可能 また、 公式サイト や GitHub では、要約すると以下の様な特徴が挙げられています。 FOSSologyは、ライセンスや著作権などのスキャンが出来るOSSです。 システムとしては、データベース+Web UI の構成です。 ワンクリックで、ソフトウェアのすべての著作権表示を含む SPDX ファイルまたは ReadMe を生成できます。 FOSSologyの導入手順 https://fossology.osuosl.org/ にテストサーバーが立っているので、ちょっと試したいときにはここで出来ます。(毎日データが初期化されます。) 外部に公開したくないコードのスキャンをする場合などは、ローカルにサーバーを構築する必要があります。 インストール 今回は、wsl2でubuntu-22.04を動かし、そこにインストールしました。 wsl2やubuntu-22.04をインストールする手順については、省略します。 公式のインストール手順解説動画があります。( https://www.youtube.com/watch?v=q12KwmPYZG4 ) 情報が古いところが有り、現在とコマンドが異なったりするので、基本的には wiki のコマンドに従う必要がありますが、どのコマンドにsudoが要るかとか、どんなログが出るか、など適宜参考にすると良いと思います。 cloneしてインストール git clone https://github.com/fossology/fossology.git cd fossology/ sudo apt-get update sudo apt install lsb-release sudo ./utils/fo-installdeps --everything ビルド cmake -S. -B./build -G Ninja cmake --build ./build --parallel sudo cmake --install ./build fossyユーザーを作成し、DBをセットアップする sudo /usr/local/lib/fossology/fo-postinstall http://localhost/repo/ にアクセス Username:fossy、password:fossyでログイン スケジューラーの設定 sudo systemctl enable --now fossology sudo systemctl start fossology PHPの設定 sudo ./install/scripts/php-conf-fix.sh --overwrite コードのアップロード 上部メニューのupload > from fileから Upload a New File 画面を開く ファイルを選択し、分析内容を選んでuploadを押す SBOMの生成 上部メニューのBrowseからディレクトリを開く CycloneDX generationボタンでCycloneDXのjsonファイルが、SPDX2 generationボタンでspdxのrdfファイルが生成できます。この例では、CycloneDX形式で出力してみます。 CycloneDXやSPDXについて、詳しくは こちら の記事をご覧ください。 この様に、ファイルごとのライセンスとcopylightの情報を含んだSBOMを生成することが出来ました。 SBOM生成以外の機能 READMEの生成 ReadME_OSS generationボタンで出来ます。Copyrightが羅列されたtxtファイルが作成されました。 ライセンス管理機能 各フォルダを開くと、その中のフォルダやファイルにどんなライセンスのファイルがあるかを確認できます。 また、それぞれのライセンスのファイルが、全体で何個あるのかも確認できます。 個別のファイルを開くと、そのファイルの内容と、そのライセンスが表示されます。自動検出が間違っていた場合は、ここから、削除や編集ができます。 Copyright このソフトウェアに含まれるcopylightの一覧を表示できます。 各項目を選択するとどのファイルにそれぞれのcopylightが記載されているか確認することが出来ます。 API 参考 APIからFOSSologyを操作することもできます。CI/CDなどに組み込む場合に活用できそうです。 まずは、上部メニューのAdmin > Users > Edit User Accountから tokenを取得します。 このtokenをHeaderに`Authorization:Bearer `の形で指定することで、各種操作を行うことが出来ます。 例えば、GET http://localhost/repo/api/v1/foldersで、フォルダーの一覧を取得できます。 利用できるAPIのドキュメントは、openapi定義yamlの形で github上 にあるので、これを swaggerエディター 等で読み込むことで、確認できます。 まとめ 今回は、FOSSologyの特にSBOMツールとしての側面について解説しました。 まとめると、 メイン機能は、コードをスキャンしてライセンスと著作権を自動検出 CycloneDXかSPDX形式のSBOMを生成可能 全部GUIで操作可能+テストサーバー有で、試すハードルは低め こんな感じです。 関連記事 SBOM解説: SBOMのメリットと導入の流れ SBOMツールをカテゴリー分けしてみた SBOMの仕様:CycloneDX(CDX)・SPDX SBOMツール紹介 ~ Dependency-Track編 ~ ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post SBOMツール紹介 ~ FOSSology編 ~ first appeared on SIOS Tech. Lab .
はじめに こんにちは、サイオステクノロジーのあさりです。今回は、PythonのWebフレームワークであるDjangoに組み込まれているDjango Adminに独自のページを追加する方法を紹介します。内容としては、DjangoAdminのモデル一覧画面におけるIDのリンク先をデフォルトの編集画面から独自で作成した詳細画面に遷移するようにしたいと思います。 環境 Python3.11 Django4.2 前提 独自のページを追加するにあたって何らかのモデルが必要となります。今回は、プロジェクト内にmyappというアプリケーションが存在し、myapp/models.pyに次のような「Book」モデルが定義されており、データベースに反映、myapp/admin.pyで管理画面に追加済みである想定です。プロジェクトの作成から管理画面への追加については こちら の記事を参考にしてみてください。 # myapp/models.py from django.db import models class Book(models.Model): class Meta: db_table = 'book' verbose_name = '本' title = models.CharField(verbose_name = 'タイトル', max_length=100) author = models.CharField(verbose_name = '著者', max_length=100) # myapp/admin.py from django.contrib import admin from .models import Book class BookAdmin(admin.ModelAdmin): list_display = ('id', 'title', 'author') admin.site.register(Book,BookAdmin) Django Adminに独自のページを追加する 今回は以下のID部分のリンク先をデフォルトの編集画面から独自で作成した詳細ページに遷移するようにしたいと思います。 独自ページ追加は以下の3つのステップで行います。 ビュー関数の作成 テンプレートの作成 URLパターンの登録 それでは実際に実装していきましょう。 ビュー関数の作成 ビューは自作もできますが、今回は単一のオブジェクトの詳細を表示するためのDetailViewという組み込みビューを使用します。DetailViewは、特定のモデルのインスタンスを取得し、それをテンプレートに渡します。それでは、myapp/views.pyで次のようなビューを作成しましょう。 # myapp/views.py from django.views.gneric import DetailView from .models import Book class BookDetailView(DetailView): model = Book #参照するモデルを指定 template_name = 'admin/myapp/book_detail.html' #データを渡すテンプレートを指定 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # fieldsに各フィールドのverbose_nameとフィールド値を格納 context['fields'] = [(field.verbose_name, getattr(self.object, field.name)) for field in Book._meta.fields] return context テンプレートの作成 先ほどのビューからデータを受け取るテンプレートを作成していきます。今回はプロジェクト直下にtemplates/adminフォルダを作成し、そこにbook_detail.htmlファイルを置きます。 {% extends "admin/base_site.html" %} {% load static %} {% block content %} <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}"> </head> <body> <h1>Book Details</h1> <!-- フィールド名とその値を表示します --> {% for name, value in fields %} <p> <strong>{{ name }}:</strong> {{ value|default:"" }} </p> {% endfor %} </body> </html> {% endblock %} 一行目でadmin/base_site.htmlを継承することにより、管理画面のヘッダーをつけることができます。今回の詳細画面ではビューから受け取ったfieldsを使って、「フィールド名:値」の形で表示されるようにしています。 次に独自に作成したtemplatesディレクトリが参照されるように、設定ファイルのTEMPLATESを次のように編集してください。 # settings.py TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ os.path.join(BASE_DIR, 'templates'), # templatesディレクトリを追加 ], 'APP_DIRS': True, ... }, ] URLパターンの登録 独自のURLパターンの登録は、ModelAdminのget_urlsメソッドをオーバーライドすることで可能です。今回は次のようにURLパターンと呼び出されるビューを登録しました。また、一覧画面でのIDのリンク先を詳細画面とするlink_to_detailメソッドを定義し、一覧画面で表示するフィールドとして設定しています。 # myapp/admin.py from django.contrib import admin from django.urls import path, reverse from .models import Book from .views import BookDetailView class BookAdmin(admin.ModelAdmin): def get_urls(self): urls = super().get_urls() # URLパターンの登録 my_urls = [ path('<int:pk>/detail/', self.admin_site.admin_view(BookDetailView.as_view()), name='detail_view'), ] return my_urls + urls # 一覧画面でIDのリンク先として詳細画面を指定 def link_to_detail(self, obj): link = reverse("admin:detail_view", args=[obj.pk]) return format_html('<a href="{}">{}</a>', link, obj.pk) link_to_detail.short_description = 'ID' link_to_detail.admin_order_field = 'id' #idに基づくソートの指定 #表示するフィールドの指定 list_display = ('link_to_detail', 'title', 'author') ... これで”/myapp/book/1/detail”のような形でアクセス可能となります。実装としては以上になります。サーバーを立ち上げてID部分を押下した際に詳細画面に遷移するか確かめてみてください。以下のようなページが表示されたら成功です。 おわりに 今回は、DjangoAdminに独自のページを追加する方法を紹介しました。今回はDetailViewを用いて単一モデルの詳細情報を取得しましたが、Djangoには他にもモデル一覧を取得するListViewなど便利なクラスが用意されているので、試してみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DjangoAdmin 独自ページの追加方法 first appeared on SIOS Tech. Lab .
こんにちは、サイオステクノロジーの佐藤 陽です。 今回は、ASP.NET Core入門シリーズ第二弾として、 Program.cs ファイル の中身について解説していきたいと思います。 ASP.NET Core をこれから使っていくよ! Program.cs って何が書いてあるの? Startup.cs どこいった? といった方はぜひ読んでみてください。 また前回の記事から繰り返しになりますが まだ自分も勉強中の身なので、記事の内容に誤りなどありましたらコメントにて指摘いただけると幸いです。 はじめに 今回はAPS.NET Core のプロジェクトの肝である(?)、 Program.cs のファイルをコードレベルで解説していきたいと思います。 ちなみにASP.NET Core 5時代のものに関しては、武井さんの記事でも紹介していただいてます。 多分わかりやすいASP.NET Core Webアプリケーション ただ、こちらもなんだかんだ 5 年前の記事であり 色々と ASP.NET Core も変わってきているため、更新の意味も込めて改めて書いてみたいと思います。 ASP.NET Coreとは? ASP.NET Core は、.NET プラットフォームをベースとするフレームワークです。 以前は、ASP.NET のフレームワークが幅広く利用されていました。 ASP.NET Core は、ASP.NET を改良したものになります。 そして ASP.NET Core も年々進化し、2024年4月現在は LTS リリースとしては ASP.NET Core 8.0 が最新のものになります。 今回の記事は ASP.NET Core 8.0 を対象としたいと思います。 ASP.NET Coreの全体像 まず初めに、 ASP.NET Core のアプリがどのように動作するかについて見ていきたいと思います。 動作を理解したうえで Program.cs の中身を見た方が理解が捗るためです。 なお前提として、今回は IIS インプロセスホスティング のケースを見ていきたいと思います。 「ホスティングについてよくわからないよー」という方は前回の記事をご覧ください。 ASP.NET Core入門 – ホスティング 解説【.NET 8】 ではまず全体の流れを図に示します。 IIS Server に含まれる ASP.NET Core Module が 、dotnet コマンドにより ASP.NET Core アプリケーションを起動します。 なおこの ASP.NET Core アプリケーションというのは 単なるコンソールアプリケーション にすぎません。 そしてこの コンソールアプリケーションのコードこそが Program.cs ファイルに含まれています 。 コンソールアプリケーションが、 IISHTTPServer をホストし、アプリを開始します。 IIS Server がリクエストを受けると IISHTTPServer へとルーティングします。 リクエストは ASP.NET Core ミドルウェアパイプラインにて処理されます ミドルウェアパイプラインでの処理後、HttpContext としてアプリケーションコードに渡され、アプリケーションコードにて処理されます といった流れとなります。 このあたりの流れは 公式のドキュメント にも記載があります。 この後、実際にProgram.csのソースコードを追っていきますが 上の図や、全体の流れと照らし合わせながら見ていただくと、より理解しやすいかと思います。 プロジェクトを作成してみる 早速プロジェクトを作ってみたいと思います。 用意するもの Visual Studio Code C# Extension .NET SDK 8.0 プロジェクト作成 以下の dotnet コマンドを利用して新規プロジェクトを作成します。 dotnet new mvc -o aspnetcore-8-mvc 実行してみる せっかく作ったので一度実行してみます。 dotnet run --project .\aspnetcore-8-mvc\aspnetcore-8-mvc.csproj 実行が完了したら、ブラウザで http://localhost:5088 にアクセスします。 すると、アプリにアクセスできるかと思います。 プロジェクトの中身を見てみる また、プロジェクトの中身としては以下のようなものが作成されるかと思います。 今回は Program.cs ファイルに絞って解説していきたいと思います。 Startup.cs クラスは? ASP.NET Core 5.0 あたりまでのバージョンをメインで開発されていた方の中には 「Startup.csファイルってどこ行ったの??」 と思われる人もいるかと思います。 ここが ASP.NET Core 5.0 と 6.0 以降のバージョンで大きな違いの 1 つでもあります。 ASP.NET Core 6.0 以降では 最小ホスティングモデル といったものが採用され Startup.cs と Program.cs が 1 つの Program.cs ファイルに統合されています。 なお、統合されたといっても機能的には同一のものであり ASP.NET Core 6.0 以降でも以前のように Startup.cs ファイルを使った記述も可能です。 「わざわざ新しい最小ホスティングモデルに切り替える必要は無い」と公式ドキュメントにも記載があります。 参考: よく寄せられる質問 (FAQ) Program.cs の中身 先ほど作成したプロジェクトの Program.cs の中身を見てみます。 var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); では早速、上から順を追って見ていきたいと思います。 Builder作成 var builder = WebApplication.CreateBuilder(args); アプリをビルドするための Builder ( WebApplicationBuilder ) を作成します。 ではこの Builder が何をするかというと ソースコード や ドキュメント を見る感じ、以下のようなことを行っているように見えます。 (聞き慣れないワードが出てきているかもしれませんが、今後のブログにて解説する予定です。) 新しい構成ソースとプロバイダーを追加する Hostされる環境の情報を取得する ログプロバイダーを追加する DIで用いるサービスを追加する HostとWebHostを構成する なおASP.NET Core5.0 以前では、以下のように書かれていた箇所に該当します。 public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } //ここの部分 public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup(); } この時、6.0以降の WebApplication.CreateBuilder() と、5.0以前の CreateWebHostBuilder.Build() を比較すると、 「ASP.NET 5.0も6.0以降も同じ処理って言ってたのにApplicationのビルダーなのかWebHostのビルダーなのかで何か違うじゃん」 といったように感じる方もいられるかもしれません。 このあたりがまだ追い切れていないのですが、以下の記事が非常に参考になりました。 Comparing WebApplicationBuilder to the Generic Host これを踏まえての自分の解釈にはなるのですが、 ASP.NET Core 5.0以前においては Program.cs アプリケーションの起動とライフタイムを管理するための WebHost を構築するコードが含まれる Startup.cs パイプラインなどの Application の要素を構築するコードが含まれる (パイプラインに関してはまた今後のブログで紹介していく予定です。) → こちら に書きました。 という区分けになっていたように見えます。 ただ、これらがひとつのProgram.csファイルに統一されるようなになったため Hos tのBuilderではなく、 Hostを含むApplication全体 のBuilderとして実装され、実装が異なっていると考えました。 ただ機能としては同じであり、 WebApplicationBuilder のプロパティとしてもHost, WebHostが含まれていることがわかります。 そのため、WebApplicationBuilderを通してHostやWebHostの構成も可能です。 イメージとしてはWebHostBuilderをWebApplicationBuilderでラップしているような感じでしょうか。 次に進みます。 DIコンテナへのサービス追加 // Add services to the container. builder.Services.AddControllersWithViews(); ここに書かれているコードは、DI コンテナにサービスを追加しているものになります。 DI コンテナ周りについては追ってブログで紹介したいと思うので、本記事では割愛します。 なおこのコードは、以前のバージョンでいうところの Startup.cs クラスの ConfigureServices メソッドで記載している箇所に該当します。 次に進みます。 WebApplicationインスタンスの作成 var app = builder.Build(); ここでWebApplicationBuilderを利用して、WebApplicationのインスタンスを作成します。 このWebApplicationのインスタンスは以下のような仕事をします。 ミドルウェアパイプラインの構築 アプリケーションの開始 続くコードで実際にこれらの処理を実装していきます。 if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); ここでは利用するミドルウェアを指定し、パイプラインを構築します。 この時、ミドルウェアが実行される順番は重要であるため、コードを記載する順番には気を付ける必要があります。 また、 上の図 のstep4にて 4. リクエストは ASP.NET Core ミドルウェアパイプラインにて処理されます と書きましたが、この処理するパイプラインを構成しているのがここのソースコードになります。 また、こちらのコードはASP.NET Core 5以前のバージョンでいうところの Configure メソッドで記載している箇所に該当します。 アプリの開始 app.Run(); このコードによって、サーバーおよびアプリケーションを起動し、ホストが終了するまで呼び出し元のスレッドをブロックします。 Program.csソースコードの中身としては以上となります。 まとめ 今回は.NET 8.0におけるASP.NET CoreのProgram.csの中身を見てみました。 ざっくりとまとめると ASP.NET Core 6にて採用された最小ホスティングモデルにより、Startup.csファイルとProgram.csファイルが統合された ただし、機能的に違いはなくどちらを採用してもよい Program.csに書かれている内容としては、コンソールアプリケーションのソースコードである コンソールアプリケーションによってホストが構成がされたのちに、実際にサーバーおよびアプリが開始される リクエストは IIS→IISHTTPServer→Middleware Pipeline→ApplicationCode といった順で処理される といった感じです。 次回以降の記事では、リクエストパイプラインや、ルーティング周りなどをもう少し詳細にみていきたいと思います。 ではまた! 参考文献 ASP.NET Core の概要 Comparing WebApplicationBuilder to the Generic Host ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post ASP.NET Core入門 – Program.cs 解説【.NET 8】 first appeared on SIOS Tech. Lab .
はじめまして! サイオステクノロジー の安藤 浩です。E2Eテストで利用されるPlaywright の入門として、インストールからコード生成、テスト実行の方法についてご紹介させていただきます。 Playwright とは Web アプリのテスト、テスト自動化が可能なNode.jsの ライブラリのことです。 特徴として以下が挙げられます。 クロスブラウザ対応 非同期処理を適切に処理して、シンプルなテストコードが書ける ブラウザ操作からコードが生成できる Visual Regression Test (VRT)に対応 ほかのE2Eテストツールは Selenium, Puppeteer, Cypressなどが挙げられ、比較対象となります。 ここからPlaywright のインストールからブラウザ操作でのテストコード生成、テスト実行、テスト実行結果の確認までご紹介します。 環境 実行環境は以下の通りです。 OS/SW Version Windows 10 Pro 22H2 VSCode 1.88.0 Node.js 20.12.2 npm 10.5.1 Playwright のインストール 対象のプロジェクトにディレクトリでPlaywright を導入したい場合、以下のコマンドを実行します。(現時点での最新バージョンは1.43.0 ) npm init playwright@latest いくつか選択肢が出てくるので、選択して初期化します。例えば、TypeScript か JavaScript でテストコードを書くかというものです。 Getting started with writing end-to-end tests with Playwright:Initializing project in '.' ? Do you want to use TypeScript or JavaScript? ... > TypeScript JavaScript ここでは以下のように設定しておきます。 √ Do you want to use TypeScript or JavaScript? · TypeScript √ Where to put your end-to-end tests? · tests √ Add a GitHub Actions workflow? (y/N) · true √ Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) · true ファイル生成後のファイル構成は以下のようになります。 Playwright Test for VSCode というVSCodeの拡張機能があるのでこちらもインストールします。 https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright この拡張機能を利用して、 ブラウザ操作からコード生成する方法を紹介します。 ブラウザ操作でのコード生成 まず、VSCodeでTestingを表示します。VSCodeのメニューのView > Testing から表示できます。 Testingの画面下部にPlaywright の拡張機能が表示されているので、「Show browser」にチェックを入れ、「Record new」を押下します。 その時、Chromiumが起動するのでアドレスバーにテスト対象のアドレスを入力します。ここではPlaywright のホームページ ( https://playwright.dev/ )を指定します。 ページが表示されたら、赤枠の箇所を押下し、マウスカーソルを黒背景のPlaywrightの箇所に移動し押下してみます。 すると、文字列が正しいかというチェックをするアサーションの画面(Assert that element contains text)が表示されるので、赤枠のチェックボタンを押下します。 ここまででVSCode上ではtest-1.spec.ts というファイルが生成され、以下のコードが生成されています。 import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { await page.goto('https://playwright.dev/'); await expect(page.locator('h1')).toContainText('Playwright'); }); 続いて、ブラウザで画面上の「GET STARTED」ボタンを押下し、画面を表示します。 先ほど同様、赤枠の文字列のアサーションのボタンを押下し、「Installation」の箇所を押下します。 アサーションの画面(Assert that element contains text)が表示されるので、赤枠のチェックボタンを押下します。 「Introduction」の箇所も同様にアサーションを追加します。 ブラウザを閉じると最終的に以下のテストコードが生成されます。test-1.spec.ts ファイルを保存しておきます。 import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { await page.goto('https://playwright.dev/'); await expect(page.locator('h1')).toContainText('Playwright'); await page.getByRole('link', { name: 'Get started' }).click(); await expect(page.locator('h1')).toContainText('Installation'); await expect(page.locator('#introduction')).toContainText('Introduction'); }); ※テストのタイトル (ここでは’test’になっている) などは分かりやすくするため適宜変更してください。詳細は https://playwright.dev/docs/api/class-test をご参照ください。 生成されたコードによるテスト実行 以下のテストコードの箇所にテスト実行ボタンが表示されるので押下するとテストが実行されます。 テスト実行後は以下のようになり実行結果が確認できます。 すべてのテストを実行したい場合は以下のコマンドを実行します。 npx playwright test テスト結果の確認 (レポートの表示) テストが完了したら、以下のコマンドを実行することでテスト結果のレポートが表示されます。 npx playwright show-report 指定のURLにアクセスするとHTML がlocalhostで見られるようになります。 各ブラウザでのテスト状況などがわかるので便利ですね。失敗した場合のテストは失敗箇所がわかるようになっています。 まとめ Playwrightの特徴とインストール、ブラウザ操作でのコード生成、テスト実行・結果確認までご紹介しました。 ブラウザ操作でのコード生成では、正確なコードであるか検証が必要かつE2Eテストでは人間の見た目に近い操作にしたいはずなのでpage.locator でIDによる指定などはしないはずなので、コードの改良は必要だと思います。 導入も容易にできそうですし、コード生成機能がついているのでメンテナンスも比較的容易になりそうだと思います。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Playwright 入門 – インストール、ブラウザ操作でのコード生成、テスト実行 first appeared on SIOS Tech. Lab .
今回はSBOMツールの一つである「bom: The SBOM Multitool」について解説します。SBOMについてよく分からないという方は、まず こちら の記事を読んでみてください。 bomとは ソフトウェア部品表 (SBOM) を作成、表示、変換できるユーティリティ Kubernetes プロジェクトの SBOM を作成するプロジェクトの一部として作成された ディレクトリ、コンテナー イメージ、単一ファイル、およびその他のソースから SPDX パッケージを生成できる汎用ツール SPDX カタログ内の 400 以上のライセンスを認識するライセンス分類子が組み込まれている Golang の依存関係分析や、 .gitignore Git リポジトリのスキャン時の完全なサポートなどがある 環境 OS、ツール バージョン Ubuntu 22.04 GO 1.21.4 bom 0.6.0 インストール GOプロジェクトなので、下記のコマンドでインストールします。 go install sigs.k8s.io/bom/cmd/bom@latest バージョンを確認します。 bom version 走査対象 JavaでWebアプリケーションを作成する際に使用される Tomcat を対象とします。 SBOMの生成 すべての SPDX ドキュメントは、名前空間を宣言する必要がありますが、今回は全て「http://example.com/」と指定しています。 YAMLファイルからBOMの作成 今回はこちらは省略します。興味のある方は 公式ドキュメント を参照してください。 現在のディレクトリからSBOMを作成 generateコマンドにoオプションで出力ファイル名、formatオプションでJsonを指定します。 bom generate -n http://example.com/ -o tomcat-spdx.json --format json . コンテナイメージから生成 generateコマンドにiオプションでコンテナイメージを指定します。 bom generate -n http://example.com/ -i tomcat:11.0 -o tomcat-image-spdx.json --format json 特定のファイルのみを対象としたい場合 generateコマンドにfオプションでファイル名を指定します。 bom generate -n http://example.com/ \ -o tomcat_spdx.json --format json \ -f java/org/apache/tomcat/JarScannerCallback.java \ -f java/org/apache/tomcat/SimpleInstanceManager.java その他のオプションについては 公式ドキュメント を参照してください。 SPDXドキュメントの構造を描画 documentコマンドにoutlineを指定します。 bom document outline tomcat-spdx.json オプションは 公式ドキュメント を参照してください SBOM 内の情報を検索 documentコマンドにquery、SPDXファイル、検索条件を指定します。 bom document query tomcat-spdx.json "depth:2 name:log4j" depthは深さ、nameは検索したい要素を正規表現で指定できる 成果物を sbom と照合してチェックする validateコマンドとして用意されていますが、こちらは開発中のため今回は省略します。 さいごに 今回はSBOMツールの一つである「bom: The SBOM Multitool」について解説しました。まだメジャーリリースが行われていないので、本来の目的であるKubernetes プロジェクトの SBOM を作成する機能はないですが、興味のある方は試してみてください。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post SBOMツール紹介 ~ bom: The SBOM Multitool編 ~ first appeared on SIOS Tech. Lab .