OmniAICreator/Qiita-1.07M huggingface dataset:
Kageki (TD4互換機) でアップダウンカウンタ

[TD4の命令を実行できる自作CPU「Kageki」](https://elchika.com/article/9ac9fd67-86c5-4b1b-a355-4f662e8af794/)でアップダウンカウンタを作ってみた。

# 仕様

以下、ビットの表記は0-originである。

* 現在のカウント値を出力ポートに出力する。
* 入力ポートのビット2が0で、ビット3が0から1になったら、カウント値を1増やす。
* 入力ポートのビット3が0で、ビット2が0から1になったら、カウント値を1減らす。

# プログラム

```
位置 機械語    アセンブリ言語
---------------------------------
0    10010000  DISP:  OUT B
1    00100000  WAIT:  IN  A
2    00001100         ADD A, 1100
3    11100101         JNC CHECK
4    11110001         JMP WAIT
5    00100000  CHECK: IN  A
6    00001000         ADD A, 1000
7    11101010         JNC NOTUP
8    01010001         ADD B, 0001
9    11110000         JMP DISP
A    00000100  NOTUP: ADD A, 0100
B    11100101         JNC CHECK
C    01011111         ADD B, 1111
D    11110000         JMP DISP
```

0番地で、カウント値を出力ポートに出力する。
1番地～4番地で、入力ポートのビット2とビット3がともに0になるまで待機する。
5番地～7番地で、入力ポートのビット3が1かをチェックする。
8番地～9番地で、(入力ポートのビット3が1だったので)カウント値に1を加算し、表示処理に移る。
A番地～B番地で、入力ポートのビット2が1かをチェックする。(このとき、ビット3のチェック処理によりAレジスタのビット3は1になっている)
C番地～D番地で、(入力ポートのビット2が1だったので)カウント値から1を減算し、表示処理に移る。

# 実行結果

入力ポートに [Pmod BTN](https://digilent.com/shop/pmod-btn-4-user-pushbuttons/) モジュールを、出力ポートに [1-Digit 7seg Board](https://elchika.com/article/fb155241-6490-4cbf-ae85-c166c3743874/#h_1-Digit%207seg%20Board) を接続して実行した。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Plz8R4CAl1U" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
PostGIS を使わない側の論理

私自身、あえて PostGIS を使わない側に立つことが多いのですが、そういった立場の論理として、bdon さんの [The Surprising Anatomy of a One-Man Map Tech Stack](https://protomaps.com/blog/one-man-map-tech-stack) の記載がいいなと思ったので、翻訳翻案して共有します。

- **PostgreSQL や PostGIS に問題があるのではない**。むしろそれらはオープンソース地理空間情報技術の可能性についての模範であり、政府での GIS に大きなインパクトを与えている。
- それらは、地理空間情報がネットワーク経由で同時書き込みされる際のリレーショナルモデルのトランザクション処理については完璧なソリューションである。ただ、**我々にとってはネットワーク経由の同時書き込みは重要ではない**のだ。
- PostGIS を、GDAL/OGR や GEOS に対する便利な SQL フロントエンドとして使う会社が多いが、GDAL/OGR や GEOS を単純に直接使っても問題が解ける場合が多い。クライアントサーバ方式のデータベースを使うことで、ポート設定やユーザ認証、プロセスマネージャなどが関わってきて、自動化がとても複雑になる。SQLite や LMDB を使って自己完結した方が単純になる。
- スケーラビリティを意識すれば、**ネットワーク越しにデータを取り出すのはオーバーヘッドが大きすぎる**ことがある。
- 単一の会社とそのワークフローおよび仮定が学術領域と産業を支配しているというのが GIS の現状である。つまり、「GIS をやる」ということが、リレーショナルデータベースを操作することであると定義されており、**ソフトウェア開発がベンダーの側に来るような形に抽象化されている**、というのが GIS の現状なのである。
SHARP Brain に Linux を入れて遊ぶ(6) - 入力

[目次](https://qiita.com/nekopro2/items/7eff2eb5e1c4480d3b30)

# 概要
SHARP Brain のキーボードとタッチパネルを取得したい

## /dev/input/event
linux系でキーボードやマウスを直接取得したいんなら、/dev/input/eventほげ を見るのが速い。
~~~
user@brain:~$ ls /dev/input/
by-path  event0  event1
~~~
と、event0 と event1 があるようだ。

ちょっと覗いてみよう。
### /dev/input/event0
タッチパネルを触ると色々データが流れてくる。
~~~
user@brain:~$ sudo od /dev/input/event0
0000000 046462 061613 156201 000016 000003 000000 004074 000000
0000020 046462 061613 156201 000016 000003 000001 004351 000000
0000040 046462 061613 156201 000016 000003 000030 003534 000000
0000060 046462 061613 156201 000016 000001 000512 000001 000000
0000100 046462 061613 156201 000016 000000 000000 000000 000000
~~~

### /dev/input/event1
キーボードを押下すると色々データが流れてくる。
~~~
user@brain:~$ sudo od /dev/input/event1
0000000 046543 061613 075246 000006 000001 000042 000001 000000
0000020 046543 061613 075246 000006 000000 000000 000000 000000
0000040 046543 061613 160504 000010 000001 000042 000000 000000
0000060 046543 061613 160504 000010 000000 000000 000000 000000
0000100 046543 061613 050232 000014 000001 000043 000001 000000
~~~

## event の内容
event の内容は linux/input.h で定義されている構造体 struct input_event である。
linuxディストリビューションによって異なるが、基本は下記の通り。
~~~
struct input_event {
  struct timeval time;
  __u16 type;
  __u16 code;
  __s32 value;
};
~~~
構造体の内容は以下のとおり。
|type  |code      |value     |内容                        |
|------|----------|----------|----------------------------|
|EV_SYN|          |          |同期信号、無視して良い      |
|EV_KEY|キーコード|押下フラグ|キーボードやボタンが押された|
|EV_REL|軸番号    |相対位置  |ホイールなどが動いた        |
|EV_ABS|軸番号    |絶対位置  |マウスが動いた              |

## テストコード
適当に作ったテストコード
https://gitlab.com/nekodevteam/brainux/-/blob/main/inputtest/inputtest.cpp

- 噂通り、稀にキー リリースを取り逃すようだ
- なんかタッチパネルは3軸取れる。。。なんだこれ

と謎は深まるばかり、追々確認しよう。
React(Next.js) + vanilla-extractにstorybookを導入する

## 環境
| 名前 | バージョン |
|:-:|:-:|
| next | 13.0.6 |
| react | 18.2.0 |
| @vanilla-extract/css | 1.9.2 |
| @storybook/react | 6.5.14 |

## 導入方法
`npx create-next-app`したプロジェクト配下で`npx storybook init`している状態にする。
以下のパッケージを追加する
```
npm i --save-dev @vanilla-extract/css @vanilla-extract/webpack-plugin mini-css-extract-plugin@1.6.2
```

`.storybook/vanilla-extract.js`を作成して、内容を以下にする
```
const { VanillaExtractPlugin } = require('@vanilla-extract/webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  webpackFinal(baseConfig, options) {
    const { module = {}, plugins = {} } = baseConfig;

    const cssRule = module.rules.find((rule) => rule?.test?.test('test.css'));
    cssRule.test = /.*(?<!\.vanilla)\.css$/;

    return {
      ...baseConfig,
      plugins: [
        ...plugins,
        new VanillaExtractPlugin(),
        new MiniCssExtractPlugin(),
      ],
      module: {
        ...module,
        rules: [
          ...module.rules,
          {
            test: /\.vanilla\.css$/i, // Targets only CSS files generated by vanilla-extract
            use: [
              MiniCssExtractPlugin.loader,
              {
                loader: require.resolve('css-loader'),
                options: {
                  url: false, // Required as image imports should be handled via JS/TS import statements
                },
              },
            ],
          },
        ],
      },
    };
  },
};
```

`.storybook/main.js`を以下に編集する
```
const path = require('path');

module.exports = {
  stories: ['../**/*.stories.mdx', '../**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
    path.resolve('./.storybook/vanilla-extract.js'),
    '@storybook/addon-links',
    '@storybook/addon-essentials',
  ],
  framework: '@storybook/react',
  core: {
    builder: '@storybook/builder-webpack5',
  },
};
```

以上で、導入完了。
【Git】よく利用するコマンド集

自分が業務でよく利用するGitコマンドを集めました。

- ローカルブランチの最新化
```
$ git pull origin main
```
- ローカルブランチの最新コミットIDの確認
（これをリモートの最新コミットIDと比較して、ローカルが最新か確認。）
```
$ git log -1 HEAD
```
- 今のブランチは何だっけ？
```
$ git branch
```
- ブランチを切り替え
```
$ git checkout <ブランチ名>
```
- 特定のブランチにプッシュする
```
$ git push <リモートリポジトリ名> <ブランチ名>
```
- 特定のブランチを削除する（ローカル）
```
$ git branch -d <ブランチ名>
```
- 特定のブランチを削除する（リモート）
```
$ git push origin --delete <ブランチ名>
```
- 間違ってしまった変更をディレクトリごと元に戻す
```
$ git checkout <ディレクトリ名>
```
- (gitコマンドじゃないけど…合わせてよく使うやつ)
特定ディレクトリ配下のファイルのタイムスタンプを再帰的に変更
```
$ find ./<ディレクトリ名>/ | xargs touch
```
# 終わりに
こういうコマンドってまとめてあると便利ですよね。汎用性の高いコマンドは今後見つけるたびに追加していこうと思います。
MQTT で受信したデータを InfluxDB v1.8 に入れる

## プログラム

```py:subscribe_temperature.py
#! /usr/bin/python
#
#	subscribe_temperature.py
#
#						Dec/08/2022
#
# ------------------------------------------------------------------
import sys
import json
import requests
import paho.mqtt.client as mqtt

# ------------------------------------------------------------------
def influxdb_write_proc(temp_in):
	print(temp_in)
#
	url="http://localhost:8086/write?db=example"
	raw_data='temp,IDX=1 tempValue=%f' % temp_in
	rr=requests.post(url,data=raw_data)
	print(rr)
# ------------------------------------------------------------------
def to_influxdb_proc(json_str):
#	print(json_str)
	unit_aa = json.loads(json_str)
	if "t" in unit_aa:
		value = unit_aa["t"]
		print(value)
		influxdb_write_proc(value)
	else:
		sys.stderr.write("*** error *** to_influxdb_proc ***\n")
#
#
# ------------------------------------------------------------------
def on_connect(client, userdata, flags, respons_code):
#	print('status {0}'.format(respons_code))
	client.subscribe(topic)
sy
# ------------------------------------------------------------------
def on_message(client, userdata, msg):
#	print(msg.topic + ' ' + str(msg.payload,'utf-8'))
	to_influxdb_proc(str(msg.payload,'utf-8'))

# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

host_mqtt = 'localhost'
port = 1883
topic = 'esp32/temperature'
#
client = mqtt.Client(protocol=mqtt.MQTTv311)
client.on_connect = on_connect
client.on_message = on_message

client.connect(host_mqtt, port=port, keepalive=60)

client.loop_forever()

sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## Systemd で動かす

プログラムを
/usr/local/subscribe に置く

```text:/etc/systemd/system/subscribe_temperature.service
[Unit]
Description = start up mqtt_client subscribe_temperature

[Service]
WorkingDirectory=/var/tmp/subscribe_temperature
ExecStart=/usr/local/subscribe/subscribe_temperature.py
Type=simple

[Install]
WantedBy=default.target
```

作業用の Directory を作成

```bash
mkdir /var/tmp/subscribe_temperature
```

起動

```bash
sudo systemctl start subscribe_temperature
```

起動したことを確認

```bash
sudo systemctl status subscribe_temperature
```

## テスト

パブリッシュ

```bash
HOST="localhost"
#
mosquitto_pub -d -t orz -m '{"t": 21.6}' -h $HOST --topic esp32/temperature
sleep 20
#
mosquitto_pub -d -t orz -m '{"t": 22.4}' -h $HOST --topic esp32/temperature
```

InfluxDB で確認

```bash
influx -precision rfc3339
```
Logicool M590でUnifyingのペアリングができない場合の対処法

なぜか、Unifyingのペアリングが切れたので、その対処法。

１．Logi Boltでペアリングの設定まで進める
２．接続先を切り替えるスイッチ（マウスホイールの下のボタン）を長押しして、ペアリングの状態にする（ここ重要。LogiBoltには書かれていない）
３．マウスの電源をOFF→ONにする
４．なぜか接続できる
【Livewire】protectedプロパティとprivateプロパティの呼び出し方

# publicの場合
```
public $count = 1;
--------------------------
Blade側
{{ $count }}
```

# private,protectedの場合
「$this」が必要になります。
```
protected $count = 1;
private $user;
--------------------------
Blade側
{{ $this->count }}
{{ $this->user }}
```
意外とここわからんくて詰まった記憶がある。

# おまけ：使い分け
publicは開発者目線でユーザーに見られても大丈夫と思えるデータを入れる。
private,protectedにはユーザーに見られたらダメなデータを入れる。

publicでは開発者ツールやソースの表示等で見られてしまうので要注意。
間違ってAPIキーとかpublicにしたら丸見えでスーパー終わ終わタイムが始まる。
僕のリモートワーク環境[ 2022 Winter ver ]

この記事は、以下のアドベントカレンダー 7日目の記事です

https://qiita.com/advent-calendar/2022/nw-engineering-are-core-output

# はじめに

僕の周りで、アドベントカレンダーにリモートワーク環境を公開する記事が散見されたので**自分の部屋のログを残す**意味も込めて晒していこうと思います



# 全体
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153265/6fd0cbe1-e7ea-5c05-9795-a919a9ec7eb9.png)


# 机
遥か昔に買った机を今でも使っています。値段も忘れてしまいました。就職したばかりだったと思うので、紀元前の話で通貨も円だったか定かではありません


特徴は、引き出しがついていることと、サイドテーブルのようなものがついています
本来はここにタワー型のパソコンを置いておくのだと思いますが、勢いで買ってしまってFF15以来電源も入っていない~~PS5~~ **PS4**が鎮座しています

机の上には大きなマウスパッドが敷かれているだけです

# モニター

ワイド過ぎると首が疲れることが分かったのでこのサイズがちょうど良いと今は思っています

- 型番：DELL S2721Q (公式では、もうサポートページしか存在していませんでした


モニターの位置は、目線より下になるようにだけ気をつけます。負担が少ないという噂を聞いたことがあるからです。人生のダメージは極力減らして生きていかなければおじさんの体は持たないのです
- <参考> https://www.fujitsu.com/jp/about/businesspolicy/tech/design/ud/vdt/index-page3.html

## HDMI スイッチャー
このモニターは、スイッチの出力ポートににつながっています
入力にはmacとリモート用のPCが接続されており、状況に応じてスイッチで切り替えられます
こんな感じの製品です
- https://www.sanwa.co.jp/product/syohin?code=SW-HD21L



モニターアームのもう片方には、macを置くことが出来る台座がついています


# キーボード
決死の覚悟で購入したHHKBを使っています。他のキーボードとの優位性は正直よくわかりません
- https://happyhackingkb.com/jp/products/hybrid_types/


これは、Bluetooth接続が4台まで登録できることが個人的にポイントでした。以下4台が登録されています
1. 私用のmacbook
1. リモート接続用pc
1. ipad
1. スマホ

~~わかりますか、3と4は使っていないと思いますよね、はい、使ってません~~


# マウス
logicoolのなにかです
- これでした
    - https://www.logicool.co.jp/ja-jp/products/mice/m720r-triathlon.910-005629.html


# スマホ
macに寄りかかっている折り紙はスマホです
最新型で、充電は不要です
時計は、03:00を永遠に表示し続けています
最近、新しいスマホを開発したようなので、この旧型を譲ってくれました。新型は、折りたたみ式になっています


# 最後に
何か気になったことなどあれば、お気軽にコメントしてくださると嬉しいです
良いリモートワークライフをお過ごしください！
Introduction to SystemVerilog - 5

## For文、If文、三項演算子

### For文

同じパターンを繰り返し記述する際にfor文を使用しての冗長記述を前回説明しました。For文はC言語と同じ文法で、

```verilog
for ( 型宣言 変数名=初期値; 終了条件; 繰り返し式 ) begin
    ...
end
```

に従います。
always_ff、always_comb内にも使用でき、一般的に型は**int**を用いて変数を宣言し、その変数はfor内に記述しているオブジェクトのポジション指定にも使用します。また構造体のインデックスとして使用することもあります。

### If文

優先順位を持つ条件を列挙して条件に合った処理を行いたい場合もあります。この場合If文を使用します。これもc言語と同じ文法で、

```verilog
if ( 条件式1 ) begin
    ...
end
else if ( 条件式2 ) begin
    ...
end
else if ( 条件式3 ) begin
    ...
end

...

else begin
    ...
end
```

のように記述します。
条件式は論理演算を含む式をを記述できます。処理系によると思いますが、0以外の定数式は常に条件が成り立っている(真と呼びます)と暗黙に判断されます。単にオブジェクトの値の場合は0以外の時に条件が真と判断されます。
条件式1から順に優先順位を持たせているので、条件式2が真であっても同時に条件式1が真であれば条件式1を処理します。また、条件式3が処理されるのは条件式1と2の条件が成立しない時、かつ条件式3が真の時です。

```always_ff @( posedge clock )```内に記述する場合はclockの立ち上がりをイベントとして条件式判定を行い適切なif文内の処理(代入操作)を行います。また、```always_comb```内に記述する場合は常に条件式判定を行い適切なif文内の処理(割り当て操作)を行います。この時``` else begin ... end```文がない記述では全ての条件が真でないということになるので割当は行われず、割り当てているオブジェクトは不定を含むことになるので注意してください。さらに複数のオブジェクトへ割り当てていて各if文内で全てのオブジェクトへ割り当てていない場合も不定が内在する可能性があります。

### 三項演算子

一つのオブジェクトに対して条件別に割り当てを変えたい場合、if文でも書けますが、他の言語同様に三項演算子が用意されています。

```verilog
assign obj_hoge = ( 条件式 ) ? 式1 : 式2;
```

条件式内容はif文と同じです。この条件が真の時式1の結果をオブジェクトobj_hogeへ割り当てます。それ以外の場合(偽と呼びます)は式2の結果を割り当てます。HDLはハードウェアを記述する言語なので式1と式2両方とも存在し、回路として実装されます。

そして条件を複数記述することができます。この場合例えば

```verilog
assign obj_hoge = ( 条件式1 ) ? 式1 :
                    ( 条件式2 ) ? 式2 :
                    ( 条件式3 ) ? 式3 :
                    ...
                                式x;
```

のように記述し、条件式nが真の時式nの結果が代入されます。最後に条件式のない式xを記述する必要があります。ない場合エラーになります。
ブラウザでのSSHでCtrl-nを押すと新規ウィンドウが立ち上がってしまう問題

Google Compute Engineの「ブラウザでのSSH」は便利だが、Ctrl-n（↓）を押すとブラウザの新規ウィンドウが開いてしまい、非常に使いにくかった。

https://hiratara.hatenadiary.jp/entry/2018/05/20/183734

SSH for Google Cloud Platformを導入することで解決した。

https://chrome.google.com/webstore/detail/ssh-for-google-cloud-plat/ojilllmhjhibplnppnamldakhpmdnibd
なんちゃってアジャイルだっていいじゃないか

# はじめに

アジャイル開発（スクラム）において

・開発対象となる機能が最初から決まっており、スコープは固定
・システム初リリース日は固定（ずらすことはできない）
・必要に応じて人員リソースを足すことも可

と、聞いたときにあなたはどう感じますか？


きっと、「そんなのアジャイルじゃない」、「スクラムとして間違っている」と感じた人が多いんじゃないでしょうか

私も最初、この話を聞いたとき、「あぁ、これはアジャイルに偽装したただのウォーターフォールだ、経営層を騙すためのなんちゃってアジャイルだ、大炎上して大変な思いをするのだろうな」と思いました

これは私が現場でアジャイルの理想と現実と向き合って戦った実体験から得た
"私なり"の「アジャイル」の価値観を語っていこうと、そういった趣旨の記事になっています

この記事はTDCソフト株式会社Advent Calendarの23日目です
https://qiita.com/advent-calendar/2022/tdc

# 1.アジャイル（スクラム）って何なんだっけ

顧客が求めるものをより迅速に市場に出していくプロセスがアジャイルだと
まぁそんなところかなと思います

各々自分にとってのアジャイルの定義（価値観）って少しずつ違うと思うので、あまりカッチリしない感じで

# 2.どこから「アジャイルじゃない！」に変わってしまうのか
何が欠けた段階でアジャイルじゃない！に変わるんでしょうか

例えば先に挙げた例３つをシンプルにするとこのような感じになる
１．開発するものが決まっている
２．納期が決まっている
３．チーム数が増える減る

これ、いずれも普通に起きる出来事じゃないでしょうか
１．開発するものが決まっている
→MVPって概念は必ず存在する

２．納期が決まっている
→プレスのことを考えれば期限があるのはエンタープレイズでは当たり前のこと
　いくらプロダクトの価値が高くとも、それを知ってもらわないことには利用されないので、蔑ろにはできない

３．チーム数が増える減る
→大規模アジャイルってものがあり、SIerという職種が存在している限りこのイベントを0にすることはできない

こんなの普通に起きるね、って内容だなと私は思うわけです
じゃぁ、こんな当たり前なことに適応できなくて何がアジャイルかと

これを受け入れないとしてしまうと、もう日本のSIerはPOCアプリ開発ぐらいでしかアジャイル開発はできないってことになってしまいせんか？

もう少しよく聞く例を出すと

４．設計書を書く
５．なぜなぜ分析をする
６．絶対見積もりをする

とかでしょうか？

設計書を書くのは、ＰＯがそこに価値があると考えているなら問題はないんじゃないでしょうか
なぜなぜ分析をして不具合の再発を防ぐことはユーザー体験の向上そのものではないでしょうか
相対見積もりって結局のところテクニックなので、絶対見積もりをする＝アジャイルじゃないとはならないんじゃないでしょうか

大抵の事は簡単に否定されてしまうと思うんですよね（賛否はあれど）

じゃぁ私の考えるアジャイルじゃなくなってしまう要素は何かというと

 **改善をしない** 

改善してないけどアジャイルだ！ってさすがに言えないと思います
レトロやめたらさすがにアジャイルじゃないと感じる、私だけでしょうか？

# 3.実体験
 **開発スコープは最初から決まっていて、リリース日も決まっていて、チーム数もタスクに応じて増やしていた案件** 
そういう案件でしたが、私はこの案件が「アジャイルでよかった！」と思っています。

じゃぁアジャイルマインドや進め方だけでもアジャイルを意識していて、結果として何が良かったのか。
超具体的な良さを伝えておこうと思います

 **・要件がすべて決まっていなくても開発が始められる！** 
　ウォーターフォールだと工程ごとに進むので、未確定な要件があるとどんどん遅れに繋がりますよね
　でもアジャイルであれば決まったところから作り始めて、変わったら修正すればいい
　これだけでもメリット特大ですよね
　いったん作ってダメなところは後で直せばいいって改善マインド

 **・レトロスペクティブのためのタイムボックスが確保されている**
　ウォーターフォール案件だとなかなか難しいですよね
　まずタイムボックスを取るだけで調整稼働がかかる、でも大丈夫、アジャイルならね
　改善をするのが当たり前であるという文化

 **・全てにおいてDEVの意見が反映させられる**
　開発の進め方や決め事がトップダウンで決まってしまうことってあると思います
　でもアジャイルをうたっている以上、DEVの意見を聞いてみよう！って流れに自然となるんです
　開発が一番うまく進むようにしたいという全員の改善意識がこの流れを生み出している


少し改善とはずれるけど、

 **・どの機能でもみんな直せる**
　バックログの優先順に作業していくおかげで、俗人化が防げていた
　●●さんがお休みした、ってことはこの機能の仕様がわからない！って事件は避けられる
　これってすごく大きいですよね

こんなこともありました

一般的にそんなのアジャイルじゃない！って言ってしまうような要素をたくさん含んでいても
アジャイルでやっててよかった！って思える箇所ってたくさん存在するはずです

LeSSでも語られている「守破離」の考え方からすれば
●●でなければならない点なんてほとんどないはずなんですよね

# 4.私にとってのアジャイルとは

結局のところ答えはシンプルで

現状を良しとせず「より良くする方法は無いのか？」と、疑問を持ち改善に全力を注ぐこと


つまり **改善** これがすべてだと思っています

もし今あなたが「なんちゃってアジャイルだ・・・嫌だ・・・」って思っていたら、
改善に目を向けてください

改善に取り組んでさえいれば、少しずつ物事は良くなり
私たちはアジャイルな心を持っていると胸を張って言えるはず。です。
AUTOSAR Demonstratorがダウンロードできないものがあるらしい。

 
AUTOSARでdemonstratorで検索すると全部が現れない。

https://www.autosar.org/search?tx_solr%5Bq%5D=Demonstrator

# Demonstrator

Demonstrator Design of Functional Cluster Update And Configuration Management

Demonstrator Design of Functional Cluster Execution Management

Demonstrator Design of Functional Cluster Identity and Access Management

Demonstrator Design of Functional Cluster Platform Health Management

Demonstrator Design of Functional Cluster Diagnostics

Demonstrator Design of Functional Cluster Communication Management

Demonstrator Design of Functional Cluster Log and Trace

Demonstrator Design of Functional Cluster Persistency

Demonstrator Design of Functional Cluster Time Synchronization

Demonstrator Design of Functional Cluster RESTful

## 20220から春に更新　

R20-11は春にDemonstratorを更新したらしい。 
R21-11も春にDemonstratorを更新したらしい。

公開URLがわかっていない。　

AUTOSAR web renewal, 使いやすい？

https://qiita.com/kaizen_nagoya/items/809af86aec6b3e19e655
rpmデータベースを壊した。

# はじめに
　現場に配属されて2か月のとき、検証機で使用していたLinuxサーバーのrpmデータベースを壊した。当時は、どのようなことをして壊したのかわからず、一人モヤモヤしていました。あとから先輩に聞いたところ、どうやら気づかぬうちに<b>「リダイレクト」</b>してしまったらしい...。

# リダイレクトとは？
　コマンドの実行結果を画面上ではなくファイルに保存することができる。

# 使い方
例えば、lsコマンドの実行結果をファイルに保存したい際に下記のように実行する。

```
$ls -l > test.txt
```

# おわりに
　<b>「リダイレクト」</b>。使いこなすことができればとても便利ですが、誤って実行してしまうと大惨事になるコマンドということがわかりました。今後もバリバリLinuxサーバーを触っていくと思うので、誤って実行してしまわないよう慎重に作業していきたいと思います。

# 参考
　・Linux - ストリーム、パイプ、リダイレクトの使用
　　https://www.infraeye.com/study/linuxz15.html
【GMC-4】パワーゲーム

学研の4ビットマイコンGMC-4で「パワーゲーム」を作成した。

# ルール

2進LEDがパワーゲージとして増減する。
たくさん光っているタイミングでボタンを押して攻撃しよう。
攻撃すると、光っているLEDの数だけ7セグメントLEDに表示された数から引かれる。
3回の攻撃で、7セグメントLEDに表示されるべき数を負にできたら成功、できなかったら失敗。

# プログラム

以下のようにレジスタおよびメモリを割り当てている。(レジスタは `power_loop` 時点のもの)

* `A` : 作業用
* `B` : 残り攻撃回数のカウント
* `Y` : パワーゲージの状態
* `[0]` : 7セグメントLEDに表示する値
* `[0xE], [0xF]` : 2進LED消灯用

[MikeAssembler](https://mikecat.github.io/mike_assembler/) でアセンブルできる。

```
target gmc4

	TIA 0x10 - 3
	CH
	TIA 0
	TIY 0xE
	AM
	TIY 0xF
	AM
	CY
	AM ; [0] = 0xF
	AO
	JUMP power_loop_reset
power_loop:
	CIY 7
	JUMP power_loop_noreset
power_loop_reset:
	CAL DSPR
	TIY 0
power_loop_noreset:
	CAL SETR
	AIY 1
	TIA 0
	CAL TIMR
	KA
	JUMP power_loop
	CAL SHTS
stopped_wait:
	KA
	JUMP stopped_next
	JUMP stopped_wait
stopped_next:
	TIA 9
	CAL TIMR
	CY
	TIY 0
	M-
	JUMP game_clear
	AM
	AO
	CH
	AIA 1
	JUMP end_loop
	CH
	JUMP power_loop_reset
game_clear:
	CAL RSTO
	CAL ENDS
end_loop:
	JUMP end_loop
```

以下が、このプログラムの機械語表現である。

```
  | 0 1 2 3  4 5 6 7  8 9 A B  C D E F
--+-----------------------------------
0 | 8 D 2 8  0 A E 4  A F 4 3  4 1 F 1
1 | 6 D 7 F  1 A E D  A 0 E 1  B 1 8 0
2 | E C 0 F  1 1 E 9  0 F 2 F  F 2 8 8
3 | 9 E C 3  A 0 7 F  4 6 4 1  2 9 1 F
4 | 4 A 2 F  1 6 E 0  E 7 F 4  A
```

# 実行結果

<iframe width="560" height="315" src="https://www.youtube.com/embed/TaQJkFaj_q4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
WinSCPでリモートサーバの隠しファイルを表示させたい

WinSCPを使用していたら、ローカルでは隠しファイルが表示されているのに
リモートでは表示されていないという現象が発生。

# 解決方法
WinSCP画面上部のオプションタブから、環境設定を開く。
左ペインの「パネル」を選択する。
「隠しファイルを表示する」のチェックボックスにチェックを入れてOKボタンを押下。
ちなみに、隠しファイルを表示するか否かは「ctl + alt + H」で変更可能。
CORSとは

## CORSの定義
- Cross Origin Resource Sharing
- 違うオリジン間で通信する時、その通信を許可するかしないかということ。
  - `オリジン` = `URLのスキーマ + ドメイン + ポート番号`
  - 一つでも違うと、「別オリジン」になる
    - https://aaa.com、https://bbb.com は別オリジン

## いつ使うの
- CORSはブラウザの機能なので、**ブラウザから通信する時**だけ関係ある。
  - 例: フロント`https://react.front` => バックエンド`https://go.api` の通信 => CORSに引っかかる
  - APIからの通信ではCORSは**適用されない**。
  - 例: https://hoge.api => https://fuga.api のAPI間で Javaの RESTTemplate、URLConnectionとかで通信はCORSに引っかから**ない**
- 基本的に、オリジンが違うとCORSに引っかかる
  - CORSを貫通したい場合、バックエンド側(通信される側)で特別に指定する必要がある

## CORSいらんくない？
- 違うオリジンから勝手に通信されたらまずいですよ...まずいでしょうよ...
  - 通信される側の方で、「お前通信してきていいよ」って指定できるので便利だよね

## 資格情報付き
- `cookie`ヘッダーとかが付いたリクエストのこと
- 資格情報: `Cookie`、`認証ヘッダー`、`TLSクライアント証明書`
- 実装的にはこうなってるときを指す。
- XHR
```js
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);
```
- Fetch
```js
fetch(url, {
  credentials: 'include'
})
```

## ヘッダー一覧
### Access-Control-Allow-Origin
- 基本。通信できるオリジンを指定する。
  - `*`で全オリジンを許可。ただし、[資格情報付き][1]でリクエストする場合は`*`は使えない(ブラウザコンソールでCORSエラーが発生する)
    - `*`の代わりに、`https://aaa.com`のように明示的に指定すればよい
```
Access-Control-Allow-Origin: *

Access-Control-Allow-Origin: https://aaa.com
```

### Access-Control-Allow-Credentials
- [資格情報付き][1]でリクエストする場合、`true`にしないとだめ。(trueにしないと、資格情報付きリクエストのときにレスポンスがフロントに公開されない)
```
Access-Control-Allow-Credentials: true
```


### Access-Control-Request-Method
- 実際のリクエストで使うメソッドをサーバに知らせる
  - プリフライトリクエスト時にこのヘッダーを使う
```
Access-Control-Request-Method: POST,GET,DELETE
```

### Access-Control-Request-Headers
- 実際のリクエストで使うヘッダーをサーバに知らせる
  - プリフライトリクエスト時にこのヘッダーを使う
```
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
```

### Access-Control-Max-Age
- プリフライトリクエストの結果をキャッシュする上限時間(秒)
  - プリフライトリクエスト一回送ってからこの時間の間は送らなくて良くなる
```
Access-Control-Max-Age: 86400
```

## CORSエラー事例
### 1.GolangのAPIサーバに、フロントからアクセス
  - http://localhost:3000 => http://localhost:8080/complaints

 
```log
xhr.js:220          GET http://localhost:8080/complaints net::ERR_FAILED 200
Access to XMLHttpRequest at 'http://localhost:8080/complaints' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

- これで解決
 
```go
import (
    "github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

func main() {
    ...
    router := gin.Default()

	// CORS設定
	config := cors.DefaultConfig()
	config.AllowOrigins = []string{"http://localhost:3000"}
	router.Use(cors.New(config))
    ...
    router.Run()

}
```

[1]:#資格情報付き
[python-oracledb入門](第1回) さようならcx_Oracle、こんにちはpython-oracledb!!



この記事は、[JPOUG Advent Calendar 2022](https://adventar.org/calendars/7680) 8 日目の記事です。7 日目は gowatana さんの[「Nutanix と Oracle Database」](https://blog.ntnx.jp/entry/2022/12/07/235802)でした。


# cx_Oracle → python-oracle
Oracle社製のPython向けのOracle Databaseアクセスドライバであるcx_Oracleは、2022年5月の改定にて[python-oracledb](https://oracle.github.io/python-oracledb/)に刷新されました。本記事執筆時点(2022/12/8)でもcx_Oracleもまだ残ってはいますが、今後の改定は為されませんので、新規アプリケーションはもちろんのこと、既存アプリケーションもタイミングを見てpython-oracledbに変更してください。

# python-oracledbで何が変わった?
python-oracledbもcx_Oracleと同じく[PEP249(Python Database API Specification v2.0)](https://peps.python.org/pep-0249/)に準拠しています。python-oracledbは実際にインストール、インポートするパッケージが「oracledb」になる点を除けば、コーディング上はcx_Oracleと基本的には変わりません。ですので、インポート部分を修正すればcx_Oracleのアプリケーションはほぼ動きます。

では何が変わったかということ、python-oracledbはThin Driverになりました。つまり、python-oracledbはOracle JDBC Thin Driverのように、Oracle Clientが不要になりました。cx_Oracleの場合はPythonアプリケーションと一緒にThick/InstantのOracle Clientを必要としましたが、python-oracledbではこれらクライアントを必要としませんので、作成したアプリケーションのセットアップがより簡単になり、アプリケーションがより配布しやすくなりました。ただし、python-oracledbはOracle Clientと共に使用することも可能です。Thin Mode(Oracle Client不使用)とThick Mode(Oracle Client使用)の両対応となります。Oracle Clientが必要になる(Thick Modeが必要になる)のは以下のケースです。
- Oracle Client 11gを使用する場合。12c以降のOracle ClientはThin ModeでもThick Modeでも利用が可能です
- cx_Oracleアプリケーションのバージョンアップの際、Oracle Clientを使用したままの形で移行したい場合。ただし、import文以外にもThick Modeを使用するためのコードの変更の必要があるので、このケースはあまりないとは思われます
- Oracle Clientが必要な機能(クライアント結果キャッシュなど)を利用する場合


# 今後の連載について
基本的にはcx_Oracle入門の焼き直しとなりますが、過去の連載で触れていない話題を加えて、より充実した内容にしたいと思います。
Rust の関数をCから呼びたい時の物語

## 概要

Rust の関数をCから呼びたい、それだけです。


## やりかた

### Rust で関数を定義

https://docs.rust-embedded.org/book/interoperability/rust-with-c.html

ここをフォローします。

まず、Rust のプロジェクトを以下のように作ります。

```
cargo new test-c
```

```Cargo.toml
[package]
name = "test-c"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[lib]
name = "mycrate"
crate-type = ["cdylib"]      # Creates dynamic lib
# crate-type = ["staticlib"] # Creates static lib
```

Cから呼びたい関数を定義します。
`rust_function`です。

```src/lib.rs
#[no_mangle]
pub extern "C" fn rust_function() {
    println!("hello, from rust!");

}
```

準備できたら、build します。

```bash
cargo build
```

```bash
target/debug/libmycrate.dylib
```
のようなdylib ファイル（もしくはsoファイル）が生成されます。




### cbindgen でC用のヘッダー作成

https://github.com/eqrion/cbindgen

上のgithubに従います。


```bash
cargo install --force cbindgen
```

cbindgenがインストールできたら、
先ほどのRust プロジェクトの中で、

```bash
cbindgen --config cbindgen.toml --crate test-c --output my_header.h
```

とすると、
`my_header.h` が生成されていることがわかります。



### C から呼ぶ

C用のフォルダを作ったとします。

```bash
mkdir test-folder
cd test-folder
touch test.cpp
```

```test.cpp
#include <iostream>
#include "my_header.h"

int main(){
  printf("hello from c\n");
  rust_function();
}
```

このフォルダに、先ほどの　
`my_header.h`、`libmycrate.dylib`　をコピーします。

コピーできたら、

```bash
g++ test.cpp -lm libmycrate.dylib
./a.out
```

で、

```
hello from c
hello, from rust!
```

と出力されたら完了です、
お疲れ様でした！



## まとめ

今回は、CからRustの関数を呼ぶということが必要になったので試してみました。
かなり特殊なシチュエーションだとは思いますが、どなたかの役に立てば幸いです。



今回はこの辺で。


@kenmaro
Datadogによるfluentdのログ転送状況の監視

 

**概要** 
---------------------------------------
fluentdを使用して、AWS上のEC2インスタンスからS3へログ転送を実施している。
今回、ログ転送状況の監視(転送遅延の発生有無)を行う要件が発生した。

この要件に対し、SaaSベースの監視ソリューション、Datadogを利用して、Fluentdの以下の項目を監視することで対応を行なった。

* bufferに滞留しているqueueの数
* データ転送リトライの数




**fluentdによるログ転送が遅延している状態とは?** 
---------------------------------------

まず、監視を行う前に、fluentdのログ転送に関連するメトリクスを整理すると以下になる。


* fluentdのキュー関連のパラメーター値


| メトリクス   | デフォルト値 |
|:-----------|:------------|
| buffer_queue_limit       | 256(個)     | 
| buffer_chunk_limit     | 8(MB)    | 
| retry_limit       | 17(回)     | 

*上記はデフォルト値であり、実際の値はプロジェクトにより異なる。


* Datadogで取得できるfluentdのMetrics
flunetndの標準プラグインin_monitor_agentを有効化することで取得できるバッファーに関するMetrics


| メトリクス| 概要 | 値が増えた時の影響 |
|:-----------|:------------|:------------|
| buffer_queue_length      | バッファーに蓄積されているキューの数        | buffer_queue_limitで設定した値を超えるとログデータがロストする         |
| buffer_total_queued_size   | バッファーに蓄積されているキューの合計サイズ      | buffer_queue_limit × buffer_chunk_limitの値を超えるとログデータがロストする       |
| retry_count      | データ再送を試みた回数       | retry_limitで設定した回数を超えるとバッファーがリセットされる         |



次に、上記を踏まえ監視対象のメトリクスと閾値を策定した。
(閾値は検討の結果を反映)


| 監視項目  | 閾値 |
|:-----------|:------------|
| bufferに滞留しているqueueの数      | 205　(buffer_queue_limit値の80%)     | 
| データ転送リトライの数 | 12　(再送開始から1時間超過前のretry_limitの数) | 



*buffer_total_queued_sizeについては、先にbuffer_queue_limitが閾値に達するので、監視対象外とする。

*retry実施回数と要する時間については、参考情報の"Fluentdの障害時動作"を参照






**設定内容** 
---------------------------------------

以下、設定した内容を記載する。

**fluentd** 
* monitor_agentの有効化の実施
/etc/td-agent/td-agent.conf　に以下のエントリーを追加する。


```ruby:/etc/td-agent/td-agent.conf
<source>

  @type monitor_agent

  port 24220

</source>
```




**Datadog Agent** 
* fluentdのメトリクスの収集設定の追加
/etc/datadog-agent/conf.d/fluentd.d/fluentd.yaml 内のエントリーを以下のように修正する。


```ruby:/etc/datadog-agent/conf.d/fluentd.d/fluentd.yaml
init_config:

instances:

  # Every instance requires a `monitor_agent_url`
  # Optional, set `plugin_ids` to monitor a specific scope of plugins.
  #-  monitor_agent_url: http://example.com:24220/api/plugins.json
  #   plugin_ids:
  #     - plg1
  #     - plg2
  #   tags:
  #     - 'test'
  #     - 'datacenter:northeast'
  # Optional, set 'tag_by' to specify how to tag metrics. By default, metrics are tagged with `plugin_id`
  -  monitor_agent_url: http://localhost:24220/api/plugins.json
     tag_by: type
```


**Datadog コンソール** 

* fluentd - Buffer queue length (chunks) のモニター設定

:::note info
Query
avg(last_5m):max:fluentd.buffer_queue_length{type:s3,environment:prd} by {host} > 205
:::

** Query内の205は今回の閾値

* fluentd - Retry count 通知 のモニター設定



:::note info
Query
avg(last_5m):max:fluentd.retry_count{type:s3,environment:prd} by {host} > 11
:::

** Query内の11は今回の閾値



**参考にした情報** 
---------------------------------------

[monitor-agentの監視スクリプトをつくった](https://qiita.com/smallpalace/items/04bcf470fab17611c277)


[Fluentdの監視](https://www.greptips.com/posts/1298/)


[fluentdの効果的な活用例と安定運用のポイント](https://atmarkit.itmedia.co.jp/ait/articles/1404/04/news004_3.html)


[Fluentdの障害時動作](http://ogibayashi.github.io/blog/2014/06/04/how-fluentd-works-in-case-of-failures/)
「アウトプット」という言葉に囚われないでほしい



日本では当たり前のように通じる”インプット”と”アウトプット”という捉え方（＝概念、切り口）について
私が調べた範囲ではあるけども、この概念が英語圏では一般的ではなかったというお話です



## Summary
* 「その情報はどこで使えるか」を意識して情報収集すると自然とアウトプットに繋がる
* （Qiitaのアドベントカレンダーの趣旨を否定するわけではないが）なにか記事を書いたりとかTwitterで情報発信することこそが”アウトプット”というのは間違いではないけども、解釈が狭く勿体ないのでは
* 「日記をつける、混乱してきたらメモに書き出す」程度のアウトプットはを日常的にできるようにしておくなど、言語化する＝日常的に情報を使う、習慣化することをおすすめしたい。

## きっかけ
以前に１年ほどオンラインで通える海外の大学に在籍していたことがあり、とある講義のカリキュラムの中で「”学習する上で重要なことはなにか”を各自で考えて発表し合う」という課題が出たことがありました。
その大学では英語で授業が行われていているのだけども、英語スキルの高くなかった私は、早く課題を終わらせようとして「インプットとアウトプットのバランスが大事」という何のひねりもない内容で発表しようと課題を進めていました。


## 違和感
大学の課題ということもあり評価指標の中に「適切なエビデンス（＝根拠）となる資料を探し出させるか」、「その資料を盗作にならないように適切なフォーマットで引用できるか」という指標が含まれていまして、まぁ無難な題材を選んだ私はノリノリで資料を探し始めたんですね。

「”インプット”、”アウトプット”だなんてジャパングリッシュっぽくなってるだけで似たような概念は英語圏でもあるでしょー」
「インプットとアウトプットのバランスが大事だよーみたいな論調でズバリ書いてくれてたらいいなー」

そんなことを考えながらググりはじめるわけなんですが、予想に反してヒット件数が少ないんですねぇ。
少し言葉を加えて調べてみても思うような資料は出てこない。

なんかそれっぽい資料が出てきたとしても言語学習の文脈で書かれていていて、汎用的な学習方法という文脈ではないんですね…
<details><summary>"input learning"とか"input output learning method"なんかで調べると…</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174872/5edaa954-3f29-088a-9cd9-f293aa91a89b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1174872/430663cc-dd64-e4be-c12d-88eba074f3fd.png)
</details>



## 気づき？
ちゃんとネイティブの人に聞いたわけではないので（在学中に質問しておけばよかった…）、私の推測の域を出ないのだけども、これはもうジャパングリッシュがどうのこうのではなくて、そもそも考え方として「インプット vs アウトプット」なんていうのは英語圏では一般的ではないよなと。
とは言え切り口が違うだけで、日本語の文脈のインプット・アウトプットに該当するニュアンスって、英語圏でもどこかしらの表現が補ってくれていると思ってて、それに該当するのが"use"なんじゃないかなと思いました。平たく言うと「情報っては使ってなんぼ」であって、"使った"ことこそがアウトプットなのではないかと思ったんですね。

これは肌感レベルのもので明確な根拠があるわけではないので、もしこの記事をここまで読んでくれている人がいれば、ぜひ自らの経験を通して検証してみてほしいです。



## 締め
昨今の「アウトプットしなきゃ！！」みたいな風潮ってどうなの？という問題提起をして締めたいと思います。

QiitaやZenn、noteに自分が収集した情報をいくら読みやすくキャッチーにまとめてみたところで、その行為自体がインプレッション増加など直接的に目標達成に結びつくようなSNSインフルエンサー（とその予備軍）でない限り、将来的に使われなかったとしたらどうでしょうか？

使われなかったとしたら、という表現は正しくないかもしれないですね。

その情報を自分が使う気が無いのに、周囲に流されて言われるがままに取りまとめた情報というのは、果たして本来目指していた「インプット&アウトプット」なのでしょうか？

このことは今回のアドベントカレンダーの趣旨に反していないと思っていて、今は腹落ちしなくてももがき苦しみ”アウトプット”している人は、将来きっと何かしらの気付きが得られると思います。

ただ、こういうアドベントカレンダーのようなイベントを目にしたり、周囲の人が勧めているからというだけで「やらなきゃ」と焦っている方は一度立ち止まってほしいと思います。きっと、そのような焦りを日記などを通して、習慣的に言語化していくほうが情報を”使う”ことにつながり、それはつまりアウトプットということにならないでしょうか。

Summaryから書いていったので、締めの部分がきれいにつながらなかったですが、私がまとめたかった（言語化したかった、使いたかった、アウトプットしたかった）内容というのは書けたと思います。
ご意見あればぜひコメント、もしくはコメントだと周囲の反応が、、、という方はぜひTwitterのDMへご連絡いただければと思います。

## おまけ ： 周囲の反応
自分のこの話を補強する意図はほぼないのだけど、課題を発表した時の周囲の反応は「んー、そうなんだ」くらいの温度感だった気がします。発表すると同じ講義を受けている生徒と、その講義を担当している先生からレビューをもらえる仕組みになっていて、そこでも資料が引用できてるかどうかとか、全体の構成についてのレビューがほとんどで、内容に関してはほとんどフィードバックがなかったはず。
そういった苦くもないけど、甘いわけでもない過去を思い出してこの話を書こうと思いました。

## おまけ : 海外の大学って？
「University of the People」という大学です。
https://www.uopeople.edu/
２年制・４年制の両方あり、コースはBusiness Administration, Computer Science, Health Scienceの３つ。
教育を受けることへの障害を取り除くことに重きをおいていて、完全オンラインで通える、学費が安い、サポートが手厚いのが強みですね。私はエンジニアを目指した時にComputer Scienceコースに在籍していたのですが、本業が忙しくなって退学しました。
ある程度の読み書きができる＆挑戦心があれば卒業できるのではと思います。もし、興味を持たれた方でちょっと話聞いてみたいみたいなということがあれば、TwitterのDMまでご連絡いただければと思います。私のあまり広くない知識でよければお答えいたします。
【Terraform】「aws_s3_bucket_versioning」の Import が timeout した時に実施した対応

## はじめに
Terraform にて S3 の Bucket Versioning の設定を Import した際に躓いた点と実際に実施した対処方法について書きます。

## 躓く前のS3のBucket Versioningの設定
- `Disabled`になっている。
    - S3の作成時点で`Disabled`を設定しているため

## 躓いた点
S3 の Bucket Versioning の設定を Import する際に以下のエラーが発生

```zsh:エラー内容
Error: error waiting for S3 Bucket Versioning status for bucket (<bucket_name>): timeout while waiting for state to become 'Enabled, Suspended' (timeout: 1m0s)
```

エラー内容を確認すると、S3 の Bucket Versioning が `Enabled` か `Suspended` の Status に切り替わるのを待っていて、タイムアウトしたという内容でした。

実行したImportコマンドは以下になります。

```zsh:コマンド
terraform import aws_s3_bucket_versioning.example bucket-name
```

## 対処方法
AWS Console にて Bucket Versioning を `Suspend` に設定し、再度 Import を実施

### 対処理由
- `Disabled`(無効) と `Suspended`(停止) のどちらに設定した場合も、Bucket Versioningが動作しないことに変わりはないため
    - Bucket Versioning の機能自体は止まっているままの状態

## 参考
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning

https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html
切れたらキレられた話

謎のアドベントカレンダー、第 11 話です。

## それは、複数拠点で同じセグメント（サブネット）を使っていた頃の話

筆者の職場では昔、数人〜十数人規模の拠点を増やす際にはセグメント（サブネット）を分けず、同じサブネット内に収容していました。

（フレッツ光のオプションサービスと、それに特化した LAN 間接続装置を組み合わせて。ただし NTT の東西を跨ぐ拠点を除く）

難しい設定も不要で楽ちんだったので、筆者以外の情シスメンバーが扱うことを想定して導入しました。

ある日のこと、複数の拠点から「LAN が繋がらなくなった」との連絡が。

サーバー室の LAN 間接続装置を見ると、LAN ポートの ACT ランプが激しく点滅しています。

とにかく何とかしないといけません。

## 仕方がないので全ての拠点を切断→ 1 つずつ戻して原因拠点の切り分け

をしていたところ、ある 1 つの拠点の偉い人から電話が掛かってきました。

**「仕事にならんからネットを切るな」「早くなんとかしろ」** と。

そう言われてもどうしようもないので適当にごまかして（？）調査を続けたところ、まさにその拠点が怪しい、ということに。

## 発見。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/c32482e9-7b69-8e02-af2e-101abd7d91d9.png)

まんまコレでした。

話を聞くと、その拠点にいたガジェット好きの A さんが、外れてぶら下がったままの LAN ケーブルを見つけて、

**「たぶんこの HUB から外れたんだろうな。刺しておこう。ヨシ！」**

とやってしまったそうです。

（本人は障害に気づかず直後に外出）

## その後

- 社内への注意喚起
- エッジ用のスイッチング HUB をループ防止機能を持ったものに置き換え
  - ちょうどその頃出回り始めたので
- 上位の L3SW でループ軽減対策
  - DoS っぽいアクセスパターンの場合に遮断

を行いました。

ただ、件の LAN 間接続装置もループ検出・遮断機能があったはず。

ですが、「同じ MAC アドレスが自分側（LDB）と対向側（FDB）に見つかったら遮断」のようなものだったと記憶しており、このケース（対向側だけでループ）に効くものではありませんでした。

ループ防止機能を過信してはダメです。

そのため、数年後の見直しの際に、単一拠点で何かあっても別拠点に波及しないよう、複数拠点で同じセグメント（サブネット）を使わないように再構成しました。

ヨシ！

---

12 日目の記事に続きます。

- **[切れたら逆ギレされた話](https://qiita.com/hmatsu47/items/4ff062081ea936a8a599)**

https://qiita.com/hmatsu47/items/4ff062081ea936a8a599
Introduction to SystemVerilog - 6

## Case文とEnum列挙

### Case文

例えば有限状態機械を記述したい場合特に、特定の条件に対して場合分けをしてそれぞれの場合について代入やassignを行いたい時があります。
例えばneru、aho、majimeの3状態を持つ有限状態機械は 

```verilog
localparam NERU = 0;
localparam AHO = 1;
localparam MAJIME = 2;
logic   [1:0] FSM;
always_ff @( posedge clock ) begin
    if ( reset ) begin
        FSM <= NERU;
    end
    else case (FSM)
        NERU: begin
            if ( aho ) begin
                FSM <= AHO;
            end
            else if ( majime ) begin
                FSM <= MAJIME;
            end
            else begin
                FSM <= NERU;
            end
        end
        AHO: begin
            if ( majime ) begin
                FSM <= MAJIME;
            end
            else if ( neru ) begin
                FSM <= NERU;
            end
        end
        MAJIME: begin
            if ( aho ) begin
                FSM <= AHO;
            end
            else if ( neru ) begin
                FSM <= NERU;
            end
            else begin
                FSM <= MAJIME;
            end
        end
        default: begin
                FSM <= NERU;
        end
    endcase
end
```

と記述できます。
これは**case**文の使用例です。caseの後のカッコ内に場合分け条件を持つオブジェクト名を記述し、caseとendcaseの間に記述します。勿論場合を評価される式は一つ(この例の場合FSM)なのでif文と違い優先順位はありません。注意したいのは```case (...) begin```と**beginを使用せず、endcaseで閉じます**。

この例ではローカルパラメータを利用して状態を保持するFSMへ代入しています。代入条件はlogicやwireといったオブジェクトとして宣言されているaho、majime、neruがif文の条件を満たす時、clockの立ち上がりエッジをイベントとして代入します。

FSMは合計４つの状態を保持できますが、"FSM == 2'h3"の状態が未定義となっています。なんらかの動作不良で未定義の状態へ遷移した場合の動作保証ができなくなるので、論理回路を合成し検証する際、未定義の状態を可能な限り排除する必要があります。これを支援するため、**default**が用意されています。

またこの例ではAHOの状態でMAJIMEでもNERU状態でもない暗黙の状態を含んでいます。if文が全て成立しない場合、代入されないのでこの時暗黙にAHOの状態となります。この暗黙の状態も検証する際にワーニングとしてレポートされるでしょう。さらに**全てが自明な場合**、caseでは暗黙の値を含まない場合にuniqueという識別子を用いて```unique case```として論理合成系を支援することができます。


### Enum列挙

この例では状態を保持するlogic FSMに対してローカルパラメータで整数値をラベル(NERU、AHO、MAJIME)へ指定して使用しました。開発をしているとたまに同じ名前でパラメータを使用している状態が発生し、想定と異なった値を代入や割り当てをしてしまうことがあります。例えばシミュレーション上なぜか違った値が表示され検証に時間を浪費する、といったことが発生しえます。

これを避けるために固有の名前を定義することができます。固有の名前を特定のオブジェクト(型)に紐づけることで誤った名前の使用を避けることができます。
例えば、

```verilog
enum [1:0] {
	NERU	= 2'b00,
	AHO     = 2'b01,
    MAJIME	= 2'b10,
    KYOMU	= 2'b11
	} ningen_f;
```

では**enum**を使用して４つの状態を列挙した列挙している定数ningen_fとしています。
文法は

```verilog
enum 幅 {
	名前1   = 値,
    名前2   = 値,
    ...
	} 列挙名;
```

で、名前を”,"で区切って列挙します。
ユーザ定義型に使用すると例えば

```verilog
typedef enum logic [1:0] {
	NERU	= 2'b00,
	AHO     = 2'b01,
    MAJIME	= 2'b10,
    KYOMU	= 2'b11
	} ningen_t;
```

とすることでlogic型に紐づいたningen_t型を用意でき、下記のように宣言して使用します。

```verilog
ningen_t    FSM;
```

これによりFSMに固有の名前(ラベル)を付与できます。使用例は先のローカルパラメータの例と同じですが、この型以外のオブジェクトで名前を使用するとエラーになります。

この型で宣言されたオブジェクトは通常名前で代入や割り当てを行いますが、直接数値で指定もでき大小比較を用いて組合せ回路を作ることを可能にしています。例えば順番が定義されている時その範囲内を条件として、あるいは範囲外を条件としたいときに有用です。また、パラメータと同様にenumで列挙した部分の修正や更新を行えばよく、冗長な書き換え作業を省くことができ、さらにコード本体に触れることが基本ないため、書き換えに伴う誤ったコーディングを防ぐことができます。
Zabbix用 RDS for MySQLインスタンスタイプ変更

**概要** 
---------------------------------------
AWS上に構築したZabbixサーバーのDBとして、RDS for MySQLを使用している。
今回、そのRDS for MySQLのインスタンスタイプ(r3.large)がEOL(*)になるため、r5世代にインスタンスタイプを変更した。

*2023年4月30日までがサポート期限



**事前調査** 
---------------------------------------

* 現在使用しているZabbixとMySQLのバージョン、左記ZabbixがサポートしているMySQLのバージョンを整理した


| 現在利用しているZabbixのバージョン| ZabbixがサポートするMySQLのVersion | 適用済みのMySQLのVersion |
|:-----------|:------------|:------------|
| 3.0.28      | 5.0.3 - 5.7.x        | 5.5.52-MariaDB (including from MySQL 5.5.52)        |






* 次にRDS for MySQL r5世代がサポートしているMySQLのバージョンを調査した。

| RDSインスタンスタイプ| 使用可能な MySQLのVersion | 備考 |
|:-----------|:------------|:------------|
| db.r5.large     | MySQL 8.0 / MySQL 5.7       |       |


事前調査の結果、r5世代にインスタンスタイプを変更しても、Zabbixサーバーには影響がないことがわかった。
そのため、インスタンス変更を行うこととした。



**DBインスタンス変更手順** 
---------------------------------------
インスタンス変更の手順を以下に記載する。

**DB インスタンスの変更**

1\. ナビゲーションペインで、[データベース] を選択し、アップグレードする DB インスタンスを選択します。 

2\. [変更] を選択します。[DB インスタンスを変更] ページが表示されます。 

3\. 以下の通り変更します。

 [設定]の[インスタンスの設定] で、新しいDB インスタンスクラスを選択します。 

新しいインスタンスタイプはr5.large

[追加設定]→[バックアップ]→[バックアップ保持期間]を変更します。(2 => 35)

*2は今回の設定値

4\.  [続行] を選択して、変更の概要を確認します。 

5\. 確認ページで、変更内容を確認します。

    変更のサマリー
    
    3) で設定した内容となっていること
    
    変更のスケジューリング
    
    [すぐに適用]を選択

 

6\.  [DB インスタンスを変更] を選択して変更を保存します。

7\.  DB engine versionが更新されたことを確認します。

8\.  [保留中のメンテナンス]に以下が表示された場合は、[今すぐ適用]→ [今すぐ適用]と進めます。


9\. [変更] を選択します。[DB インスタンスを変更] ページが表示されます。 

10\. 以下の通り変更します。

[追加設定]→[バックアップ]→[バックアップ保持期間]を変更します。 (35 => 2)

11\.  [続行] を選択して、変更の概要を確認します。 

12\. 確認ページで、変更内容を確認します。

    変更のサマリー

    10) で設定した内容となっていること

    変更のスケジューリング

    [すぐに適用]を選択

13\. [DB インスタンスを変更] を選択して変更を保存します。

14\. DBを選択し、[メンテナンスとバックアップ] → [バックアップ] → [自動バックアップ]が10)で設定した内容に変更されたことを確認します。



**フェイルオーバーでの再起動の実施**

パフォーマンス向上のため、Zabbixサーバー#1と同じAZ上でRDSを起動します。

1\. AWS Management Console にサインインし、Amazon RDS コンソール (https://console.aws.amazon.com/rds/) を開きます。 

2\. ナビゲーションペインで、[データベース] を選択し、ZabbixのDBを選択します。 

3\. [アクション] → [再起動]を選択します。

4\. [Reboot DB Instance]画面で、[フェイルオーバーし再起動しますか?] を選択しフェイルオーバーを実施します。

5\. [Reboot]]を選択して、再起動を行います。

6\. リージョンとAZが 通常時のものになっていることを確認します。

以上
Reactの状態管理の設計について考える

こちらの記事は金属加工プラットフォームを開発・運用する[Catallaxy](https://catallaxy.me/)の[Catallaxy Advent Calendar 2022](https://qiita.com/advent-calendar/2022/catallaxy)の12/9の記事となります。

Reactを使っている既存システムの状態管理を整理していくうちに色々問題があったので、どういう点が問題だったのかと解消方法を考えてみました。

# 前提

既存システムでは、各コンポーネントで必要な情報を取得するために都度APIを呼び出すようにしています。
いわゆるReduxを用いたFluxパターンみたいなことはしていません。

# 状態を管理する粒度が曖昧で起きた問題

## 画面全体で状態が共有されてしまっている

一つの画面内に、A、B、Cのようなコンポーネントがあった場合に、既存の実装では画面全体で同じデータ構造を使っている箇所がありました。
A・B・Cで必要なデータ構造がそれぞれ違うのですが、汎用的な型定義がされていて実際にそれぞれのコンポーネントで必要なデータ構造がどうなっているのかわかりませんでした。

仮に
- A（オーバービュー）
- B（詳細）
- C（オプション）

とすると、扱いたいデータの粒度はそれぞれ異なっているのですが、実際に定義されている型はAもBもCも含むような型になっていた感じです。

このときにBで更新があってそれをトリガーにAの表示状態を更新しようとした時に、BのオブジェクトをAに渡して表示を更新しようとしている箇所がありました。
型定義としては合っているのでAのオブジェクトはBのもので上書きされるのですが、実際にはAの型定義はBの型定義で包含されない状態だったので、Aで表示されていたものが意図せず変更されてしまいました。

これは当初の設計で意図していた部分（各コンポーネントで必要なデータをAPIから呼び出して取得する）が、修正を続けるうちに曖昧になってしまったために起きたと考えられます。

問題を起こさないためには、A・B・Cでそれぞれ必要な型定義をしてそれぞれのコンポーネントを疎結合にするようにしないといけないなぁと思いました。

## コンポーネント間でのPropsの引き渡し

状態管理ライブラリを用いる前提の設計では起こりづらい問題なのかもしれませんが、既存システムではコンポーネントの上流から下流にPropsを引き渡すような設計をしていました。
これが、前述のA・B・Cのような大きなコンポーネント間でもPropsの引き渡しが起こってしまっていたため、結合が密になってしまっていました。

例として挙げると、Aの孫コンポーネントからAにハンドラー経由で渡されてきたものが、そのままBを経由してPropsづたいにBの孫コンポーネントまでそのまま渡されていました。
大雑把に考えるとAの孫コンポーネント→A→B→Bの孫コンポーネントというひと繋がりの結合になってしまっていて、Aの孫コンポーネントでそのPropsに修正を加えた時にすべてのつながりを追って検証しないといけなくなってしまうことになります。

このような場合、AとBの間での引き渡し時に分離をする必要があるので、Propsのオブジェクトをそのまま渡すのではなくて再定義されたもの、もしくはAPIから取得し直したものをBの孫コンポーネントに渡すようにしなければいけないかなと思いました。

# 状態へのアクセス方法を管理する

各コンポーネント内、システムグローバルで様々な情報を保持すると思いますが、アクセスできる情報は整理・制限が必要だと感じました。
この辺の設計をせずに「あー、ここにデータあるから使おう」とかやってしまうと、上記のような問題が発生しやすくなると思います。
また、形骸化しやすいので設計をしたらチームへの共有が必要になりますね。
ESLintとかプログラミング設計でこの辺が制限・設計できればいいのですが、仕組み的に難しい所もあると思います。

## 状態管理ライブラリで管理された状態へのアクセス方法

状態管理ライブラリを採用することになったときに、RecoilやJotaiのようなAtomアーキテクチャのものを選定していたのですが、お手軽に扱える一方で、使用する手段やスコープを狭めないと思わぬ変更がされると思います。
なので、Reactの場合はカスタムフックからのみ値を変更できるようにしたりしてその辺りのケアをする必要があります。
色々調べてたら似たような設計を見つけたので参考にしたいです。

https://zenn.dev/yoshiko/articles/607ec0c9b0408d#recoil%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9Fglobal-state%E3%81%AE%E7%AE%A1%E7%90%86

# まとめ

状態の管理については
- 状態を変更できるスコープ
- 状態を共有するスコープ

これらを必要最小限にして、コンポーネント間では

- 情報の受け渡しはオブジェクトのキーのみ
- シンプルなイベントトリガーを使う

のようになるべく結合度を低くしていくような設計が必要だと思いました。

状態管理のライブラリや設計パターンによってこの辺は多少変わってくるかもしれませんが、必要以上にオープンな設計にしていると思わぬデグレが発生しやすくなるのは間違い無いかなと思います。
コードレビューをするときも影響範囲が読みにくいですしお寿司。
Introduction to SystemVerilog - 2

## 宣言とパラメータ

### 宣言

前回ポートを宣言して使用する場合を例を利用して説明しました。その際**input**と**output**でポートを宣言しました。これらの宣言子の他にレジスタ(reg)や配線(wire)などの宣言子も用意されています。

宣言は

```verilog
宣言子  幅  オブジェクト名;
```

の形式に従います。幅はオブジェクトの持つビット幅を指定します。オブジェクトは複数列挙できます。列挙する際は","で区切ります。幅の指定は例えば

```verilog
[7:0]
```

のように記述すれば8ビット幅を指定できます。この場合、降順で7, 6, 5,..., 2, 1, 0と各ビットが並びます。昇順での指定も可能です。またソフトウェアプログラム同様にSVでも**0から始まります**。

定数で幅を指定する場合、複数のオブジェクトで同じ目的で同じ幅を指定したい時がよくあります。またその幅を変えてみたいこともよくあります。特にモジュールを再利用したい場合にこのような要望が発生します。

### パラメータ

SVではパラメータを設定することでこれを可能にしています。モジュール内でのみパラメータを使用したい場合、

```verilog
localparam ローカルパラメータ名 = 値;
```

とローカルで使用することを宣言する**localparam**宣言子を使用して記述します。ローカルパラメータの値は数式で与えることもできます。先の例の場合

```verilog
localparam WIDTH = 8;
wire [WIDTH-1:0]  w_a;
wire [WIDTH-1:0]  w_b;
```

のように使用します。値を修正するだけで、同じローカルパラメータ指定しているすべてのオブジェクトに対して適用されるので、いちいち各オブジェクトを修正する手間を省けます。

さらにモジュールを使用する際にも幅といった値を個々に対して変えたい場合もあります。
この時は例えば

```verilog
module instance_name 
#(
    parameter パラメータ名 = 値
)( ... );
...
endmodule
```

としてパラメータを宣言して使用します。このパラメータ宣言ではデフォルトの値を指定します。パラメータの値は数式で与えることもできます。このモジュールを使用する場合、たとえばパラメータとして**param_hoge**を宣言している場合は

```verilog
instance_name #(
    .param_hoge( 8  )
) object_name1 (
...
);
...
instance_name #(
    .param_hoge( 5  )
) object_name2 (
...
);
...
instance_name #(
    .param_hoge( param_foo  )
) object_name3 (
...
);
```

といった形で指定します。コンマ+パラメータ名+(+値+)で記述します。また列挙する際は","で区切ります。この例では３つめのオブジェクトではパラメータあるいはローカルパラメータでパラメータ渡しています。オブジェクト宣言でパラメータ指定を省略した場合、デフォルト値が暗黙に用いられます。
Next.jsはじめました

この記事は [Howtelevision Advent Calendar 2022](https://qiita.com/advent-calendar/2022/howtelevision) 9日目の記事です。

8日目は@Syoituさんによる「[PokeAPIを利用した二次開発](https://qiita.com/Syoitu/items/d4833cc0a0663fdfeed3)」 でした。

こんにちは、ハウテレビジョンで外資就活の開発をしている菅と申します。
弊社では今夏からフロントエンドの技術スタックとしてNext.jsを導入しました。
最終的にすべてのフロントエンドの実装をNext.jsで置き換えることを目標に、技術負債解消プロジェクトチームを結成し、日々古のコードたちと戦っております。
本記事では、Next.jsを導入してみてよかったこと、苦労したことを書いていきたいと思います。

# 現在の外資就活ドットコム

弊社が運営する外資就活ドットコムは2010年に始まったサービスです。
フレームワークはCakePHPを使用していますが、プロダクトの成長速度に保守が追いつかずに継ぎ接ぎが多く頭が痛い状況です。
React.js + Golangへの置き換えを新規開発・運用の傍らで試みてきましたが、数年経った現在でも半分以上はCakePHPで実装されています。
更に申し上げると、Reactで実装されている部分もCakePHPのviewの中にReactを挿入する形で使用しています。
ここはReactで実装してるから早く終わるよね〜と甘い見積もりをしていると、ところがどっこいCakePHP側を触らないといけなかったということが起きかねません。

# 段階的リプレイス

とはいってもいきなりすべてのコンテンツをリプレイスしてリリースするのは現実的ではありません。
以下のルールでリプレイスを開始しました。

- 1コンテンツごとなど区切りやすい単位でリプレイスしていく
- 別アプリケーションとしてデプロイし、リプレイスされたコンテンツのURLのみnginxでリダイレクトをかけてNext.js製アプリケーションをユーザーに表示する

現在の予定としては一年半ほどかけてリプレイスが完了する見通しです。

# いざ出陣

最初のリプレイス対象として「相談室」というコンテンツに白羽の矢が立ちました。
理由としては

- React.js + Golang (in CakePHP) で実装されているコンテンツなので、バックエンドのエンドポイントがすでに存在している
- 他コンテンツよりも比較的小規模である

などがありました。

## よかったこと

- すべてTypeScriptファイルなので型の安全性が担保される

これまでも部分的にTypeScript化されているものはありましたが、基本的にはjsファイル…。
格段に作業効率が上がり、安心感を持って開発をすることができるようになりました。

- 単純に早い

言わずもがなですが表示もbuildもdeployも早くなりました。
開発環境由来のタイムロスを最小化することで精神衛生の状態も向上しました。

- 古い書き方のコードを一掃することができた

こちらも言わずもがなですが、Next.jsで再実装することによってClassコンポーネントでの実装やhooksを使わない実装などを一掃することができました。
現在のコードもいずれ古くなってしまうので、継続的にリファクタにも力をいれていきたい所存です。

## 苦労したこと

- PHPで実装していた細かいDBとの通信をすべてGolangで再実装する必要があった

当然ですが、PHPだからこそできていた実装方法はできなくなりました。
Next.jsにapiをもたせる方法もありましたが、今回のリプレイスではすべてバックエンド側はGolangに受け持ってもらっています。

- 秘伝のタレを読みといていく必要があった

今までのツケなので文句を言う筋合いはないのですが、つらいものがありました…

- 外資就活ドットコムのスマホアプリのwebViewで表示するとNext.jsのルーティングがエラーになってしまい、力技で解決する他なかった

あまりの謎現象にチーム全員で頭を抱えました。
おそらくスマホアプリ側の実装の問題によるもののため、一旦力技で解決し、根本的解決にむけて引き続き調査と作業を続けています。

# まとめ

- 技術負債は本当につらい
- 技術負債はこまめに解消した方がいい
- Next.js最高！
- Next.jsで開発をしたい方、新しい技術が好きな方、ぜひ一緒にハウテレビジョンで働きましょう！
- ご応募お待ちしております！

https://recruit.howtelevision.co.jp/
ConoHaでOPNsense入れてVPNをやる話(前編)

本稿は [ConoHa Advent Calendar 2022](https://qiita.com/advent-calendar/2022/conoha) 16日目の記事です。

VPNネタかぶっちゃいましたが懲りずに自分の誕生日を押さえてあわよくば祝ってもらおうと思っている horiken1216 です。
去年すっぽかしたので今年はちゃんと書きます。


ときにクリスマスといえばVPNですよね？
ですよね？

__です。__

というわけでConoHaにVPNルーターを立てていきましょう。

## VPNとは
「VPN とは」でぐぐってください。

## なにをするの？
ここでは下図のような構成で仮想ネットワークを作り、リモート端末とかクラウドとか家とか家とか家とかを仮想拠点経由でつないでおらがVPNを構築、世界中をおらがローカルエリアにしちまいましょうということをします。

![ConoHa_VPN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21166/de7ae967-876f-245c-f549-69c4b1274645.png)

※ただこの方法で職場のPCとか参加させて人んちのネットワークに穴開けるのはあまりお勧めしません。一見便利でもセキュリティインシデントがあった場合には自分の首を絞めることになりますし、自分のクビだけで済めばまだいい方でしょう。

※VPN＝IP偽装みたいに思ってる方もいるかもしれませんが、そんなのはオマケ機能にすぎません。リモート端末と自宅、データセンター、クラウドを仮想的に繋いでしまえばもっと ~~ヤバ~~ もとい便利な使い方がたくさんあります。

## Linuxとか入れてOSSの組み合わせで作るの？

今回は __OPNsense__ というソフトウェアルーターを使っていきます。簡単です。黒い画面(ほとんど)見なくてOKです。ただインストールまでにちょっとコツが要るのでその点を説明していきます。

## でもConoHaにVPNルーターのテンプレとかないし
実はあるんだわ、実は。イメージアップロードしてマウントしてブートして云々なんて面倒くさい奴は今回は一切なし。早い安いうまい！

## というわけで構築していきます。

### VMスペック
__1G__ のやつで十分。多分 _512MB_ のやつでも大丈夫でしょう。

### OS
ここがミソで __FreeBSD__ を選ぶ。__ZFS__ を選んでおくと手間がありません。
OPNsense は FreeBSD ベースの m0n0wall からフォークしたソフトウェアルーターで、FreeBSD からコマンド一発(数発)で OPNsense 化できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21166/a82b1844-559a-a4e1-f6aa-507911bcba08.png)

### オプション
適当にやって。
接続許可ポートはとりあえず _web_ だけ開けておけばよいでしょう。
あとで _OPNsense_ 先生自体の設定が終わったらどうせ全開放します。

## FreeBSD を OPNsense 化するんだわ
```
# pkg install ca_root_nss
# fetch https://raw.githubusercontent.com/opnsense/update/master/src/bootstrap/opnsense-bootstrap.sh.in
# sh ./opnsense-bootstrap.sh.in -r 22.7
```
はい終わり。バージョンの指定とかは適宜確認してください。
リブートしたら君のVMはもう _OPNsense_ だ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21166/fcce65c0-473c-d64a-2431-52bf9077877e.png)

## 初期設定
ログインするとこんなCUIになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21166/2f0d1475-be34-3998-8762-2a64914babb3.png)
ここで設定していくのは`1) Assign interfaces`と`2) Set interface IP address`の2項目。 

#### Assign interfaces
ConoHa側でVMに複数インターフェースを接続している場合は、MACアドレスを確認して _WAN_ 側にグローバルのインターフェースをアサインします。ここで注意が必要なのが、もし複数インターフェースが見えていても、ここでは _LAN_ 側にインターフェースをアサインしてはいけない。 _WAN_ だけを設定するのがポイントになります。 _LAN_ 側は空白で。

ConoHa側のプライベートセグメントにも出ていきたい場合は、全部終わってから足を生やしましょう。

#### Set interface IP address
_WAN_ 側インターフェースのIPアドレスは _DHCP_ 任せでOK。

ここまで設定が終われば HTTPS でログイン画面にアクセスできるはずです。
(WANから設定画面にログインなんて怖いって？その感覚は正しい。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21166/b8833640-7769-01d0-0cc9-d41ae2c777e9.png)
ロイグインできない場合は _LAN_ 側インターフェースをアサインしてしまっていないか確認しましょう。

ここまでで _ConoHa_ への _OPNsense_ のインストールができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21166/d6e00730-9502-3c35-c36a-7a6b3311c919.png)


## さーて、後編の内容は？
- 管理者用のVPNを設定して、管理画面への接続許可をVPN側に絞る
- VPNクライアントアカウント/証明書の払い出しとクライアント設定、クライアント間相互通信の許可
- あっーーー！！会社のネットワークに穴開けたらマルウェアを持ち込んでしまって路頭に迷う羽目に

の、3本です。
来年もまた見てくださいねー！
ウフフフフフ