GitHub Actions に Apple Silicon がやってきました!
GitHub Actions: Introducing the new M1 macOS runner available to open source! GitHub Actions: macOS 14 (Sonoma) is now available 先日Perlをビルドして遊んでみました。
actions-setup-perlがApple M1上で動くようになりました 今回はMySQLとRedisをビルドしてみたお話です。
shogo82148/actions-setup-mysql shogo82148/actions-setup-redis actions-setup-mysql v1.31.0, actions-setup-redis リリースのお知らせ actions-setup-mysql v1.31.0, actions-setup-redis v1.33.0 から M1 macOS に対応しています。 runs-on: キーに macos-14 を指定すると M1 を利用できます。
jobs: build: runs-on: macos-14 steps: - uses: actions/checkout@v4 - name: Set up MySQL uses: shogo82148/actions-setup-mysql@v1.31.0 M1による高速化 今日現在(2024-02-04)のMySQL最新安定版リリースは 8.0.36 です。 MySQL 8.
GitHub Actions に Apple Silicon がやってきました!
GitHub Actions: Introducing the new M1 macOS runner available to open source! GitHub Actions: macOS 14 (Sonoma) is now available 新しいコンピューティング環境がでてやることといえばアレですよね。 Perlのビルド。 というわけでやっていきましょう。
actions-setup-perl v1.28.0 リリースのお知らせ actions-setup-perl v1.28.0 から M1 macOS に対応しています。 runs-on: キーに macos-14 を指定すると M1 を利用できます。
jobs: build: runs-on: macos-14 steps: - uses: actions/checkout@v4 - name: Set up perl uses: shogo82148/actions-setup-perl@v1.28.0 M1による高速化 今回のリリースにあたり、バージョン違いコンパイルオプション違いの 全148種類 のPerlバイナリを再ビルドしました! Perl 5.38.2 のビルド時間で比較すると、x64では 11m 27s かかっていたビルドが、M1では 4m 6s へと大きく改善しました。 64.
ちょっとした用事で Forwarded ヘッダーの解析をしたくなったので、解析ライブラリを書いてみました。
shogo82148/forwarded-header 背景 Amazon API GatewayのHTTP Proxy Integrationを利用しているプロジェクトで、 クライアントのIPアドレスを知りたい用件がありました。
リバースプロキシの運用に慣れている人なら、「クライアントのIPアドレスを取得したい」と聞いて真っ先に思いつくのは X-Forwarded-For ヘッダーでしょう。 しかし、HTTP Proxy Integrationはこのヘッダーを付与しません。
なんとかIPアドレスを取得できないかと調べてみると、HTTP Proxy IntegrationはForwardedヘッダーを付与することがわかりました。
Amazon API Gateway: Explaining HTTP Proxy in HTTP API Forwardedヘッダーは RFC 7239 で標準化されているヘッダーです。 リバースプロキシによって失われてしまう情報を補完するために利用します。
RFC 7239: Forwarded HTTP Extension RFC 7239: Forwarded HTTP拡張 Forwarded - MDN Forwardedヘッダーを見ればクライアントのIPアドレスもわかります。 たとえば以下の例では 192.0.2.60 がクライアントのIPアドレスです。
Forwarded: for=192.0.2.60; proto=http; by=203.0.113.43 X-Forwarded-Forヘッダーは単純なカンマ区切りのテキストだったので、Split関数で十分でした。 一方Forwardedヘッダーは構造化されているため、パーサーが必要です。 そこまで複雑ではないので、実装してみました。
使い方 解析は Parse関数を呼び出すだけです。
package main import ( "fmt" "net/http" "os" forwardedheader "github.com/shogo82148/forwarded-header" ) func main() { header := make(http.
AWS SDK for Go v2を使っているプロジェクトで、以下のようなエラーが発生しました。
{"time":"2024-01-09T06:45:00.239872","level":"fatal","message":"not found, ResolveEndpointV2"} 解決策 github.com/aws/aws-sdk-go-v2 名前空間の下にあるモジュールをすべて最新版にアップデートしましょう。
go get -u "github.com/aws/aws-sdk-go-v2/..." 原因 AWS SDK for Go v2 v1.23.0 (2023-11-15) で入った以下の変更が原因です。
Feature: BREAKING CHANGE: V2 endpoint resolution middleware has changed steps from Serialize to Finalize. Middleware that indexes off of this field will need to be updated accordingly.
特徴: 重大な変更: V2エンドポイント解決ミドルウェアは、SerializeからFinalizeへのステップが変更されました。このフィールドをベースにインデックスを付けるミドルウェアは、それに応じて更新する必要があります。(ChatGPTによる和訳)
なんでこんなひどいことするの 😭(1年3か月ぶり、2回目)
前回壊れたとき(参考:AWS SDK v2 for Goが壊れた、Googleお前もか)はコンパイルエラーで気がつけたのですが、今回のエラーは実行してみないとわかりません。 マイナーアップデートで入れるのはやめてくれ・・・。
参考 Release (2023-11-15) [SOLUTION IN THREAD] “not found, ResolveEndpointV2” service modules released on or after 11/15/23 are incompatible against previous runtimes (and vice versa) #2370 SOLUTIONが書かれたコメント AWS SDK v2 for Goが壊れた、Googleお前もか
shogo82148/go-retry は指数的バックオフを行ってくれるライブラリです。
Goで指数的バックオフをやってくれるgo-retryを書いた v1.2.0 でジェネリクスを導入した新しいインターフェイスを追加しました。
新インターフェイス Goで指数的バックオフをやってくれるgo-retryを書いたの最後のまとめで、僕らのやりたいことを全部詰め込んだこんなコードを書きました。
func DoSomethingWithRetry(ctx context.Context) (Result, error) { var res Result var err error policy.Do(ctx, func() error { ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() res, err = DoSomething(ctx) return err }) return res, err } これが以下のようにちょっとシンプルになります。
func DoSomethingWithRetry(ctx context.Context) (Result, error) { return retry.DoValue(ctx, policy, func() (Result, error) { ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() return DoSomething(ctx) }) } math/randの実装変更に合わせた最適化 math/randパッケージ には Int, Intn などトップレベルに関数があります。 Go 1.
この記事は、Perl Advent Calendar 2023 25日目の記事(代打)です。 24日目は@shogo842148で「PerlにClass構文がやってきた」でした。
AWSでカナダ(カルガリー)リージョンが利用可能になりました!
The AWS Canada West (Calgary) Region is now available それに合わせて p5-aws-lambda のビルド済みレイヤーも公開しました!
Perl本体: arn:aws:lambda:ca-central-1:445285296882:layer:perl-5-38-runtime-al2023-x86_64:3 Paws: arn:aws:lambda:ca-central-1:445285296882:layer:perl-5-38-paws-al2023-x86_64:4 参考 The AWS Canada West (Calgary) Region is now available shogo82148/p5-aws-lambda AWS::Lambda
この記事は、Perl Advent Calendar 2023 24日目の記事(代打)です。 23日目は@doikojiで「【さらばpptxよ】perlとJavaScriptとHTMLで超手軽にスライドを作る」でした。
今年のPerlの重大ニュースといえば 「PerlにClass構文がやってきた」 ことですよね[要出典]。 (※ただしExperimental) Advent Calendar でClassをメインに取り上げることなかったなと思ったので、ちょっと触ってみました。
とりあえず動かしてみる perlclassの例です。 警告が出ないように no warnings 'experimental::class' で抑制だけしました。
use v5.38; use feature 'class'; no warnings 'experimental::class'; class My::Example 1.234 { field $x; ADJUST { $x = "Hello, world"; } method print_message { say $x; } } My::Example->new->print_message; 実行すると Hello, world と出力されます。
Hello, world newの引数を受け取る My::Example->new には引数を渡すことができます。 Perl 5.38時点では :param field属性を使って、フィールドを初期化できるようです。
use v5.38; use feature 'class'; no warnings 'experimental::class'; class My::Example 1.
この記事は、Perl Advent Calendar 2023 22日目の記事(代打)です。 21日目は@shogo82148で「5.36以降でのサブルーチンプロトタイプを復習する」でした。
万策尽きたいっちーです。 そういえば今年こんなこともあったなーと思い出したので、メモとして残しておきます。
HTTP::Tiny 0.083からデフォルトでTLSの証明書を検証するようになりました 今年の6月11日リリースの HTTP::Tiny 0.083 からデフォルトで TLSの証明書を検証するようになりました!
検証してみた HTTP::TinyはPerlのコアモジュールに含まれている、超有名HTTPクライアントです。 「えっ、むしろ今まで検証してなかったの?」って思いますよね。
僕もそう思いました。というわけで証明書の検証していないことの検証してみましょう。
まずはお手元に古いHTTP::Tinyを用意します。
cpanm HTTP::Tiny@0.082 検証には不正な証明書を返すサーバーが必要です。 今回は badssl.com を利用しました。 有効期限の切れたサイトへのアクセスを試してみます。
# get.pl use v5.38; use HTTP::Tiny; my $response = HTTP::Tiny->new->get('https://expired.badssl.com/'); die "Failed!\n" unless $response->{success}; say $response->{content}; 実行してみると・・・
% perl get.pl <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="/icons/favicon-red.ico"/> <link rel="apple-touch-icon" href="/icons/icon-red.png"/> <title>expired.badssl.com</title> <link rel="stylesheet" href="/style.css"> <style>body { background: red; }</style> </head> <body> <div id="content"> <h1 style="font-size: 12vw;"> expired.
この記事は、Perl Advent Calendar 2023 21日目の記事(代打)です。 20日目は@doikojiで「低レベルperlスクリプトのススメ(その2)」でした。
いよいよネタが尽きて途方にくれているいっちーです。 ネタも尽きてn番煎じな気はしますが、サブルーチンプロトタイプの書き方について復習です。
プロトタイプ サブルーチンプロトタイプとは一言でいうと、引数パーサーの挙動をカスタマイズする仕組みです。 たとえば、Perlの組み込み関数 push は第一引数の配列に要素を追加する関数ですが、 これと同じものを普通は定義できません。
sub my_push { # TODO: 中身を実装する } my @hoge = (1, 2); my_push @hoge, 3, 4, 5; # my_push 1, 2, 3, 4, 5; と配列が展開されてしまって、 `@hoge` にはアクセスできない 「Perlのサブルーチンプロトタイプについて」から自作pushの例を引用します。
sub my_push(\@@){ my ($arr_ref, @arr) = @_; for(@arr){ $$arr_ref[$#$arr_ref+1] = $_; } } my @hoge = (1, 2); my_push @hoge, 3, 4, 5; # my_push \@hoge, 3, 4, 5; と解釈される Perl 5.
この記事は、Perl Advent Calendar 2023 18日目の記事(代打)です。 17日目は@tecklで「Perlのレガシーシステムを少し更新した話」でした。
背景 最小のELFを作る記事を見かけて、「自分もやってみよう!」と思ってやってみました。
最小限のELF ただ、僕はバイナリーエディターとはあまりお友達になれていないので、 ELFを出力するPerlスクリプトを書くことにしました。 そうしたらPerl製のアセンブラーっぽいものができた、というお話です。
shogo82148/minimum-elf Minimum ELF ELFとして実行できるだけの必要最低限の機能しか実装していないので、 プログラムの終了処理を書く以外、大したことはできません。 それでも実行可能なバイナリーを吐くので、 「これはアセンブラーだ!」 と言い張ることにします。
完成したELFファイルはDockerイメージに焼き込み、 GitHub Container Registry にあげてあるので、 docker pull で完成品をダウンロードできます。
$ docker pull ghcr.io/shogo82148/minimum-elf:latest $ docker images ghcr.io/shogo82148/minimum-elf:latest REPOSITORY TAG IMAGE ID CREATED SIZE ghcr.io/shogo82148/minimum-elf latest cd926faef0a2 13 days ago 188B わずか188バイト!
もちろん docker run で実行できます。 x86_64, arm64 どちらでも動くはずです。
実装 NASM っぽい構文を PerlのDSLとして実装し、ELFファイルを書き出しています。 たとえばELFのヘッダーを書き出す部分は以下のようになっています。
label($elf_start); my $elf_size = $elf_end - $elf_start; db 0x7F, "ELF"; # e_ident db 2; # 64-bit architecture.