OmniAICreator/Qiita-1.07M huggingface dataset:
ファイルが削除できない

# 環境
Debian 13 (Testing)

Debian Live をビルドしている最中に Ctrl+C で止めたら、削除できないファイルができた。


```
# rm -rf chroot
rm: cannot remove 'chroot/dev/pts/0': Operation not permitted
rm: cannot remove 'chroot/dev/pts/ptmx': Operation not permitted
```
はてな?

```

# chattr -i -a *
```

してみたけど変わらず。

```
# ls -alh
total 4.0K
drwxr-xr-x 2 root root      0 Jul  2 21:35 .
drwxr-xr-x 3 root root   4.0K Jul  2 22:14 ..
crw--w--w- 1 root tty  136, 0 Jul  2 21:43 0
c-w--w--w- 1 root root   5, 2 Jul  2 21:35 ptmx
```

行頭の c ってなんだっけ。

/dev/tty とかで使っているデバイスファイルらしい。chroot のためにリアルのデバイスとつながっている最中かな?

マウント状況を調べてみると、それらしいものが見つかりました。
```
devpts-live on /root/livework/chroot/dev/pts type devpts (rw,relatime,gid=5,mode=620,ptmxmode=000,x-gvfs-hide)
```
umount しようとしたけれど

```
# umount devpts-live
umount: /root/livework/chroot/dev/pts: target is busy.
```

うーん、めんどくさくなったので母艦を再起動。そうするとマウント解除して削除できるようになりました。
[CDK For Terraform]EventBridgeとChatbotを実装する

# 実施のきっかけ

RDSのイベントサブスクリプションの機能があり、
通知先にSNSトピックを指定していたのですが、通知がきていないことに気づきました。

サポートに確認したのですが、
RDSのイベントサブスクリプションはChatbotに対応していないみたいで、
EventBridge + Chatbotで実装することにしました。


## 実際のコード

https://github.com/Myabaou/cdktf-eventbridge-chatbot

前提条件は記載のとおりですが、Dockerがインストールされていて
対象AWSアカウント上でChatbotとSlackの連携が完了していれば動くはずです。

MakefileでAWSのプロファイル名を指定しているのでそこは実行環境に合わせて
変更する必要があります。


## TIPS

- Cloudformationのスタック名にアンダーバーが入っているとエラー

そのため以下のように文字列を置換しています。

```typescript
const channelIdWithoutHyphens = channelId.replace(/_/g, "");
```

- SNSのアクセスポリシーがデフォルトのままだと通知が飛ばない


https://dev.classmethod.jp/articles/event-bridge-notify-sns/

これドンピシャでした。
以前もハマった気がしたのですが、きちんとアウトプットしておかないと忘れがちですね。


- 対象チャンネルに @aws を招待しよう

これも忘れがちなので注意


## 次回予告

RDSイベント通知の実装はまた別記事にしていきます。（まだ実装中）
しぶとく生き残るCentOS6の環境にOpenSSH9.8p1のClientからSSHできるようにする2つの方法

## はじめに

皆様CentOS6のことはご存知でしょうか。とっくにEoLを迎えて、インターネットに直に繋がるような環境は流石に皆様滅ぼされたことと思います。

しかし、検証用環境などでしぶとく生き残るCentOS6環境がいるかもしれません。

そんな環境につなぐときに、`~/.ssh/config`にこんな感じで記載していたかもしれません。

```ssh:~/.ssh/config
Host arikitari
    IdentityFile ~/.ssh/arikitari_id_rsa
    HostKeyAlgorithms ssh-dss,ssh-rsa
    PubkeyAcceptedKeyTypes  ssh-dss,ssh-rsa
```

## 事象: Bad key types 'ssh-dss,ssh-rsa'.

さて、私は~~変態的な環境が好きなので~~pacmanが大好きなので、Windowsでmsys2を使っています。

執筆中の現在世の中を騒がせているOpenSSH regreSSHion対応(CVE-2024-6387)のために、おもむろに`pacman -Syuu`してパッケージの更新をかけると、OpenSSHのバージョンが上がりました。

アップデート中のログは虚空送りしてしまったので代わりにこれを。

```
$ssh -V
OpenSSH_9.8p1, OpenSSL 3.3.1 4 Jun 2024
$pacman -Qs openssh
local/openssh 9.8p1-1 (net-utils)
    Free version of the SSH connectivity tools
$ls -l /var/cache/pacman/pkg/ | grep openssh
-rw-r--r-- 1 yumetodo なし  982K 10月  5  2023 openssh-9.5p1-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 yumetodo なし   566 10月 11  2023 openssh-9.5p1-1-x86_64.pkg.tar.zst.sig
-rw-r--r-- 1 yumetodo なし  991K 12月 19  2023 openssh-9.6p1-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 yumetodo なし   566 12月 19  2023 openssh-9.6p1-1-x86_64.pkg.tar.zst.sig
-rw-r--r-- 1 yumetodo なし  993K  3月 12 05:10 openssh-9.7p1-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 yumetodo なし   566  3月 16 19:53 openssh-9.7p1-1-x86_64.pkg.tar.zst.sig
-rw-r--r-- 1 yumetodo なし 1022K  7月  2 00:07 openssh-9.8p1-1-x86_64.pkg.tar.zst
-rw-r--r-- 1 yumetodo なし   566  7月  2 02:20 openssh-9.8p1-1-x86_64.pkg.tar.zst.sig
```

openssh-9.7p1-1からopenssh-9.8p1にあがったっぽいですね。

そして任意のサーバーにSSHしようとすると・・・

```
Bad key types 'ssh-dss,ssh-rsa'.
.
.
.
terminating, 4 bad configuration options
```

等と言ってSSHできないわけです。

## 解決策1: `ssh-dss`を除去する

幸いにしてCentOS6はHostKeyとして`ssh-rsa`に対応しているので、`ssh-dss`を除去するだけでひとまず対応はできそうです。


```diff_ssh:~/.ssh/config
Host arikitari
     IdentityFile ~/.ssh/arikitari_id_rsa
+    HostKeyAlgorithms ssh-rsa
+    PubkeyAcceptedKeyTypes  ssh-rsa
-    HostKeyAlgorithms ssh-dss,ssh-rsa
-    PubkeyAcceptedKeyTypes  ssh-dss,ssh-rsa
```

## 解決策2: CentOS6側でHostKeyにecdsaを追加する

まずどうにかしてCentOS6サーバーに繋いで、以下の作業をします

```bash
$ sudo ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C '' -N ''
$ sudo chmod 600 /etc/ssh/ssh_host_ecdsa_key
$ sudo chmod 640 /etc/ssh/ssh_host_ecdsa_key.pub
$ sudo vi /etc/ssh/sshd_config # HostKey /etc/ssh/ssh_host_ecdsa_key を追記
$ sudo /etc/rc.d/init.d/sshd restart
```

クライアント側の `~/.ssh/config` を編集します。

```diff_ssh:~/.ssh/config
Host arikitari
     IdentityFile ~/.ssh/arikitari_id_rsa
+    PubkeyAcceptedKeyTypes +ssh-rsa
-    HostKeyAlgorithms ssh-dss,ssh-rsa
-    PubkeyAcceptedKeyTypes  ssh-dss,ssh-rsa
```

参考にしたのはこれ。これの場合はCentOS6から別環境、って感じだったので逆手順ですね。

https://zenn.dev/dsta50/articles/77cefe0bc9b6e9
【応用情報技術者試験】ソートアルゴリズムを理解するリンク集

# 概要
ソートアルゴリズムについて、何度勉強しても忘れてしまうので、自分の学習用として、各ソートの概要と、理解するためのyoutubeのリンク集を纏めました。

# 目次
#### ソートの種類
- [クイックソート](#クイックソート)
- [バブルソート](#バブルソート)
- [挿入ソート](#挿入ソート)
- [選択ソート](#選択ソート)
- [シェルソート](#シェルソート)
- [ヒープソート](#ヒープソート)
- [マージソート](#マージソート)
#### その他の用語
- [内部ソート](#内部ソート)
- [外部ソート](#外部ソート)

# ソートの種類

# 内部ソート

## クイックソート
1960年に[アントニー・ホーア](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%82%BD%E3%83%BC%E3%83%88)が開発したソートアルゴリズム。
ランダムなデータをソートする際にとても速いとされている手法。
「基準値」を決め、そこから大小二つのグループに分けていく方法を繰り返す。
[インプレースソート](https://ja.wikipedia.org/wiki/In-place%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0)なので、メモリを節約できる。

https://www.youtube.com/watch?v=I4Z5N20Baps

https://www.youtube.com/watch?v=a3yXjNhGwt0

## バブルソート
ソート手法の中でも有名なソート方法。
隣同士を比較して、どちらの値が大きいか (小さいか) で、隣同士を入れ替えるかどうかを判断していく。
「バブルソート」という名称は、[ケネス・アイバーソン](https://ja.wikipedia.org/wiki/%E3%82%B1%E3%83%8D%E3%82%B9%E3%83%BB%E3%82%A2%E3%82%A4%E3%83%90%E3%83%BC%E3%82%BD%E3%83%B3) が1962年に出版した本 「A Programming Language」に由来すると考えられている。

https://www.youtube.com/watch?v=WY-_iKLNhA0

https://www.youtube.com/watch?v=IHFBb0wYBR0

## 挿入ソート
インプレースソートの一つ。
あらかじめ整列されているデータに新しくデータを追加する際に効果的な手法。

https://www.youtube.com/watch?v=z0YcQIqyV5Q

## 選択ソート
インプレースソートの一つ。
数あるランダムなデータの中で最小値を探し (選択し) 、値が小さい順に並べていく手法。

https://www.youtube.com/watch?v=DdL_ipwaU0k&t=58s

https://www.youtube.com/watch?v=A1UuoXNoy2w

## シェルソート
インプレースソートの一つ。
挿入ソートや選択ソートを改良化したソート法として知られている。
1959年に[ドナルド・シェル](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%8A%E3%83%AB%E3%83%89%E3%83%BB%E3%82%B7%E3%82%A7%E3%83%AB)が考案した。
ざっくりとデータを大小の順に並べておき、最終的に挿入ソートを使用して綺麗に並べるという手法。

https://www.youtube.com/watch?v=nfklhZbfSNA

## ヒープソート
インプレースソートの一つ。
ヒープ (heap) とは、「積み重なる」や「堆積する」といった意味をもつ。
[完全二分木](https://wa3.i-3-i.info/word14926.html)を使用する。
[二分木](https://ja.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%9C%A8)とは、全てのノードの子ノードが2つ以下のツリー構造のことを指す。「完全二分木」は「二分木」の中でも、全ての葉が同じ「深さ」を持つ二分木を指す。
ランダムなデータを完全二分木の構成にし、そこから最小値 (最大値) を取り出して整列させるということを繰り返す。

https://www.youtube.com/watch?v=X0ESspSiLIc&t=313s

# 外部ソート

## マージソート
既に整列してある複数個ある列を、1個の列にマージする際に有効的な手法。
外部ソートに対しても適用できる。

https://www.youtube.com/watch?v=FLSNQo793es

https://www.youtube.com/watch?v=RrQO9qse3h8

# その他の用語

## 内部ソート
パソコンのメモリ上の配列のみでソートを行うことを内部ソートと呼ぶ。

## 外部ソート
外部記憶装置（ディスクや磁気テープ）とやり取りを行いながらソートを行うことを外部ソートと呼ぶ。

***
**[記載した応用情報技術者試験の記事まとめ](https://qiita.com/MetroOsamu/items/550001240d76e24f505f)**
Conoha のコントロールパネルで、ご利用中のVPSはありませんと表示されたら

Conoha のコントロールパネルで、ご利用中のVPSはありませんと表示された時の解決方法です。
次のように表示されました。私は、2台のVPS を使用しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/9313669a-4531-e54b-26fb-f7c72a11f9d1.png)

左したのバージョン切り替えで、バージョンを2.0 にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c744e8e2-3f56-8fdd-8d33-18227fb5d65b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/201ba3bb-9197-3e4b-e087-8633a8e2734d.png)

こんな説明が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e8f08211-f794-f8e8-3b3d-ed7dd2434f68.png)

Ver 2.0 に切り替わりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/76ff3b2e-21f0-0165-45e2-9bcc3ad4392d.png)

使っている2台のサーバーが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/83e27f5e-fa44-902d-2e38-9b03bc6b8aad.png)
picoCTF 2024 writeup format string 0

## format string 0 (Binary Exploitation)

Can you use your knowledge of format strings to make the customers happy? Download the binary here. Download the source here. Connect with the challenge instance here: nc mimas.picoctf.net 60866

配布ファイル
・format-string-0
・format-string-0.c

タイトルが「format string」となっているのでおそらくformat string attack(書式文字列攻撃)でフラグが得られるのだろう。とりあえず、`nc mimas.picoctf.net 60866`を実行してみる。
```
> nc mimas.picoctf.net 60866
Welcome to our newly-opened burger place Pico 'n Patty! Can you help the picky customers find their favorite burger?
Here comes the first customer Patrick who wants a giant bite.
Please choose from the following burgers: Breakf@st_Burger, Gr%114d_Cheese, Bac0n_D3luxe
Enter your recommendation: Gr%114d_Cheese
Gr                                                                                                           4202954_Cheese
Good job! Patrick is happy! Now can you serve the second customer?
Sponge Bob wants something outrageous that would break the shop (better be served quick before the shop owner kicks you out!)
Please choose from the following burgers: Pe%to_Portobello, $outhwest_Burger, Cla%sic_Che%s%steak
Enter your recommendation: Cla%sic_Che%s%steak
ClaCla%sic_Che%s%steakic_Che(null)
picoCTF{7h3_cu570m3r_15_n3v3r_SEGFAULT_f89c1405}
```
フラグが出てきてしまった。

`picoCTF{7h3_cu570m3r_15_n3v3r_SEGFAULT_f89c1405}`


`Enter your recommendation`のところでどうしてその選択肢を選んだのかを説明していく。
最初の選択肢は、`Breakf@st_Burger, Gr%114d_Cheese, Bac0n_D3luxe`の3つ。書式文字列攻撃を念頭におくと、%が含まれている選択肢が怪しいと考えた。`Gr%114d_Cheese`を入力すると次に進んだ。
2回目の選択肢は、`Pe%to_Portobello, $outhwest_Burger, Cla%sic_Che%s%steak`の3つ。これも最初の選択肢と同様に%が含まれている選択肢を選ぶわけだが、2つあることに気づく。`%t`と`%s`を比較してフラグが出てきそうなのは`%s`なので`Cla%sic_Che%s%steak`を選び、入力した。すると、フラグが得られた。
【SPIKE Prime×Python】時間が整数で発狂した

# あ…ありのまま今起こった事を話すぜ!
「時間ベースで処理するタイプの台形制御ができたぞー」
「さあ、実行しよう！」
「い、1秒ごとにしか速度が変わらないぞ？？？」
「これ整数で返されとるやんけー」
# 問題点
SPIKE PrimeにはMicropythonで用意された`time`モジュールとLegacyバージョンに限り`Timer`クラスがサポートされています。
しかし、`Timer`クラスのドキュメントを見るととんでもないことが書いてあります。

> 秒数が整数型で返されます。

これってどこに需要があるタイマーなんでしょうか。

では先ほど紹介した`time`モジュールを使えばいいじゃないかということですが、こちらもどちらのバージョンともに整数が返されます。

```py
# SPIKE Legacyのみ可
from spike.control import Timer
timer = Timer()
print(timer.now()) # int型

# SPIKE Legacy、SPIKE 3 どちらとも可
import time
print(time.time()) # int型
```
# 検証
## 待機関数
```py
# SPIKE Legacyのみ可
from spike.control import wait_for_seconds
wait_for_seconds(1.5) # 正しく1.5秒待つ

# SPIKE 3のみ可
import runloop
await runloop.sleep_ms(1500) # 正しく1.5秒待つ

# SPIKE Legacy、SPIKE 3 どちらとも可
import time
time.sleep(1.5) # 正しく1.5秒待つ
```
Pythonには`wait_for_seconds`関数があるのでそちらで
少数型を正しく処理してくれるか試すと、こちらも問題なく少数秒で待ってくれました。

## `time_ms`と`time_ns`
```py
import time
print(time.time_ms / (10**3)) # 整数部分しか変化しない
print(time.time_ns / (10**9)) # 整数部分しか変化しない
```
それぞれ細かい数値を取得できる`time_ms`と`time_ns`ですが、SPIKEの同じプログラム内で何度呼び出しても秒数が1秒ごとにしか更新されません。残念ですが使い物にならなさそうです。
## `perf_counter`
```py
import time
print(time.perf_counter()) # NameError: name 'perf_counter' is not defined
```
精度が高い時間を呼び出したい時に定評のある`perf_counter`ですが、残念ながらSPIKE Primeには存在しないようです。
## ブロック言語
![タイマー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883745/906b4ddf-eae0-28f4-fb73-cbea14a90b8f.png)

Pythonなのが悪いのかと思い、ブロック言語環境で時間を取得してみると、何の問題もなく少数まで取得できました。

# 解決策
上の検証結果から、内部では少数秒で処理されているが`time`系の関数では取得できないことがわかります。

じゃあどうするんだというと`tick`を使います。これはCPU時間をベースに`time`関数と同じような動作が期待できます。
```py
import time
print(time.tick_ms() / (10**3)) # float型
print(time.tick_ns() / (10**9)) # float型
```
ただ肝心の少数型で返してくれる`tick`関数というものは存在しないので割り算で少数型にします。

`tick`関数は`time`関数に比べてなにか信頼性がないというか、私は少し不安ですが今はこれしか思いつかないので、`tick`を使っていきます。
# 参考文献

https://afrel.co.jp/product/spike/technology-spike/prime/software/1732/

https://docs.micropython.org/en/v1.15/library/utime.html
SSH鍵の生成と使用ガイド（Windows対応）

# なぜssh-keygenを使う？
リモートサーバに接続する際、毎回パスワードを入力するのは面倒です。「ssh-keygen」を使用すると、パスワード入力の手間を省き、セキュリティを向上させつつ、リモートサーバへのアクセスを簡単にできます。

# Windows環境
### 1. .sshフォルダの作成
まず、.sshフォルダが存在しない場合は、以下のコマンドでフォルダを作成します：
```
mkdir "%USERPROFILE%\.ssh"
```
### 2. SSH鍵の生成
コマンドプロンプトを開き、以下のコマンドを実行します：
```
ssh-keygen -t rsa -b 4096 -f "%USERPROFILE%\.ssh\id_rsa" -N ""
```

このコマンドを実行すると、次のようなメッセージが表示されます。
```
Generating public/private rsa key pair.
Your identification has been saved in C:\Users\YourUsername\.ssh\id_rsa
Your public key has been saved in C:\Users\YourUsername\.ssh\id_rsa.pub
The key fingerprint is:
SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX YourUsername@YourComputer
The key's randomart image is:
+---[RSA 4096]----+
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
+----[SHA256]-----+
```
このメッセージが表示されれば、SSH鍵の生成は完了です。

### 3. SSH鍵をアップロード
SSH鍵の秘密鍵と公開鍵が生成されたら、リモートサーバにSSH鍵の公開鍵をアップロードします。PowerShellを開いて、以下のコマンドを実行します：
```powershell
type $env:USERPROFILE\.ssh\id_rsa.pub | ssh [username]@[remote_host] "cat >> .ssh/authorized_keys"
```
この操作の際、リモートサーバのパスワードを一度だけ入力する必要があります。

# ジャンプサーバ環境（Linux）
ジャンプサーバを使用している場合、ジャンプサーバ内でも同様の手順を繰り返す必要があります。
### 1. SSH鍵の生成
```
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
```
### 2. 公開鍵のアップロード
```
ssh-copy-id [sshユーザ名]@[リモートサーバのホスト or IP]
```
:::note warn
Windowsではssh-copy-idコマンドが標準で利用できないため、ジャンプサーバ（通常はLinux環境）で実行することを想定しています。
:::


# まとめ
SSH鍵の生成と使用には、以下のようなメリットがあります：
1. セキュリティの向上：強力な暗号化により、パスワード認証よりも安全です
1. 利便性の向上：パスワード入力が不要になり、ログインプロセスが簡素化されます
1. 管理の容易さ：中央集中型の鍵管理が可能になります
1. 自動化の促進：スクリプトやツールによる自動ログインが容易になります

ssh-keygen コマンドを適切に使用することで、これらのメリットを最大限に活用し、リモートサーバとの安全で効率的な通信を実現できます。
TiDBのseverless driver向けのエミュレーターとしてServerless MySQL HTTP(SMH)を作った話

## はじめに

[TiDB](https://docs.pingcap.com/)というMySQL互換のサービスがあり、それを[serverless driver](https://docs.pingcap.com/tidbcloud/serverless-driver)で利用してみることにした。しかしTiDBには、AWSの[LocalStack](https://www.localstack.cloud/)やFirebaseの[Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite)のような、いわゆるローカルの開発環境におけるserverless driver向けのエミュレートサービスがないみたいだった。

そこで、ないなら作ろう！という事で、今回Serverless MySQL HTTP(SMH)を作ってみたので、それについて取り上げたいと思う。

https://github.com/yutak23/serverless-mysql-http

※TiDBのserverless driverはEdge環境（Cloudflare WorkersやVercel Edge Functionsで利用される）

## TiDBとは？

以下のサイト等がわかりやすいかと思います。

https://zine.qiita.com/interview/202308-pingcap/

## 今回作ったServerless MySQL HTTP(SMH)について

TiDBでは[@tidbcloud/serverless](https://github.com/tidbcloud/serverless-js)というライブラリを利用することで、HTTPリクエストでTiDBに対してリクエストを送り、データベースの操作ができる。

@tidbcloud/serverlessを利用することで、エッジ環境でもTiDBが利用できる反面、普段MySQLを利用しているときの開発手法が利用できないデメリットに直面する。
具体的には、基本的にMySQLを利用しているアプリであれば、DockerなどでMySQLサーバーをローカル環境で立てて、プロダクション環境のMySQL[^1]には接続することなく開発を行うと思う。しかし、@tidbcloud/serverlessを利用する場合、HTTPでTiDBにリクエストをするため、そのリクエストをローカル環境のMySQLに向けても動作しない（以下の図のようにプロトコルが違う）。
[^1]:AWSのRDSやAurora、AzureのAzure Database for MySQL、GCPのCloud SQL for MySQLなど

![](https://storage.googleapis.com/zenn-user-upload/116010af0f8b-20231127.png)

そのため、HTTPリクエストをMySQLプロトコルに変換する（プロキシする）ようなサービスが必要になる。そのサービスがServerless MySQL HTTP(SMH)になる。

このサービスを利用することで、以下の図のようにTiDBへのHTTPリクエストをSMHが受け取り、それをMySQLプロトコルに変換してくれる。それにより、@tidbcloud/serverlessを利用していても、ローカル環境のMySQLで開発をすることができるようになる。

![](https://storage.googleapis.com/zenn-user-upload/ee6f8caf88dd-20231127.png)

Serverless MySQL HTTP(SMH)自体はDockerイメージとして利用できるようにしています。

https://hub.docker.com/r/yutak23/serverless-mysql-http

※上記の内容の通り、今回開発したSMHは[TiDB Cloud Serverless Driver (Beta)](https://docs.pingcap.com/tidbcloud/serverless-driver)でのTiDBを利用する場合を対象にしている。また、TiDBのserverless driverもサポートしている。

## 仕組みについて

仕組みはかなりシンプルで、SMHはHTTPリクエストを受け取るNode.jsのExpressサーバーとして実装している。そのエンドポイントで[node-mysql2](https://github.com/sidorares/node-mysql2)を利用してMySQLに対してSQLをクエリしている。HTTPレスポンスは@tidbcloud/serverlessが要求する形にコンバートする必要があるので、そこは少し実装する上でポイントになった。

## まとめとして

TiDBを利用する際に、ローカルの開発環境に閉じて（本番サービスに接続せず）開発できるようにするためのサービスとしてServerless MySQL HTTP(SMH)を開発したことを紹介させていただいた。やはり、ローカルの開発環境からは本番サービスに接続したくないという事はあると思う（そうでなければLocalStackやFirebase Local Emulator Suiteは開発されなかったと思う）ので、今回開発したServerless MySQL HTTP(SMH)がどなたかの役に立てばいいなと思っている。
プログラミングやPC作業中に本格的なキューバ葉巻を楽しむメリット

コンピューターの前に座って仕事をしていると、ストレスが溜まり、集中力が低下することがあります。そんな時、本格的なキューバ葉巻を楽しむのはいかがでしょうか。Duty Free Cuban Cigarsでは、キューバの一流葉巻工場から直接仕入れた最高級のハバノスを提供しています。

プログラミングに没頭しながら、豊かな風味と芳醇な香りを放つ葉巻を味わうことで、創造性とモチベーションが高まります。複雑なコードに取り組む間、葉巻のスムーズな口当たりとバランスの取れた味わいが、思考をクリアにし、アイデアを刺激します。

また、仕事の合間に葉巻を楽しむことで、リラックスした気分になり、ストレス解消にも効果的です。本物のキューバ葉巻の味わいは、あなたのPC作業をより楽しく、充実したものにしてくれるでしょう。

Duty Free Cuban Cigarsは、品質と信頼性が保証された葉巻を提供しています。キューバの熟練した職人によって手巻きされた葉巻は、一本一本が芸術品のような仕上がりです。https://dutyfreecubancigars.com/ から、あなたのPC作業を向上させる最高級のハバノスを手に入れてください。本格的なキューバ葉巻で、プログラミングやPC作業の体験を新たなレベルへと引き上げましょう。![.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3829443/3c0f57c6-0cd3-9c30-b7ec-b7fa14901b15.png)
PHPのアクセス修飾子について

PHPには、public、private、protectedの3つのアクセス修飾子があり、これらはクラスのプロパティやメソッドに対するアクセス制限を設けるために使用されます。それぞれ異なるアクセスレベルを定義し、クラスの設計と使用を適切に行うために重要な役割を果たします。

### 目次

1. public
2. private
3. protected
4. アクセス修飾子の違いと使用例
5. アクセス修飾子の適切な使用方法

### 1. public

### 定義

クラスのプロパティやメソッドがクラスの外部からもアクセス可能になる。

### 使用ケース

クラスの機能を外部に公開し、外部からの利用を容易にするために使用。

### 例

```php
class MyClass {
    public $publicProperty = 'I am public';

    public function publicMethod() {
        echo 'This is a public method';
    }
}

$instance = new MyClass();
echo $instance->publicProperty; // 出力: I am public
$instance->publicMethod(); // 出力: This is a public method
```

### 2. private

### 定義

クラスのプロパティやメソッドが、そのクラス内部からのみアクセス可能になる。

### 使用ケース

クラスの内部状態を保護し、外部からの直接的なアクセスを防ぐために使用。

### 例

```php
class MyClass {
    private $privateProperty = 'I am private';

    private function privateMethod() {
        echo 'This is a private method';
    }

    public function accessPrivate() {
        echo $this->privateProperty; // OK
        $this->privateMethod(); // OK
    }
}

$instance = new MyClass();
// echo $instance->privateProperty; // エラー
// $instance->privateMethod(); // エラー
$instance->accessPrivate(); // 出力: I am private This is a private method
```

### 3. protected

### 定義

クラスのプロパティやメソッドが、そのクラス自体、及びそのクラスを継承したサブクラスからアクセス可能になる。

### 使用ケース

クラスの内部状態を保護しつつ、継承による拡張を可能にするために使用。

### 例

```php
class MyClass {
    protected $protectedProperty = 'I am protected';

    protected function protectedMethod() {
        echo 'This is a protected method';
    }
}

class SubClass extends MyClass {
    public function accessProtected() {
        echo $this->protectedProperty; // OK
        $this->protectedMethod(); // OK
    }
}

$instance = new SubClass();
$instance->accessProtected(); // 出力: I am protected This is a protected method
// echo $instance->protectedProperty; // エラー
// $instance->protectedMethod(); // エラー
```

### 4. アクセス修飾子の違いと使用例

- **public**: 外部からアクセス可能。クラスのインスタンスを通じて、外部から直接プロパティにアクセスしたり、メソッドを呼び出したりできます。
- **private**: クラス内部からのみアクセス可能。クラスの外部からはアクセスできず、クラスの内部からのみアクセス可能です。
- **protected**: クラス自体およびそのサブクラスからアクセス可能。クラスの外部からはアクセスできず、クラスの内部から、及び継承したサブクラスからのみアクセス可能です。

### 5. アクセス修飾子の適切な使用方法

- **public**: クラスの機能を外部に公開し、他のクラスやコードから直接使用できるようにする場合に使用します。例えば、APIのエンドポイントとして機能するメソッドや、設定可能なプロパティなどです。
- **private**: クラスの内部でのみ使用されるメソッドやプロパティに使用します。これにより、外部からの不正なアクセスを防ぎ、クラスの内部状態を保護します。例えば、計算や処理の中間ステップとして使用するメソッドなどです。
- **protected**: クラスを継承するサブクラスで使用されるメソッドやプロパティに使用します。クラスの内部状態を保護しつつ、サブクラスでの拡張を可能にします。例えば、サブクラスで共通して使用されるロジックやデータを保持するプロパティなどです。
- 
これらのアクセス修飾子を適切に使用することで、クラスの内部状態を保護しつつ、外部からのアクセスを制御することができます。これにより、クラスの設計と使用を適切に行うために重要な役割を果たします。private と protected が少し似ていますが、protectedは継承したサブクラスからもアクセス可能である点が異なります。
Unity学習記録 #011 コレクション（ディクショナリ）

# コレクション
複数のデータをひとまとめにして管理できる変数で代表的なものは３つ
・配列（要素数が固定されて扱われる代表的なデータ構造）
・リスト（要素の追加、削除、挿入ができるデータ構造）
・ディクショナリ（要素に "キー" と "値" がセットで格納させるデータ構造）

今回はディクショナリ（Dictionary）について学習していきます。

## ディクショナリ
ディクショナリは要素に "キー" と "値" がセットで格納させるデータの配列構造を持ちます。値に関しては重複してもいいですが、同じスコープ内で重複するキーは設定できません。また、リスト同様に要素は可変的に使用できます。

### ディクショナリの宣言
まずは構文です。
```csharp
Dictionary<キーの型, 値の型> dictionary = new Dictionary<キー, 値>();
```

初期値を設定するコードを書いてみます。
一行で記述してもいいですが、長くなるので要素ごとに改行してコードを見やすくしています。
```csharp
//初期値を設定する場合
Dictionary<string, int> myDictionary = new Dictionary<string, int>(){
    { "apple", 10 },
    { "banana", 20 },
    { "orange", 30 }
};

//初期値を設定しない場合
Dictionary<string, int> myDictionary = new Dictionary<string, int>();
```

### 要素の呼び出し
配列やリストはインデックス番号を指定して要素の値を呼び出しました。
ディクショナリはキーを指定して、対応する値を呼び出します。
```csharp
//キーに対応する値を呼び出し
Dictionary<string, int> myDictionary = new Dictionary<string, int>(){
    { "apple", 10 },
    { "banana", 20 },
    { "orange", 30 }
};

Debug.Log(myDictionary["apple"]);
```

ディクショナリに登録されている全てのキーと値をセットで呼び出すコードを書いてみます。
変数の中身を確認するときに便利です。
```csharp
// すべての要素（キー：値）をコンソールに書き出し
Dictionary<string, int> myDictionary = new Dictionary<string, int>(){
    { "apple", 10 },
    { "banana", 20 },
    { "orange", 30 }
};

foreach (KeyValuePair<string, int> pair in myDictionary)
{
    Debug.Log($"{pair.Key}: {pair.Value}");
}
```

### 要素の追加・削除
次に、要素を添削するコードの書き方をみてみます。
```csharp
//要素の追加・削除
Dictionary<string, int> myDictionary = new Dictionary<string, int>();

// キーと値を追加
myDictionary.Add("apple", 10);
myDictionary.Add("banana", 20);
myDictionary.Add("orange", 30);

//要素の確認
foreach (KeyValuePair<string, int> pair in myDictionary)
{
    Debug.Log($"{pair.Key}: {pair.Value}");
}

//要素の削除
myDictionary.Remove("banana");

//要素の確認
foreach (KeyValuePair<string, int> pair in myDictionary)
{
Debug.Log($"{pair.Key}: {pair.Value}");
}
```

### キーが存在するかの確認
要素にキーが存在するかを調べる方法を書いてみます。
bool値で結果を返します。
```csharp
//キーの存在確認
Dictionary<string, int> myDictionary = new Dictionary<string, int>(){
    { "apple", 10 },
    { "banana", 20 },
    { "orange", 30 }
};

// キーが存在するかどうかを確認
Debug.Log(myDictionary.ContainsKey("banana"));
Debug.Log(myDictionary.ContainsKey("grape"));
```

### 値の変更
値の変更はキーを指定して、更新したい値を記述します。
```csharp
Dictionary<string, int> myDictionary = new Dictionary<string, int>(){
    { "apple", 10 },
    { "banana", 20 },
    { "orange", 30 }
};

myDictionary["apple"] = 15;
Debug.Log(myDictionary["apple"]);
```
キーの変更はできません。変更したい場合は、一度キーを削除して新たにキーと値をセットで追加します。

### 添書
これまでに記載した記事で主要な制御構文は一通り学習しました。
メモ程度の内容ですが、他の制御構文も気になる方はぜひ他の記事も併せて見てください。

クラスやインスタンス、メソッドなどまだ学習する内容はありますが、今後はUnityで小規模なプロジェクト（ゲーム開発が学習しやすいと思っている）を作りながら重要だと思う部分を切り出してメモを残していこうと思います。
反復学習で必要な情報があれば随時それぞれの記事に追加・修正していこうと思います。
curlの証明書エラーを回避してVoltaをインストールする

Voltaをインストールする際にcurlの証明書エラーでハマったので回避方法をメモしておく。

# [公式](https://docs.volta.sh/guide/getting-started)のコマンド
`curl https://get.volta.sh | bash`

# 証明書エラー回避コマンド
`curl -k https://get.volta.sh | sed 's/curl --/curl -k --/g' | bash`

### コマンドの説明
一般的にcurlコマンドで証明書エラーを回避するには`-k` or `--insecure`オプションを付ける。

公式のシェルスクリプト`https://get.volta.sh`は内部でもcurlコマンドが使用されており、単純に`-k`オプションを付けるだけではうまくいかない。

そのため、`sed`コマンドでシェルスクリプト内のcurlコマンドにも`-k`オプションを差し込んで実行している。
【Ruby】最近発見した便利な記述方法メモ

ここ数日qiitaを巡回していて見つけたRubyで完結に書ける実装方法メモ。
### |
```ruby
array1 = ["a", "b"]
array2 = ["b", "c", "d"]

array1 | array2
# => ["a", "b", "c", "d"]
```
配列と配列を結合して1つの配列を返す。
重複する要素は1つにまとめられる。
### &
```ruby
array1 = ["a", "b"]
array2 = ["b", "c", "d"]

array1 & array2
# => ["b"]
```
共通する要素のみを取り出して配列として返す。
### array.map(&:method)
```ruby
array = ["a","b", "c"]
array.map(&:upcase)
# => ["A", "B", "C"]

array.map(&: * 2)
# => error
# mrthodじゃないから処理できない
```
`array.map{|item| item.method}`を簡潔に書くことができる。
picoCTF 2024 writeup heap 0

## heap 0 (Binary Exploitation)

Are overflows just a stack concern? Download the binary here. Download the source here. Connect with the challenge instance here: nc tethys.picoctf.net 61024

配布ファイル
・chall
・chal.c

とりあえず、`nc tethys.picoctf.net 61024`を実行してみる。
```
> nc tethys.picoctf.net 61024

Welcome to heap0!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever info you want to the heap, I already took care of using malloc for you.

Heap State:
+-------------+----------------+
[*] Address   ->   Heap Data   
+-------------+----------------+
[*]   0x565ae0abb2b0  ->   pico
+-------------+----------------+
[*]   0x565ae0abb2d0  ->   bico
+-------------+----------------+

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice:
```
選択肢が用意されていて、数字を入力するとそれに対応したことができるらしい。`2. Write to buffer: (write to your own personal block of data on the heap)`これを選ぶと、バッファをいじれそうなので、とりあえずオーバーフローを試みる。

```
Enter your choice: 2
Data for buffer: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice: 4

YOU WIN
picoCTF{my_first_heap_overflow_c3935a08}
```
フラグが得られた。

`picoCTF{my_first_heap_overflow_c3935a08}`

ちなみに、ソースコードを見てみると、
```c
if (!strcmp(safe_var, "pico")) {
    printf("\nYOU WIN\n");

    // Print flag
    char buf[FLAGSIZE_MAX];
    FILE *fd = fopen("flag.txt", "r");
    fgets(buf, FLAGSIZE_MAX, fd);
    printf("%s\n", buf);
    fflush(stdout);

    exit(0);
```
という記述があり、safe_varがpicoと一致しなければフラグが得られるようになっていた。
```c
input_data = malloc(INPUT_DATA_SIZE);
strncpy(input_data, "pico", INPUT_DATA_SIZE);
safe_var = malloc(SAFE_VAR_SIZE);
strncpy(safe_var, "bico", SAFE_VAR_SIZE);
```
safe_varはinput_dataのすぐ後に領域が確保されていた。
```c
void write_buffer() {
    printf("Data for buffer: ");
    fflush(stdout);
    scanf("%s", input_data);
}
```
バッファ(input_data)への書き込みはscanfで行われ、文字数制限は行われていない。
```
Heap State:
+-------------+----------------+
[*] Address   ->   Heap Data   
+-------------+----------------+
[*]   0x565ae0abb2b0  ->   pico
+-------------+----------------+
[*]   0x565ae0abb2d0  ->   bico
+-------------+----------------+
```
上記、アドレス値よりinput_dataとsafe_varには0x20の差があり、入力文字の33文字目からsafe_varに書き込まれるようになっている。よって、バッファに33文字以上書き込めばフラグが得られる。
GitHub Actionsでterraform applyする前にIAMロールのセッション時間を確認しよう(自戒)

構築に時間がかかるリソース(Aurora)をGitHub Actionsから`terraform apply`で作成しようとしたら、1時間くらいで`ExpiredToken`エラーが出てワークフローが落ちました。

```sh
│ Error: failed to upload state: operation error S3: PutObject, https response error StatusCode: 400, RequestID: ********, HostID: ********, api error ExpiredToken: The provided token has expired.
```
このエラーは、TerraformがAWSの状態ファイルをS3にアップロードしようとした際に、IAMロールのセッションが既に期限切れになっていたために発生しました。

# 解決案
まず、ワークフローでAssumeRoleするIAMロールの最大セッション時間を変更します。

![スクリーンショット 2024-07-03 9.54.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/680e05d8-1383-dda8-f68d-5b7731eaab04.png)

![スクリーンショット 2024-07-03 10.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/f64a6bd5-2f76-186c-4c75-46d09a4f6a77.png)

あとはワークフローのAWSクレデンシャルを設定するステップで、`role-duration-seconds`を変更すればOKです。

```yml
      - name: Setup AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ap-northeast-1
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_TO_ASSUME }}
          role-session-name: GitHubActions
          role-duration-seconds: 7200 # 2 h
```
418 I'm a teapot...HTTPの中の特異なステータスコード

418 I'm a teapotは，HTTPの中の特異なステータスコード．皆さんはこのステータスコードを知っているだろうか？

# 418 I'm a teapotって何？

418 I'm a teapotは、HTTP非標準のクライアントエラーステータスコードである．このコードは，サーバーがティーポットであり，コーヒーを淹れることを拒否していることを示す

# 起源と歴史

1. **誕生**: 1998年4月1日、RFC 2324「Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)」の一部として発表された

2. **目的**: エイプリルフールの冗談として、Internet Engineering Task Force (IETF)によって作成された

3. **意図**: インターネット標準化プロセスへの風刺と、技術コミュニティにおけるユーモアの重要性を示すことを意図していた

# 技術的詳細

1. **プロトコル**: HTCPCP（Hyper Text Coffee Pot Control Protocol）に定義されている

2. **使用状況**: 実際のHTTP通信では使用されないが，一部のウェブサーバーやアプリケーションで実装されている

3. **レスポンス本文**: 通常，このステータスコードと共に「Short and stout」（背が低くて太い）というメッセージが返される

# 文化的影響

1. **開発者コミュニティ**: 多くの開発者に親しまれ，プログラミングの文化の一部となっている

2. **実装例**: Google.com、Node.js、ASP.NETなど、有名なプラットフォームでイースターエッグとして実装されている

3. **グッズ化**: Tシャツやマグカップなど、テクノロジー関連のグッズにもなっている

# 一時は消えかかっていた

1. **削除の提案**: 2017年、HTTPの仕様から削除される可能性が浮上した

2. **保護**: 「Save 418」運動が開発者コミュニティによって展開された

3. **結果**: 多くの支持を集め、最終的に存続が決定した

# 意義

1. **技術的ユーモア**: 厳格になりがちな技術標準に，ユーモアと創造性をもたらしている

2. **コミュニティの結束**: このコードを守る動きは，開発者コミュニティの結束力を示した

3. **教育的価値**: HTTPプロトコルやステータスコードの学習において，興味を引く話題として活用されている

418 I'm a teapotは開発者の中での文化になっているだろう．これからもネットワークの文化の一端になると思う．
cscの作法 その512

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
RSSビュアーを作れ。


# サンプルコード

```
using System;
using System.Drawing;
using System.Windows.Forms;

	public class WebApp: Form {
		Panel m_plControls;
		TextBox m_tbUrl;
		Button m_btSrc,
			m_btLinks;
		WebBrowser m_wbDoc;
		TextBox m_tbView;
		public WebApp() {
			Text = "br2";
			m_plControls = new Panel();
			m_plControls.Height = 32;
			m_tbUrl = new TextBox();
			m_tbUrl.Width = 240;
			m_tbUrl.Left = 20;
			m_tbUrl.Top = (m_plControls.Height / 2) - (m_tbUrl.Height / 2);
			m_tbUrl.KeyDown += new KeyEventHandler(UrlKeyDown);
			m_tbUrl.Text = "http://qiita.com/ohisama@github/feed.atom";
			m_plControls.Controls.Add(m_tbUrl);
			m_btSrc = new Button();
			m_btSrc.Text = "htmlソース";
			m_btSrc.Left = m_tbUrl.Bounds.Right + 20;
			m_btSrc.Top = (m_plControls.Height / 2) - (m_btSrc.Height / 2);
			m_btSrc.Click += new EventHandler(SrcClick);
			m_plControls.Controls.Add(m_btSrc);
			m_btLinks = new Button();
			m_btLinks.Text = "リンク一覧";
			m_btLinks.Left = m_btSrc.Bounds.Right + 20;
			m_btLinks.Top = (m_plControls.Height / 2) - (m_btLinks.Height / 2);
			m_btLinks.Click += new EventHandler(LinksClick);
			m_plControls.Controls.Add(m_btLinks);
			Controls.Add(m_plControls);
			m_wbDoc = new WebBrowser();
			m_wbDoc.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(DocCompleted);
			Controls.Add(m_wbDoc);
			m_tbView = new TextBox();
			m_tbView.Multiline = true;
			m_tbView.Height = 64;
			Controls.Add(m_tbView);
			ClientSize = new Size(800, 600);
		}
		protected override void OnResize(EventArgs e) {
			m_plControls.Width = ClientSize.Width;
			int iDocWidth = ClientSize.Width;
			int iDocHeight = ClientSize.Height - (m_plControls.Height + m_tbView.Height);
			m_wbDoc.Size = new Size(iDocWidth, iDocHeight);
			m_wbDoc.Top = m_plControls.Top + m_plControls.Height;
			m_tbView.Width = ClientSize.Width;
			m_tbView.Top = m_wbDoc.Top + m_wbDoc.Height;
		}
		public void UrlKeyDown(Object sender, KeyEventArgs e) {
			if (e.KeyCode == Keys.Enter)
			{
				m_wbDoc.Navigate(m_tbUrl.Text);
			}
		}
		public void DocCompleted(Object sender, WebBrowserDocumentCompletedEventArgs e) {
			m_tbUrl.Text = m_wbDoc.Document.Url.ToString();
		}
		public void SrcClick(Object sender, EventArgs e) {
			m_tbView.Text = m_wbDoc.DocumentText;
		}
		public void LinksClick(Object sender, EventArgs e) {
			HtmlElementCollection hecList = m_wbDoc.Document.Links;
			String stView = "";
			int i = 0;
			foreach (HtmlElement elm in hecList)
			{
				if (elm.GetAttribute("href") != null)
				{
					stView += i.ToString();
					stView += " - " + elm.GetAttribute("href").ToString();
					stView += "\r\n";
					i++;
				}
			}
			m_tbView.Text = stView;
		}
		[STAThread]
		public static void Main() {
			WebApp app = new WebApp();
			Application.Run(app);
		}
	}



```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1a43527a-32c6-58dc-27b2-fad229b1bc5e.png)


以上。
PowerVSでの「手動構成したDirect Link」と「自動構成したCloud Connection」の見分け方

# はじめに
PowerVSと、x86系のIBM Cloud（VPCやClassic）は、デフォルト状態では繋がっていません。
これらを接続するための方式は、時期によって数パターンありました。

①Direct Link 1.0時代： ②より前
②Direct Link 2.0時代（手動構成）： 2020年10月中旬〜
③Cloud Connection時代（自動構成）： 2021年5月20日頃〜
④PER時代： 日本では2024年3月〜

②は、ユーザーがDirect Link 2.0をオーダーした後、caseを起票し、PowerVS側サポートに接続を依頼します。構成手順は[こちら](https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-ordering-direct-link-connect)。

③は、ユーザーがCloud Connectionをオーダーすると、それに連動してDirect Link 2.0が作成され、自動処理でPowerVSとx86 IaaSが繋がります（case不要）。構成手順は[こちら](https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-cloud-connections)。

PowerVSが東京と大阪で提供開始したのが下記の通り②より後ですので、日本のDCで①を使っている環境は無いはずです。
・PowerVS東京リージョン開設：2020年10月末
・PowerVS大阪リージョン開設：2021年3月末

2024年7月現在、下記の状況になっています。
・新規に作成したワークスペースはPERに対応している。
・2024年3月以前に作成したワークスペースで②③の構成になっている環境は、そのままの状態が維持されている（自動的にPER対応にはなる訳ではない）。


PERに移行したいけど自分の環境は②と③どっちだっけ？という状況もありえますので、この記事では②と③を区別する方法について書きます。

# 自動構成したCloud Connectionsの見分け方

順番は前後しますが、まず、③Cloud Connection（自動構成）の見分け方です。
下記の2箇所を確認する事で、「自動構成したCloud Connection」であることを確認できます。

1\. 管理ポータルのCloud Connections（クラウド接続）の画面で接続が作成されている。
https://cloud.ibm.com/power/cloud-connections

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/85138236-f13b-3058-12df-5ba147d72e82.png)

2\. Direct Linkの詳細画面に下記の文言がある。
Direct Linkの詳細画面は、管理ポータルで、下記の一覧画面から、Cloud Connectionsと同じ名前の接続を選択します。
https://cloud.ibm.com/interconnectivity/direct-link

> このDirect Linkは読み取り専用です。 リンク固有のアクションは、サービス・プロバイダー・ポータルを介して開始する必要があります。

ブラウザが英語表示の場合、下記となっています。

>This direct link is read-only. Link-specific actions must be initiated through the service provider portal.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/421fff64-95ed-5461-e4d8-8a6bdb590c51.png)

Cloud Connection（自動構成）の環境を、PER環境に切り替える手順のdocsは下記となります。
https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-per#migrate-per

# 手動構成したDirect Link 2.0の見分け方

続いて、②Direct Link 2.0（手動構成）の見分け方です。
下記の2箇所を確認する事で、「手動構成したDirect Link 2.0」であることを確認できます。

1\. 管理ポータルのCloud Connections（クラウド接続）の画面で接続が作成されていない。
https://cloud.ibm.com/power/cloud-connections

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/211818f8-902a-c1c7-c0d5-93bf644ccaef.png)


2\. Direct Linkの詳細画面に、Cloud Connectiosの時の「このDirect Linkは読み取り専用です。 （後略）」の文言が無い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59627/c858a92b-68bf-ec76-4e88-53d131be63b1.png)

Direct Link 2.0（手動構成）の環境を、PER環境に切り替える手順のdocsは下記となります。
https://cloud.ibm.com/docs/power-iaas?topic=power-iaas-migrate-ws-per
また、下記もご参照ください。
https://qiita.com/y_tama/items/f709a2030e85ef0ef382
情シスのあるあるまとめ！問い合わせと業務内容それぞれ5選と解決方法を紹介–情報システム部門を刺激するメディア「情シスのじかん」より

「情シスのじかん」は、情報システム部門のプロフェッショナルを対象としたメディアです。実務に役立つノウハウや革新的なアイデアを提供し、学びとネットワーキングの場を提供することを目指しています。最新の技術動向やベストプラクティス、成功事例を通じて、情シス担当者のスキルアップをサポートします。

ここで、Qiitaの読者の皆様向けに、「情シスのじかん」で公開された記事をピックアップ＆サマリ紹介します！Qiitaは技術者向けの情報共有プラットフォームとして、より実践的で具体的な技術情報を提供する場です。情シスのじかんは、特に情報システム部門に特化した内容を中心にしていますが、両者の強みを活かして、プロフェッショナルの皆様に有益な情報をお届けします。

### 情シスのあるあるまとめ！問い合わせと業務内容それぞれ5選と解決方法を紹介
![josys_aruaru.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3816554/ef9f12a1-45cc-f4d1-42bc-b3fa00d2e2d9.jpeg)

この記事では情シスのあるあるを紹介します。情シスのあるあるは、問い合わせと業務内容の分野でわけられます。また、悩みについてのあるあるや解決方法についても紹介しますのでぜひご覧ください。

https://josys.wingarc.com/josys-keyword-josys-common-things

### 情報システム部門を刺激するメディア「情シスのじかん」とは？
![情シスのじかんbyWingArc1st (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3816554/89afaa7e-b941-a10a-c813-8485daca4502.png)

初めまして、『情シスのじかん』です。
近日遂に、日本中の情シス部門のあなたを刺激するメディアが発足します！🚨
さぁ、テクノロジーを飼い慣らし、仕事や生活の質を向上させ、一緒に未来を切り拓きましょう。皆様の生活リズムに合わせた情報発信で、常に寄り添い、共に未来を切り拓くためのメディアです。

ぜひ、情報システム部門の皆様の活動の取材をさせてください。

https://josys.wingarc.com/about
図書館の悩み

# 概要
私の行ってる図書館は、珍しく「パソコン優先席」が５席あり、「Free Wi-Fi」もある。
しかし、WiFiが安定しない、繋がらない。
机にLANケーブルのソケットがあるが、自分のノートPCには、LANケーブルはさせない。
図書館のスタッフに迷惑かけるのも、気が引けるので、自己解決した。

# 解決策
家から、使っていないブロードバンドルーターを持ってきた。
机のLANケーブルに繋ぐ。
ルーターをAPモードに設定して、起動。
ノートPCからWiFiでルーターに入る。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6a32567e-288c-3169-eff6-058f458edd4a.png)


# まとめ
図書館のWiFiが安定しないので、野良WiFiを立ち上げた。


以上。
インボイス制度について登録から活用までをわかりやすく徹底解説–情報システム部門を刺激するメディア「情シスのじかん」より

「情シスのじかん」は、情報システム部門のプロフェッショナルを対象としたメディアです。実務に役立つノウハウや革新的なアイデアを提供し、学びとネットワーキングの場を提供することを目指しています。最新の技術動向やベストプラクティス、成功事例を通じて、情シス担当者のスキルアップをサポートします。

ここで、Qiitaの読者の皆様向けに、「情シスのじかん」で公開された記事をピックアップ＆サマリ紹介します！Qiitaは技術者向けの情報共有プラットフォームとして、より実践的で具体的な技術情報を提供する場です。情シスのじかんは、特に情報システム部門に特化した内容を中心にしていますが、両者の強みを活かして、プロフェッショナルの皆様に有益な情報をお届けします。

### インボイス制度について登録から活用までをわかりやすく徹底解説
![IMG_6454.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3816554/e4dce4c6-758d-257d-77fa-424c3942ccd3.jpeg)

この記事ではインボイス制度について解説しています。消費税を正しく運用するためのインボイス制度は、免税事業者、課税事業者によって登録すべきかが変わります。また、税金の計算方法についても紹介しますのでぜひご覧ください。

https://josys.wingarc.com/invoice-system

### 情報システム部門を刺激するメディア「情シスのじかん」とは？
![情シスのじかんbyWingArc1st (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3816554/89afaa7e-b941-a10a-c813-8485daca4502.png)

初めまして、『情シスのじかん』です。
近日遂に、日本中の情シス部門のあなたを刺激するメディアが発足します！🚨
さぁ、テクノロジーを飼い慣らし、仕事や生活の質を向上させ、一緒に未来を切り拓きましょう。皆様の生活リズムに合わせた情報発信で、常に寄り添い、共に未来を切り拓くためのメディアです。

ぜひ、情報システム部門の皆様の活動の取材をさせてください。

https://josys.wingarc.com/about
Goのcontextを使ってみる

## WithCancel

WithCancel()でキャンセル用のcontextを作成しておき、2秒待ってから、cancel()を実行して処理を中止するように、longRunningTask()に伝えています。

こうすることで、それ以上実施する必要のない処理を止めることができるようになります。

```go
package main

import (
	"context"
	"fmt"
	"time"
)

// 長時間かかる処理をシミュレートする関数
func longRunningTask(ctx context.Context) {
	select {
	case <-time.After(5 * time.Second):
		// 処理が完了した場合
		fmt.Println("Task completed")
	case <-ctx.Done():
		// キャンセルやタイムアウトが発生した場合
		fmt.Println("Task canceled:", ctx.Err())
	}
}

func main() {
	// キャンセル可能なコンテキストを生成
	ctx, cancel := context.WithCancel(context.Background())

	go longRunningTask(ctx) // 長時間かかる処理を非同期で実行

	// 2秒後にキャンセルを呼び出す
	time.Sleep(2 * time.Second)
	cancel()

	// 処理が完了するか、キャンセルされるまで待つ
	time.Sleep(6 * time.Second)
	fmt.Println("Main function completed")
}
```

## WithTimeout

withTimeout()を使えば、上記の処理をよりシンプルに書くことができます。

3秒後にキャンセルが実行されるcontextを作成して、longRunningTask()に処理を中止するように伝えることが可能です。

```go
package main

import (
	"context"
	"fmt"
	"time"
)

func longRunningTask(ctx context.Context) {
	select {
	case <-time.After(5 * time.Second):
		// 処理が完了した場合
		fmt.Println("Task completed")
	case <-ctx.Done():
		// キャンセルやタイムアウトが発生した場合
		fmt.Println("Task canceled:", ctx.Err())
	}
}

func main() {
	// タイムアウト付きのコンテキストを生成（3秒後にタイムアウト）
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel() // 3秒後に処理を中止

	go longRunningTask(ctx)

	time.Sleep(6 * time.Second)
	fmt.Println("Main function completed")
}
```

## WithDeadline

WithDeadline()を使うと、指定の時刻までに処理が完了されなければキャンセルすることが可能になります。WithTimeout()が**指定時間経過後**なのに対して、こちらは**指定期日までに**、という点が異なっています。

```go
package main

import (
	"context"
	"fmt"
	"time"
)

func longRunningTask(ctx context.Context) {
	select {
	case <-time.After(5 * time.Second):
		// 処理が完了した場合
		fmt.Println("Task completed")
	case <-ctx.Done():
		// キャンセルやタイムアウトが発生した場合
		fmt.Println("Task canceled:", ctx.Err())
	}
}

func main() {
	// 現在の時刻から3秒後にタイムアウトするコンテキストを生成
	deadline := time.Now().Add(3 * time.Second)
	ctx, cancel := context.WithDeadline(context.Background(), deadline)
	defer cancel()

	go longRunningTask(ctx)

	time.Sleep(6 * time.Second)
	fmt.Println("Main function completed")
}
```
AWSのロール切替URL（色指定あり）

# 概要

AWSのロール切替画面URLでは、初期表示されるAWSアカウントID（`account`）、IAMロール名（`roleName`）、表示名（`displayName`）、色（`color`）を指定できる。次のような書式になる。

```
https://signin.aws.amazon.com/switchrole?account=account_id_number&roleName=role_name&displayName=text_to_display&color=xxxxxx
```

カラーは、以下のカラーコードのいずれかを指定する。

* `ea7158`（Red）
* `fbc8aa`（Orange）
* `efda95`（Yellow）
* `b4d699`（Green）
* `83d4e8`（Blue）

# 詳細

AWSのロール切替画面のURLには、初期表示するAWSアカウントID、IAMロール名、表示名をクエリストリングで入れておける。よく使うものはブラウザブックマークに入れておくと便利。これは以下の公式情報で紹介されている。

> 手動でリンクを作成して、次の手順のステップ ステップ 5 にスキップできます。リンクを作成するには、次の形式を使用します。
> `https://signin.aws.amazon.com/switchrole?account=account_id_number&roleName=role_name&displayName=text_to_display`
> （[ロールの切り替え (コンソール) - AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-console.html#id_roles_iam_user-switch-role-console-things-to-know)）

紹介されていないものとして、実は色も `color=#xxxxxx` のようにカラーコードを指定しておくことができる。

ただしロール切替画面での色指定が色名（Red、Orange、Yellow、Green、Blue）になったタイミングで、有効なカラーコードもこの5色に相当するものだけになった。「[カラーコードが指定されたスイッチロール用URLを作成する(カラーコードアップデート版) - Techfirm Cloud Architect Blog](https://techblog.techfirm.co.jp/entry/aws-switch-role-url)」で、指定可能なカラーコードがまとめられていた。

|URLでの指定値|ロール切替画面での初期表示|
|---|---|
|`color=ea7158`|Red|
|`color=fbc8aa`|Orange|
|`color=efda95`|Yellow|
|`color=b4d699`|Green|
|`color=83d4e8`|Blue|

# 参照

以下を参考にしました。

* [ロールの切り替え (コンソール) - AWS Identity and Access Management](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_use_switch-role-console.html#id_roles_iam_user-switch-role-console-things-to-know)
* [カラーコードが指定されたスイッチロール用URLを作成する(カラーコードアップデート版) - Techfirm Cloud Architect Blog](https://techblog.techfirm.co.jp/entry/aws-switch-role-url)
ESLintをカスタマイズしてみた

VSCodeで拡張機能として入れているESLintの設定を、プロジェクト限定でカスタマイズ。

1. ESLint初期化して、`eslint.config.mjs`を生成する
    ```bash
    npm eslint --init
    ```
    .
2. 追加で、air-bnbのルールセットを適用してみる
    ```bash: 
    npm i eslint-config-airbnb-typescript
    ```
    .
3. `eslint.config.mjs`でimportする

    ```javascript
    import pkg from 'eslint-config-airbnb-typescript';
        
    // 省略
    
    const airbnbRules = pkg.rules;
    
    export default [
    
      // 省略
      
      {
        rules: {
          ...airbnbRules,
        },
      },
    
      // 省略
      
    ];

これからも使いそうなので、記録に。
readonlyなプロパティも書き換えられうる

## readonly修飾子
オブジェクトの型を宣言するときに、プロパティ名の前に`readonly`をつけることで、そのプロパティを読み取り専用にすることができます。
```ts
type ReadonlyObj = {
  readonly num: number
}


const readonlyObj: ReadonlyObj = {
  num: 314
}

readonlyObj.num = 217 //型エラーが発生
```
`readonly`によって読み取り専用にしたプロパティ`num`を値`217`へと直接書き換えようとすると、以下のように型エラーが発生します。
```
Cannot assign to 'num' because it is a read-only property.(2540)
```
`readonly`をつけることによって、変更されたくないプロパティを型で明示することができます。
## readonly なプロパティでも変更されうる
この`readonly`修飾子をプロパティにつけている場合でも、**関数を介すことで値が書き換えられてしまう**場合があります。

```ts
type Obj = {
  num: number
}

type ReadonlyObj = {
  readonly num: number
}

const readonlyObj: ReadonlyObj = {
  num: 314
}

const changeNum = (obj: Obj) => {
  return obj.num = 271
}

console.log(readonlyObj) //{ "num": 314 } 
changeNum(readonlyObj) // readonlyなプロパティを型エラーなしで書き換えられてしまう。
console.log(readonlyObj) //{ "num": 271 } 
```
上の例のように、引数で受け取ったオブジェクトの`num`というプロパティの値を直接`271`に変更する関数`changeNum`について考えてみます。

この`changeNum`に`readonly`な`num`プロパティを持つオブジェクト`readonlyObj`を渡すと、型エラーなしでプロパティの書き換えができていることがわかります。

**`readonly`がついているからといって、プロパティの値が一切変わらないわけではない**ということは、頭の片隅にいれておくと混乱が少なくすむかもしれません。
Anacondaを使わずPythonにGDALをインストールする方法

PythonにGDALをインストールする手順で躓いた際の解決方法の備忘録です。私はGDALでしか検証していませんが、地理空間系の解析に必要な他のライブラリ（basemap, Cartopy, cftime, Fiona, netCDF4, pygeos, pyproj, rasterio, Rtree, shapely）についても同様の手順が使えそうです。

# GDALのインストールでエラー発生

久々に画像解析の作業を行うことになり、PCにPythonをインストールしました。次いで必要なパッケージも`pip`コマンドを使ってインストールしていったのですが、GDALをインストールしようとしたところ、エラーが出て止まってしまいました。

```terminal
> pip install gdal

Collecting gdal
  Using cached gdal-3.9.1.tar.gz (840 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: gdal
  Building wheel for gdal (pyproject.toml) ... error
  error: subprocess-exited-with-error
  × Building wheel for gdal (pyproject.toml) did not run successfully.
（中略）
  error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools" (https://visualstudio.microsoft.com/visual-cpp-build-tools/)
```

以下のサイトでも「GDALは複雑なので追加のステップが必要かも」(Due to the complex nature of GDAL and its components, different bindings may require additional packages and installation steps. )と説明されています。

https://pypi.org/project/GDAL/

ただ、エラー文の通りにVisual C++をインストールしても、なぜか上と同じエラーが出てしまいうまくいきません。試行錯誤していたところ、以下の方法で解決できたので紹介します。なお、こちらで紹介する手順はおそらくWindowsにしか対応していないと思われます。Macユーザーの方のお役には立てないかもしれません。

# 検証した環境

Windows 11
Python 3.11.1

# .whlファイルを使ってGDALをインストール

実は、以前はこのような問題にはあたりませんでした。というのも、インストーラーの取得を`pip`コマンドに頼っていなかったためです。Pythonパッケージのインストーラーを公開してくれているサイトから個別にダウンロードしていました。その方法は当時所属していた研究室のブログで紹介しました。

https://biometblog.blogspot.com/2019/01/python-windows-64-bit.html

今回もその方法に立ち返って試そうとしたのですが、その時に頼っていたサイト（[https://www.lfd.uci.edu/~gohlke/pythonlibs/](https://www.lfd.uci.edu/~gohlke/pythonlibs/)）は残念ながら閉鎖してしまったようです。ただ嬉しいことに、同じ人が改めてGitHubにインストーラーを公開してくれています。

https://github.com/cgohlke/geospatial-wheels

こちらのサイトにアクセスし、最新のリリースのページに移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607418/b78104ef-32ce-8bb5-2466-70344eceabd1.png)

リリースページ内に上がっている多くのパッケージの中から、必要なパッケージを探します。ファイル名は、[ソフト名]-[ソフトのバージョン]-[対応するPythonバージョン]-[対応するPythonバージョン２]-[Windowsのビット数].whlとなっています。今回はPCのビット数が64、Python 3.11で使用するものを探していたので、「GDAL-3.8.4-cp311-cp311-win_amd64.whl」をダウンロードしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607418/91d73671-5a6b-6842-0753-ff0f7353f2b3.png)

ダウンロードできたら、ターミナルに以下のように打ち込むとインストールできます。

```terminal
cd [ダウンロード先のパス]
pip install [ファイル名].whl
```

# なぜAnacondaを使わないの？

私は試していませんが、Anacondaを使用するとかなり簡単にインストールできるらしいです。

https://qiita.com/nokonoko_1203/items/55faf4455f7986080e59

では、なぜAnacondaを使用しないのか？　ということになりますが、私の場合は単にPythonをたまーにしか使用しないせいで、Anadondaを使用するという発想に至らなかっただけです…

ただ、たまたまこの記事を書いている最中、Anacondaが有償提供の方針となったことを知りました。もしかしたらPythonそのままの環境を使う機会が増えるかもしれません。
【Figma Plugins】Figma PluginsでAnnotationを作成する

## はじめに
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/cfefc38a-a878-565f-25c0-b7dded50077c.png)
FigmaのPluginを開発する際、Annotationを作成したいと思ったことはありますか？
この記事では、Figma PluginsでAnnotationを作成する方法を解説します。

## Annotationを作成する
:::note warn
Annotationを作成するには、editorType が devの時のみ設定できます。
Anotationを読み取るには、どのモードでも可能です。
:::

Annotationを作成するには、`annotations` を利用することで、Annotationが作成されます。

```ts
annotations: ReadonlyArray<Annotation>
```

annotationsのInterfaceは以下のようになっています。
```ts
interface Annotation {
  readonly label?: string
  readonly properties?: ReadonlyArray<AnnotationProperty>
}
```

Annotationを作成できるのは、以下のノードタイプでサポートされています。

+ `ComponentNode`
+ `ComponentSetNode`
+ `EllipseNode`
+ `FrameNode`
+ `InstanceNode`
+ `LineNode`
+ `PolygonNode`
+ `RectangleNode`
+ `StarNode`
+ `TextNode`
+ `VectorNode`

### 使い方

```ts
const node = figma.currentPage.selection[0]

// Add an annotation note
node.annotations = [{ label: 'Main product navigation' }]

// Pin the fill property
node.annotations = [{ properties: [{ type: 'fills' }] }]

// Add an annotation with a note and width property pinned
node.annotations = [
  { label: 'Pressing activates animation', properties: [{ type: 'width' }] },
]

// Clear an annotation
node.annotations = []
```

## まとめ
この記事では、Figma PluginsでAnnotationを作成する方法を解説しました。
ぜひこの記事を参考にAnnotationを作成してみてください！

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaで記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
【Node.js】Lambdaから社内環境のSQL Serverに接続する方法

## はじめに
AWS Lambdaから社内環境のSQL Serverへの接続方法について紹介していきます:point_up_tone1:
SQLServerへの接続部分で具体的な値の例が無く、苦戦したのでより具体的に値を記載しようと思います！

## 開発内容
### パッケージのインストール
Node.jsでSQLServerへアクセスするために必要なパッケージをインストールします

```
npm install mssql
```
https://github.com/tediousjs/node-mssql

### Lambdaの設定
特定の環境からのみアクセス可とするため、VPCの設定を行います。
Lambdaの設定タブのVPC からVPC、サブネット、セキュリティグループを設定します。

### ソースコード

```javascript
// パッケージの読み込み
const sql = require('mssql')

// SQL Serverの設定
const config = {
  user: 'sa',
  password: 'XXXXXXX', // 設定したパスワード
  server: '192.168.X.X',
  database: 'DATABASE_NAME', // DB名
}

exports.handler = async (event) => {
  console.log(event)
 
  try {
    const parameter = event.queryStringParameters
    const userId = parameter.userId;
 
    // SQL Serverに接続
    await sql.connect(config)

    // ユーザー情報取得用のSQLを実行    
    const result = await sql.query
      `SELECT * FROM ユーザー情報 WHERE USER_ID = ${userId}`
 
    // 接続を閉じる
    await sql.close();
 
    const record = JSON.stringify(result.recordset)
 
    return {
      statusCode: 200,
      headers: {
        'Access-Control-Allow-Origin': '*'
      },
      body: record
    }
  } catch (err) {
    console.log('SQL ERROR:' + err)
 
    // 接続を閉じる
    await sql.close();
 
    return {
      statusCode: 500,
      headers: {
        'Access-Control-Allow-Origin': '*'
      },
      body: 'ERROR'
    }
  }
};
```

## さいごに
初めてSQLServerと接続の実装を行ったため、上手くいかない原因の特定に時間が掛かり、実装が大変でした・・
こちら参考になれば幸いです:koala::dizzy: