OmniAICreator/Qiita-1.07M huggingface dataset:
JTRegビルド備忘録[Ubuntu 22.04]

# おねがい
この記事を参考にしてビルドに失敗した方は後学のためにコメントをいただけますと幸いです。
質問にもお答えできる限りお答えしますので是非コメントを残してください。

# 環境
OS : Ubuntu 22.04.3 LTS

前回の[JDKビルド](https://qiita.com/tabatad/items/de0530f0c84be6c93acb)の続きになります。

# 手順

## 1. 資材ダウンロード
```
$ cd ~/work
$ git clone git@github.com:openjdk/jtreg.git
```

## 2. ビルド実行
```
$ bash make/build.sh --jdk $JAVA_HOME
```

## 3. 成果物確認
```
$ ./build/images/jtreg/bin/jtreg -version
jtreg 7.3.1-dev+0
Installed in /home/tabatad/work/jtreg/build/images/jtreg/lib/jtreg.jar
Running on platform version 16.0.2 from /usr/local/lib/jdk-16.0.2+7.
Built with Java(TM) 2 SDK, Version 16.0.2+7 on October 03, 2023.
Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
Use is subject to license terms.
JT Harness, version 6.0 ea b24 (October 03, 2023)
Java Assembler Tools, version 7.0 ea b09 (October 03, 2023)
TestNG: testng-7.3.0.jar, guice-5.1.0.jar, jcommander-1.82.jar
JUnit: junit-platform-console-standalone-1.9.2.jar
```

## おまけ
JTRegのありかを環境変数`JT_HOME`に追加しておく。
```
$ sudo unzip ~/work/jtreg/build/images/jtreg.zip -d /usr/local/lib/
$ vim ~/.bashrc
#########################
# 以下を追記
export JT_HOME=/usr/local/lib/jtreg
#########################
```

# 参考
- OpenJDK jtreg building.md

https://github.com/openjdk/jtreg/blob/master/doc/building.md
エックスサーバーにSSH接続【レンタルサーバー】

# XserverにSSH接続

```bash
ssh -p10022 xs123456@sv14460.xserver.jp
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3353802/f31218af-4a9e-6e55-6df3-a2a1a51a6b6a.png)

# SSHキーの登録

## SSHキーの生成

```bash
ssh-keygen
# すべてエンター
```

## SSHキーのコピー

```bash
cat ~/.ssh/id_rsa.pub
```

## コピーしたSSHキーをサーバーパネルで登録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69767/13ffe6ba-a611-7ff9-8b9a-9913d26f8fe2.png)

:::note info
改行区切りで複数のSSHキーを登録できます。
:::

ONになっているかも確認しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69767/f016b3fd-de38-95db-24f1-c296a9b674fd.png)




# cronの設定 番外編

まず、SSH接続します

```bash
# cronの設定
[xs123456@sv14460 ~]$ crontab -e

# cronの設定の確認
[xs123456@sv14460 ~]$ crontab -l
* * * * * pwd >> pwd.log
* * * * * id >> id.log


[xs123456@sv14460 ~]$ cat /home/xs123456/pwd.log
/home/xs123456

[xs123456@sv14460 ~]$ cat /home/xs123456/id.log
uid=20001(xs123456) gid=1000(members) groups=1000(members),20001(xs123456)
```

`/home/xs123456/pwd.log` と `/home/xs123456/id.log` が作成されます。

cronの実行ユーザは`xs123456`で、作業ディレクトリは`/home/xs123456`となります。
Azure ADのアプリにロール未設定なのにサインインできてしまう問題の解決法

# 背景

アプリの登録のApplication IDを使用してWebアプリを作ったところ、エンタープライズアプリケーションに未登録、つまりロールを何も持たないユーザがサインインできてしまう問題が発生しました。

無事解決に至ったので解決方法を共有します。

# 原因

エンタープライズアプリケーションのManage>Propertiesにある「Assignment required? (Yes/No)」の項目が「No」に設定されていたことでした。
（おそらく日本語だと項目名は「必須の割り当て」）

https://learn.microsoft.com/ja-jp/azure/active-directory/manage-apps/application-properties#assignment-required

ドキュメントから説明文を引用します：

> このオプションを [いいえ] に設定すると、すべてのユーザーがサインインできるようになり、その他のアプリケーションやサービスがアプリケーションへのアクセストークンを取得できるようになります。 このオプションを使用すると、組織に招待された可能性のある外部ユーザーもすべてサインインできます。
GAS(Google Apps Script)でファイル分割

GoogleDrive上に1ファイルで100GBを超えるファイルがアップロードされており、WEBダウンロードに失敗するという事象が発生した為にGoogleDriveにアップロード済のファイルを1ファイル100GB未満に分割するファイル分割用のGAS(Google Apps Script)を作成しました。

今回はChatGTPのアドバイスのみで作成することが出来ました。
ここで完成版のスクリプトを公開します。

### スクリプトの説明
分割対象のファイルのfileIDと分割ファイルサイズのsplitSize、分割ファイル出力先のフォルダのfolderIdをスプレットシートで指定して、ファイル分割処理を行います。
分割したファイルはワイルドカードを使用したファイル連結コマンドで結合出来るように元のファイル名末尾に「_part001」～「_parNNN」を連番で付与します。

### GASの使い方
分割対象ファイルのアイテムID、分割ファイルサイズ(bytes)、分割ファイル出力先フォルダのアイテムIDを入力して
「ファイル分割GAS実行ボタン」を押します。
ファイル分割処理が終了すると「終了しました」と表示されます。

### GAS本文
```
function BunkatsuFunction() {


//  スプレッドシートの読み込み
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  //  シートの選択
  const sheet = spreadsheet.getSheetByName('ファイル分割');
  //  セルの選択
  const range1 = sheet.getRange('B3');
  //  セルの値を取得する
  const fileId = range1.getValue();
  //  セルの選択
  const range2 = sheet.getRange('C3');
  //  セルの値を取得する
  const splitSize = range2.getValue();

  var range3 = sheet.getRange('D3');
  //  セルの値を取得する
  var folderId = range3.getValue();

// ファイルを取得
  var file = DriveApp.getFileById(fileId);
  var fileName = file.getName();
  var fileSize = file.getSize();

  // ファイルのバイトデータを読み取る
  var fileData = file.getBlob().getBytes();

  // 分割ファイルを作成
  var startByte = 0;
  var partNumber = 1;

  while (startByte < fileSize) {
    var endByte = Math.min(startByte + splitSize, fileSize);
    var partData = fileData.slice(startByte, endByte); // ファイルデータを分割

    // partNumberを3桁のゼロパディングで生成
    var partNumberString = Utilities.formatString('%03d', partNumber);

    // 分割ファイルを作成し、指定のフォルダに保存
    var partBlob = Utilities.newBlob(partData, 'application/octet-stream', fileName + "_part" + partNumberString);
    DriveApp.getFolderById(folderId).createFile(partBlob);

    // 次の分割を準備
    startByte = endByte;
    partNumber++;
  }

  // 完了メッセージを表示
  Logger.log("ファイルを分割しました。");
}
```

### 分割したファイルの結合方法
下記のようなコマンドで結合します。
```
copy /b C:\WORK\*_part* C:\WORK\sample.zip
```

### あとがき
テストでは10MBのファイルを1MBに分割できるかを確認したのみですが
時間のある時に100GBを超えるファイルを処理できるかも確認しようと思います。
javascriptでのソート機能について

## はじめに
この記事ではtableタグの一覧をjavascriptでソートするだけの機能を備忘録もかねて記載しています。

## ソース内容
百聞は一見に如かず、ソースは以下の通りです。
```index.html
<html>
<head>
<meta charset="utf-8">
<title>タイトル</title>
</head>
<body>
    <table>
        <thead>
            <tr>
              <th>name</th>
              <th>num</th>
              <th data-override="Score">price</th></tr>
          </thead>
          <tbody id="target_table">
            <tr>
              <td>りんご</td>
              <td>3個</td>
              <td data-override="disqualified">300円</td></tr>
            <tr>
              <td>なし</td>
              <td>2000個</td>
              <td>2億円</td></tr>
            <tr>
              <td>すいか</td>
              <td>1個</td>
              <td>500円</td></tr>
            <tr>
              <td>青春</td>
              <td>1回</td>
              <td>プライスレス</td></tr>
          </tbody>
     </table>
      
</body>
<script src="script.js"></script>
</html>
```

```script.js

// tableタグを取得
var target = document.getElementById("target_table");
var rowElements = target.rows;

// 取得したデータをpriceでソートする
var result =Array.from(rowElements).sort(function(line1, line2) {
    return (line1.cells[2].innerText < line2.cells[2].innerText) ? -1 : 1;  //オブジェクトの昇順ソート
});

// ソートしたデータを挿入（移動）
for(var i = 0; i < result.length; i++){
    target.appendChild(result[i]);
}

```

これで、以下の画像のようにpriceでソートされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616088/2b9ef734-22f1-e774-3279-7ebd99401fd6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616088/ce0648cf-0a56-6859-c181-ba4ccbca5ad2.png)

※単純に文字列で比較しているので、この順序になっている。
Laravel でCSVダウンロードと画面遷移を同時に行う方法

# 結果：セッションに入れる
セッションに入れてblade側でリダイレクト。

#### web.php
```php
// ダウンロードできるようにルートを書いておきます。
Route::get('/download-csv', [App\Http\Controllers\HomeController::class, 'downloadCsv'])->name('download.csv');
```
#### CsvController
```php
use Illuminate\Support\Facades\Session;

// exportCsv()にCSV出力の処理を書いてます。
$file = $this->exportCsv($request);
// セッションに入れる
Session::flash('csv.file', $file);
```

#### HomeController
```php
public function downloadCsv(Request $request)
{
    $file = $request->get('file');

    if ($file) {
        return response()->download(public_path($file))->deleteFileAfterSend();
    }
}
```

#### app.blade.php
```php
// headに追加
...
<head>
    @if(Session::has('csv.file'))
        <meta http-equiv="refresh" content="0.5;url={{ route('download.csv', ['file' => Session::get('csv.file')]) }}">
    @endif
</head>
```


# おわりに

結構苦労したのでどなたかのお役に立てると嬉しいです。
yarnコマンド実行時のエラー「code: 'ERR_OSSL_EVP_UNSUPPORTED'」の解決法

## ファイル構成
- index.html
```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    ...
  </head>
  <body>
    ...
    <script src="dist/bundle.js"></script>
  </body>
</html>

```

- package.json
```json
{
  "license": "MIT",
  "scripts": {
    "webpack": "webpack"
  },
  "dependencies": {
    "webpack": "5.22.0",
    "webpack-cli": "4.5.0"
  }
}

```

- webpack.config.js

```js
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
};
```

他にも少しディレクトリとファイルがありますが今回重要だと思うのは上記ファイルになりますので他は割愛させて頂きます。


## 概要
```zsh
$ yarn webpack --mode=development
```
ターミナル上で上記を実行してdistディレクトリを作成して、bundle.jsファイルを作ろうとしました。
そうしたら、下記のようなエラーが出ました。

```zsh
$ yarn webpack --mode=development
yarn run v1.22.19
$ webpack --mode=development
node:internal/crypto/hash:71
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported


〜〜〜〜省略〜〜〜〜


  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

Node.js v19.0.0
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

```

その後色々とエラーコードを検索してweb上で調べまくっていたら全く同じエラーのstack overflowのページにたどり着きました。
- [Webpack build failing with ERR_OSSL_EVP_UNSUPPORTED [duplicate]](https://stackoverflow.com/questions/69394632/webpack-build-failing-with-err-ossl-evp-unsupported)

そして判明したことは、
<strong>「Node.js17以降のバージョンではOpenSSLの関係でWebpack 4.xは動作できなくなっている」</strong>
ということでした。

自分が上記のコマンドを入力した時のNode.jsのバージョンは19.0.0でした。
そしてstack overflowのページでは「16.13.1にダウングレードするとうまくいきました」とのコメントがあったので、自分も同じく16.13.1にダウングレードした所、無事にコマンドが通りました。

```zsh
$ yarn webpack --mode=development
yarn run v1.22.19
$ webpack --mode=development
asset bundle.js 4.03 KiB [emitted] (name: main)
runtime modules 670 bytes 3 modules
cacheable modules 92 bytes
  ./src/index.js 36 bytes [built] [code generated]
  ./src/bar.js 56 bytes [built] [code generated]
webpack 5.22.0 compiled successfully in 154 ms
✨  Done in 2.31s.

```

ということで無事にdistディレクトリにbundle.jsファイルが出来ました。
自分の備忘録として書きましたが、もし誰かの参考になれば幸いです。
お読み頂きましてありがとうございました。

---
ちなみに自分は今回Node.jsをダウングレードするにあたりNode.jsのバージョン管理ツールの「N」を使用しました。
参考サイト：[n (Node.js管理) のインストール手順](https://qiita.com/tora_oba/items/2761452fe8c2b0035ba0)

### 今回参考にさせて頂いたサイト
- [Webpack build failing with ERR_OSSL_EVP_UNSUPPORTED [duplicate]](https://stackoverflow.com/questions/69394632/webpack-build-failing-with-err-ossl-evp-unsupported)
- [n (Node.js管理) のインストール手順](https://qiita.com/tora_oba/items/2761452fe8c2b0035ba0)
CheerpJのJavaからブラウザベースへの移行が、エンタープライズJavaアプリケーション向けリモート・デスクトップ・ソリューションを凌駕する理由

![My-project-1-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486144/0dfbce83-bccc-09f9-4bae-b3abab4c3b90.jpeg)
[]()
現在のめまぐるしい世界では、アプリケーションへのリモート・アクセスは必需品となっており、ユーザーはどこからでも、どのデバイスからでもソフトウェアやデータにアクセスできるようになっている。Javaアプリケーションへのリモートアクセスに関しては、[JavaからJavaScriptとWebAssemblyへのコンパイラであるCheerpJと](https://leaningtech.com/cheerpj/)、Citrixのようなリモート・デスクトップ・ソリューションの2つがよく使われる選択肢です。このブログ記事では、CheerpJがデスクトップJavaアプリケーションにアクセスするための優れた選択肢である理由を探ります。

**1 - インストールの手間なし**
リモートデスクトップソリューションと比較してCheerpJを使用する主な利点の1つは、インストールの必要がないことです。CheerpJでは、ユーザーは[追加のソフトウェアやプラグインをインストールすることなく、ウェブブラウザから直接Javaアプリケーションにアクセスすることができます](https://leaningtech.com/does-java-still-work-in-chrome-and-edge-introducing-cheerpj-as-the-solution/)。これにより、複数のデバイスやプラットフォームにリモートデスクトップソリューションを展開する際にしばしば発生する複雑さや互換性の問題が解消されます。

**2 - プラットフォームの独立性**
CheerpJのウェブベースのアプローチは、比類のないプラットフォーム独立性を提供します。AOTコンパイラのパワーを活用し、JavaバイトコードをJavaScriptブラウザで読み取り可能なコードに変換し、最新のウェブブラウザからアクセスできるようにします。対照的に、リモート・デスクトップ・ソリューションは通常、クライアント・ソフトウェアのインストールを必要とし、特定のオペレーティング・システムに限定されることが多い。CheerpJのマイグレーション・ソリューションは、Javaアプリケーションのプラットフォーム非依存性を可能にし、シームレスなユーザー体験を保証します。

**3 - セキュリティの強化**
セキュリティは、リモートアプリケーションアクセスの重要な側面です。CheerpJは堅牢なセキュリティフレームワークを提供し、ウェブブラウザ固有のセキュリティ機能を利用して、不正アクセスを防止し、機密データを保護します。CheerpJは、ブラウザのサンドボックス内でJavaアプリケーションを直接実行するため、ネットワークレベルのセキュリティ対策に依存する従来のリモート・デスクトップ・ソリューションに関連する潜在的な脆弱性を排除します。ブラウザのセキュリティメカニズムを活用することで、CheerpJは機密情報の安全性を確保し、機密データを扱う組織にとって好ましい選択肢となります。

**4 - 優れたパフォーマンス**
パフォーマンスは、CheerpJが優れているもう一つの分野です。JavaバイトコードをJavaScriptに変換することで、CheerpJは最適なランタイムパフォーマンスを保証し、待ち時間を最小化し、応答性を最大化します。このアプローチは、画面共有やネットワーク集約的なリモートデスクトッププロトコルの必要性を排除し、その結果、キビキビとしたシームレスなユーザー体験をもたらします。ユーザーは、物理的な場所に関係なく、リアルタイムでリモートからJavaアプリケーションを操作できるため、生産性と効率が向上します。

**5 - 費用対効果と拡張性**
CheerpJは、Javaアプリケーションのリモートアクセスのためのコスト効率の高い代替ソリューションを提供します。Javaアプリケーションをブラウザベースのアプリケーションに近代化する技術として、従来のリモート・デスクトップ・ソリューションに関連する高価なインフラストラクチャやライセンス費用が不要になります。導入とメンテナンスのオーバーヘッドが大幅に削減されるため、あらゆる規模の組織にとって理想的な選択肢となります。さらに、CheerpJのスケーラビリティは、ハードウェアへの追加投資を必要とすることなく、ユーザー需要の増加に対応するJavaアプリケーションの楽なスケーリングを可能にします。

**結論**
移植性とリモートJavaアプリケーション・アクセスの領域において、CheerpJのJava-to-browserソリューションは、Citrixのようなリモート・デスクトップ・ソリューションと比較すると、明らかな勝者として浮上する。そのインストール不要の性質、プラットフォーム非依存性、強化されたセキュリティ、優れたパフォーマンス、費用対効果により、個人と組織の両方にとって魅力的な選択肢となっている。CheerpJを使えば、ブラウザーからJavaアプリケーションにアクセスすることは、手間のかからないシームレスな体験となり、ユーザーはいつでもどこからでも生産的になることができます。

ですから、Javaアプリケーションにリモートアクセスするための信頼できる効率的な方法をお探しなら、CheerpJは間違いなく検討すべきソリューションです。ウェブベースのテクノロジーの力を取り入れ、どこからでもアクセスできるJavaアプリケーションの真の可能性を引き出してください！

https://leaningtech.com/legacy-modernisation-jp/

引用元：https://leaningtech.com/why-cheerpj-out-performs-remote-desktop-solutions-for-enterprise-java-applications/
ソフトウェア開発の成功への道：SDLCの6つの基本フェーズ

![what-is-SDLC-jp.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512901/46a89c5b-0ec9-f422-c1b7-4e4b147108d5.jpeg)

ソフトウェア開発は、スムーズなプロセスとタイムリーなプロジェクト完了が不可欠です。その鍵はSDLC（Software Development Life Cycle）にあります。このプロセスは、ソフトウェア開発を成功させるためのステップバイステップの計画です。

**要件の収集と分析**
まず、プロジェクトの目標と制約を明確にし、顧客やステークホルダーからの要件を収集・分析します。これがプロジェクトの方向性を確立する第一歩です。
**UI/UXデザイン**
ユーザーがソフトウェアを楽しんで使えるようにすることが重要です。ユーザーインターフェース（UI）とユーザーエクスペリエンス（UX）の設計は、このフェーズで行われます。
**ソフトウェア開発**
設計が完了すると、実際のソフトウェア開発が始まります。プログラミング言語を使用して、コードが書かれます。
**ソフトウェアテスト**
開発が完了すると、ソフトウェアの品質を確保するためのテストが行われます。バグやエラーを特定し、修正します。
**展開**
テストが成功したら、ソフトウェアは実際の環境に展開されます。ユーザーが利用できるようになり、価値を提供します。
**運用と保守**
ソフトウェアが運用され続けるために、定期的な保守作業が行われます。新しい機能の追加やバグの修正が含まれます。

これらのフェーズを効果的に管理することは、プロジェクトの成功に不可欠です。SDLCを理解し、実践することで、ソフトウェア開発プロジェクトをスムーズに進め、品質の高い成果物を提供できます。詳細については、[こちら](https://ltsgroup.tech/jp/blog/sdlc-software-development-life-cycle-definition-phases/)をご覧ください。

Website: [https://ltsgroup.tech/jp/](https://ltsgroup.tech/jp/)
Tel: (+84) 24-6660-7474
Mail: contact@ltsgroup.tech
Fanpage: [https://www.linkedin.com/company/lts-group-vietnam/](https://www.linkedin.com/company/lts-group-vietnam/)
AWS Terraform のエラー - CloudWatch のサブスクリプションにLambda実行権限を与える

# エラー

> Error: putting CloudWatch Logs Subscription Filter (****):
>  InvalidParameterException: Could not execute the lambda function. Make sure you have given CloudWatch Logs permission to execute your function.

# 解決

aws_lambda_permissionの指定で、ソースとなるCloudWatchのログのARNは、以下のようにワイルドカード指定が必要だったみたいだ

Terraform公式より

```tf
resource "aws_lambda_permission" "logging" {
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.logging.function_name
  principal     = "logs.<REGION>.amazonaws.com"
  source_arn    = "${aws_cloudwatch_log_group.default.arn}:*"
}
```




# 確認手段

AWSマネージメントコンソールで、CloudWatchのログを選んでサブスクリプション登録・Lambdaへの関連付けをおこなうと、Lambdaの画面でリソースベースの許可状態を見られる

Lambda関数 > 設定 > リソースベースのポリシーステートメント 

この設定をTerraformでも踏襲した


# 参考


Lambda でのリソースベースのポリシーの使用
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/access-control-resource-based.html

Terraform公式

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
JDKビルド備忘録[Ubuntu 22.04]

# おねがい
この記事を参考にしてビルドに失敗した方は後学のためにコメントをいただけますと幸いです。
質問にもお答えできる限りお答えしますので是非コメントを残してください。

# 環境
OS : Ubuntu 22.04.3 LTS

# ビルド対象JDK
- openjdk jdk17(Public archive)

https://github.com/openjdk/jdk17

# 手順
## 1. 資材ダウンロード
```
$ mkdir ~/work
$ cd ~/work
$ git clone git@github.com:openjdk/jdk17.git
```

## 2. ビルド用JDK配備
※すでにjavaコマンドが使えるなら不要
```
$ cd /usr/local/lib
$ sudo wget https://github.com/adoptium/temurin16-binaries/releases/download/jdk-16.0.2%2B7/OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz
$ sudo tar xf OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz
$ sudo rm OpenJDK16U-jdk_x64_linux_hotspot_16.0.2_7.tar.gz
$ vim ~/.bashrc
#########################
# 以下を追記
export JAVA_HOME=/usr/local/lib/jdk-16.0.2+7
export PATH=$JAVA_HOME/bin:$PATH
#########################
$ source ~/.bashrc
$ java --version
openjdk 16.0.2 2021-07-20
OpenJDK Runtime Environment Temurin-16.0.2+7 (build 16.0.2+7)
OpenJDK 64-Bit Server VM Temurin-16.0.2+7 (build 16.0.2+7, mixed mode, sharing)
```

## 3. 必要パッケージのインストール
※環境によって過不足が発生する可能性あり
```
$ sudo apt -y install build-essential autoconf make zip unzip file
$ sudo apt -y install libfreetype6-dev libcups2-dev libx11-dev libxext-dev libxrender-dev libxrandr-dev libasound2-dev libffi-dev libxt-dev libxtst-dev libfontconfig-dev
```

## 4. configureの適応
```
$ cd ~/work/jdk17
$ bash configure
```

## 5. ビルド実行
```
$ make images
```

## 6. 成果物確認
```
$ ./build/*/images/jdk/bin/java -version
openjdk version "17-internal" 2021-09-14
OpenJDK Runtime Environment (build 17-internal+0-adhoc.tabatad.jdk17)
OpenJDK 64-Bit Server VM (build 17-internal+0-adhoc.tabatad.jdk17, mixed mode, sharing)
```

# 苦労した点
- 不足しているパッケージがわからず、`bash configure`を実行して不足がでれば追加する手法を取らざるを得なかった。

# 参考
- OpenJDK jdk17 building.md

https://github.com/openjdk/jdk17/blob/master/doc/building.md
雑魚のためにAWS Copilotで設定できるCPUリソースを調査した

# はじめに

※2023年10月3日の話です

AWS Copilotは手動でAWSのサービスを連携させる必要がなくAWSのサービスを連携させることができます．  
manifestファイルに使いたいリソースについて書いておいて`copilot svc deploy`とかってコマンド叩くと全部組んでくれます．
~~平易な言葉で書こうと思いましたが，違ったらごめんなさい．雑魚なので許してください．~~

そんなこんなで使っていたのですが，CPUとmemoryの設定が公式ドキュメント通りにしてもうまく行かなかったので調査してみました．

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-cpu-memory-error.html

<b>※これが自分の環境だけなのか，他の全ての環境に当てはまるのかはわかりません．</b>

## 追記

自分が利用していたのが，`Request-Driven Web Service`だったのですが，公式ドキュメントにCPUとmemoryの選択肢が載っていました．さすがAmazonさん．

https://docs.aws.amazon.com/ja_jp/apprunner/latest/api/API_InstanceConfiguration.html#apprunner-Type-InstanceConfiguration-Cpu


# やったこと

manifestファイルのCPUとmemoryの値を変更させながらデプロイして，デプロイがうまくいくかどうか試しました．

結果はこの通りです．
※CPU=8192以上は個人的に使わないなと思ったのでテストしていません．

| CPU   | memory                   | 結果 |
|-------|--------------------------|------|
| 256   | 512, 1024                | OK   |
| 512   | 512                      | NG   |
|       | 1024                     | OK   |
|       | 2048, 3072               | NG   |
| 1024  | 1024                     | NG   |
|       | 2048, 3072, 4096         | OK   |
|       | 6144                     | NG   |
| 2048  | 2048, 3072               | NG   |
|       | 4096, 6144               | OK   |
|       | 8192, 10240              | NG   |
| 4096  | 8192, 10240, 12288       | OK   |
|       | 14336, 16384             | NG   |


CPU対memory=1:2~4という比率でデプロイできました．
法則性だけで言えば，CPUの2倍のmemory量に設定すれば動く，くらいですかね．

ちなみに，14336, 16384はそもそも書き方が違う，というエラーが返ってきました．
~~エラー文を記録しておけばよかった．~~

そもそものmemory選択肢としては```512 / 1024 / 2048 / 3072 / 4096 / 6144 / 8192 / 10240 / 12288```しかないようです．
チンパンプレーで存在しない`memory=5120`に設定したときに吐き出されたエラー文がそう言っていました．

```bash
Resource handler returned message: "1 validation error detected: Value
'5120' at 'instanceConfiguration.memory' failed to satisfy constraint
: Member must satisfy regular expression pattern: 512|1024|2048|3072|4
096|6144|8192|10240|12288
```

# おわりに

Copilotの制約なのか，manifestファイルの他の設定値の制約なのか，アプリの内容の制約なのか，2023年10月3日の仕様なのかは謎のままです．

詰まっている人がいれば何か参考になりますように．
Javaで「指定した位置に文字列を挿入する」の動作を確認してみた

# 概要

Javaで「指定した位置に文字列を挿入する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/stringbuilder/index2.html

# 実装

以下のファイルを作成しました。
```JSample2_1.java
class JSample2_1{
  public static void main(String[] args){
    StringBuilder sb = new StringBuilder();
    sb.append("ABC");
    sb.append("DEF");
    System.out.println(sb.toString());

    sb.insert(2, "XYZ");
    System.out.println(sb.toString());
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample2_1.java 
$ java JSample2_1 
ABCDEF
ABXYZCDEF
```

# まとめ

何かの役に立てばと。
chrome拡張機能作り方

# manifest.json作成
まずフォルダを作成します(名前何でも良し)
そこの中に`manifest.json`を作ります。
中身

```json:manifest.json
{
  "name": "サンプル",
  "version": "1.0",
  "manifest_version": 3,
  "description": "Sample Chrome Extension",
    "icons": {
    "16": "icons/16.png",
    "48": "icons/48.png",
    "128": "icons/128.png"
  },
  "content_scripts": [{
    "matches": ["https://www.google.com/*"],
    "js": [
      "alert.js"
    ]
  }]
}
```

# alert.js作成
alert.jsを作成し開きます。
そしてこう入れます。

```javascript:alert.js
window.alert('入れたい言葉');
```

# icon作成
好きな画像を三枚用意して1つ目は128.pngという名前で保存。
2つ目は48.pngという名前で保存。
3つ目は16.pngという名前で保存。
そして
128.pngを128×128pxにして保存。
48.pngを48×48pxにして保存。
16.pngを16×16pxにして保存。
フォルダの中にiconsというフォルダを作ります。
そして
128.pngと48.pngと16.pngをiconsフォルダに入れます。
これokです
今回の拡張機能の仕組みはgoogle.comにアクセスすると
上にアラート（ポップアップ）が出てきます。
# 導入仕方
`chrome://extensions/`
に行って
まずデベロッパーモードのスイッチをオンにします。
![Screenshot 2023-10-06 07.27.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569677/91684552-3d16-f70e-b5ce-15d94981c0dd.png)
その次に上に
![Screenshot 2023-10-06 07.28.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569677/17934e1b-49c7-8323-b8d2-c50f14c78be9.png)
これがあるのでこれを押してフォルダのインポートをします。
そうすると追加されるはずです

## 次の記事

https://qiita.com/simasimanekosan/items/958cd445c951f9a93c94
ping使用詳細説明

windowsにはコマンド「ping/?」でpingの用法を検索し: 
Usage: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
            [-r count] [-s count] [[-j host-list] | [-k host-list]]
            [-w timeout] [-R] [-S srcaddr] [-c compartment] [-p]
            [-4] [-6] target_name

Options:
    -t             Ping the specified host until stopped.
                   To see statistics and continue - type Control-Break;
                   To stop - type Control-C.
    -a             Resolve addresses to hostnames.
    -n count       Number of echo requests to send.
    -l size        Send buffer size.
    -f             Set Don't Fragment flag in packet (IPv4-only).
    -i TTL         Time To Live.
    -v TOS         Type Of Service (IPv4-only. This setting has been deprecated
                   and has no effect on the type of service field in the IP
                   Header).
    -r count       Record route for count hops (IPv4-only).
    -s count       Timestamp for count hops (IPv4-only).
    -j host-list   Loose source route along host-list (IPv4-only).
    -k host-list   Strict source route along host-list (IPv4-only).
    -w timeout     Timeout in milliseconds to wait for each reply.
    -R             Use routing header to test reverse route also (IPv6-only).
                   Per RFC 5095 the use of this routing header has been
                   deprecated. Some systems may drop echo requests if
                   this header is used.
    -S srcaddr     Source address to use.
    -c compartment Routing compartment identifier.
    -p             Ping a Hyper-V Network Virtualization provider address.
    -4             Force using IPv4.
    -6             Force using IPv6.
OpenSSH Authentication Agentでパスフレーズの省略をしているはずなのに省略にならない

# 問題
OpenSSH Authentication AgentでSSH接続時にパスフレーズの省略をしているはずなのに、C#で作成したプログラムからSFTPでファイルを送ろうとするとパスフレーズの省略が上手くいかないという問題が発生しました。

## 詳細
以下のような現象
- 秘密鍵へのアクセス権があるユーザーで、PowerShellやコマンドプロンプトを起動し、SSH接続した場合はパスフレーズを省略して接続できる
- C#でプロセスを起動させ、SFTPコマンドで接続しようとするとパスフレーズを入力しなければならない

# 解決策
どうやらLoadUserProfileをTrueにしていないとOpenSSH Authentication Agentに登録した秘密鍵とパスフレーズを取得できないらしい。
``` powershell
p = New Process()
p.StartInfo.UserName = 秘密鍵へのアクセス権のあるユーザー
p.Password = ユーザーのパスワード
p.FileName = プロセスで起動させたいファイルパス
p.LoadUserProfile = True
```

# 今回の教訓
手動でPowerShellを開いた場合と、作成したプログラムから開く場合では、権限が異なる場合がある。
これは覚えておきましょう。
Railsでバッチ処理が動いていなかった問題を解決したのでメモメモ

どうもこんにちは。

今回は以下の記事で紹介した`delayed_job`で実装したバッチ処理が動かなかった問題を解決したので、備忘録としてまとめたいと思います。

バッチ処理の基本的な手順は以下の記事をご覧ください。

https://qiita.com/PDC-Kurashinak/items/dd852f001914def58e83

# バッチ処理って？

そもそものバッチ処理についておさらいします。

バッチ処理とは、決まった時刻や時間間隔で行う処理のことです。

例えば、「10分間隔でメール送信ジョブを動かす」「決まった時間に過去のデータを削除する」などですかね。

# 今回のエラーについて

今回のエラーは、「決まった時間に実行したいジョブが実行されなかった」というものです。

## 概要

`config/schegule.rb`に以下のように記述したコードが動きませんでした。

```ruby
every 10.minute do
  runner "Batch::WatchDelayedJob.job_destroy"
  runner "Batch::WatchDelayedJob.send_alert"
end
```

## エラー時の状況

AWS ElasticBeanstalkから取得したログから判断した状況について説明します

### cronの実行状況

cronの実行は問題なく動作していました。

`bundle exec bin/rails runner -e staging '\''Batch::WatchDelayedJob.job_destroy'\''`が10分おきに実行されていたので、「`schegule.rb`の記述は反映されているな」と判断できます。

### crondサービスの動作確認

amazon Linuxではcronサービスを`crond`と呼ぶらしいです。

ElasticBeanstalkのRailsコンソールにSSH接続して、crondサービスの動作状況を確認しました。

```terminal
sudo systemctl status crond
```

実行結果

```
# sudo systemctl status crond
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since 月 2023-10-02 08:22:26 UTC; 1 day 1h ago
 Main PID: 2249 (crond)
   CGroup: /system.slice/crond.service
           └─2249 /usr/sbin/crond -n
```

Activeと記載されているので、問題なく動作していそうですね。


### rails runnerの動作

次にElasticBeanstalkの実行環境にSSH接続して、直接`rails runner`を実行してみました。

実行したコマンドは以下です。

```terminal
bundle exec bin/rails runner Batch::WatchDelayedJob.job_destroy
```

これを実行した時に、期待していた処理が正常に動きました。

### 原因箇所の特定

以上の２箇所の状況から、「`schegule.rb`で予約したコマンドが、crondサービスで実行されるものの、`rails runner`として実行できていないのでは？」という仮説を立てました。

そのため、私はこう考えました。

「**crondサービスを使って、関節的に実行環境のターミナルでrails runnerを実行すればいいじゃん！**」ということに気づきました。

なぜなら、「直接であれば`rails runner`のコマンドを実行できるから。」です。

## 解決

`config/schegule.rb`に以下のようにコードを記述しました。

```ruby
every 10.minute do
  command "cd /var/app/current && export $(cat /opt/elasticbeanstalk/deployment/env) && bin/rails runner Batch::WatchDelayedJob.job_destroy"
  command "cd /var/app/current && export $(cat /opt/elasticbeanstalk/deployment/env) && bin/rails runner Batch::WatchDelayedJob.send_alert"
end
```

`command`とすることによって、実行環境のターミナルを叩くことができます。

`cd /var/app/current`はソースコードの場所です。

`export $(cat /opt/elasticbeanstalk/deployment/env)`は環境情報を吐き出しています。

`bin/rails runner Batch::WatchDelayedJob.send_alert"`で処理したいジョブのコマンドを叩きます。

以上の流れで、バッチ処理が正常に動くようになりました。

# まとめ

今回のエラーは半日くらい戦っていました。

crondサービス上でrunnerコマンドが動かないのは謎なので、調査をしていきたいと思います。

記事を書いていて思いましたが、日に日に原因の切り分けが上手くなってきているような。。。

以上
AWS SAMでDynamoDB使う時のテンプレート

# はじめに
SAM template使う時、DynamoDBの定義に関して毎回調べてる気がするのでここに残しておきます。

# コード

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  description

Globals:
  Function:
    Timeout: 30
    MemorySize: 128

Resources:
  SomeFunction:
    Type: AWS::Serverless::Function
    Metadata:
      BuildMethod: go1.x
    Properties:
      CodeUri: some_function/
      Handler: bootstrap
      Runtime: provided.al2
      Architectures:
        - x86_64
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref SampleTable
      Environment:
        Variables:
          SAMPLE_TABLE: !Ref SampleTable

  SampleTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: 'SampleTable'
      AttributeDefinitions:
        - AttributeName: 'id'
          AttributeType: 'S'
        - AttributeName: 'value'
          AttributeType: 'N'
      KeySchema:
        - AttributeName: 'id'
          KeyType: 'HASH'
        - AttributeName: 'value'
          KeyType: 'RANGE'
      BillingMode: PAY_PER_REQUEST

Outputs:
  SomeFunction:
    Description: "First Lambda Function ARN"
    Value: !GetAtt SomeFunction.Arn
```
Microsoftのテクニカル サポートがすばらしかった件

# Autehnticatorのアカウントをスマホから誤って削除してしまった

今回記事にするのは、自分の失敗談です(笑)
誰でもミスはするものですが、ミスをしたときは本当にパニックになって、Web記事を調べたりして対処方法を探すものですが、自分の場合、結果的にMicrosoftテクニカル サポートに連絡することで解決しました。
このテクニカル サポートの対応がとてもすばらしいかったので記事にしたいと思いました。

## 発端
何が起きたかと言えば、「Autehnticatorのアカウントをスマホから誤って削除してしまった」です。
自分はMicrosoft 365 Business Standard を契約して利用していて、Microsoft Authenticatorを使ってアカウントの認証をしています。

ここ最近MFA認証を使用する機会が多く、スマホのAuthenticatorのアカウントが増えてきたのですが、すでに使わなくなったものもありました。
そこで整理しようとしていたところ、誤ってMicrosoft 365の認証アカウントを削除してしまいました。

## ログインできない
どんな状態になっていたか。
1. Microsoft管理のアカウントセキュリティとしてAuthenticatorのみが登録されている
1. ログインをしようとすると認証のためスマホ側でAuthenticatorでの処理が必要となる
1. ところがスマホにそのアカウントがない
1. 結果認証処理ができずにログインできなくなった

以下の画像の電話がなく、Authenticatorだけの状態でした(これは復帰後の画像)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/f46b0392-06c3-27a1-90ee-54f926d54ff7.png)

本当に慌てました。
自分のPC上のMicrosoft OneDriveも当然使えないです。
何か別の認証はあるのかといろいろとWeb記事を探しました。
該当するものは見つかりませんでした。

Web記事でよく見かけたのは、Microsoft管理画面から新しい認証方法を登録する方法でした。それができないから困っているのに・・・。
対応するためには、Microsoft管理画面のアカウントセキュリティから認証方法の情報をリセットすればいいというのは分かるのですが、それをどうすればできるのかが分からなかったです。
今回削除してしまったアカウントが管理者アカウントだからです。

もう一つ思いついたのは、別の認証方法(SMSなど)を登録できればと思いましたが、そのためにはAuthenticatorでの認証が通過しないとできない。

## 本家に頼る！
こうなったらやっぱりMicrosoftに頼るしかないと思い検索をかける。
Microsoftのサイトはたくさんありすぎで、どこからどこにたどればいいのか分からず、それでもなんとかたどりついたのがこちらでした。
[国または地域別に Microsoft 365 for business サポートの電話番号を検索する](https://learn.microsoft.com/ja-jp/microsoft-365/admin/support-contact-info?view=o365-worldwide#japan)
ここにテクニカルサポートの番号が掲載されていました。
Microsoft 365 Business Standard用の番号にかけます。時間は20時ごろ。
こういうのはなかなか電話はつながらないものだから・・・と最初からあきらめモードでかけたところ、すぐに電話がつながりました！
時間帯もあったとは思いますが、電話がつながるというだけでうれしいものです。

## 状況説明
Authenticatorのアカウントを削除してしまったこと、認証できなくなったことを伝え、本人確認を済ませると、「受付ができたので、受付の順番に担当者から連絡します」とのこと。時間帯もあり翌日になるとのことでした。
この時の対応はとても丁寧で安心して眠れました。

## 翌日
電話がお昼ごろにありました。
その際自分が打ち合わせ中だったため、12時過ぎのかけ直しをお願いいたしましたが、快諾という感じの受け答え。
しかも、本当に12時すぐくらいに再び電話をもらえました。
サポート体制がしっかりしていると感じるところです。
対応してくださった方の話し方も丁寧。
手続きに海外の部署の承認が必要なものだということで、その手続きに入ってよいかとの確認、アカウントの本人確認となり、早ければ本日中、遅くとも3日以内に対応しますとのこと。
こういうときいつまで待てばいいのかなぁとやきもきすることが多いですが、「本日夕方に処理を実行する際にご連絡します。もし明日以降の処理となった場合も、本日夕方にお電話してそれをお伝えいたします」との言葉。
相手を心配させないそうした対応フローというのがきちんとできているのを実感！

夕方改めてお電話をいただき、無事にアカウント復旧。
サポートなのだから当たり前のことかもしれませんが、本当に困っているときのこういうサポートの丁寧や受け答えは感謝でいっぱいです。
ServiceNow の 3種類のインシデントの UI の比較

例えば itil ユーザーがインシデントを閲覧する場合、主に下記3種類のUIがあります。
Tokyo Version の時に各UIの違いをわかる範囲でまとめてみました。
1. UI16 (Classic UI, Platform UI, Core UI)
2. Next Experience UI (Classic UI, Platform UI)
3. Configurable Workspace

### 比較表
各UIの名前をそれぞれ「UI16」、「Next」、「Conf」と省略して記載しています。 

| 観点 |「UI16」|「Next」 |「Conf」|
|:-:|:-:|:-:|:-:|
| フォームに表示できる項目数 | 多い | 多い | 少ない |
| ログイン直後のスタートページ | 最後に見たダッシュボード、 またはホームページから選べる。ただし、Tokyo ではホームページは非推奨 | 自由に選べる | 自由に選べる |
| Contextual search | フォームで使用できる | フォームで使用できる | Agent assistで使用できる |
| 会話機能 | Connect chat を使用 | Side barプラグインを使用 | Side barプラグインを使用 |
| レコードに紐づかない会話 | Tokyo では非推奨だが可能 | レコードに紐づく会話のみ可能 | レコードに紐づく会話のみ可能 |
| 1つのUIで業務ができるか | できる | できる | リストに承認やナレッジベース等がない。 そのため、上位のロール保持者の業務はワークスペースだけでは完結しない。 できることを目指すには業務に合わせてワークスペースのカスタマイズが必要 |
| 他のUIへ移動できてしまうか | 移動しない | ヘッダのメニューから簡単に「Conf」も見ることができてしまう。 下記の対策が必要 |  ヘッダのメニューから簡単に「Next」も見ることができてしまう。 下記の対策が必要 |
| ドキュメント | 充実 | 充実 | 少ない |
| カスタイズに必要な工数 | 作りが比較的シンプルなため少なめ | 作りが比較的シンプルなため少なめ | 作りが比較的複雑なため多め |
| ATF対応 | あり | あり | なし |

なお、UI16 を使うことに決定した場合、新しいUIへの切り替えを促す画面がadmin 権限を持つユーザーに対して表示されるのを防ぐ必要があります。（参考）
[インスタンスのアップグレード後に Next Experience のようこそ画面をオフにする](https://docs.servicenow.com/ja-JP/bundle/tokyo-platform-user-interface/page/administer/navigation-and-ui/task/remove-welcome-splash-screen.html "ServiceNow 製品ドキュメント")

### 補足
他のUIへ移動できてしまうか、の対策について。

#### Next Experience UI を使用の場合
下記のいずれかの対策が必要です。
- ワークスペースを非表示にする。
- ワークスペースのフォームレイアウトやフォームアクション、関連リスト等をNext Experience UIと同様にしておく。
- ワークスペースを使用しないように周知する。

#### Configurable Workspace を使用の場合
下記のいずれかの対策が必要です。
- Next Experience UI のインシデントモジュールを非表示にする。
- Next Experience UI のフォームレイアウトやUIアクション、関連リスト等をワークスペースと同様にしておく。
- Next Experience UI を使用しないように周知する。

弊社ブログへも[同様の記事](https://alpcom.co.jp/blog/20231004/?utm_source=Qiita&utm_medium=post&utm_campaign=ysi&utm_id=20231004)を投稿しております。
GitHub上で、マージした内容をrevertする

## こんな時に

- 誤ったブランチにマージしてしまった！ピンチ！という時

## やること

- revertしたいPull requestを開いて、画面下のほうにある「Revert」ボタンを押下すると、revert用のPull requestが自動で作られる

## 学んだこと

- Pull requestの内容をまるっと取り消したい時は、コードを開かなくてもGitHub上で完結するので便利ですね
ubuntu(virtual box)にphpMyAdminをインストールしてみた

参照サイト
https://www.yokoweb.net/2020/08/16/ubuntu-20_04-phpmyadmin-install/


# apache2をインストール・設定する
## apache2をインストールする
```terminal:terminal
sudo apt install apache2
```

## fqdn.confを生成する
```terminal:terminal
sudo vi /etc/apache2/conf-available/fqdn.conf
```
```conf:/etc/apache2/conf-available/fqdn.conf
ServerName mysqlserver
```




## fqdn.confの設定を反映させる
```terminal:terminal
sudo a2enconf fqdn
systemctl reload apache2
```


## 動作確認する
### コマンド
```terminal:terminal
sudo apache2ctl configtest
Syntax OK
```
### webブラウザ
http://localhost/

It works!が表示されればOK



# phpをインストール・設定する
## phpをインストールする
```terminal:terminal
sudo apt install php libapache2-mod-php
```

## phpがインストールできたか確認する
```terminal:terminal
php -v
PHP 8.1.2-1ubuntu2.14 (cli) (built: Aug 18 2023 11:41:11) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.2-1ubuntu2.14, Copyright (c), by Zend Technologies
```

## 動作確認する
### info.phpを生成
```terminal:terminal
sudo vi /var/www/html/info.php
```
```php:/var/www/html/info.php
<?php
  phpinfo();
?>
```
### webブラウザ
http://localhost/info.php

PHPの情報ページが表示されればOK




# phpMyAdminをインストール・設定する
## phpMyAdminをインストールする
```terminal:terminal
sudo apt install phpmyadmin
```
- 自動再設定するwebサーバーはapache2を選ぶ
- dbconfig-commonで設定しますかははいを選ぶ

## 動作確認する
### webブラウザ
http://localhost/phpmyadmin/

phpMyAdminのログインページが表示されればOK
PHP勉強記録(1日目)

<h1>1.はじめに</h1>

今日から記録として、その日自分がした勉強の記録を残していこうと思います。
途中から始めようと思ったので、初歩からのスタートではないのですが...
現在Udemyの教材などで勉強中！

<h2>2.PHPでのDB接続を共通化</h2>

```dbconnect.php
<?php
    $db = new mysqli('Host','Post','Username','Pass');
?>
```
```index.php
<?php
    require('dbconnect.php');
?>
```
毎回DBの接続の情報を記載するの手間かかるなぁと思っていた時にちょうど教材で解説してくれて助かった。
間違えそうな箇所はなさそうなので、一番最後に付ける;を忘れないように気を付ける。

<h2>3.見出し部分を一部だけ表示させる。</h2>

```index.php
<?php
    <h2><a href="sample01.php?id=<?php echo $hoge; ?>">
        <?php echo htmlspecialchars(mb_substr($hogehoge,0,50));?></a></h2>
?>
```

現在は一言投稿のようなものが出来る掲示板の作成しているが
長文が投稿された際に、一部分だけ表示させるのに使用する。
Internet-DraftのIETFへの提出方法

## 2023年10月3日時点での方法
* xml形式で執筆したI-Dを用意します。

* 以下のページにアクセスします。

https://datatracker.ietf.org/submit/

* xmlファイルを選択してアップロードします。

* サーバ側でアップロードされたファイルがチェックされ、結果が表示されます。

* submitterをクリックし、自分の名前とメールアドレスが入力されたことを確認して、submitをクリックします。

* サブジェクトが"Confirm submission of I-D"からはじまる電子メールが送信されるので、そのメール本文に記載されるURLをクリックすると、web画面でconform submission and post I-Dが表示されるので、クリックします。

* webページが、I-Dのページに遷移し、internet-drafts@ietf.orgより、New Version Notificationからはじまるサブジェクトの電子メールが送られてきます。

## 実はマニュアルポストになってしまった
何度もI-Dを提出しているのですが、今回、その1件がmanual postになってしまい、上記の手順でpostされず、 IETF Secretariatが処理するとのメールが送られてきました。どこで操作を間違ったのか。Secretariatに、お手数をおかけすることになってしまったようです。なお、このI-Dは、無事、6時間後にpostされました。

## 実は、この数年で、I-D提出処理が、結構変わりました
そう、しょっちゅう、I-Dを提出するわけでもないので、些細な変化に気づかなかったりします。今、気づいたのは、

https://datatracker.ietf.org/

にログインせずに処理したこと。というのも、長い間、ログインはできず、比較的最近ログイン可能になったのでした。

大きく変わったのは、(1) xml2rfcのversionが2から3に変わったこと、(2)上記しましたが、アカウントを作成してログイン可能(前提)になったこと、です。xml2rfcのversionが変わった時は、それまでのxmlファイルが、xml2rfcで全く通らなくなってしまい、結構苦労しました。rfcの参照の方法も変わったと思います。

この文章、私の備忘録も兼ねて、何かわかれば追加・更新していきます。
「UMLモデリング入門」を読んで


[UMLモデリング入門](https://www.amazon.co.jp/dp/4822283585)を読んだので、感想を書く。

# 本自体について

タイトルに「UML」とあるがUMLの解説書というわけではなく、あくまで述べられている主題はモデリングに関してであり、UMLはそのための説明手段といった立ち位置だった。

「モデルとは何か」といった基礎的な部分から、3つの側面

- 静的モデリング
- 動的モデリング
- 機能モデリング

について、果ては業務分析〜要求設計までの仮想事例まで説明されてる。

# 感想

## 「もの−こと−もの」の構造

> 「ものごと」は「もの」と「もの」の関わりから生ずる「こと」なのです。
これが概念モデルでの意味のある最小単位と言えます。(中略)
最初の最小単位を足がかりにして他の「もの」や「こと」の構造を展開していきます。(p.127)

例としていくつか「こと」から派生して「もの」や「こと」を考えてみる。

- 「注文」: 「購入者」と「商品」
    - ギフト配送(購入者≠送り先)を考慮したいので「送り先」の概念を追加
    - 予約や受注生産の考慮が必要なので「注文タイプ」の概念を追加
- 「配送」: 「依頼主」と「送り先」
    - 「依頼主」と「送り先」のそれぞれには必ず住所があるので「住所」型を導入
        - 「住所」は郵便番号、都道府県、市区町村...からなるのでそれぞれを型として導入
    - 冷蔵や冷凍を考慮したいので「クール区分」の概念を追加
    - 梱包資材やサイズによるサービスの違いを考慮したいので「サービスタイプ」の概念を導入

こんな感じで、この考えはいざ概念モデリングをするぞとなったときに、取っ掛かりとして大変役立ちそうだと思った。

## 制約

> モデリング作業の大半は、多重度やロールも含めて、制約を明らかにして記述すること(p.121)

ドメイン駆動設計では、エンティティや値オブジェクトの生成時に制約を課すことで、無効な状態のインスタンスの存在を許さないようにする。「軽量DDDはアンチパターンに陥りやすい」とよく言われるが、この課すべき制約が十分にモデリングされていないがために、役に立たないエンティティや値オブジェクトのクラスが作られてしまうのが所以なのかなと感じた。

## 抽象だけじゃだめ

静的・動的・機能モデリングのいずれにおいても、シナリオ、特にアンチシナリオを考えることでモデルのデバッグができる。
（アンチシナリオ＝モデルの問題点を鋭くえぐるテストシナリオのこと）

考えた抽象から一度具体的な事例に落とし込んで考えてみることで、抽象側がより洗練される。

７章の記載の「クリーニング店のビジネス」をモデリングする演習を実際にやってみた際にもこれは感じた。
内容としては、施主へのインタビューと業務プロセス図から概念モデルを導出し、その後で別途示されたシナリオに沿ったオブジェクト図を書く、といったものだった。一度インタビューに沿って概念モデルを書いたのだが、オブジェクト図を書く段階になって、インタビュー中には一度も現れなかった「ドライクリーニング」というシナリオが初めて現れたため、一度書いた概念モデルを修正・拡張し「クリーニング種類」という型を導入した。

著者の別著である「UMLモデリングの本質」で述べられている「モデルの揺さぶり」はこのことなのであろう（本自体は読めていないが、説明文を読む限りではそう）。

最初に考えたモデルの元になったシナリオ（施主へのインタビューなど）が全てのケース・パターンを網羅しているとは限らないし、むしろしていないほうが多そう。
ドメインエキスパート自身が当たり前にやってることというのは、言われないとそれが特筆すべき事項だと気付かないものだし、門外漢であるモデラーがきちんと引き出してあげないといけないのだろうなと感じた。


### 意味波

この「モデルの揺さぶり」の話に、「[プログラマー脳](https://www.amazon.co.jp/dp/4798068535)」の13章で紹介されていた「意味波(semantic wave)」と近いものを感じた。

簡単に言うと「初心者が物事を理解する際の認知プロセスは、抽象→(アンパッキング)→具体→(リパッキング)→抽象、という流れである」といった内容なのだが、大抵のモデラーはモデリング対象のビジネスドメインにおいて初心者なので、当たらずとも遠からずかもしれない？

## その他印象に残った細かい点

- モデル＝ある人のある状況に関する明示された**解釈**
- ある概念の意味を正確に述べるのは困難、単独の概念でなく他の概念との関わりの中で意味を述べる。
- モデリングの段階では型か属性か固定するよりも必要に応じて相互に変換するのが自然
- べき型の概念
- ビジネスプロセスには「フィードバック回路」があり、知識が蓄積・再利用・再生産される
- ユースケース記述とそれに対するユースケース図の役割（ユースケース間の関係を図示する）
SAM で PuLPをローカル起動した時に苦労した話

# 背景
　AWS Lambdaを利用してバックエンド開発を行っていた際、ローカルサーバーを起動した時にエラーが発生。PythonランタイムでPuLPと呼ばれるライブラリを使用していたのだが、デプロイ環境やpytest時には問題なく計算できるのに、ローカルサーバー起動時のみ計算できない。

# 目的
　AWS SAM にてPythonランタイムのLambda関数でPuLPライブラリを用いる際、ローカルサーバーでのプログラム実行時に発生した`'PULP_CBC_CMD: Not Available`による`PulpSolverError`を調査した結果、原因と、間に合わせだが解決方法が分かったので共有する。
なお、私のデバイスのみでしか発生しない、もしくは解決しない可能性もある。

# 結論
## 原因
  `sam build`実行時に生成される`\.aws-sam\build\pulp\solverdir\cbc\linux\64\`内の`cbc`というファイルのパーミッションが`-rw-r--r--`になっている。
このcbcファイルは`-rwxr-xr-x`でなければ使用できず、`pip install pulp`等でインストールすると`-rwxr-xr-x`になっているはずのファイル。

## 解決方法
　下記のようにコマンドを実行。カレントディレクトリはプロジェクトディレクトリ直下。
```sh
sam build
chmod +x /.aws-sam/build/pulp/solverdir/cbc/linux/64/cbc
sam local start-api
```
Velocity Table Sort

        function sortTable(columnIndex) {
            var table, rows, switching, i, x, y, shouldSwitch;
            table = document.getElementById("sortableTable");
            switching = true;
            
            while (switching) {
                switching = false;
                rows = table.rows;
                
                for (i = 1; i < (rows.length - 1); i++) {
                    shouldSwitch = false;
                    x = rows[i].getElementsByTagName("td")[columnIndex];
                    y = rows[i + 1].getElementsByTagName("td")[columnIndex];
                    
                    if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
                        shouldSwitch = true;
                        break;
                    }
                }
                
                if (shouldSwitch) {
                    rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
                    switching = true;
                }
            }
        }
sudoについて

## 環境
Ubuntu20.4

## はじめに
root権限でないと実行できないコマンド、編集できないファイルがある場合、コマンドの先頭にsudoをつけて、root権限で実行することがよくあります。長らく、sudoはroot権限で実行できるようにするための専用コマンドだと思っていました。自分の場合、ほぼ、よのような用途でしか利用することがないため、その解釈で完全に間違っているわけではありません。しかし、root権限に限定してしか使えないといったことはありません。例えば、test1ユーザーでログインしていて、test2ユーザーとしてコマンドを実行したい場合も、sudoを使って実行することができます。別ユーザーとしてログインする場合は、suコマンドを使うことが多いかも分かりませんが、sudoを使うこともできます。sudoを使えば、ワンライナーで、コマンドが実行ができるといったメリットがあります。

## sudoersについて
sudoの設定を記述するファイルが、**/etc/sudoers**です。このファイルをエディタで編集する場合は、普通のエディタを使うのではなく、visudorといった、/etc/sudoers編集用の専用エディタを使います。viでも編集することはできますが、viの使用は推奨されていません。/etc/sudoersにはroot権限の実行に関する重要な設定が記述されています。重要なファイルであるため、編集機能が強化されています。visudorには文法チェック機能があり、/etc/sudoersに文法的な誤りがあると、更新ができないようになっています。

/etc/sudoersを直接にはあまり触りたくない場合は、/etc/sudoers.dの中に任意のファイルを作成して、/etc/sudoersの中に、つぎの１行を追加して、読み込むといった使い方もあります。こちらの方が一般的な使い方だと思います。
```/etc/sudoers
includedir /etc/sudoers.d
```

## sudoersの書き方
/etc/sudoersの中につぎの記述があります。この記述で、rootはどのユーザーでもログインができ、どのコマンドでも実行ができることになります。
```/etc/sudoers
root    ALL=(ALL:ALL) ALL
```

test1ユーザーがtest2ユーザーとしてログインして、コマンドを実行したい場合の設定です。
```/etc/sudoers
test1    ALL=(test2) ALL
```

本来なら、test1ユーザーがログアウトして、test2ユーザーでログインしなおして、コマンドを実行することになりますが、いちいち、そのような操作をするのは面倒です。
上記の設定を行うと、test1ユーザーでログインしている状態のままで、あたかも、test2ユーザーとしてログインしている状態を作れて、lsコマンドが実行できるようになります。それが下記のコマンドです。
```
$sudo -u test2 ls
```

つぎのようにすれば、test1ユーザーが、test2ユーザーとしてログインできて、実行できるコマンドは、lsコマンドだけに限定させることができます。このような設定を行うことで、test2ユーザーが他の人に実行させられては困るコマンドをブロックさせることができるため、セキュリティを高めることができます。
```
test1 ALL=(test2) /bin/ls
```
rails6でスタイルシートからwebpackerで管理されている画像にアクセスする

## はじめに
rails6を使って開発していて画像の扱いでかなりハマりました。
その時のメモを残します。

## 環境
`ruby 3.0.6`
`rails 6.1.7`
`webpacker 5.4.3`
`node 16.20.1`

## rails6のフロントエンド
rails6ではフロントエンドにデフォルトで`webpacker`が使われています。
`webpacker`は`webpack`をラップしたライブラリであり、より高度なフロントエンドの設定ができるようになりました。

ただ既存の`sprocket`を使った管理もできるように残しているようで`rails new`をすると以下のようなディレクトリが吐き出されます。

私のざっくりとした理解ですが、assets配下のファイルは`sprocket`で管理され、`app/javascript`配下のファイルは`webpacker`で管理されるようです。

![スクリーンショット 2023-10-03 17.06.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/d2963a6e-01dc-fed7-94c0-65d8279b9552.png)

## 画像をwebpackerで管理する
フロントエンドのファイルは`webpacker`の管理で統一したかったので、`app/javascript`配下にimagesディレクトリを作成し、そこでファイルを管理することにしました。

`webpacker`で画像を管理するためには画像をロードするライブラリが必要なようです。

```terminal
yarn add file-loader
```

次に`webpacker`の設定を更新します。

```yml:webpacker.yml
default: &default
  ...
  additional_paths: ['app/javascript']
  ...
```

あとはスタイルシートから画像のパスを指定してあげるだけです。

```scss:hoge.scss
.example {
  background-image: url('~images/example.jpg');
}
```

この`~`は設定ファイルで指定した`app/javascript`を示しています。
日本企業のビジネスニーズを支える生成系AI - Amazon Bedrockの可能性に行ってきました！

皆さん、こんにちは。
KDDI CCoE（*1）の柴田です。

今日はAWSの生成AIサービスであるAmazon Bedrockのセミナー、
**日本企業のビジネスニーズを支える生成系AI - Amazon Bedrockの可能性** に行ってきました！
https://generativeai-seminar-oct-inperson.splashthat.com/

このイベントで学んだことを超速報レポートします！（*2）

※1：CCoE = Cloud Center of Excellence の略称。
自社内のクラウド利用推進をさまざまな形で支援・牽引する専任組織を指す。

※2：超速報のため、テキストOnlyとなります。ご了承ください。

# Amazon Bedrock 日本のお客様へのメッセージ
Amazon Web Services Inc.　
Vice President　Generative AI　Amazon Bedrock 統括　
ヴァシ・フィロミン（ Vasi Philomin )のセッションでした。

+ 機械学習によるイノベーションはAmazonのDNAである
・Amazon.comでの毎分4,000個の取引
・Alexaでの毎週10億件のインタラクション
・Prime Airのドローン配送
・毎日160万個のパッケージ発送

これらの業務を、人と、機械学習されたロボットが一緒に働くことで実現している

+ 生成AIの活用メリット
・カスタマーエクスペリエンスの向上
　チャットボット、バーチャルアシスタント、会話分析、パーソナライゼーションなど
・社員の生産性/創造性の向上
　会話型検索、テキスト要約など
・ビジネスプロセスの最適化


+ 生成AIジャーニー
・最も簡単な構築方法
　**Amazon Bedrock**！！！
　インフラ管理不要、複数モデルから選択可能、自社データを活用してモデルを非公開でカスタマイズ
　**東京リージョン利用開始まもなく**！！
・データによる差異化
　Fine-tune
　ex) コンタクトセンター
　　誰が、何について、どんな感情で言っているのか知りたいので、ラベリングしていく

　　Bedrockでは、利用者データはプライベートかつセキュアに管理される
　　→基盤モデルの学習に使われない、暗号化される、VPCから出ない、GDPRやHIPAAなどの国際規格に準拠

　　Agents for Amazon BedrockがPreview
　　　・タスクを細分化してオーケストレーション可能
　　　・APIを呼び出して実行可能
　　　・とある地域のホテルの割引を加味して、実際に予約するデモ

・最も高性能、低コスト
　AWS TrainiumやAWS Inferentia2で実現

・生産性向上
　**Amazon CodeWhisperer**（AIコーディングコンパニオン）
 コード提案をリアルタイムで生成、脆弱性のコードをスキャン、似ているコードにフラグ付けし、フィルタ化可能

　**Amazon CodeWhisperer customization capability**　Coming Soon...
　社内コードに基づいて、ソースコードを提案してくれる

+ 生成AIジャーニー：まとめ
1. 正しいユースケースを選択
2. トレーニングを活用し、あらゆるスキルレベルのデベロッパーをスキルアップ
3. Amazon Bedrockで基盤モデルを検討し、PoCを始める 


## 事例セッション：ユーザー企業における生成系 AI 基盤サービスへの期待
株式会社竹中工務店 執行役員 デジタル室長 博士（工学）
岩下 敬三さんのご講演でした。

+ 建設業界の課題
1. 大幅な生産性向上・魅力向上
2. 建設資材の高騰
3. カーボンニュートラル

すべての業務をデジタル化していくことで課題解決に着手

+ デジタル化の取り組み
・デジタルによるベテランの知識・経験の継承
・デジタルによる人財育成

企業内の経験/実績/技術に関する専門的知識と一般常識を持ち、かつ、
人間味のあるやり取りで相談に乗ってくれる**デジタル棟梁**を
生成AIで実現することに挑戦している

+ 生成AIをデジタル統領にするためには？
世の中の一般常識だけでなく、自社の業務ルールや保有技術などの情報を持たせる
Bedrock+KendraでRAGのプロトタイプを開発

+ Amazon Bedrockを先行利用してみて
企業内情報を活用した生成AIシステムを作りやすい

# 事例セッション〜アクセンチュアが推進する生成系 AI のビジネス活用

アクセンチュア株式会社 執行役員 ビジネスコンサルティング本部 AIセンター長　博士（理学）
保科 学世さんのご講演でした。

+ 生成AIの取り組み
CodeWhispererを活用して、開発作業を30%向上している

+ アクセンチュアは、大規模言語モデルが業界平均で40%、ビジネスに影響を及ぼすという調査を行った
・ **生成AIに影響を受けない業界はもはやない。** 最低でも25%は影響を受ける
・ **人の仕事がAIに奪われるという次元ではない。** 労働力不足の減少に対して、生成AIを活用しない選択肢はない

+ Amazon Bedrockを含む複数のAIを組み合わせ、社内外データとの連携、
データセキュリティも考慮した「AI Hub プラットフォーム」を提供している

# 事例セッション〜富士ソフトが取り組んだ Amazon Bedrock の検証結果概要と可能性
富士ソフト株式会社　執行役員 ソリューション事業本部　副本部長
山本 祥正さんのご講演でした。

+ 検証結果
ご興味ある方はお問い合わせを！とのこと

+ LLM活用シナリオ
・風土醸成から始まる段階的な活用が望ましい

+ 検証してみて分かった優位性
・回答の優位性
　Kendraとの連携により、ピンポイントな回答を可読性高く取得できる
・コストの優位性
　データ整備コスト、ランニングコストとも、Bedrock + Kendraは他社サービス比較で優位

+ デジタルツインと生成AIも実現済み
・生成したテキストをダッシュボードへ表示（AWS IoT TwinMakerと統合）
　IoT領域のグラフや数値の見える化に加え、近況を人に分かりやすいコメントを表示

-----

セッションレポートは以上になります。
Amazon Bedrockの東京リージョン展開、CodeWhispererの新サービスといった
エキサイティングな発表に加えて、事業会社/開発会社での検証事例もあり、
Amazon Bedrockへの期待が高まったセッションだったと思います。

KDDIでも、みのるん @minorun365 がAmazon Bedrockを活用したプロダクトを開発しています！
ご興味ある方はぜひご覧ください！
https://developers.kddi.com/blog/44TMD1pcdiTqR2CMzrdpZo

KDDI CCoEとしても、生成AIは今後のクラウド利活用において重要なテーマと認識しています。
技術キャッチアップ〜社内利用サポート〜事例創出〜情報発信と、らしい活動をしていきます！
ChatGPTのプラグイン(Show Me Diagrams)を使ってみた

# やったこと
ChatGPT Plus Pluginsを初めて使ってみたので備忘録としてメモ。

## 使ったプラグイン
以下のプラグインを利用した。
    1. Show Me Diagramsプラグイン

## プラグインの利用方法
前提として、月20ドルの有償プランであるChatGPT Plusに登録する必要あり。
ChatGPT Plusに登録後、ChatGPTのメイン画面から「GPT-4」を選択し、「Plugins」を選択する。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567984/50d8ba40-36c6-ecde-c205-1c9bed86288e.png">

「Plugin」を押すと、「Plugin store」が表示される。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567984/92e89bc4-d025-6e32-bcd5-c23b70057d9a.png">

「Plugin store」から希望するプラグインをインストールする。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567984/f869b94b-4765-2709-13a6-9fdce307808e.png">

## Show Me Diagramsプラグイン
Show Me Diagramsをインストールする。
画面遷移図の作成を指示すると、ChatGPTが以下の通り作成してくれる。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567984/15ac3bcf-09ce-b21f-62a6-6637dc900e6e.png">


## 参考文献
クジラ飛行机，“生成AI・ChatGPTでPythonプログラミング アウトプットを10倍にする！”，ソシム株式会社，2023
Renderで簡単なwebアプリをデプロイしてみた

# はじめに
Pythonでウェブアプリを作成しており、デプロイのやり方を調べていたのですが最近Herokuが有料化になったと知りました。

そこで、調べていく中で無料でデプロイできるRenderというものを知ったので備忘録を兼ねてやり方をメモしていこうと思います。

## 1. 今回デプロイするもの
PythonのフレームワークであるFlaskを使った簡単なWebアプリを作成してそれをデプロイします。

URLにアクセスすると、ブラウザ上に`Hello World!`というテキストが表示されるというものです。

```app.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'
```

使用したライブラリの依存関係をrequirements.txtに明記しておきます。
```requirements.txt
Flask
Gunicorn
```
`Gunicorn`はFlaskやDjangoなどのPythonのフレームワークで開発されたアプリケーションを実行する際に使用します。また、Pythonのフレームワークの一つであるFastAPIでは`uvicorn`がよく使われます。

ローカル環境で動作確認をしておきます。

```
$ FLASK_APP=app.py flask run
```
![スクリーンショット 2023-10-03 16.12.19（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741553/5890d8a0-f5ea-9014-dc17-ef9f4e3ebb7d.png)

`Hello World!`と表示されているのでwebアプリはきちんと動くことがわかりました。

最終的にデプロイしたものがこのように表示させることができればデプロイ成功となります。

## 2. GitHubアカウントの作成
Renderを使用する際にGitHubアカウントが必要になるので事前にアカウント登録をしておきます。

## 3. GitHubにアプリのレポジトリを作成
Renderで作成したアプリケーションをデプロイするにはGitリポジトリが必要になります。なので、先ほど作成したファイルのリポジトリをここで作成します。

## 4. Renderアカウントの作成
https://dashboard.render.com/register?next=/

RenderのHPにアクセスし、自分のアカウントを作成します。

## 5. デプロイに関する設定

まずDashboard画面の右上にある「New +」と記載されているボタンをクリックし、「New Web Service」を選択します。

次に、下のような画面が出るので「Build and deploy from a Git repository」を選択します。

![スクリーンショット 2023-10-03 16.18.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741553/f7d57558-9ab8-157a-45a9-ce68da6909a6.png)

すると、GitHub上にある自分のレポジトリが表示されるので、今回デプロイしたいレポジトリを選択します。

最後に細かな設定があるのでそれを設定していきます。

Name：デプロイするサービス名を決定します。URLの一部に名前が入ります。

Region：一番日本から近いSingaporeを選択しました。

Branch：デプロイしたいファイルがあるGitのBranchを選択します。

Runtime：使用している言語を選択します。

Build Command：
```
$ pip install -r requirements.txt
```
とします。

Start Command：
これはwebアプリを起動するためのコマンドになります。
Flaskでwebアプリを作成していれば
```
$ gunicorn app:app
```
と設定します。
FastAPIで作成していればここが
```
$ uvicorn main:app --host 0.0.0.0 --port $PORT
```
となります。詳細についてはrenderのドキュメントに記載されています。

https://render.com/docs/deploy-flask

https://render.com/docs/deploy-fastapi

最後に「Create Web Service」をクリックしてデプロイされるのを待ちます。

無事にデプロイ完了したらURLが表示されるので、そこにアクセスしてローカルで動かした時と同じ動作をしていればデプロイ完成です。


# まとめ
簡単なwebアプリですが、実装からデプロイまで無事に行うことができました。

簡単なものでしたが自分が作ったwebアプリがURLとなって公開されるのはとても嬉しいものですね。感動しました。

デプロイは初めてだったのですが、renderの操作も簡単ですぐにデプロイすることができました。

今回はPythonのFlaskによるアプリのデプロイ方法を整理しましたが、他のフレームワークで作ったものをデプロイする際にStartCommandはどのように設定したらいいのか詳しくは理解できていないのでこれから使いながら学んでいきたいと思います。
WSL上で[safe] directory = %(prefix)///wsl....を設定しても、fatal errorが出てしまう

当方Windows11を使用しています。
Source treeを使いたく、wsl上にgit cloneしたものをgitconfigへ設定しようとしていたのですが

```
fatal: detected dubious ownership in repository at (省略)
To add an exception for this directory, call:
git config --global --add safe.repository '%(prefix)///wsl.localhost/Ubuntu/home/username/repository_name
```

とエラーが出るばかりで上手くいきませんでした。

ubuntu上でvimを使って設定したり、git config --global --add safe.repository '%(prefix)~~を打ち込んだりしていました。

結論ubuntu上で触っていたのがよくなかった....

## 解決策
Source Treeのターミナルから設定したら上手くいきました。

そもそもSource Treeはwindows側の設定を見に行くらしい。サーチ不足でした。
vscodeでmdがプレビュー表示されない

# エラー
vscodeで.mdファイルを編集しようとしたときに`[ctlr] + K → V`でプレビュー表示しようとした際に、以下のエラー分が表示された。

```
Error loading webview: Error: Could not register service worker: InvalidStateError: Failed to register a ServiceWorker: The document is in an invalid state..
```
# 環境
* vscode : 1.79.2
* Ubuntu 20.04.6 LTS



# 対処法
調べたところ再起動で解決するらしいが、windowを閉じるだけでは上手く行かない。


psコマンドで確認。→裏で動いていた
pkillを用いて再起動

治った


よくわかんないけど治ったからヨシ