OmniAICreator/Qiita-1.07M huggingface dataset:
なぜかAzure Storage accountsの接続エラーが発生した

# 経緯

C#で作ったWebAPI経由で、Azure Storage accountsにファイルをアップロードしたりダウンロードしたり、削除したりするアプリを保守運用しています。
そのアプリに、ユーザからエラー報告が来ていたため、調査・修正を行いました。

※先に述べておきますが、明確なエラー原因は分かりませんでした。修正コード書いているうちに勝手に直っていました。

# エラー内容

手書きで写したので、間違いなどあるかもしれませんが、、

```:エラーメッセージ
Microsoft.WindowsAzure.Storage.StorageException: Unable to connect to the remote server
 ---> System.Net.WebException: Unable to connect to the remote server
 ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond // IDアドレスとポート番号？ // at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapShot, SocketAddress socketAddress) At System.Net.ServicePoint.ConnectSoketInternal(Boolean connectFailure, Socket s4, Socket s6, Soket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
 --- End of inner exception stack trace
 --- at System.Net.HttpWebRequest.GetResponse() at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) in // ディレクトリ //
 --- End of inner exception stack trace
 (後略)
 ```

 もうちょっと詳しく見ると、404エラーが返ってきたと書いてありました。

# 調査

調査、修正は以下の流れで行いました。

1. エラー報告を受け、調査を開始
1. 検証環境ではエラーが再現しないことを確認
1. 本番環境でのエラーが再現することを確認
1. ローカル環境でもエラーは再現しないが、本番環境のAzure Storage accountsの接続文字列を使うと再現した
   →コードは特に問題が無く、本番環境のAzure Storage accountsが問題っぽい？
1. 本番環境と検証環境のAzure Storage accountsを比較するが、特に差異は見当たらず
1. 以前、本番環境のAzure ADを利用したログインだけが出来なくなった経験があるため、Nugetパッケージを疑ってみることに
   Azure Storage accountsにアクセスするのに利用していたNugetパッケージは「WindowsAzure.Storage」だが、**非推奨**になっていた。
   そこで、今回はこのパッケージを原因と仮定し、「Azure.Storage.Blobs」を使ったものに書き換えることにした。
1. コードを修正し、ローカルで本番環境のAzure Storage accountsに接続すると、ファイルを取得できたため、そのまま作業を進める
1. 修正が完了し、検証環境でのテストも完了したが、適用前に本番環境のエラーが再現するか確かめてみたところ、なぜかファイルが取得できた、、

ということで、なぜか勝手に直っていたので、金曜日ということもあり、本番環境適用は見送りました。

# 原因

原因は以下の2つだろう、という推測で終わりました。
1. 本番環境のAzure Storage accountsが不安定だった
1. 非推奨のNugetパッケージ「WindowsAzure.Storage」を使っていた

# 最後に

Nugetパッケージに限らず、利用しているものが非推奨になっていないか、なども気をつけないといけませんね、、
javascript joinメソッド

## Joinメソッドとは
配列に対して使用できるメソッドの一つ
配列に入っている要素を引数で指定した文字で、区切り、文字列連結する


引数なしで呼び出すとデフォルトである、カンマ区切りで実行される

## 例
```
const names = [Alice, Bob, Hanako];

names.join('/') → Alice/Bob/Hanako
names.join('')  → AliceBobHanako
names.join()    → Alice,Bob,Hanako
```
Poetryのかゆいところを解決! コンテナ内のroot以外のユーザーでPoetryを動かす方法

## はじめに
コンテナ内のroot以外のユーザーで、`poetry install`をするときに権限の問題が困ることはありませんか？

今回はコンテナ内のroot以外のユーザーで、`poetry install`を実行する方法を紹介します。

## 内容
### 1.Poetry自体のインストール
まずDockerfileで`curl`、`gcc`、`sudo`、`poetry`をインストールします。
```Dockerfile
FROM python:3.9-buster

USER root

RUN apt-get -yq update && \
    apt-get -yqq install curl gcc sudo && \
    curl -sSL https://install.python-poetry.org | python3 -
```

`poetry`自体のインストールはルートユーザーで行う必要があります。
`poetry`は`/root/.local/bin`に保存されます。

### 2.Poetryを動かす
devcontainerでコンテナを立ち上げた後、root以外のユーザー(例`vscode`)で`poetry`を動かします。

`poetry`は先述のように`/root/.local/bin`にあります。以下のように絶対パスを指定しても実行できません。（もちろんパスを通しても同じです）

```bash
$ /root/.local/bin/poetry install 
bash: /root/.local/bin/poetry: Permission denied
```

そこで`sudo`権限を使えば`poetry`のコマンドの実行ができます。

```bash
$ sudo /root/.local/bin/poetry install
```

ただ毎回`sudo /root/.local/bin/poetry`と打つのは面倒です。
そこで、`alias poetry="sudo /root/.local/bin/poetry"`とすれば、以下のように`poetry install`が通ります。

```bash 
$　alias poetry="sudo /root/.local/bin/poetry"
$　poetry install
```

参考になれば幸いです。(そこそこ力業なので、最適なソリューションではないかもしれませんがご了承ください。)


---

追記:
PoetryではなくRyeを使えば、上記のような問題は発生しないので、筆者的にはRyeがおすすめです。
Macでよく使うショートカットキー

# まえがき
この記事は私が普段使っているショートカットキーを列挙したものです。
載ってなくて「これは便利だぞ」ってものがあったらコメントいただけると嬉しいです。
## コピー
`command + c`
## ペースト
`command + v`
## Finderでファイルを移動
移動元ファイルをコピーしてから移動先で`command + option + v`
## 全選択
`command + a`
## 起動中のアプリ切り替え
`command + tab`
## アプリを終了
`command + q`
## アプリを強制終了
`command + option + esc`
## ロック
`command + control + q`
## ウィンドウの切り替え（Chromeなど）
`option + tab`
## URLバーにカーソルを移動（Chromeなど）
`command + l`
## 印刷（対応アプリのみ）
`command + p`
## 検索（対応アプリのみ）
`command + f`
## スクリーンショットメニュー
`command + shift + 5`
## 画面全体のスクリーンショット
`command + shift + 3`
## 選択範囲のスクリーンショット
`command + shift + 4`
## Spotlightを開く
`command + space`
## 音量・光量調整（微）
`option + shift + 調整ボタン`
## サウンドの設定
`option + 無音or音量小or音量大`
## ディスプレイの設定
`option + 光量小or光量大`
【SwiftUI】TexのMarkdownのリンクを制御する

# はじめに
SwiftUIのTextでマークダウンが使えるのを知っていますか？
マークダウンでリンクが使えるのですが、このリンクをタップした時の処理を自前で実装できるんです。

これができると何ができるのかというと、
同じマークダウン内に移動する目次なんかを簡単に実装することができるようになります。

# サンプルアプリ
目次を選択すると、その項目へ移動します。
![Simulator Screen Recording - iPhone 15 - 2024-01-26 at 21.27.27.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2ac2f47c-c699-ea57-25a6-160d8347e395.gif)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollView {
            ScrollViewReader { proxy in
                VStack {
                    Text("""
                        # 目次
                        - [テキスト10](10)
                        - [テキスト20](20)
                        - [テキスト30](30)
                        - [テキスト40](40)
                        - [テキスト50](50)
                        - [テキスト60](60)
                        """)
                        .environment(\.openURL, OpenURLAction { url in
                            // urlで受け取れるのは()の中のもの
                            // 現在、urlの型はURLなのでStringに変換する
                            let id = url.description
                            // ScrollViewを移動させる
                            withAnimation {
                                proxy.scrollTo(id, anchor: .center)
                            }
                            // handledを返すことによって自前で処理をかける
                            return .handled
                        })
                        .frame(maxWidth: .infinity, alignment: .leading)
                    
                    ForEach(0..<100) { index in
                        Text("テキスト\(index)")
                            .id(index.description)
                            .frame(maxWidth: .infinity)
                            .containerRelativeFrame(.vertical)
                            .background(.red.opacity(0.6), in: .rect(cornerRadius: 8))
                    }
                }
                .padding(20)
            }
        }
    }
}
```

# おわり
公式ドキュメント見てたら発見しました

# 公式ドキュメント
https://developer.apple.com/documentation/swiftui/openurlaction
Error: failed to start validator: Failed to create ledger at test-ledger: blockstore error エラーへの対処法

## はじめに
`solana-test-validator`を実行したら、次のようなエラーが出ました。
```bash
Error: failed to start validator: Failed to create ledger at test-ledger: blockstore error
```
バリデーターの起動に失敗しているようです。

## 結論

https://solana.stackexchange.com/questions/4499/blockstore-error-when-starting-solana-test-validator-on-macos-13-0-1/4761#4761

このページを参考にコマンドを実行し、エラーが解消されました。

### 原因
上記のページによると、

tarプログラムには複数のバージョンがあり、MacOSにはデフォルトでBSD tarが搭載されています。
しかし、`solana-test-validator`はGNU tarを想定しています。

GNU tarの依存性が解決するまでの間、BSD tarをGNUバージョンに置き換えることで、この問題を回避することができます。

### 対処法

homebrewをインストールしていない場合は、インストールします。

次に、GNUのtarをHomebrewを使用してインストールします。
```bash
brew install gnu-tar
```

インストールが完了したら、`~/.zshrc`ファイルに`export PATH=...`の行を追加してPATHを更新します。

```bash
echo 'export PATH="/opt/homebrew/opt/gnu-tar/libexec/gnubin:$PATH"' >> ~/.zshrc
```
 または、エディタを使用して`~/.zshrc`を開き、以下の行を追加します。
```bash
export PATH="/opt/homebrew/opt/gnu-tar/libexec/gnubin:$PATH"
```

最後に、`~/.zshrc`の変更を反映させるために以下のコマンドを実行します。
```bash
source ~/.zshrc
```
AMD社FPGA（旧Xilinx)での画像認識

機械学習結果の推論をエッジデバイスで推論する際の選択肢は増えた方がいい。

そのような選択肢についての情報に気が付きにくい状況にある（と思う）。
AMD社FPGA（旧Xilinx)での画像認識のプラットフォームにZebraがあることに気づいたのでメモする。


## AMD Xilinx
AMD-ザイリンクス [AIに世界最高レベルの効率をもたらす　ゼロ ダーク シリコン　ソリューション](https://www.slideshare.net/NaohisaSumikawa/amdxilinxaivck500020220602r1pdf)

Xilinx [Zynq™ UltraScale+™ MPSoC](https://www.xilinx.com/products/silicon-devices/soc/zynq-ultrascale-mpsoc.html)

Xilinx[すぐ試せる! エッジからクラウドまで対応するアダプティブなAIプラットフォームとは](https://www.avnet.com/wps/wcm/connect/onesite/a02a8e0b-6d9b-4cd2-973c-af838d90c712/Avnet+AI+Discovery+Day+2020+-+Xilinx.pdf?MOD=AJPERES&CVID=nnV7ltu&CVID=nnV7ltu&attachment=false&id=1606202252717)

> Mipsology社のZebraプラットフォーム シームレスかつ高パフォーマンスを実現

上記のスライドのp.30, 31がMipsology社のZebraプラットフォームの記載。

![Screenshot from 2024-01-26 20-44-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/cd2f750a-64f1-da02-bb9f-9043da56422a.png)

![Screenshot from 2024-01-26 20-57-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/6dc1f62e-7e9b-bdee-f750-5cf22970ab50.png)

Xilinx [ZEBRA™ BY MIPSOLOGY: ACCELERATING NEURAL
NETWORK INFERENCE](https://www.xilinx.com/content/dam/xilinx/publications/solution-briefs/zebra-mipsology-solution-brief.pdf)
---
[Mipsology](https://www.dev.mipsology.com/hardware/)


Mipsology [ZEBRA® AI SOFTWARE](https://www.dev.mipsology.com/product/)]
---

brycen [FPGA AI ACCELERATION FPGA AI アクセラレーション with Mipsology Zebra®](https://www.brycen.co.jp/front-page/ja/core-technology/zebra/)

https://www.brycen.co.jp/core-technology/zebra/

![](https://www.brycen.co.jp/wp-content/themes/brycen/img/core-technology/zebra/zebra_pic2.jpg)

---
## OKI アイディエス
OKI　アイディエス [AMD FPGA対応 DNN高速アクセラレーション ディープラーニング推論アクセラレータ AMD Zebra™](https://www.oki-oids.jp/solution/products/Zebra.html)

>Zebraのその他の特長
業界標準フレームワーク各種をサポート
Caffe, TensorFlow, PyTorch, ONNX, MXNET

>コード変更一切必要なし
新しい言語、フレームワーク、APIやツールは不要

OKI　アイディエス [AI／DL開発・デザインサービスのご案内](https://www.oki-oids.jp/solution/products/AI_DL_Service.html)
OKI　アイディエス "OKIアイディエス　現場で使えるエッジAI セミナー ～FPGA／SoCへの実装と開発事例のご紹介～"のセミナーを開催することがあります。

Youtube [OKIアイディエスWebセミナー「高位合成・高位検証プロセス、AIディープラーニング推論アクセラレーターMipsology Zebra」【OKI公式】](https://www.youtube.com/watch?v=mDP0CPkhXFU)

Youtube [OKIアイディエスWebセミナー　AIデザインサービス【OKI公式】](https://www.youtube.com/watch?v=xH3FozB5FYQ&list=PLBLX3iYj5qBlWQvXwPRIKgILNfv4Aj_1X&index=4)

YouTubeOKI【沖電気工業株式会社】[「ザイリンクス FPGA対応 DNN高速アクセラレーション ディープラーニング推論アクセラレータ Mipsology Zebra」【OKI公式】](https://www.youtube.com/watch?v=iUahiM4KC9c)
---
AVANET [Mipsology FPGAカード向けAIアクセラレーション](https://www.avnet.com/wps/portal/japan/products/c/fpga-solutions/xilinx/deep-learning/)

AVANET [CPU/GPUアクセラレーターをはるかにしのぐ性能を持つ FPGA 知識不要の超高速推論エンジン Zebra](https://www.avnet.com/wps/portal/japan/products/c/fpga-solutions/xilinx/mipsology-zebra/)
---
ネットワンシステムズ株式会社 [Mipsology Zebra：FPGAを使用した高効率な推論プラットフォーム](https://www.netone.co.jp/knowledge-center/blog-column/20201221-1/)

---
PR 解説記事
[日本の産業界に向け、AI活用における“発見”を――AI Discovery Day 2020 開催レポート](https://news.mynavi.jp/techplus/kikaku/20201202-1548084/)

個人の記事　[AMD (Xilinx) が Mipsology(Zebra)をお買い上げ](https://vengineer.hatenablog.com/entry/2023/08/25/170000)

もっと情報がほしいなあ。
svelteのpopstateの発火と$pageの変更タイミングのずれ

# はじめに
svelteを使っていて、popstateの発火時に、`$page.url.href`と`window.location.href`で取得される値が異なっていて困ったので調べてみました。

# 環境
以下のようなコードを用意します。
```react:+page.svelte
<script lang="ts">
  import { page } from "$app/stores";

  let uid = 0;
  let state = {};

  function pushState() {
    uid += 1;
    history.pushState(uid, "", `/${uid}`);
  }

  function popState(event: PopStateEvent) {
    console.log($page.url.href, window.location.href);
    state = event.state;
  }
</script>

<svelte:window on:popstate={popState} />

<button on:click={pushState}>click me</button>

<pre>{JSON.stringify(state)}</pre>
```

このコードは以下URL内の改変です。
https://svelte.dev/repl/ecfaef5f5e5f02c2ebf160b4ce06ac0a?version=4.2.9

`click me`を押した後、この中の`console.log`の結果が異なります。

例えば、`click me`を2回押したとき、`{{url}}/2`になります。
その後、ブラウザの戻るボタンを押した時、`$page.url.href`の結果は`{{url}}/2`ですが、`window.location.href`の結果は`{{url}}/1`になります。


# 調べた結果
そもそも、popstateの発火時として、`document はまだ反映されていないかもしれないことを考慮に入れておくことが重要です`とあります。

> When writing functions that process popstate event it is important to take into account that properties like window.location will already reflect the state change (if it affected the current URL), but document might still not. If the goal is to catch the moment when the new document state is already fully in place, a zero-delay setTimeout() method call should be used to effectively put its inner callback function that does the processing at the end of the browser event loop: window.onpopstate = () => setTimeout(doSomeThing, 0);

https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event

> popstate イベントを処理する関数を書くときには、 window.location のようなプロパティはすでに状態の変化を反映していますが（それが現在の URL に影響する場合）、 document はまだ反映されていないかもしれないことを考慮に入れておくことが重要です。新しい文書の状態が完全に反映された瞬間を捉えることが目的であれば、遅延ゼロの setTimeout() メソッド呼び出しを使用して、処理を行う内部の callback 関数をブラウザーのイベントループの最後に効果的に配置する必要があります。例えば window.onpopstate = () => setTimeout(doSomeThing, 0); のようにします。

https://developer.mozilla.org/ja/docs/Web/API/Window/popstate_event

ただ、今回の例であれば`console.log`のタイミングで`document.URL`を見ても、`window.location.href`と同じ値が返ってくると思います。
また、その続きである`新しい文書の状態が完全に反映された瞬間を捉えることが目的であれば ～～～`の部分の通り、`console.log`の後に`setTimeout(() => console.log($page.url.href), 0);`を入れてみると、`window.location.href`と同じ値になります。

ちなみに、`$page.url`の変更タイミングは恐らくここになります。
https://github.com/sveltejs/kit/blob/99612ace885a6085b87e1ee1f38b0eea9ae2ba14/packages/kit/src/runtime/client/client.js#L2172-L2173
上の方を見ていくと、`addEventListener('popstate'`とあるため、popstateの発火タイミングのずれによって変更されてないため、値が取れないということが分かります(試しにlog埋め込んでみると分かります)

# まとめ
どうも似たような質問も飛んでました。
https://www.reddit.com/r/sveltejs/comments/14frcs4/browsers_popstate_event_handling/

解決方法としては`setTimeout`を使ってでも`$app/stores`の`page`を用いるか、ここはいっそ`window.location.href`の二択になると思います。
もし他に良案があれば教えてください。
STM32C011J4M7で遊ぶ3(完)(コンパイル編)(Lチカ成功)(Arduino)

まとめへ

https://qiita.com/caa45040/items/46c5b041ebd8d5e8ba88


目的
とりあえずコンパイルしてみる
Lチカ成功

STM32

STM32C シリーズ

STM32C0

STM32C011

STM32C011J4 8ピン(J4,J6)

STM32C011J4M7 パッケージ(温度の耐性)(M7)



![o_cop897.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/aad17bbd-6956-2cfd-885a-6177b9a9740d.jpeg)

![o_cop898.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/461e1f7e-31a3-44b2-a675-9fcc5c513b1b.jpeg)

![o_cop899.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f3f9dc3a-8408-4b5b-12f9-85ff659eb50c.jpeg)




```c++


/*
  Blink

  Turns an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(PA12, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(PA12, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(PA12, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}


```
ラズパイでfail2banが起動しない


```
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
```

Raspberry Pi OSにfail2banをインストールしてみたものの以下のようなエラーが出て起動に失敗する。

```
$ sudo systemctl start fail2ban
$ sudo systemctl status fail2ban
fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset>
     Active: failed (Result: exit-code) since Fri 2024-01-26 20:42:16 JST;>
   Duration: 524ms
       Docs: man:fail2ban(1)
    Process: 1287 ExecStart=/usr/bin/fail2ban-server -xf start (code=exite>
   Main PID: 1287 (code=exited, status=255/EXCEPTION)
        CPU: 410ms

 1月 26 20:42:15 cactus systemd[1]: Started fail2ban.service - Fail2Ban Se>
 1月 26 20:42:16 cactus fail2ban-server[1287]: 2024-01-26 20:42:16,134 fai>
 1月 26 20:42:16 cactus fail2ban-server[1287]: 2024-01-26 20:42:16,198 fai>
 1月 26 20:42:16 cactus fail2ban-server[1287]: 2024-01-26 20:42:16,199 fai>
 1月 26 20:42:16 cactus systemd[1]: fail2ban.service: Main process exited,>
 1月 26 20:42:16 cactus systemd[1]: fail2ban.service: Failed with result '>
 ```
'\>'以降省略...。

```
$ sudo fail2ban-server start
2024-01-26 20:46:05,106 fail2ban.configreader   [1308]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
2024-01-26 20:46:05,176 fail2ban                [1308]: ERROR   Failed during configuration: Have not found any log file for sshd jail
2024-01-26 20:46:05,184 fail2ban                [1308]: ERROR   Async configuration of server failed
```

調べた結果、OSに/var/log/auth.logなどを出力するrsyslogがインストールされていないためっだった。
rsyslogの代わりにsystemd journalを使うように設定すれば上手くいった。

```
$ sudo vi /etc/fail2ban/jail.conf
[DEFAULT]
backend = systemd

〜略
```

```
$ sudo systemctl start fail2ban
$ sudo systemctl status fail2ban

fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset>
     Active: active (running) since Fri 2024-01-26 20:47:30 JST; 3s ago
       Docs: man:fail2ban(1)
   Main PID: 1318 (fail2ban-server)
      Tasks: 7 (limit: 8740)
        CPU: 554ms
     CGroup: /system.slice/fail2ban.service
             └─1318 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

 1月 26 20:47:30 cactus systemd[1]: Started fail2ban.service - Fail2Ban Se>
 1月 26 20:47:30 cactus fail2ban-server[1318]: 2024-01-26 20:47:30,954 fai>
 1月 26 20:47:31 cactus fail2ban-server[1318]: Server ready
```


```
$ sudo fail2ban-server start
2024-01-26 20:50:13,722 fail2ban.configreader   [1350]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
Server ready
```

（systemctlでfail2banは起動しているのでfail2ban-server startはいらない。起動メッセージ確認のため）

...そして一夜明けて
```
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     67
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 20
   |- Total banned:     20
   `- Banned IP list:   〜略

```

動いています。
STM32C011J4M7で遊ぶ2(接続編)

次へ

https://qiita.com/caa45040/items/3ab1e5376ec25a763fde

目的
とりあえず繋いでみる

1 PB7
2 VDD
3 GND
4 PA2

8 SWCLK
7 SWDIO
6 PA12
5 PA11

![o_cop896.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f92046d5-0527-08a3-0eb9-1b0b1a8f4abe.jpeg)

![o_cop895.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fbc59c65-55ce-da8c-9987-d520f2b1f3b0.jpeg)
GitHubを使おうとしたらfatal: Authentication failed for~のエラーが出たのでその対処法

##  エラーが出た背景

GitHubを使おうとしたらfatal:Authentication failed for~というエラーが出たのでその対処方法を書きます。

## そもそもの原因

GitHubではアカウントの安全性を保つためにパスワード認証でのGit操作を廃止してトークン認証でのGit操作に変更しています。

https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/

↑GitHubブログのGit操作のトークン認証要件より

なのでトークン認証に切り替える必要があります。

## 解決方法

この記事を参考に解決しました
Personal access tokens (classic)の登録をすると解決できます。
その手順を紹介します。

https://dev.to/jasurkurbanov/fatal-github-error-authentication-failed-for-command-line-4dmn

## Personal access tokens (classic)を作る


### まずSettingsに移動する

GitHubにログインしてもらって右上にある自分のアイコンを押します。
メニューの下の方にあるSettingsというボタンを押します。


### Personal access tokens (classic)に移動する

Settingsを押すと左側に Personal access tokensのボタンがあると思うので、
そこからTokens (classic)を押します。


### 実際にPersonal access tokens (classic)を作っていく

Tokens (classic)のボタンを押すと、Generate new token のボタンがあると思うので、その中のGenerate new token (classic)を押します。
その後認証が必要になるので認証を完了してください。
その後Note,Expiration,Select scopesを記入し、
Generate tokenを押してください。


### トークンを保存する

Generate tokenを押すと実際にトークンが発行されます。
トークンがコピーできると思うので、コピーしてどこかに保存しておきましょう。

これで認証用のトークンを作ることができました。


### 実際に使ってみる

```terminal
terminal

git push 
```
などをしてみると

GitHubのUsernameとさっき作ったトークンをPasswordのところに入力するとpushができます。

これでGitHubが使えるようになります。
Progate +α メモず【Sass】

# はじめに
Sass - CSSの拡張言語です！！CSSが楽しかったので今回も楽しみ。
拡張子は`.scss`
メモ群なので、気になった見出しをご覧ください！
# メモず
## `Sass`と`SCSS`の２種類がある！
いきなりびっくりw
### 違い
|  | 親子関係 | ファイル拡張子 | 互換性 |
| ---- | ---- | ---- | ---- |
| `Sass` | インデントで表す | `.sass` | 通常のCSSファイルは直接扱えない |
| `SCSS` | 波かっこやセミコロン<br>（通常のCSSと同じ） | `.scss` | 通常のCSSもSCSSとして機能する |
`Sass`の「インデントで親子関係を表す」のは魅力的だけど、
互換性を考えると`SCSS`も良い。
ぶっちゃけ大きな差はないので、方言・趣味みたいなもん。
学習にも差はない。片方学べば両方使えるっぽい。
#### Progateでは`SCSS`を扱う
## 親子関係を表せる：入れ子構造
これこれ！欲しかったやつ！！
```css
.header {
	color: red;
}
.header ul {
	padding: 10px;
}
```
と書かなきゃいけなかったのが、
```scss
.header {
	color: red;
	ul {
		padding: 10px;
	}
}
```
と書ける。いやあ素晴らしい。
・・・こう書けるのが普通だよな？と思わなくもないが
## `&`：`State`や`Class`の書き方
```scss
.button {
	opacity: 0.8;
	&:hover {
		opacity: 1;
	}
}
```
`&:hover`で`.button:hover`と同じ意味になる。いいね。
```scss
.container {
    .header {
        background: lightblue;
        &.important {
            background: red;
        }
        & .title {
            font-size: 20px;
            &.highlight {
                color: yellow;
            }
        }
    }
}
```
こんな感じで、クラスからさらにクラス、などのケースでも使える。
## `$`：変数も使える！！偉すぎ！！
`$var_name: value;`で変数を定義。
例えば、
```scss
$base-color: #eae6d9;
$accent-color: #c6d587;
$sub-color: #588d67;
header {
	background-color: $sub-color;
	color: $base-color;
}
.main-wrapper {
	background-color: $base-color;
	color: $sub-color;
	.border {
		background-color: $accent-color;
	}
}
```
みたいなことができる。カラーコードを覚えなくていい。
必要に応じて更新もできるし、全体の色使い調整も1カ所変えるだけでいい。
## `@mixin($arg1, $arg2...)` / `@include`：スタイルのデータセット
引数なしでも使える ↓
```scss
@mixin lesson-card {
	width: 300px;
	padding: 40px;
}
.lesson-1 {
	@include lesson-card;
}
.lesson-2 {
	@include lesson-card;
}
```
引数にデフォルト値を与えることも可能
```scss
@mixin button-style($color: blue, $fontsize: 16px) {
    background-color: $color;
    font-size: $fontsize;
    border: none;
    border-radius: 3px;
    padding: 5px 10px;
    color: white;
}

.button-default {
    @include button-style(); // 両方の引数をデフォルト値で使用
}

.button-red {
    @include button-style(red); // 色を赤に変更し、フォントサイズはデフォルト値を使用
}

.button-large {
    @include button-style(red, 20px); // 色とフォントサイズの両方を指定
}
```
## 関数の定義`@function name($arg) {@return}
```scss
// 画面サイズに基づいてパディングを計算する関数
@function calculate-padding($screen-size) {
    @if $screen-size > 1200px {
        @return 20px;
    } @else if $screen-size > 800px {
        @return 15px;
    } @else {
        @return 10px;
    }
}

.container {
    padding: calculate-padding(800px); // 画面サイズが 800px の場合のパディング
}
```
`if` / `else`も使える！！ 最高。
ちなみに、`rgba`や`darken`などの機能も関数と呼ぶらしい。
# 終わりに
内容としてはめっちゃシンプル。だけど、使い勝手はめちゃくちゃ変わる。
めっちゃコスパ良い学習でした。期待していた通り。楽しかった～！

SCSSを知らない人、CSSが楽しかった人、めちゃくちゃおすすめです。
最新の接尾辞配列構築program

接尾辞配列を高速に構築すると言えばdivsufsort! 線形時間で構築すると言えばInduced Sorting! などといった内容に違いない! かつてそう言われていた時代があったかどうかは定かではないかもしれません。
そんな歴史的背景はどうでもいいかもしれないとして、最新鋭の構築技法を紹介します。
## libsais
名前から分かる通りInduced Sortingの改良版です。Yuta Mori氏が手掛けた[sais](http://wpage.cocolog-nifty.com/wp/2010/08/sais-241.html)に改良を施しまくった傑作です。[github](https://github.com/IlyaGrebnov/libsais)にその全貌が公開されています。作者はあのGRZipIIを生み出したIlya Grebnov氏です。
## libcubwt
GPUを動員して高速化を図っています。最悪計算時間はO(n log n)とのことですがlibsaisより概ね数倍高速です。詳細は[github](https://github.com/IlyaGrebnov/libcubwt)をご覧下さい。v1.0.0はともかくv1.5.0以降は完全にBurrows-Wheeler transform構築に特化している御様子。他の言語への移植が難しそうな気がします…。
## 応用
libsaisを利用したfile圧縮program。可読性皆無のごみである事を御了承下さい。ごみになり損ねた奴は[ココ](https://github.com/da0ka/bsc-m03js)。ちなみに本家[bsc-m03](https://github.com/IlyaGrebnov/bsc-m03)v0.2.1の移植作だったりします。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qByggzG" data-user="xezz" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/xezz/pen/qByggzG">
  bsc-m03 v0.2.1</a> by xezz (<a href="https://codepen.io/xezz">@xezz</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## Ilya Grebnovのその他代表作
BWT系圧縮で有名な **bzip2** や **DGCA**(日本産) を凌ぐ高性能圧縮噐の開発者として、どこぞの界隈ではあまりにも有名。
* [GRZip](https://www.sac.sk/download/pack/grzip.zip)(骨董品)
* [GRZipII](https://web.archive.org/web/20050217191526/http://magicssoft.ru/?folder=projects&page=GRZipII)(名器)
* [bsc](https://github.com/IlyaGrebnov/libbsc)(超高速)
* [bsc-m03](https://github.com/IlyaGrebnov/bsc-m03)(高圧縮)
* [esa-matchfinder](https://github.com/IlyaGrebnov/esa-matchfinder)(超高速にLZ系列求める)
【Rails】carrierwaveでファイルをアップロードする時に、元々のファイル名(オリジナル名)をカラムに保存されるようにする

## はじめに
carrierwaveで投稿に添付ファイルをアップロードする機能を作成しました。
その機能では、ローカル環境に保存するためセキュリティの問題でファイルを保存するときにランダムなファイル名に変更されるようにしております。
しかし、画面にファイル名を表示する時は元々のオリジナルのファイル名を表示する必要がでてきたので、今回はこの問題を対応した。
carrierwaveでのファイルの投稿機能自体については省略します。

## 環境
`ruby 3.1.2p20`
`Rails 7.0.4`

## 変更前のテーブル
|Posts|
|:--|
|title|
|text|
|attachment_file|

## 実際に対応したこと
Postsテーブルにoriginal_file_nameカラムを追加して、attachment_fileを保存する前ににファイルのオリジナルのファイル名をoriginal_file_nameに保存する処理を追加しました。

## original_file_nameカラムを追加します
~~~ruby:db/migrate/20240101XXXXXX_add_column_posts.rb
class AddOriginalFileNameToPosts < ActiveRecord::Migration[7.0]
  def up
    add_column :posts, :original_file_name, :string
  end
  def down
    remove_column :posts, :original_file_name
  end
end
~~~
`$ railis db:migrate`

## 変更後のテーブル構造
|Posts|
|:--|
|title|
|text|
|attachment_file|
|original_file_name|

## オリジナルのファイル名を保存するメソッドをuploader.rbに作成します。
~~~ruby:app/uploaders/post_detail_file_uploader.rb
# 元々のファイル名をsetする
def set_original_file_name
model.original_file_name = file.original_filename if file.present?
end
~~~
`file.original_filename`でファイル名を取得できます。
それで取得したファイル名を
`model.original_file_name`に代入するだけの凄くシンプルなコード

## 作成したメソッドをbefore_saveを使用してpost.rbでモデルが保存される前に実行するように設定します。
~~~ruby:app/models/post.rb
before_save :set_original_file_name

def set_original_file_name
  detail_file.set_original_file_name if detail_file.present?
end
~~~

##
これで元々のファイル名をカラムに保存できるので、元々のファイル名で扱いたい時はこのカラムを呼び出すことで対応できるようになりました。
EKSのPlatformVersion更新でcorednsのpodが起動しなくなった話

### corednsがずっとPending
EKS作成後、なぜかcorednsがずっとpending
```
$ kubectl get pod -n kube-system
NAME                      READY   STATUS    RESTARTS   AGE
coredns-5cb878ffc-ppxd6   0/1     Pending   0          171m
coredns-5cb878ffc-tb578   0/1     Pending   0          171m
```

今までは以下の2番の手順でアノテーションを削除することで起動できていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/896507/4371d40f-3548-5269-302a-5f91b59c3be4.png)

https://docs.aws.amazon.com/eks/latest/userguide/fargate-getting-started.html#fargate-gs-coredns


しかしある日そのアノテーションは使用されなくなり、以下のコマンドが失敗する。
```
$ kubectl patch deployment coredns \
>     -n kube-system \
>     --type json \
>     -p='[{"op": "remove", "path": "/spec/template/metadata/annotations/eks.amazonaws.com~1compute-type"}]'
The request is invalid
```
というかこのアノテーションって何のために記載されていたのだろうか。


### 原因と対処
結果的には、podを再起動することで解決。

原因はFargate profileが適用される前にcorednsのpodが起動したためだと思われる。
しかしEKS作成時点でcorednsのpodはFargate profile適用前に自動で起動するので、Fargate Profile適用後にかならずpodを再起動しなくてはならないのでは。

そして、今までの手順に記載されていたアノテーションの削除は、
アノテーションの削除が必要なのではなく、podを再起動させるための手段だったのかなと推測。


### PlatformVersionの更新には注意を！
こういう小さな変更は告知なしで実施される傾向があると思います。
どうやら、EKSのPlatformVersionが更新されるタイミングで細かい仕様が変更が行われているようです。

今回は、公開されているドキュメントの更新より先にEKSのPlatformVersionが更新されていました。
EKS Clusterのバージョンは当然意識すると思いますが、PlatformVersionの更新には注意が必要ですね。
「技術的には可能です。やり方は色々あります。」から言葉が続かない「なんちゃって」エンジニアの処方箋

# 「技術的には可能です。やり方は色々あります。」
Webアプリの開発をしていると「技術的に可能です。やり方は色々あります。」
ということを耳にすることがありますが、その発言マジで価値がないです。
*自戒の念を込めて

たとえば、その振る舞いは「家は貸せます。物件も色々あります。」
と「語るだけ」の不動産屋には何の価値もないのと同じではないでしょうか？

選択肢を持っているのは、
不動産屋としても技術屋としも価値ではなく
「前提条件」です。

選択肢を多く提示できることは当たり前。
選択肢のメリット・デメリットを提示し、
顧客が自分(自社)に適した選択肢を選べるように
手助けをすることがプロの条件ではないでしょうか？

あえて、表題に繋げるならば「やり方は色々あります。」で止まるのではなく、
その発言の先に「それぞれのメリット、デメリットをまとめるとこうです。」が
続けることがプロとして重要だと私は考えています。

# 選定で技術のプロに求められていること
そこで、私は技術のプロとして、求められていることは、
「お客に最も適した選択を導き出すこと」だと理解しています。
*数多ある選択肢を示すだけして、知識マウントを取りたいなら話は別です(笑)

そこで、技術のプロとして、期待値に応え、
目の前に広がる膨大な選択肢を絞り込むために
取り組むべきことは、下記の4つだと思っています。

・各選択肢の違い、メリット、デメリットを説明できるようにすること
・客の顕在化していない重要な選定条件を抜け漏れ少なく聞き出すこと
・客にそれぞれの選択肢の違いを追体験させられる準備をすること
・選択の前後での期待値のギャップを埋めるため最大限の努力をすること

です。繰り返しになりますが、
技術屋が技術的な選択肢を豊富に持っているのは当たり前です。
これらの活動を通し、客の最大限の成果に技術屋はコミットすべきです。

# 普段、どのように技術を習得しておくべきか
そこで、新しい技術を身につけるときに、技術屋としては、
下記の5つを意識しておくべきだと私は思います。

・その技術で解決できる課題はなにか？
・その技術と類似した技術がないか？
・他の類似した技術との違いはなにか？
・それぞれの技術がハマるケースとハマらないケースは何か？
・実際に使ってみた際の所感は？

これらを言語化しておくことで、
「技術的には可能です。やり方は色々あります。」の
その先の言葉が紡げるようになるのではないでしょうか？

備忘録として、ここにまとめさせていただきます。

また、皆さんが技術を習得する際に意識されていることがあれば、
コメントお待ちしております！
Amazon SES の bluk 送信にて "List-Unsubscribe" ヘッダを追加する

本記事は、Amazon SESにて、`SendBulkEmail`, `SendBulkTemplatedEmail`, `SendTemplatedEmail` or `SendEmail` (`send_bulk_email`, `send_bulk_templated_email`, `send_templated_email` or `send_email`)を使用してメールを大量送信している方、が対象となります。

---

現在、GoogleやYahooによる”メール送信者のガイドライン”の中で、大量メール送信者は、下記の対応が必要となっています。

- [Google - 1 日あたり 5,000 件以上のメールを送信する場合の要件](https://support.google.com/a/answer/81126?visit_id=638416590663890276-2292961685&rd=1&hl=ja&sjid=11361266357807161227-AP#requirements-5k&zippy=%2C%E6%97%A5%E3%81%82%E3%81%9F%E3%82%8A-%E4%BB%B6%E4%BB%A5%E4%B8%8A%E3%81%AE%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E8%A6%81%E4%BB%B6)

その中の、”簡単に登録解除できるようにする”という項目 -

- [Google - 簡単に登録解除できるようにする](https://support.google.com/a/answer/81126?visit_id=638416590663890276-2292961685&rd=1&hl=ja&sjid=11361266357807161227-AP#subscriptions&zippy=%2C%E6%97%A5%E3%81%82%E3%81%9F%E3%82%8A-%E4%BB%B6%E4%BB%A5%E4%B8%8A%E3%81%AE%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E8%A6%81%E4%BB%B6)

の中で、

- 送信メールのヘッダに、`List-Unsubscribe-Post`及び`List-Unsubscribe`を追加する。

という要件があります。
~~Amazon SESにて、`SendBulkEmail`、`SendBulkTemplatedEmail`、`SendTemplatedEmail`、`SendEmail`を使用してメールを送信している場合、現状、それを実装することができません。~~
最新のライブラリにて、API v2(`sesv2`)の`SendBulkEmail`、`SendEmail`でカスタムヘッダーを追加できるようになり、その実装ができるようになしました。

以上。
iptablesの優先順位について

## はじめに
iptablesのREJECTとACCEPTの挙動についての備忘録。
以下の場合についてを調査。
1. 同じIPアドレスに対してACCEPTとREJECTがある場合どうなるのか
1. ロンゲストマッチ（最長一致検索）が有効なのか

## 結論

1. 同じIPアドレスに対してACCEPTとREJECTがある場合は上部にあるものが適用される(ACCEPTされたあとにREJECTされることはない)
1. ロンゲストマッチ（最長一致検索）はなく、上部で一致したものが適用される

## 検証内容
サーバーを二台用意し、iptablesを操作するサーバーでnginxを起動し、もう片方からcurlを試みる。

#### 1. 同じIPアドレスで上部にACCEPT, 下部にREJECTがある場合
- 接続できる
```
# iptables -A INPUT -p tcp --dport 80 -s 10.10.10.11 -j ACCEPT
# iptables -A INPUT -p tcp --dport 80 -s 10.10.10.11 -j REJECT
# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  10.10.10.11           anywhere             tcp dpt:http
REJECT     tcp  --  10.10.10.11           anywhere             tcp dpt:http reject-with icmp-port-unreachable

# curl -i -s http://10.10.10.10:80 | head -n2
HTTP/1.1 200 OK
Server: nginx/1.24.0
```

#### 2. 同じIPアドレスで上部にREJECT, 下部にACCEPTがある場合
-  接続できない
```
# iptables -A INPUT -p tcp --dport 80 -s 10.10.10.11 -j REJECT
# iptables -A INPUT -p tcp --dport 80 -s 10.10.10.11 -j ACCEPT
# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
REJECT     tcp  --  10.10.10.11           anywhere             tcp dpt:http reject-with icmp-port-unreachable
ACCEPT     tcp  --  10.10.10.11           anywhere             tcp dpt:http

# curl http://10.10.10.10:80
curl: (7) couldn't connect to host
```

#### 3. ロンゲストマッチ（最長一致検索）が有効なのか
- ロンゲストマッチ（最長一致検索）のようなものはなく、上部のものが優先される
```
# iptables -A INPUT -p tcp --dport 80 -s 10.0.0.0/8 -j ACCEPT
# iptables -A INPUT -p tcp --dport 80 -s 10.10.10.11 -j REJECT
# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  10.0.0.0/8           anywhere             tcp dpt:http
REJECT     tcp  --  10.10.10.11           anywhere             tcp dpt:http reject-with icmp-port-unreachable
# curl -i -s http://10.10.10.10 | head -n2
HTTP/1.1 200 OK
Server: nginx/1.24.0
```
```
# iptables -A INPUT -p tcp --dport 80 -s 10.0.0.0/8 -j REJECT
# iptables -A INPUT -p tcp --dport 80 -s 10.10.10.11 -j ACCEPT
# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
REJECT     tcp  --  10.0.0.0/8           anywhere             tcp dpt:http reject-with icmp-port-unreachable
ACCEPT     tcp  --  10.10.10.11           anywhere             tcp dpt:http

# curl -i http://10.10.10.10
curl: (7) couldn't connect to host
```
VyOS で DNS フォワーダーを構成する

# はじめに

VyOS は、Linux ベースのソフトウェアルーターで、単なるルーティング以外にも、豊富な機能を持っているので、自身やチームのラボを構築する際に、非常に便利です。
個人的には、vSphere のラボを構築する際にも、必須級のソフトウェアになっています。

↓こちらの記事で、簡単な紹介もしています。

https://qiita.com/iwaseyusuke/items/0ac51439f476a36fb3ff

今回は、小技レベルですが、VyOS に DNS フォワーダーを設定することで、クライアント端末から見た場合に、「VyOS がデフォルトゲートウェイかつ、DNS サーバーになってくれるので設定が楽！」を実現しようと思います。


## (補足) 構成イメージと使い所の例

今回、構成する環境のイメージは、↓このような状況です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245234/04c3a202-d3e9-bed3-7572-30f30070665a.png)

必ずしも VyOS がデフォルトゲートウェイである必要はありませんが、図中の Jump Box (踏み台サーバー) や、ESXi、VM 等からの DNS クエリを VyOS が中継できるようにしておくことで、各機器への設定を簡単にしたいような場合に便利です。

また、冒頭で引用の記事の再掲になりますが、VyOS の DHCP 機能と組合せて、デフォルトゲートウェイとしても VyOS 自身、DNS サーバーとしても VyOS 自身の IP アドレスを配布することで、VyOS 配下のネットワーク (図中では Lab という枠で囲まれた範囲) に閉じて、ネットワーク設計が出来たりします。

https://qiita.com/iwaseyusuke/items/0ac51439f476a36fb3ff


# 手順

参考にしている VyOS 公式ドキュメントは、こちらです。

https://docs.vyos.io/en/latest/configuration/service/dns.html

また、転送先の DNS サーバーを VyOS 自身が利用している DNS サーバーと同じものにする場合、下記の設定も関連してきます。

https://docs.vyos.io/en/latest/configuration/system/name-server.html


## TL;DR;

VyOS の操作がわかる方には、実際の設定例を見ていただく方が早いかと思います。

```text: フォーマット
service {

    dns {
        forwarding {
            allow-from <network>
            listen-address <address>
            system
        }
    }

}
system {

    domain-search {
        domain <domain>
    }

    name-server <address>

}
```

```text: 設定例
service {

    dns {
        forwarding {
            allow-from 192.168.0.0/24
            listen-address 192.168.0.254
            system
        }
    }

}
system {

    domain-search {
        domain example.com
    }

    name-server 10.0.0.1

}
```


## 設定解説

```text
set service dns forwarding system
```

DNS クエリを転送する先の上位 DNS として、VyOS 自身が利用している DNS サーバー (System DNS) を利用するように指定します。

```text
# フォーマット
set service dns forwarding name-server <address> port <port>

# 設定例
set service dns forwarding name-server 10.0.0.1 port 53
```

もし、VyOS 自身が利用している DNS サーバーではなく、別の DNS サーバーを利用する場合に利用します。

```text
# フォーマット
set service dns forwarding allow-from <network>

# 設定例
set service dns forwarding allow-from 192.168.0.0/24
```

どのネットワークに所属するクライアントからの DNS クエリを許可し、DNS サーバーに転送するのかを指定します。

:::note warn
**注意**
IPv4 ネットワークの場合、`0.0.0.0/0` を指定することで、全てのネットワークに対して、許可することも可能ですが、DDoS 攻撃などで悪用される可能性もありますので、考慮が必要な環境では、注意して設定してください。
:::

```text
# フォーマット
set service dns forwarding listen-address <address>

# 設定例
set service dns forwarding listen-address 192.168.0.254
```

DNS フォワーダーとして、どの IP アドレスで待ち受けるのかを指定します。
IPv4 ネットワークの場合、`0.0.0.0` を指定することで、VyOS に割当たっている全ての IP アドレスで待ち受けるので便利です。

以降は、`service dns forwarding system` を設定している場合において、VyOS 自身が利用する DNS サーバーの設定方法になります。

```text
# フォーマット
set system name-server <address>

# 設定例
set system name-server 10.0.0.1
```

1行で 1つの DNS サーバーしか指定できませんが、複数行設定することが可能ですので、複数台の DNS サーバーを設定することが可能です。

```text
# フォーマット
set system domain-search <domain>

# 設定例
set system domain-search example.com
```

ドメインサーチリスト、DNS 検索サフィックスなどとも呼ばれるフィールドの設定です。
こちらも 1行で 1つしか指定できませんが、複数行 (VyOS 1.5.x 時点では、最大 6つ) 設定することが可能です。
bcryptを導入でcannot load such file -- bcrypt

# 初めに
パスワードのハッシュ化でgemをインストールしたときに上手くいかなかったので書きます。

# 問題
今回はbcryptというgemを導入してパスワードの安全化を目指しましたが、以下エラーが起きました。

![スクリーンショット 2024-01-26 7.55.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536873/df31207a-e07e-e06e-1d96-fc8bd5884e27.png)

① Gemfileに以下インストールするgemを記述
② bundleインストール
③ Userモデルにhas_secure_passwordを記述

この辺りの手順を見直しましたが、解決できません。

```
gem 'bcrypt'
```

```ruby
class User < ApplicationRecord
  has_secure_password
  validates :name,  { presence: true }
  validates :email, { presence: true } 
end
```

# 解決方法

Dockerコンテナを停止して、再起動したら解決できました。環境構築の仕方によりますが、Dockerで構築していなければ、```rails s``` で再起動すれば上手くいきそうです。

```
docker compose up
```

# 終わりに
PCに問題が起きたときに再起動するのと同様に、プログラミングにおいてもエラーが起きたときにサーバーを停止することでエラーを解決できることを知りました。
定期的なファイル削除

```
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace WPF.Utils
{
    public class FileUtil
    {
        private static readonly string DirectoryPath = @"C:\YourDirectoryPath";
        private static readonly TimeSpan DeleteInterval = TimeSpan.FromHours(12);

        static async Task Main()
        {
            var cts = new CancellationTokenSource();
            Console.CancelKeyPress += (sender, args) => { args.Cancel = true; cts.Cancel(); };

            while (!cts.Token.IsCancellationRequested)
            {
                await DeleteOldFilesAsync();
                await Task.Delay(DeleteInterval, cts.Token);
            }
        }

        private static async Task DeleteOldFilesAsync()
        {
            try
            {
                var directoryInfo = new DirectoryInfo(DirectoryPath);
                var currentTime = DateTime.Now;

                foreach (var file in directoryInfo.GetFiles())
                {
                    if (currentTime - file.LastWriteTime > DeleteInterval)
                    {
                        file.Delete();
                        Console.WriteLine($"ファイル {file.Name} が削除されました。");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"エラー: {ex.Message}");
            }
        }
    }
}
```
App ServiceにPythonアプリをローカルGitを用いてデプロイ

# 初めに
App Serviceにアプリを登録して機能を検証することが多いため、今回はMSが提供しているPythonのサンプルWebアプリをローカルgitを用いてデプロイします。

# 必要なソフトウェア
- git
- Azure CLI

# 手順
1. Azure PortalからApp Serviceの画面へ移動し、[作成]->[Webアプリ]を選択します <br><br>
2. 以下のように情報を入力し、[確認および作成]をクリックすることでApp Serviceのインスタンスをプロビジョンします
   - サブスクリプション: 任意
   - リソースグループ: 任意
   - インスタンス名: 任意
   - 公開: コード
   - ランタイムスタック: Python 3.12
   - 地域: Japan East
   - 価格プラン: 任意(VNet統合が必要な人はBasic)
   - ゾーン冗長: 無効
   - 他項目: 既定値 <br><br>
3. App Serviceの設定画面から[デプロイセンター]へ移動します <br><br>
4. ページ上部の[設定]から[ソース]を[ローカルGit]に選択し、画面上部の[保存]ボタンを押します <br><br>
5. 後で使用するため、ページ上部の[FTPS資格情報]から[ローカルGitユーザー名]と[パスワード]を控えておきます<br><br>
6. 次に、MSがFlaskを用いた[サンプル](https://github.com/Azure-Samples/msdocs-python-flask-webapp-quickstart)を用意しているので```git clone```でローカルPCにダウンロードします
   ```
   git clone https://github.com/Azure-Samples/msdocs-python-flask-webapp-quickstart
   ```
   <br>
7. Azureのデプロイ先のリモートリポジトリをローカルPCに追加をするために以下のコマンドを入力します
   ```
   git remote add azure  https://<app-name>.scm.azurewebsites.net/<app-name>.git  // <app-name>はApp Serviceに付けた名前
   ```
   <br>
8. 以下のコマンドを入力すると、ユーザー名とパスワードを聞かれるため、先ほど控えていた [ローカルGitユーザー名]と[パスワード]を入力することで、アプリがデプロイされます。
   ```
   git push origin main:master // ローカルのブランチはmainだが、デプロイ先はマスターのため指定が必要 
   ```
   <br>
9. 今回のアプリがポート5000番で受け付けており標準ではそのポートにアクセスできないため、App Serviceの設定画面から[構成]を選択し、[新しいアプリケーション設定]から以下のように変数を追加します
   - 名前: WEBSITES_PORT
   - 値: 5000<br><br>
10. App Serviceの既定のドメインにアクセスすることでWebアプリにアクセス出来ます

# 参考資料
- [クイックスタート: Python (Django または Flask) Web アプリを Azure App Service にデプロイする](https://learn.microsoft.com/ja-jp/azure/app-service/quickstart-python?tabs=flask%2Cwindows%2Cazure-cli%2Cvscode-deploy%2Cdeploy-instructions-azportal%2Cterminal-bash%2Cdeploy-instructions-zip-azcli)
- [Azure App Service へのローカル Git デプロイ](https://learn.microsoft.com/ja-jp/azure/app-service/deploy-local-git?tabs=cli)
- [ローカルGitの裏側](https://github.com/projectkudu/kudu/wiki)
モグライダー「さそり座の女」

# はじめに
M-1で実装できそうなネタを教えてもらったので書きました。

https://note.com/exo513/n/n793a3d56bde1

3人とも可愛い
https://x.com/mgrd33/status/1481212541582049286?s=20

## ともしげの初期コード
```python
import random

zodiac_list = ["牡羊座", "牡牛座", "双子座", "蟹座", "獅子座", "乙女座", "天秤座", "蠍座", "射手座", "山羊座", "水瓶座", "魚座"]
gender_list = ["女", "男", "その他", "回答しない"]

def mikawa():
    while True:
        zodiac = random.choice(zodiac_list)
        gender = random.choice(gender_list)

        if zodiac == "蠍座" and gender == "女":
            print(f"モグライダー「{zodiac}の{gender}ですか？」美川さん「そうよ、私は{zodiac}の{gender}~♡」")
            break  # 条件を満たしたらループを終了
        else:
            print(f"モグライダー「{zodiac}の{gender}ですか？」美川さん「いいえ」")

# 関数を実行
mikawa()
```
出力例
```python
モグライダー「山羊座の男ですか？」美川さん「いいえ」
モグライダー「獅子座のその他ですか？」美川さん「いいえ」
モグライダー「水瓶座のその他ですか？」美川さん「いいえ」
...
モグライダー「蠍座の女ですか？」美川さん「そうよ、私は蠍座の女~♡」
```
最悪47(12×4-1)通り「いいえ」と答えさせられる美川さんが大変気の毒である。
あと、ともしげは一回聞いて違った組み合わせを忘れていそうなので、「いいえ」が47回ではすまない可能性が高い。美川さんがかなり気の毒である。


## 芝さんのコードレビュー後
```python
def mikawa(z, g):
    for zodiac in zodiac_list:
        if zodiac == "さそり座":
            print(f"モグライダー「{zodiac}ですか？」美川さん「ｺｸﾘ」")
            for gender in gender_list:
                if gender == "女":
                    print(f"モグライダー「{zodiac}の{gender}ですか？」美川さん「そうよ、私はさそり座の女~♡」")
                    break
                else:
                   print(f"モグライダー「{zodiac}の{gender}ですか？」美川さん「惜しい、私はさそり座の女~♡」")
        else:
            print(f"モグライダー「{zodiac}ですか？」美川さん「いいえ」")


print(mikawa(zodiac, gender))

```
出力
```
モグライダー「牡羊座ですか？」美川さん「いいえ」
モグライダー「牡牛座ですか？」美川さん「いいえ」
モグライダー「双子座ですか？」美川さん「いいえ」
モグライダー「かに座ですか？」美川さん「いいえ」
モグライダー「獅子座ですか？」美川さん「いいえ」
モグライダー「乙女座ですか？」美川さん「いいえ」
モグライダー「さそり座ですか？」美川さん「ｺｸﾘ」
モグライダー「さそり座の女ですか？」美川さん「そうよ、私はさそり座の女~♡」
```
芝さんのコードレビューにより、美川さんが「いいえ」と回答する回数を、最大47回から7回までに減らすことができました。

# 感想
確かに、美川さんは太陽星座×月星座×ASCまで当てて欲しいかもしれないし、性別が2種類だけしかない時代でもないので、最適性を損なわずに計算量を落とすことは大事だなと学びました。
langchainでAzure OpenAIのAPIを叩くときの仕様が若干変わってたのでメモ

## 背景
langchainを久々に触ったら今後若干仕様が変わるとのwarningが出たのでメモ。

## 使い方
環境変数は以下のように設定(API versionはこれを使ってね！っていうお触れ書きがOpenAI側からあったような気もするが、忘れたので後で追記する)


```
OPENAI_API_TYPE="azure"
OPENAI_API_VERSION="2023-09-01-preview"
OPENAI_API_KEY="*********************"
AZURE_OPENAI_ENDPOINT="https://xxx.openai.azure.com/
```

新たに`langchain-openai`をインストール。
`langchain.chat_models`から叩いていたが、langchain v0.2.0から変更になるらしい。

```bash
pip install langchain-openai
```
コード上では以下のように使う。

```python
from langchain-openai import AzureChatOpenAI

llm = AzureChatOpenAI(azure_deployment="deployment_name")
```
keyを使わずにMenuItemに共通スタイルを設定する

MenuItemに共通のスタイルを設定したい。
keyを使えば簡単に設定できるけど、keyを使わずに設定したい。

## 成功例

```C#:xaml
<Style TargetType="Menu">
    <Style.Resources>
        <Style TargetType="MenuItem">
            <Setter Property="FontSize" Value="16"/>
        </Style>
    </Style.Resources>
</Style>
```

## 失敗例

```C#:xaml
<Style TargetType="MenuItem">
    <Setter Property="FontSize" Value="16"/>
/Style>
```
bashのシグナル(割込)処理

# bashでシグナル処理を行う。
bashのシグナル受信処理は trap というビルトインコマンドで定義する。

# sigint(Ctrl-C)を受け取ってみる
bashスクリプト動作中にCtrl-Cを押すと停止するので、シグナルを受信して止まらないようにしてみる。

```bash:tsig.sh
#!/bin/bash

trap getsig 2

function getsig() {
echo '僕は死にましぇん！'
}

while [ 1 ]
do
echo 'sleep 1'
sleep 1
done
```

# 終わるときは
別端末からPSでプロセスIDを調べて
kill [process id]
で終了させる

# Signal番号は色んな意味がある
今回の例はsigintの2を指定していますが、
シグナル番号には色んな意味があるので、manで調べて適切なシグナル処理をしましょう！！
初学者のReactアプリ開発奮闘記

# はじめに
エンジニア一年目のA.Kと申します。よろしくお願いします。
**Reactの学習を始めてちょうど10日**になります。
Udemyの講座でReactの基礎を学習し終えたため、**初めてのアウトプット**を行いました。
技術的な内容ではなく、個人の感想ベースで書いていきます。

# 今回行ったアウトプット
Reactで**学習記録アプリ**を作成しました！

### 実装機能
* 学習内容・学習時間の追加
* 学習内容・学習時間の一覧表示
* 学習時間の累計表示
* 各項目が未入力の場合はエラーメッセージを表示

### 今回の成果物は…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3675500/32fc3b57-4d82-dcd2-e5f5-822c2f59edc8.png)


初めての成果物・・・！なんだか恥ずかしいですね（笑）
**今回は最低限の機能実装のみで、コンポーネント化やスタイリングにはまだ取り組んでいません。**
先輩エンジニアやChatGPTのサポートを得ながら、2日で作成しました。
簡素な仕様ですがかなり苦労したし、完成すると達成感がすごい。

# はじめてのアウトプット三カ条（私見）

### 一人でやりきらなくてもいいんですよ！
もちろん自走できるに越したことはないですし、その状態を目指したいと考えています。
ただ、駆け出しレベルであれば **使えるサポートは使う** のが良いと思いました。
（正直ChatGPTがいなかったら未完成だったかも。。）
ただし、完全に頼りきりになるのではなく、自分の思考を定期的にはさみましょう。
**まずは一つのアプリを作り切って、成功体験を積んでいく** と自信に繋がります。
(実際完成するとすごく達成感湧きます！やってよかった！)

### アウトプットで自分の現在地を知る
コードを書いていると **「なんだかこの処理苦手だな。。」「このエラー何度も遭遇するな。。」** みたいな場面があると思います。逆も然りで、自分が好きで得意と感じる作業もあるでしょう。
このように **現時点での自分の習熟度を知ることで、今後の学習計画が立てやすくなります。**
**正解をなぞるだけのハンズオンだと、達成感はあるもののこのような感覚は生まれづらい**でしょう。

### コードレビューって大事！
少し勇気がいることですが、知り合いや先輩方にコードを共有して**アドバイスをもらうことで、モチベーションが向上します。**
特に**処理内容に関しての質疑や修正**を通して、**自分で書いたコードに対する解像度や説明能力がかなり鍛えられます！**
あとは、**改善点だけでなく良い点も聞いちゃいましょう。**
（自分の書いたコード褒められるってめっちゃくちゃ嬉しいんですよ。。。）
# おわりに
今回はReact学習初心者として初めてアプリを作成した感想を述べました。
ちなみに **着手当初はわからないことが多すぎて絶望**でした（笑）
ちなみに前回の記事にその様子をまとめています。。（トレンド入りありがとうございます！）

https://qiita.com/AK_React/items/0a9b4b2c4430a39a9ce9

でも、**実際に完成したものが手元に残るとすごく嬉しいし、誇らしく思えました。**
今の時代、調べれば何でも出てくるので大丈夫です。**何とかなります。**
今後もReactを学びながら、こういった簡単なアプリをいくつか作成していく予定です。
ぜひ学んだことをアウトプットしていきましょう！！
【jQuery】Nightly BuildsのDataTablesプラグインを使っていたら突如エラーになった

# 概要
今まで使用できていたページ（jQueryを使用）が突如動かなくなってしまいました。

検証ツールのConsole Logを見ると以下のようにありました。こちらの記事では、以下エラーの原因と解決方法について解説します。

```
dataTables.buttons.min.js:44 Uncaught TypeError: t.ext.features.register is not a function
    at dataTables.buttons.min.js:44:337
    at dataTables.buttons.min.js:5:281
    at dataTables.buttons.min.js:5:308
(anonymous) @ dataTables.buttons.min.js:44
(anonymous) @ dataTables.buttons.min.js:5
(anonymous) @ dataTables.buttons.min.js:5

jquery.dataTables.js:6188 Uncaught TypeError: val.apply is not a function
    at jquery.dataTables.js:6188:16
    at Array.map (<anonymous>)
    at _fnCallbackFire (jquery.dataTables.js:6187:50)
    at _fnCreateTr (jquery.dataTables.js:3065:4)
    at _fnDraw (jquery.dataTables.js:3346:6)
    at _fnReDraw (jquery.dataTables.js:3435:3)
    at _fnInitialise (jquery.dataTables.js:4577:3)
    at Object.success (jquery.dataTables.js:321:7)
    at i (jquery.min.js:2:27603)
    at Object.fireWith [as resolveWith] (jquery.min.js:2:28369)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/8b045da6-7baf-60f7-568f-090a0589fa23.png)

この画面にはデータテーブルとして表を表示していましたが、それらをソートや検索しようとしても、`Uncaught TypeError: val.apply is not a function`が再度出るだけでした。何をやっても同じエラー。なぜだ...この前まで使えていたのに...!

履歴を確認しましたが、コードをいじっていたのは数ヶ月前で、その時は普通に動作していました。突如動かなくなったので、焦りました汗

# 原因

エラーが発生したのは、Nightly Buildsと呼ばれる、開発中のバージョンを利用していたからでした。

今回利用していたのは、jQueryのプラグインであるDataTables。
DataTablesは、HTMLテーブルに対してソート、ページング、フィルタリングなどの機能を提供するライブラリです。JavaScript（jQuery）プラグインです。

そのDataTablesのバージョンがNightly Buildという開発版のバージョンだったのです（前任者が書いたコードなのでなぜNightlyだったのかは不明...ですが本番では使うべきではない）。

Nightly Buildはテストが十分に行われていない可能性があり、CDNの方が安定して使えるとのことで、CDNに切り替えてみたらエラーが消えました。

> NIGHTLY BUILDSと呼ばれるテスト中のバージョン
> 引用元：[jQueryのダウンロード方法](https://allabout.co.jp/gm/gc/42693/)

「ナイトリービルド」とググればたくさん用語の解説が出てきますが、その名の通り毎晩作業や改修があるようなテスト目的のビルドであり、基本的に一般ユーザー向けのものでははありません。

最近だと、Githubでも「GitHub Copilot Nightly」というVSコード向けの拡張機能がありましたね。あれはプレリリース版として提供されたものでしたので、似たような意味合いのはずです。

# 解決方法

ということで、以下のコードがエラー発生時の該当箇所です。

```base.html
    <link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
    <script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
```

以下のようにCDN版に修正することでエラーがなくなり解決しました。

```base.html
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css">
    <script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script>
```

※ちなみに、datatablesはjQueryのプラグインですので、必ずjQueryのCDNの後に記述します。逆にするとエラーになります

安定版はAPIの変更が少ないですし頻繁に更新されることもないので、一般的には本番環境での使用ではCDNが推奨されていますね。
DataTablesの公式サイトはこちら：[DataTables | Table plug-in for jQuery](https://datatables.net/)

CDN（Content Delivery Network）は、ウェブコンテンツを効率的に配信するためのネットワークのこと。世界中のデータセンターを使っているので、ユーザーがアクセスした時に近いところからコンテンツを配信してくれます。これにより、読み込み速度がはやくなったり、サーバの負荷を分散させています。AWSのAmazon CloudFrontとかもそうですね。