OmniAICreator/Qiita-1.07M huggingface dataset:
Terraformでdestroyするときに「BucketNotEmpty」が出たときの対処法


S3バケットに対して`destroy`したときに

```bash
BucketNotEmpty: The bucket you tried to delete is not empty
```

とか言われて怒られることが結構あるんですよね  

#### 対処（CLI）

メッセージの通りなんですが、
S3バケットの中身が空でない（NotEmpty）の状態でバケット自体削除できないわけです。

なので、CLIで消してしまうというのが一つの手

```
aws s3 rm s3://bucket-name --recursive
```

いちいち消すのが面倒くさい（tfでやりたいときは）ときは下記の通り

#### 対処（Terraform）

```terraform
resource "aws_s3_bucket" "default" {
  bucket        = "bucket-name"
}

resource "null_resource" "default" {
  triggers = {
    bucket   = aws_s3_bucket.default.bucket
  }
  depends_on = [
    aws_s3_bucket.default
  ]
  provisioner "local-exec" {
    when = destroy
    command = "aws s3 rm s3://${self.triggers.bucket} --recursive"
  }
}
```

**解説**
null_resourceブロックをつかって
`depends_on`で依存関係を作る
↓
`local-exec`の`when=destroy`で実行するタイミングを`destroy`時だけに限定
↓
CLIでS3の中身を消す

いじょ！
AWS Elastic Beanstalk

#AWS Elastic Beanstalkとは？
**「定番構成の構築・アプリデプロイの自動化サービス」**
#特徴
・速く簡単にアプリケーションをデプロイ可能
・Auto Scalingによりコストを抑えながらスケーラビリティを確保
・Java,PHP,Ruby,Python,Node.js,.NET,Docker,Goなどに対応

#構成要素
**アプリケーション**
・トップレベルの単位
・バージョン、環境、環境設定が含まれている入れ物

**バージョン**
・デプロイ可能なコード
・S3上ででのバージョン管理
・異なる環境に異なるバージョンをデプロイ可能

**環境**
・各環境に応じて構築されるインフラ環境
・バージョンをデプロイ
・例)ELB＋EC2など

**環境設定**
その環境に関連するリソースの動作を定義する設定パラメータ
例)EC2インスタンスのタイプ、AutoScalingの設定など

#環境のタイプ
**ロードバランシング、AutoScaling環境**
・高い可用性
・ウェブサーバ環境：ELB+AutoScaling
・ワーカー環境：SQS+AutoScaling

**シングルインスタンス環境**
・EC2インスタンス１台構成
・開発環境構築のために低コストで構築可能

#環境の種類
**ウェブサーバー環境**
・スケーラブルなウェブアプリケーションを実行
・ELB+AutoScaling
・環境ごとにDNS名付与

**ワーカー環境**
・バッチアプリケーションを構築
・SQS+AutoScaling
・ワーカーホスト内でWebアプリケーションが動作

**Sqsd**
ワーカーホスト内で動作するデーモン
Webアプリからの応答
・200OKの場合→SQSからメッセージを削除
・200OK以外の場合→VisibilityTimeout後にSQSからメッセージが取得可能
・応答なし→InactivityTimeout後にSQSからメッセージ取得可能
定期的なタスク実行

#デプロイメント
**In Place Deployment(Rolling Deploy)**
インスタンスの現行環境のものをそのまま利用し、新しいリビジョンのコードをその場で反映させる

**Blue/Green Deployment(Red/BNlack Deployment)**
新しいリビジョンのコードを、新しいインスタンスに反映させ、インスタンスごとに入れ替える

#デプロイに関する設定
バッチタイプ：一度にデプロイを反映させる台数をどう決めるか設定
・割合(%)：現在起動中のインスタンスの合計数に対する割合で構成
・固定：決まった台数で絶対値で指定
バッチサイズ：各バッチにデプロイするインスタンスの数または割合

#デプロイ戦略
**環境設定の変更**
・環境とその環境に関連づけられているリソースの設定変更も可能
例）インスタンスタイプの変更
　　ELBのヘルスチェック設定変更など
・環境設定の変更によりインスタンスの置換が必要な場合も様々な方式から選択可能
　・無効：All at Onceでアップデート
　・ヘルスに基づくローリング：ヘルスチェックの結果が正常なら次のバッチをアップデート
　・時間に基づくローリング：指定した時間が経過したら次のバッチをアップデート
　・Immutable：新規インスタンスを作成して入れ替え

#環境設定のカスタマイズ
**環境設定**
・その環境に関連するリソースの動作を定義する設定パラメータ
例)EC2インスタンスタイプ、AutoScalingの設定など
・各リソースに対してデフォルトの環境設定が定義
環境作成時に直接設定、保存済み設定、.ebextensionsのいずれかでカスタマイズ可能

**保存済み設定**
・起動中の環境で使用している環境設定を保存可能→Amazon S3に設定ファイルとして保存
・保存した環境設定を再利用可能、作成時に指定

**.ebextensions**
・環境で利用しているリソースの高度なカスタマイズが可能
・環境に対する様々な操作を自動化と集約可能
・ユースケース
　(1)ソフトウェアインストール
　(2)インストールしたソフトウェアの実行

#モニタリング
**基本ヘルスレポート**
・環境のヘルスステータス
・ELBヘルスチェック
・CloudWatchメトリクス

**拡張ヘルスレポート**
・OSレベルのメトリクス
・アプリケーションレベルのメトリクス

**拡張ヘルスレポートの主なメトリクス**
・EnvironmentHealth
・インスタンスの状態
・リクエスト総数および各レスポンスコード毎の数
・Xパーセントの完了にかかった平均時間
・LoadAverage1min：１分間のLoad値の平均値
・InstanceHealth：現在のインスタンスのヘルスステータス
・RootFilesystemUtil：使用ディスク容量
・CPU使用状況詳細
PowerShellでIISのWEBアプリケーションを作成

powershellを活用すればIISのあらゆる処理をコマンド実行できます。
環境構築の自動化・効率化にご活用ください。

```powershell
#管理者として実行
Start-Process powershell.exe -Verb runas
#IISを操作するモジュールをインポート
Import-Module WebAdministration
#アプリケーションを作成
New-Item "IIS:\Sites\Default Web Site\YourSite" -PhysicalPath "C:\inetpub\wwwroot\YourSite" -type Application
LetsEncryptのワイルドカード証明書でハマった

## 環境
    ・CentOS 7.4
    ・Nginx 1.12.2
    ・Certbot

## 証明書作成
certbotで以下コマンド実行。（manualオプションを使用）

    certbot-auto certonly --manual \
    --preferred-challenges dns-01 \
    --server https://acme-v02.api.letsencrypt.org/directory \
    -m xxx@xxxx.co.jp \
    -d *.domain.com

実行すると質問形式になるので答えていく。
以下までくると、_acme-challengeをHostNameとしてValueをコピペしてドメイン管理しているサービスにTXTレコードとして登録しておく。

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Please deploy a DNS TXT record under the name
    _acme-challenge.domain.com with the following value:

    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX(これをコピペ)

    Before continuing, verify the record is deployed.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

登録後すぐにはDNSレコードが反映されないのでじっとここで我慢。digで↑で登録したValueになっているか確認。（この時は反映されるまで30分ほどかかった。）

    dig txt _acme-challenge

反映されると次に進めていき完了。（反映される前に実行したりで何度かエラーになりました。）
成功すると以下に配置されるのでNginxのConf設定も以下に書き換える。

    /etc/letsencrypt/live/domain.com-0001/fullchain.pem
    /etc/letsencrypt/live/domain.com-0001/privkey.pem

## 自動更新でエラー
証明書を自動更新するために以下コマンドを定期処理にて実行。

    certbot-auto renew --force-renewal

コマンドを手動で実行したところエラーになったのでconfig確認。

    vi /etc/letsencrypt/renewal/domain.com-0001.conf 

確認すると、authenticatorが以下のようになっていた。

    [renewalparams]
    authenticator = manual

authenticatorをnginxに修正。念のためinstallerも追加。

    [renewalparams]
    authenticator = nginx
    installer = nginx

再度コマンド実行すると正常に証明書が更新できました。
PowerShellを管理者権限で実行

最もシンプルな方法は、実行ファイル(.ps1)を右クリックで「管理者として実行」…違う違うそうじゃない。プログラム上でまかなえる方法をお探しでしょう。

シンプルに以下のようにファイル内の先頭に以下のおまじないを記述しておけば実現できます。

```powershell
Start-Process powershell.exe -Verb runas
```
容量用法を守ってご使用ください。くれぐれもお気をつけて。
ubuntuのVPSを契約したら、すぐにやること

# ubuntuのVPSを契約したらやること(2021年3月版)
セキュリティなどの観点・近年の鍵交換の主砲から、簡単にインストールができるようになってきました。
そこで2021年版のVPS契約後~最低限のインストールの方法までを書き残しておきます。
何かミスやバージョン違いでエラー等がありましたら、ご連絡お願いします。

1. ユーザーの作成
1. ssh鍵の用意
1. sshdの設定
1. ファイアウォール設定
1. 再起動
1. 設定確認
1. fishのインストール
1. 開発環境のセットアップ

# ユーザーの作成
```bash
# ユーザーを作成する
adduser user_name

# sudoを使えるようにする
gpasswd -a user_name sudo
```

# 鍵を用意する
公開鍵をgithubにアップロードしている前提です。
(アップロードしてあるとhttps://github.com/{{username}}.keys から鍵をみることができます)

```bash
su user_name
mkdir ~/.ssh 
# githubからダウンロードします。
curl https://github.com/{{username}}.keys > ~/.ssh/authorized_keys
# 権限設定
sudo chmod 600 ~/.ssh/authorized_keys
exit
```
# sshの設定を変更しましょう。
```bash
nano /etc/ssh/sshd_config
```
```diff:/etc/ssh/sshd_config
- Port 22
+ Port 2222

- PermitRootLogin prohibit-password
+ PermitRootLogin no

- #PasswordAuthentication yes
+ PasswordAuthentication no
```
# ファイアウォールの設定
```bash:bash
sudo ufw allow 2222 # ← 上記で設定したポート
sudo ufw enable
```

# 再起動
```
reboot
```

# 設定確認
設定が終わったら、PCからSSHしてみましょう。

```bash
ssh -p 2222 username@ipaddress
```

# 設定確認
ログインができたら、使う予定のshellなどをインストールしましょう。
fishを入れるのがおすすめ

```bash:bash
sudo apt-add-repository ppa:fish-shell/release-3
sudo apt-get update
sudo apt-get install fish
# 末尾に /usr/local/bin/fish を追加
sudo nano /etc/shells
chsh -s /usr/local/bin/fish
```

# 終わりに
ちょっと覚書っぽく、書き殴ってしまいましたが、セキュリティは最低限抑えましょう。
fishは最高。寿司食えんけど。

## 参考文献
- [ubuntu ユーザを追加して sudo 権限をつける](https://qiita.com/white_aspara25/items/c1b9d02310b4731bfbaa)
- [新しいサーバ起動後に最低限行うべき SSH 設定](https://qiita.com/noraworld/items/2f72035544a04d88b9e3)
- [GitHub に登録した SSH 公開鍵は全世界に公開されている](https://blog.id774.net/entry/2013/12/16/441/)
- [ufwを使って簡単にファイアウォールを設定する](https://qiita.com/yoh-nak/items/46935af3c5c4036e93b3)
- [fish shell - 3.x release series](https://launchpad.net/~fish-shell/+archive/ubuntu/release-3)
Angular Material

##AngularMaterialをインストール
下記コマンドを実行

```
ng add @angular/material
```
コマンド実行後に下記画面が表示される
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/e193d769-2991-d9c0-81f0-e6b2d74c0512.png)
アプリケーションのメインカラー(左)、サブカラー(右)を選択。
カスタマイズもでき、後から変更も可能みたい。
進めるとアニメーションの聞かれるので必要ならYESでOK。

##コンポーネントを表示
ファイルに以下追加

```app.module.ts
import { MatSliderModule } from '@angular/material/slider';
imports: [
  MatSliderModule
],
```
```app.component.html
<mat-slider min="1" max="100" step="1" value="1"></mat-slider>
],
```

##確認
スライダーが表示される。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/57ea1ff2-86ae-092e-cd76-a00cf6e34887.png)

##その他
公式サイトにボタン、テーブル、入力欄等色々。
基本的に「app.module.ts」に使いたいやつインポートでいけるかな
https://material.angular.io/components/categories
Angular Jasmine + Karma でテスト

・Jasmine + Karma で単体テスト
Jasmine：テストフレームワーク
Karma：タスクランナーでコードが書き換わるたびに実行

##Jasmineでテストコードを書く
テストコードは.spec.tsの名称のファイルに記述する必要がある。
コンポーネント作成する際に対になる形で.spec.tsファイルも自動生成される。

app.componentにtitleを追加。
テストコードでtitleの値が「my-app」であるかテストする。

```app.component.ts
export class AppComponent {
  title = 'my-app';
}
```
```app.component.spec.ts
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  });

  it('titleは"app"', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.componentInstance;
    expect(app.title).toEqual('my-app');
  });
});
```

##テスト実行
下記コマンドで実行

```
ng test
```
成功の場合
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/3b16c7ea-8232-0ec5-099b-847ae372ffba.png)
失敗の場合（「my-app」を「app」に変更）
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/dd8f08e5-c1f3-1471-73f2-0cc4da3e62b2.png)

##期待値のチェック
・期待値との完全一致をチェック　　toEqual()　　　　　　　　　　　　
・期待値が含まれるかをチェック　　toContains()
・返り値がTrueかどうかをチェック　toBeTrusty()
・返り値がundefinedかをチェック　expect(a.foo).toBeDefined()
・返り値がundefinedかをチェック　expect(a.foo).toBeUndefined()
・返り値がnullかをチェック　　　　expect(a.foo).toBeNull()
Angularのルーティングの設定

##動作
「PageA」のリンクボタン押下でURLの移動を伴う画面遷移
URLが「/pageA」になり、画面に「PageA」が表示されるようになる

・ボタン押下前
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/39d7ac60-b8fa-9ad8-483d-f18ab017f804.png)
・ボタン押下後
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643549/93067798-b776-c9ba-f65f-bbea67d05903.png)

##サンプルコード
```app.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
}
```
```app.component.html
<h1>Home</h1>
<div>
  <a routerLink="pageA">PageA</a>
</div>
<router-outlet></router-outlet>
```
```pageA.component.ts
import { Component } from '@angular/core';
@Component({
  templateUrl: './pageA.component.html'
})
export class PageAComponent {
}
```
```pageA.component.html
<h1>PageA</h1>
```
```app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { PageAComponent } from './pageA.component';

@NgModule({
  declarations: [
    AppComponent,
    PageAComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```
```app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { PageAComponent } from './pageA.component';

const routes: Routes = [
  {path: 'pageA', component:PageAComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
```
・routesの設定で、パスとコンポーネントの対応。
　URLのパスが一致するコンポーネントを読み込み。
　pathにワイルドカード(**)を指定で一致しない場合の設定もできる。
Gradleのbuild.gradleファイルについてメモ

##build.gradleファイルについて
build.gradleファイルはGroovyで書かれたスクリプトファイル。
Gradleでは様々なプラグインを利用していて、javaソースをコンパイルできるのは
ここでjavaのプラグインを定義しているから。
その他にもビルドするのに必要なライブラリも定義している。

①plugins（プラグインの定義）
　javaのコンパイル、アプリケーションの実行ができるのはここで定義しているから。

```
plugins {
    id 'java'
    id 'application'
}
```
②dependencies（依存性の定義）
　ビルドするために必要なライブラリを定義。

```
dependencies {
　　implementation 'org.springframework.boot:spring-boot-starter-web'   
}
```

③repositories (リポジトリの定義）
　MavenCentralリポジトリからライブラリをダウンロードする。
　自分のほしいライブラリを記述

```
repositories {
    mavenCentral()
}
```
④task（タスクの定義）
　タスクはメソッドのようなもの。
　複数の処理を一つにまとめたようなもので「run」「compileJava」もタスクになる。

```
task タスク名 {
    処理
}
```
SpringBoot GradleのDB接続メモ

##DB接続設定
①「src/main/resources/application.properties」にDB接続情報を設定

```application.properties
spring.datasource.url=jdbc:oracle:thin:@(server):1521:(sid)     　　　//（１）
spring.datasource.username=(username)　　　　　　　　　　　　　　　　　　 //（２）
spring.datasource.password=(password)                             　　//（３）
spring.datasource.driverClassName=oracle.jdbc.driver.OracleDriver    //（４）
```
（１）(server)(sid)にJDBCでの接続URLを設定
（２）(username)にDBへの接続ユーザを設定
（３）(password)にDBへの接続パスワードを設定
（４）DBのドライバを設定

②「build.gradle」にOracle接続用定義を設定
Oracle接続用jarとJPAライブラリ(ojdbcXX)の定義を追加

```build.gradle
dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  compile files('lib/ojdbc6.jar')
}
```

③Repositoryクラス
JpaRepositoriクラスを継承することでselect等を行うメソッドを自動生成してくれる
カッコのエンティティへのアクセス用のリポジトリ

```DemoRepository.java
@Repository
public interface DemoRepository extends JpaRepository <demoEntity, Long> {
}
```

④Entityクラス
@Entityでエンティティクラス
@Tableで指定したテーブルへのアクセス用エンティティクラス
@DataでGetter,Setterメソッドを使用できる

```demoEntity.java
@Entity 
@Table(name="テーブル名")
@Data
public class demoEntity {
  @Id
  private Integer id;

  @Column(name="カラム名")
  private String name;
}
```
⑤Controllerクラス
コントローラクラスからリポジトリを呼び出してデータを取得

```DemoController.java
@RestController
public class DemoController {
  @Autowired
  private DemoRepository demoRepository;

  public List<demoEntity> demoDataList(){
    return demoRepository.findAll();
  }
}
```
FirebaseでのデプロイでPlease verify that the package.json has a valid "main" entryが出た時の対処方法。

#はじめに
Firebaseでデプロイしようとしたらこんなエラーメッセージが出たので対処方法を教えます。

##エラー内容
```
=== Deploying to 'animelike-81816'...

i  deploying firestore, functions, hosting
i  firestore: reading indexes from firestore.indexes.json...
i  cloud.firestore: checking firestore.rules for compilation errors...
✔  cloud.firestore: rules file firestore.rules compiled successfully
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
✔  functions: required API cloudbuild.googleapis.com is enabled
✔  functions: required API cloudfunctions.googleapis.com is enabled
i  functions: preparing functions directory for uploading...

Error: Error parsing triggers: Cannot find module '/Users/＿＿＿/React/functions/lib/index.js'. Please verify that the package.json has a valid "main" entry

Try running "npm install" in your functions directory before deploying.

```

簡単にいうとfunctionsフォルダがなんかおかしいぞ。おかしいからnpm installしとけ。とのこと。

##対処方法

functionsフォルダの中のpackage-lock.jsonを一度削除してください。
そしてnpmを再インストール

```
$ cd functions
$ npm install
$ firebase deploy
Deploy complete!
```

日本語の記事だと出てこなかったので海外サイトで探しました。
参考にしたサイト↓
https://stackoverflow.com/questions/66207737/please-verify-that-the-package-json-has-a-valid-main-entry
Dataloaderの扱うファイルの文字コードをUTF-8に変える【セールスフォース】

* この記事はDataloaderのver48.0.0を使っています。

#####忘備録としてデータローダーでUTF-8のファイルを扱うための設定方法を残しておく

1. 上部メニューよりSettingを選択し設定画面を開きます。
![setting01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261412/1aa8f0e1-bb1c-30df-3584-38c5472cfcbe.png)

1. 中程にある「Read all CSVs With UTF-8 encoding」と「Write all CSVs With UTF-8 encoding」のチェックボックスにチェックを入れOKを押せば完了です。
![setting02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261412/b08ef95d-d6d1-a1fe-6613-7473e4a615f6.png)
Shopify Storefront APIのCustomerAccessTokenの期限

# はじめに
ShopifyのStorefront APIの[CustomerAccessToken](https://shopify.dev/docs/storefront-api/reference/customers/customeraccesstoken)の有効期限が公式リファレンスに明記されておらず、フォーラムでも期間を明記した回答はなかったので検証しました。

**※ これはバージョン2020-10での検証です。今後APIのバージョン変更に伴って変更される可能性があります。**

# 検証
```graphql
mutation customerAccessTokenCreate($input: CustomerAccessTokenCreateInput!) {
  customerAccessTokenCreate(input: $input) {
    customerAccessToken {
      accessToken
      expiresAt
    }
    customerUserErrors {
      code
      field
      message
    }
  }
}
```
公式リファレンスの[customerAccessTokenCreate](https://shopify.dev/docs/storefront-api/reference/customers/customeraccesstokencreate)のmutationを送信して`expiresAt`を確認しました。
2021年3月31日18時36分実行で`2021-05-12T09:36:18Z`と帰ってきています。
2021年5月12日18時36分なので[CustomerAccessToken](https://shopify.dev/docs/storefront-api/reference/customers/customeraccesstoken)の有効期限は**42日**です。

# 結果
ShopifyのStorefront APIバージョン2020-10での[CustomerAccessToken](https://shopify.dev/docs/storefront-api/reference/customers/customeraccesstoken)の有効期限は**42日**でした。

# APIバージョン
Shopify Storefront: 2020-10

# 関連ページ
https://shopify.dev/docs/storefront-api/reference/customers/customeraccesstokencreate

https://shopify.dev/docs/storefront-api/reference/customers/customeraccesstoken
１コマンドでVisual Testingを試せるツールを作りました

# はじめに

皆さんこんにちは@rueyjyeです。

二年前に[Gazo-san](https://github.com/lifull-dev/Gazo-san)を公開し、Qiitaにも紹介記事を投稿しました。内容はGazo-sanの使い方をメインに説明しました。
[画像差分検知ツール「Gazo-san」入門](https://qiita.com/rueyjye/items/85f5c94957e775437f89)

当時は画像を個別で撮影してからGazo-sanコマンドで画像パスを指定し、結果の差分画像をそのまま見るという手順でした。
かなり手順が多く、結果の画像はどこを見ればよいか分かりにくいものでした。

今回は、撮影、差分計算、レポートを一回で全部できるツールを作りました。
これでVisual Testingを簡単に始められると思います。

# Gazo-san-reportとは

Visual Testing三つの要素の「撮影」、「差分計算」、「レポート」が一体化したツールです。
全部の処理をDocker imageに書いて、一コマンド実行で構築できるツールです。

リポジトリ: [Gazo-san-report](https://github.com/rueyaa332266/gazo-san-report)

Visual Testingの要素については[別の記事](https://www.lifull.blog/entry/2019/12/16/110000)がありますので、興味がある方はご覧ください。

Gazo-san-reportは二つのURLを渡して、それぞれのペーじのキャプチャを撮影、差分を計算し、最後はHTMLのレポートを生成します。

URLベースで差分を表示するので、異なる環境間のVisual Testingと相性がいいと思います。例：開発コードが反映した後、開発環境と本番環境の違いをチェックする。

今はまだ対応してないですが、今後撮影機能を使わずに画像を渡すだけでもレポートまで作成する機能追加したいと思います。

# 試しましょう

基本README通りでやればできると思います。

使い方はDockerコンテナを起動するだけです。
BaseURLとCompareURLの環境変数で比較したいURLの設定が出来ます。
ここの例はGoogle日本語ページと英語ページの比較です。

```bash
docker run -it -d --rm -v `pwd`:/report --env BaseURL="https://www.google.com/?hl=ja" --env CompareURL="https://www.google.com/?hl=en" aa332266/gazo-san-report:latest
```

コマンドを実行したら、コンテナ内でページの撮影、差分計算、レポート作成の処理を行います。
結果的に画像保存用のimagesディレクトリとレポートの`report.html`が作成されます。

# レポートについて

HTMLのレポートをブラウザで開きたら、以下のように表示します。
![report_example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/9dab49f3-6cae-5a4c-2ff0-4781059df810.png)
BASE: Google日本語ページの画像 (https://www.google.com/?hl=ja)
COMPARE: Google英語ページの画像 (https://www.google.com/?hl=en)
DIFFERENCE: Gazo-sanで計算した差分画像

※ ここのBASEとCOMPAREの画像はGazo-sanの`create-change-image`オプションを有効にして、認識したパーツを緑枠で表現している状態です。

差分画像中の差分箇所が分かりにくいとのフィードバックをいただくことがありますが、実はGazo-sanの差分はマッチングしたパーツの差分のみ表示しているので、マッチングしたパーツがないと赤い枠が全く出ない状況があります。

その時は`create-change-image`オプションで作成した緑枠がありの画像をみれば分かりやすいと思います。Gazo-san-reportはデフォルトで有効にしています。

BASEとCOMPAREにマッチングできていないパーツを緑枠で表示しています。つまりDIFFERENCEに差分が出ないですが、緑枠を見ればBASE画像にしかないパーツとCOMPARE画像にしかないパーツが表示されます。

そして、3つの画像を並んでいる状態で左右を見ながら差分がわかりやすく見つけられるかなと思います。

|BASE|COMPARE|
|:-:|:-:|
|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/4c809dba-50c8-afa7-bf89-6d9fb5314254.png">|<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189885/01b94358-63e9-2098-4815-51d0e591239f.png">|
👆 緑枠は各画像独自のパーツです


補足：たまに完全に同じパーツなのに、マッチングしてない状況があります。ここのGoogleの例だと、虫眼鏡とマイクのアイコンの部分がマッチングしてない状態です。その場合はマッチング判定のアルゴリズムが検知できていなかったきからです。こちらは申し訳ございませんでしたが、今後少しつづ調整できたらと思います🙏

# 最後に

今回はVisutal Testingのキャプチャ撮影→差分計算→レポーティングが一体化したツールを作りました。

Gazo-sanの差分が分かりづらい問題はレポートの緑枠も合わせて参照すればより分かりやすくなると思います。

また、今は1ケースのレポートしか作成できないですが、今後複数ケースの差分をまとめたレポートが作れる状態を目指して改良し続けていきます。

みなさんもぜひ[Gazo-san-report](https://github.com/rueyaa332266/gazo-san-report)でVisual Testingをお試しください。
Jenkinsバージョンアップ後にハマった件

# はじめに

- 1年ぶりにjenkins本体のバージョンを最新(2.286)まで一気に更新したところ、大ハマリしたので問題と対処法をメモしておく
- 環境はEC2(Amazon Linux 2)上に構築したものとする

# (1) java.lang.IllegalStateException: An attempt to save the global configuration was made before it was loaded

## 状況
- jenkins再起動後にこのエラーが出て何もできない状態になる
- プラグインのバージョンを上げずに、jenkins本体のバージョンを最新まで上げてしまった場合に起こる模様

## 対策
- jenkinsを安定版の2.263に一旦ダウングレードして再起動(a)
  - ここですんなり起動すれば問題ないものの、今回は次の(2)の問題が発生

```
sudo yum downgrade jenkins-2.263
sudo systemctl restart jenkins
```

- 再起動後、GUI上でプラグインのバージョンを上げる
- プラグインのバージョンアップ後に再度jenkinsを最新版までバージョンアップし、再起動

```
sudo yum install jenkins
sudo systemctl restart jenkins
```

# (2) com.thoughtworks.xstream.mapper.CannotResolveClassException: hudson.security.LDAPSecurityRealm

## 状況
- jenkins再起動後にこのエラーが出て何もできない状態になる
- (1)の(a)でダウングレード後に発生

## 対策
- `/var/lib/jenkins/config.xml` のバックアップを取っておく
- `/var/lib/jenkins/config.xml` の `<securityRealm ...>...</securityRealm>` を削除する
  - 今回はLDAP認証の設定なので、これにより既存ユーザとしてはログインできなくなる
  - (role-strategyで運用している場合)匿名ユーザにadminロールを一時的に付ける
    - `/var/lib/jenkins/config.xml` の `<authorizationStrategy ...>` のうち、adminロールのassignedSIDsに `<sid>anonymous</sid>` を追加する

```
<authorizationStrategy class="com.michelin.cio.hudson.plugins.rolestrategy.RoleBasedAuthorizationStrategy">
    [...]
    <role name="admin" pattern=".*">
    <permissions>
        [...]
    </permissions>
    <assignedSIDs>
        <sid>anonymous</sid>
        [...]
    </assignedSIDs>
    </role>
    [...]
</authorizationStrategy>
```

- `/var/lib/jenkins/config.xml` を編集したら再起動し、(1)の(a)に戻る

参考: https://stackoverflow.com/questions/55742680/jenkins-fails-to-start-after-restart-due-to-com-thoughtworks-xstream-mapper-cann

# (3) jenkins slave(agent)とのJNLP接続が切れる

## 状況
- jenkins slaveとの接続が全て切れている

## 対策
- グローバルセキュリティの設定のうち、agent用のポート(TCP port for inbound agents)が無効になっていないか確認
  - 無効になっている場合は適当なポートを指定する
- jenkins slaveホスト側のjnlpUrlを確認して変更
  - 旧: `"java ... -jnlpUrl http://{host}/computer/agent_name/slave-agent.jnlp"`
  - 新: `"java ... -jnlpUrl http://{host}/computer/agent_name/jenkins-agent.jnlp"`
  - ポリコレの流れでmaster/slaveという用語の見直しがあったためと思われる
- jnlpUrlの変更後、JNLP接続を張り直す

参考: https://issues.jenkins.io/browse/JENKINS-35452
SQL データベース、テーブル、カラムの追加から削除まで

こちらの記事では、私が学んだSQLについて記載しております。
自身の忘れないためのメモとしております。
間違っている部分もあるかもしれませんので、ご了承ください。



#データベースの追加/削除
```
・記述方法
creat database データベース名；

＊＊＊命名ルール＊＊＊
最初の名前は半角アルファベット！！！！

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
***データベースの削除＊＊＊
・記述方法
drop database データベース名;

```

#テーブルの追加/削除

```
・記述方法
create table 追加したいテーブル名(id int not null auto_increment primary key, tilte varchar(255) not null);

↑↑上記の文の意味↑↑
・列名　id
 -int・・・整数型
 -not null・・・nullを許可しない
 -auto_increment・・・idを自動的にふる
 -primary key・・・主キーの設定

・列名　title
 -varchar(255)・・・最大255文字の可変長文字列型
 -not null・・・nullを許可しない

-----------------------------------------------------------------------
＊＊＊テーブルの削除＊＊＊
・記述方法
drop table テーブル名;
テーブルを削除してしまうと簡単に復旧しないので注意！！！！！

```

#テーブル構造の変更
```
＊＊＊テーブルの列の追加＊＊＊
・記述方法
alter table テーブル名 add 追加したい列名（カラム名） int after id;

例　テーブルusresに、ageのカラム名を追加したい
alter table users add age int after id;

-----------------------------------------------------------------------
***テーブルの列名を変更＊＊＊
・記述方法
alter table テーブル名 change 変更前のカラム名 変更後のカラム名 int;

-----------------------------------------------------------------------
＊＊＊テーブルの列名の削除＊＊＊
・記述方法
alter table テーブル名 drop 列名；

```

##補足
#####show databases; 
登録しているデータベース全てを確認できる。

#####show tables;
データベース内のテーブルを確認できる。

#####show columns from テーブル名;
テーブルの構造を確認できる。
dump1090-faのサーバーをNginxにする

`dump1090-fa`をインストールすると、自動的に`lighttpd`が導入されます。
`lighttpd`は軽量で良いのですが、僕は`Nginx`が大好きなので切り替えたいと思います。

# 環境

当然のことながら`dump1090-fa`など、`ADS-B`を受信する環境が整っているものとします。
私は[FlightAware](https://flightaware.com/adsb/piaware/install)と[Flightradar24](https://www.flightradar24.com/share-your-data)に記載の公式ガイドに則ってインストールしました。

```
Linux raspberrypi 5.10.17-v7+ #1403 SMP Mon Feb 22 11:29:51 GMT 2021 armv7l GNU/Linux
```

# `lighttpd`に別れを告げる

「ごめん、君のことは友達以上に思えない」

```bash
sudo systemctl stop lighttpd && sudo systemctl disable lighttpd
```

停止のみでアンインストールはしないでおきます。

先に停止しないと、`Nginx`をインストールするときにポートで競合してエラーになります。
二股はよくないですもんね。

# `Nginx`にアタックする

「あ、あの…、ずっと君のことが…！」

```bash
sudo apt install nginx
```

特に何もなくサクッと入ると思います。

# 設定

諸々お好みの設定にしてください。

`dump1090-fa`関連の設定だけピックアップします。
下記ファイルを、アクセスを待ち受ける`server`ディレクティブ内にインクルードすれば動きます。

```skyaware.conf
location ^~ /skyaware/ {
    alias /usr/share/skyaware/html/;
}
location ^~ /skyaware/data/ {
    alias /run/dump1090-fa/;
}
```

簡易的にですが雛形も記しておきます。

```sites-enabled/default.conf
server {
        listen [::]:80;
        listen [::]:443 ssl http2;

        root /var/www/example.com;

        index index.php index.html;

        server_name example.com;

        # Location settings
        location / {
                try_files $uri $uri/ =404;
        }

        include conf.d/skyaware;  # Standby for SkyAware

        # SSL configuration
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
}
```

# おわりに

`http2`に対応できたり、`CSP`を設定できたりと`Nginx`の方がモダンに色々できてよいですね。
`Certbot`も標準で対応しているので更新の手間も少ないです。

手軽に移行できるので皆さんもぜひ試してみてください。
【Ruby】chopメソッドで末尾の改行コードを取り除く方法

#プログラミング勉強日記
2021年3月31日

#chopメソッドとは
　末尾の改行コードを削除することができるメソッド。(文字列の改行コード以外の文字列の末尾の1文字を削除する。)chop!メソッドを使うと、末尾の改行コードを取り除いた文字列を元の文字列に書きかえる。

```ruby:chopメソッドの使い方
# 末尾にのみ改行コードを持つ文字列の場合
str = "Hello World\r\n"
chopStr = str.chop
#=> "Hello World"

str = "Hello World"
chopStr = str.chop
#=> "Hello Worl" 
```

```ruby:chop!メソッドの使い方
str = "Hello World\n"
str.chop!
#=> "Hello World"

str = "Hello World"
str.chop!
#=> "Hello Worl"
```

```ruby:空文字の場合
str = ""
str.chop
#=> ""

str.chop!
#=> nil
```

#参考文献
[instance method String#chop](https://docs.ruby-lang.org/ja/latest/method/String/i/chop.html)
[instance method String#chop!](https://docs.ruby-lang.org/ja/latest/method/String/i/chop=21.html)
Flutter 1.12以上に更新したら、android(タスクキル)へのpush通知後にクラッシュするようになった

#はじめに
タイトルの通りです。
Flutterを1.12に更新したところ、
android端末(タスクキル、バックグラウンドで起動していない状態)へpush通知を送った時に、
通知が表示されず、クラッシュした際のダイアログが表示されるようになりました。

#Flutter1.12更新時の対応
下記の対応を行いました。
https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects

#今回発生していること(推測)
上記の[Flutter1.12更新時の対応](https://qiita.com/drafts/e747308d63711820d664/edit#flutter112%E6%9B%B4%E6%96%B0%E6%99%82%E3%81%AE%E5%AF%BE%E5%BF%9C)の中で下記を削除しました。

```
android:name="io.flutter.app.FlutterApplication"
```

プロジェクトで使用しているライブラリの中で、上記がまだ残っているものがありました。

参考 : 
https://github.com/FirebaseExtended/flutterfire/issues/1754

#解決法(未実施)
ライブラリがFlutter1.12に対応していれば、
そのライブラリを更新すれば解決すると思われます。

#解決法(暫定)
ライブラリを更新しようとしたところ、
Flutter 2.12に更新する必要がありそうでした。
Null Safetyの対応をする必要があるため、
今回はFlutterの更新を見送りました。
peeweeでSELECTを使う場合の使い分けについて

前回の記事でpeeweeの全文検索についての方法をまとめましたが今回は通常のSELECTに焦点を当てて
内容を整理してみようかと思います。

# 参考資料
- 参考資料
 - [PythonのORMのPeeweeを使ってデータベースを操作してみる(2019年8月版)](https://qiita.com/mima_ita/items/9d4e1d0afac1865acdbb)
 - [公式ドキュメント](http://docs.peewee-orm.com/en/latest/)

# 環境
 - peewee:3.14.2
 - python3.8

# 記載する取得方法について
ここではpeeweeで推奨されている```atomic()```を使用した方法を紹介します
```atomic()```の詳細については以下を参照してください

 - [APIドキュメント atomic( )](http://docs.peewee-orm.com/en/latest/peewee/api.html#Database.atomic)

# 全件取得の場合

全件取得の場合は単純にselectで取得します
返却値は配列で取得できるので配列の中身を
```model_to_dict(query)```を使用してDictに変換します

```
    try:
        with db.atomic():
            query = TEST_DB.select()
    except Exception as e:
        db.rollback()
        raise(e)

    return model_to_dict(query) # model_to_dictで取得データをdictに変更する
```

# 条件を指定した取得の場合
条件を設定する場合はwhereに検索条件を挿入します
またフィルタリングを行う場合はselectに引数で指定します
返却値は配列で取得できるので配列の中身を
```model_to_dict(query)```を使用してDictに変換します

```
    try:
        with db.atomic():
            query = TEST_DB.select(
                        TEST_DB.cat) \                 #取得するカラムを絞る場合はselectのパラメータに対象カラムを指定
                        .where(
                            TEST_DB.cat =="検索条件",    #検索条件をwhereに指定する
                            TEST_DB.is_deleted == False
                        )
    except Exception as e:
        db.rollback()
        raise(e)

```

# 1件だけ取得する場合
1件だけ取得する場合はget()を使用します
※get()を使用する場合は1件が確実に取得できる場合です
　取得できなかった場合はDoesNotExistがスローされます

```
    try:
        with db.atomic():
            query = TEST_DB.select(
                        EST_DB.cat) \                 #取得するカラムを絞る場合はselectのパラメータに対象カラムを指定
                        .where(
                            TEST_DB.cat =="検索条件",    #検索条件をwhereに指定する
                            TEST_DB.is_deleted == False
                        ).get()　# 1件だけ取得する場合は指定する
    except TEST_DB.DoesNotExist as ne:
        db.rollback()
        raise(ne)
    except Exception as e:
        db.rollback()
        raise(e)

    return model_to_dict(query) # model_to_dictで取得データをdictに変更する
```
返却値は配列ではなく1件のみのデータで取得されますのでそのまま
```model_to_dict(query)```を使用してDictに変換します
Salesforceのグローバル検索で優先表示されるオブジェクトについて

#グローバル検索で優先表示されるオブジェクトについて
　Salesforceで画面の最上部から行うことができる「グローバル検索」ですが、
　検索結果に優先的に表示されるオブジェクトがあります。

　例）下図の例では取引先が優先表示されている状態
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657185/8ce4efde-8fff-b0a4-d837-1c8f0a82ea60.png)

　この優先的に表示されるオブジェクトに出る条件は「よく利用するオブジェクト」に設定されているか否かになります。
　では「よく利用するオブジェクト」にはどのように設定すればよいか？ですが・・・

　非常に簡単で「優先表示したいタブにアクセスする」だけで設定されます。
　※設定は各ユーザ単位になるため、AユーザでタブにアクセスしてもBユーザには優先表示されません。

　試しにと取引先責任者にアクセスした後にグローバル検索を行うと下記の通り表示されます。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657185/ecdaffbc-a7a4-eb77-1d60-2d66aabe7b40.png)


#補足
　この「よく利用するオブジェクト」ですが、Sandbox作成の際には本番環境からSandboxには引き継がれません。
　そのためSalesforceを利用されているお客様が受入試験環境（Sandbox）で、普段本番で利用されている検索結果と
　異なるというお問合せなどが発生する可能性があります。
　上記のような形でタブにアクセスして頂くようご案内する必要があります。

　また優先表示されないからといって結果に全く表示されていないわけではなく、
　グローバル検索の結果画面の左側「検索結果」-「上位の結果」のエリアから[表示件数を増やす」を押下頂くことで、
　優先表示されなかったオブジェクトも含め参照することが可能になります。
　
　例）
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657185/d9a74209-2617-dd37-f267-d0f44404e419.png)
エラー処理のカスタム

**エラー処理ののカスタマイズ**
<h1>カスタマイズする理由</h1>
本番を想定したエラー画面のを出す仕組みがありますが、railsで作りました感があり、ダサい
そこでエンドユーザーに使ってもらうにはエラー画面のデザインを整えたり、ユーザーによって便利になるようにカスタマイズして整えてやると良い

<h2>railsのエラー処理の概要</h2>
エラー処理に置いてプログラムを調整できるポイントは次の３点
1.デバック用/本番用のエラー画面の切り分け
2.railsの本番用エラー画面のカスタマイズ
3.アプリケーション固有のエラー処理の追加

**１デバック用/本番用のエラー画面の切り分け**
環境ごとの設定ファイル内のconfig.consider_all_requests_localがtrueのよきにデバック用。falseの時に本番用のエラー画面が表示されることになります。

**2railsの本番用エラー画面のカスタマイズ**
本番用のエラーは、public/500.htmlなどが対応します。エラー画面のファイルはHTTPステータスコードごとに用意する仕組みになっています。
**実際によく発生するのは**
**404** ルーティングで行き先となるActionが見つからない、モデルで設定したidのレコードが見つからないなど
**500** システム全般エラー
デフォルトでは404,422,500の三つのエラー画面が作成されるので、これらにデザインを当てればデフォルトではないエラー画面が作れる

**3アプリケーション固有のエラーの処理の追加**
特定のアクションの特定の例外については専用的な処理をしたい場合や、比較的手軽に動的エラー画面を出した場合はコントローラに用意されてるrescue/fromというメゾットを使う
[Shopify] リスクの高い注文を確定前に確認する方法


Shopify での不正注文またはチャージバックを防ぐための方法を紹介。

# 不正解析

Shopifyでは不正解析機能が搭載されています、様々なクライテリアでその決済が不正かどうか判断してくれます。
詳細はこちらを参照ください。
https://help.shopify.com/ja/manual/orders/fraud-analysis

# Shopify Flow

Shopify Flowはもうしこうなら、こうする、みたいなロジックをノーコードでつくることができます。
そして既にいくつものテンプレートが準備されているので、やりたいことに近しいものを選択してあとはカスタマイズすればいいだけです。

Shopify Flowのインストールはこちらから
https://apps.shopify.com/flow?locale=ja

# リスクの高い注文を処理する

Shopify Flowを使い、リスクの高い注文を事前に通知をもらい確定するテンプレートを仕様します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/f19b52cd-9c8b-0aa0-e4fc-fb1b231b26a4.png)

下記の図を平たく説明すると、もし注文リスクがHIGHでない場合は決済確定、もし注文リスクがHIGHだったらメールを通知して手動で決済を充てる必要がある旨お知らせする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/aaab82d6-418d-4557-3ba3-262fdaffa3d3.png)

HIGHではなくてMIDDLEでも確認したいという場合はフローの編集から値を変えればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/a92ab775-5396-08e5-4621-7b094d35e58d.png)

これらの設定を有効するには設定ページより、支払いの確定を手動で注文支払いを確定するを選択している必要があります。（でないと・・自動的に支払い確定となってしまいフローが有効になりません）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/15b7f002-45a4-9694-33a6-b4efca0e9802.png)

これで、不正注文の可能性が高いものはすべて目視してから確定またはキャンセルすることができます。
Amplifyでサインイン画面をカスタマイズする方法【React】

# やりたいこと
次のようにセルフサインアップ（Create Account）をさせたくないときなど、項目を調整したい場合のメモ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200228/b27435fe-092a-5f2d-f5b6-152c64edaa58.png)
# 方法
次のように`AmplifyAuthenticator`を使うと実現できます

```jsx
import React, { useContext } from 'react'
import { AmplifyAuthenticator, AmplifySignIn } from '@aws-amplify/ui-react'

// サインアップを隠す場合はhideSignUp属性を指定
const Signin = () =>(
    <AmplifyAuthenticator >
        <AmplifySignIn slot="sign-in" hideSignUp></AmplifySignIn>
    </AmplifyAuthenticator>
)
```

# 参考
こちらがソースですが、公式からはちょっとたどり着きにくい場所にあります
https://docs.amplify.aws/ui/auth/authenticator/q/framework/react
Kubernetes の環境を作りたい [Raspberry Pi 編 6] 64 bit で出直しました 

前回

https://qiita.com/yosukei3108/items/7bfa469c0f796e4cbd56

こちら (http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos-altarch/7.9.2009/isos/aarch64/images/) のイメージで CentOS 7 をインストールしなおし、何事もなかったかのように Docker のインストールができました。


``` console
# yum install docker-ce docker-ce-cli containerd.io
(略)
================================================================================
 Package                   Arch    Version               Repository        Size
================================================================================
Installing:
 containerd.io             aarch64 1.4.4-3.1.el7         docker-ce-stable  26 M
 docker-ce                 aarch64 3:20.10.5-3.el7       docker-ce-stable  18 M
 docker-ce-cli             aarch64 1:20.10.5-3.el7       docker-ce-stable  29 M
(略)
================================================================================
Install  3 Packages (+12 Dependent packages)

Total download size: 84 M
Installed size: 380 M
Is this ok [y/d/N]: y
(略)
# docker --version
Docker version 20.10.5, build 55c4c88
```

``` console
# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
256ab8fe8778: Pull complete
Digest: sha256:308866a43596e83578c7dfa15e27a73011bdd402185a84c5cd7f32a88b501a24
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```

やったぜ！！

ワーカー ノードの 3 台分もここまでの手順をやり直したら続き書きます。
Vitis HLS と Vivado で作った回路を PYNQ を使って FPGA 上で動かすまで ー①コードを書くー

諸事情あり，このページは以下のページに移行しました．
ご愛読ありがとうございます．

https://blog.n-hassy.info/2021/05/vitis-hls-to-fpga-1/
備忘録(?)：SSHキーの設定からSourceTreeの連携について

# SSHキーの設定、やってみました

むかーしむかし、SSHキーの設定について理解ができなくて
苦手意識ができました。

ですが、GitHubから「SSHキーの設定お願いします〜！」と
メッセージが来てしまったので、
SSHキーの設定からSourceTreeの連携方法修正を
頑張ってやってみました！！！

(ずっとあるかどうかわからないポートフォリオ、個人制作ですが
安全面などを考えると必要ですからね！！)


## 手順について
大まかですが、大体こんな感じです。
**<font color="blue">① SSHキーを作成
② GitHubに登録
③ SourceTreeのアカウント設定を変更</font>**

## 実際にやってみた
SSHキー作成からSourceTree設定の作業は、
こちらを参考にしました。

https://qiita.com/ozkknnt/items/054746c687936200a281

<hr>
### ① SSHキーを作成
まずはSSHキーの作成から。
ターミナルで指定のコマンドを入力して、
SSHキーを作成します。

<hr>
### ② GitHubに登録
作成したSSHキーをGitHubに登録→確認を行います。
確認作業を終えたらSourceTreeで設定を行いますが、
私の場合、確認の時に**<font color="red">「PTY allocation request failed on channel 0」</font>**というエラー文言が出てきました。

https://teratail.com/questions/248586

ですが、上記サイトで確認したところ、特に問題はないみたいでした。

・・・が、新しく**<font color="red">「Host key verification failed」</font>**という文言が・・・！！！
こちらも調べてみたところ、

https://note.affi-sapo-sv.com/ssh-verification-failed.php


上記サイトで、この文言への返答(?)を「yes」にしたら解決できるとのことだったので
その通りにやってみたことで、無事解決することができました。

<hr>
### ③ SourceTreeのアカウント設定を変更
手順通りに
アカウント設定 → プロトコル設定をSSHに変更　で完了です。

<hr>

## まとめ
SSHキー作成からSourceTree設定までの作業は、
以下のサイトの手順通りに行えば問題はないかと思います。

https://qiita.com/ozkknnt/items/054746c687936200a281


私のように
**<font color="red">「PTY allocation request failed on channel 0」</font>**
**<font color="red">「Host key verification failed」</font>**
というエラーが出てしまった場合は、以下のサイトを参考に
対応してみるといいかと思います。

https://teratail.com/questions/248586

https://note.affi-sapo-sv.com/ssh-verification-failed.php


ではでは・・・😌
postgresでselectで得た結果をカンマ区切り文字列にして1行で取得したい

題の通りの備忘録

fruitというテーブルがあるとして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508560/1e95a654-cfde-3c3f-9742-404a4d38a1ba.png)

これを、「りんご,すいか,みかん,もも」という文字列で得たい。

    select
        array_to_string(
            array(
                select fruit.fruit_name
                from fruit
                order by fruit.id
            ),
        ',');


見ての通り配列にしてからカンマ区切り文字列に直してます。

取得結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508560/5b39910c-a796-9390-d62e-5a1d3e1996dd.png)
AWS ChaliceでEC2とRDSを自動で起動停止するLambdaを作成（祝日対応版）

https://qiita.com/danishi/items/4b5fa88458ca656ada97

こちらの記事の祝日対応版です。

Google Calendar APIを使って起動日が祝日の場合は処理を行わないように。
また、Google Calendar APIだと正月や会社の休日に対応できないので、環境変数に別途例外休日を設定できるようにしています。

記事のコードにimport文と祝日判定のためのロジックを追加。

```python:app.py
import datetime
import urllib.request
import json
```

```python:app.py
def change_instances_state(event, target='ec2', state='Start', dryrun=True):

    if is_holiday():
        return  # 休日なら処理終了

    if state == 'Stop':  # 停止させる条件
```

```python:app.py
def is_holiday():
    now = datetime.datetime.now()
    app.log.debug(now)

    # 環境変数で設定した休日と比較
    days = now.strftime('%m/%d')
    env_holidays = os.environ['HOLIDAYS'].split(',')

    if days in env_holidays:
        app.log.info("%s is env holiday." % days)
        return True

    # Google Calendar APIから祝日判定
    url = 'https://www.googleapis.com/calendar/v3/calendars/japanese__ja@holiday.calendar.google.com/events'
    query = {
        'key': os.environ['GOOGLE_CALENDER_API_KEY'],
        'timeMin': now.strftime('%Y-%m-%d') + 'T00:00:00Z',
        'timeMax': now.strftime('%Y-%m-%d') + 'T23:59:59Z'
    }

    try:
        with urllib.request.urlopen('{}?{}'.format(url, urllib.parse.urlencode(query))) as r:
            response = json.loads(r.read())
            app.log.info(response)

            if r.getcode() != 200:
                app.log.error("Google Calendar API response not OK.")
                return True

            if 'items' in response and len(response['items']) > 0:
                summary = response['items'][0]['summary']
                app.log.info("{} is {}.".format(days, summary))
                return True

    except urllib.error.URLError as e:
        app.log.error(e.reason)
        return True

    return False
```

Google Cloudのコンソールから[Google Calendar API](https://console.cloud.google.com/marketplace/product/google/calendar-json.googleapis.com)を有効にしてAPIキーを発行します。

発行したAPIキーでこんな感じの呼び出しで祝日が取れればOK。
`https://www.googleapis.com/calendar/v3/calendars/japanese__ja@holiday.calendar.google.com/events?key=[API_KEY]&timeMin=2021-04-29T00:00:00Z&timeMax=2021-04-29T23:59:59Z`

発行したAPIキーと例外休日の設定を追加します。

```json:.chalice/config.json
{
  "version": "2.0",
  "app_name": "schedule-startstop",
  "stages": {
    "dev": {
      "lambda_timeout": 20,
      "environment_variables": {
        "DRYRUN": "True",
        "TZ": "Asia/Tokyo",
        "HOLIDAYS": "01/01,01/02,01/03,12/31",
        "GOOGLE_CALENDER_API_KEY": "**********************************"
      }
    }
  }
}
```

これでデプロイすれば祝日、例外休日判定付きで同じように使うことができます。
【NPM】package.jsonの中のdependenciesとdevDependenciesの違い

package.jsonの中のdependenciesとdevDependenciesの違いについて。

##目次

1. [dependenciesとdevDependenciesの違い](#dependenciesとdevdependenciesの違い)
1. [package.jsonの役割](#packagejsonの役割)
1. [dependenciesに追加する方法](#dependenciesに追加する方法)
1. [devDependenciesに追加する方法](#devdependenciesに追加する方法)
1. [npm installとは？](#npm-installとは)
1. [npm installとnpm updateの違い](#npm-installとnpm-updateの違い)
1. [どっちを使うべきか？](#どっちを使うべきか)
1. [（補足）dependenciesのみに追加する方法](#補足dependenciesのみに追加する方法)


<br>
##package.jsonの例

```json:package.json
{
  "name": "twitter",
  "private": true,
  "dependencies": {
    "@rails/actioncable": "^6.0.0",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "5.2.1",
    "turbolinks": "^5.2.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.11.2"
  }
}
```

##dependenciesとdevDependenciesの違い
**本番環境で使うパッケージか、開発環境で使うパッケージか**の違い。

通常、開発環境は変更内容の即時コンパイルやテスト機能など、本番では不要な処理を実行することが多い。

本番にも適用すると重くなってしまうため、本番と開発環境で必要な機能を分けている。


###・dependencies
本番環境で使うパッケージ。


###・devDependencies
開発環境でのみ使うパッケージ。ユニットテストやJSの縮小やコンパイルなど。


<br>
##package.jsonの役割
package.jsonに記述してあるパッケージは、実際に**インストールしたものではない**。

package.jsonはどのパッケージのどのバージョンをインストールするかを指定した買い物リスト。

実際にインストールしたパッケージは、package-lock.jsonに記載される。（自動記載のため編集不要）

```:インストールの流れ
package.json　（買い物リスト）
 ↓
npm install　（インストール）
 ↓
package-lock.json　（買ったもの）
```

<br>
##dependenciesに追加する方法
`npm install <パッケージ名>`を実行すると、package.jsonとpackage-lock.jsonのdependenciesの２つに追記される。

devDependenciesに追加したい場合は`--save-dev`オプションをつける。

###devDependenciesに追加する方法
オプションで`--save-dev`をつける。

`npm install --save-dev <パッケージ名>`を実行すると、package.jsonとpackage-lock.jsonのdevDependenciesの２つに追記される。


<br>
##npm installとは？
npm installを実施すると、package.jsonに記述されたパッケージがインストールされる。

dependenciesもdevDependenciesもどちらもインストールされる。


##npm installとnpm updateの違い
・`npm install`
package.jsonに記載してあるパッケージをインストールする。package-lock.jsonやyarn.lockに記載されている依存関係のあるパッケージもインストールする。

・`npm update`
package.jsonに記載されている最新のパッケージをインストールする。依存関係で不足しているパッケージがあればそれらも新たにインストールする。

https://docs.npmjs.com/cli/v7/commands/npm-install
https://docs.npmjs.com/cli/v6/commands/npm-update


###どっちを使うべきか？
`npm update`がおすすめ。不足しているパッケージもインストールしてくれる。



<br>
###（補足）dependenciesのみに追加する方法
オプションで`--production`をつける。

・`$npm install --production`
春なのでさくらの花と花びらをCSSで再現

# どうも7noteです。さくらの花と花びらをCSSで再現

（cssで作った花と花びらの見本）
![hana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/bb3bff6f-e2f1-a6ff-c8c7-b6a03ff492a1.png)
![hanabira.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/3ce52191-f92f-6054-3a90-fd792ce4b148.png)


再現シリーズ、季節に合わせていろいろ作っていきたいと思います。
季節に合わせたサイトとかって個人的にめっちゃ好きです。きれいなデザインやわかりやすい構成のWEBも素晴らしいと思いますが、どこかに造り手の遊び心が入っているサイトって素敵だなって思います。

そんなサイト作りができるクリエイターになりたいものですね。

ではでは日本の春といえば桜🌸かなと思ったのでさくらをCSSで再現していきます。

## さくらの花の作り方

![hana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/44fb4a6b-a69b-83d5-7758-7c71a8f24be2.png)

```index.html
<div class="sakura">
  <div class="petal01"></div>
  <div class="petal02"></div>
  <div class="petal03"></div>
  <div class="petal04"></div>
  <div class="petal05"></div>
</div>
```

```style.css
.sakura {
  position: relative;
}
	
.sakura div {
  width: 50px;
  height: 80px;
  background: #FBA5D1;
  border-radius: 50%;
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: center bottom 20px; /* 回転の基準を下の方に指定 */
}
.sakura .petal02 { transform: rotate(72deg);} /* 5枚なら72度ずつ */
.sakura .petal03 { transform: rotate(144deg);}
.sakura .petal04 { transform: rotate(216deg);}
.sakura .petal05 { transform: rotate(288deg);}

/* 三角形の花びらの先 */
.sakura div::before {
  content: "";
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 15px 10px 0 10px;
  border-color: #fff transparent transparent transparent; /* 背景色と同じ色を指定 */
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
}
```



## さくらの花びらの作り方

```index.html
<div class="petal"></div>
```

```style.css
.petal {
  width: 50px;
  height: 50px;
  background: #FBA5D1;
  border-radius: 100% 0 100% 0;
  position: relative;
}
	
.petal::after {
  content: "";
  position: absolute;
  top: -14%;
  left: -10%;
  display: block;
  width: 100%;
  height: 100%;
  background-color: #FBA5D1;
  border-radius: 100% 0 100% 0;
  transform: rotate(-15deg);
}
```

![hanabira.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/6cc1401b-2a6b-b41f-4fb4-e6a5fa580155.png)

## まとめ

この作り方でjsと組み合わせて桜吹雪を再現する方法もあるようです。

https://web-dev.tech/front-end/javascript/cherry-blossom-petal-falling-effect/

参考:https://web-dev.tech/front-end/javascript/cherry-blossom-petal-falling-effect/


他にもさくらの色としてで使えそうな色見本をいくつか用意していますので、お好みで好きな色で作ってみてください。

![color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/24269ddc-847b-e7cf-8d1a-4835639722e5.png)

```css
.A {background: #fdeeef;}
.B {background: #eddbd8;}
.C {background: #f4b3c2;}
.D {background: #EC90B8;}
.E {background: #FBA5D1;}
```

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
lstripとrstripのどっちがどっちか二度と忘れない

リファレンスマニュアルには先頭とか、末尾とか書いてあるので、lead?rear?とか考えたけど、

"l" = left
"r" = right

これでいいですよね。

##lstrip -> String
文字列の先頭にある空白文字を全て取り除いた新しい文字列を返します。空白文字の定義は " \t\r\n\f\v" です。

##rstrip -> String
文字列の末尾にある空白文字を全て取り除いた新しい文字列を返します。空白文字の定義は " \t\r\n\f\v\0" です。
さくらのクラウドのオブジェクトストレージが新しくなったので料金シミュレータを作ってみた

# 概要
本日さくらのクラウドのオブジェクトストレージがリニューアルオープンされました:hugging:

従来からのサポートしているS3互換APIに加えて、さくら間のデータ転送についてはデータ転送料がかからないという仕様になっております。
VPSをフロントエンドにしてログなどのデータの保存先という使い方に向いているかと思います。
合わせてある程度の利用量がセットになった基本料金が設定されているので、リクエスト数やオブジェクト数はカジュアルな用途であればこの範囲に収まるかとお思います。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100935/fc9febee-d521-7ea3-d8b4-1b3573c9f12d.png)
https://cloud.sakura.ad.jp/specification/object-storage/


# 簡易料金シミュレータ

従来と比較して料金計算の変数が増えたのでお見積りが円滑に行えるように簡易的なスプレッドシートを作成しました。

新オブジェクトストレージ料金シミュレータ
https://docs.google.com/spreadsheets/d/1fZ82LzW9kB5n7yNch7Xmd5nm6xWR4OehYhx2A7VnRFA/edit#gid=0

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100935/bc9e1b17-f8f5-5a74-6db7-e096f75e2fa3.png)

緑色の箇所に月間利用量の想定値を記載いただくことで概算が出力されます。

<font color="Red">**※本シミュレーションは簡易的なものであり、非公式なものであることを理解の上ご利用ください**</font>

それでは素敵なオブジェクトストレージライフを:raised_hands:
Pwnable.kr-[flag] writeup

>Papa brought me a packed present! let's open it.
>
>Download : http://pwnable.kr/bin/flag
>
>This is reversing task. all you need is binary

とりあえずwgetしてファイルを調べます。

```
soma@soma-E200HA:~/mine/pwnable/flag_pwn$ file flag
flag: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=96ec4cc272aeb383bd9ed26c0d4ac0eb5db41b16, not stripped
soma@soma-E200HA:~/mine/pwnable/flag_pwn$ ./flag
I will malloc() and strcpy the flag there. take it.
```
一見親切に見えますがgdbで何故かうまくデバッグできないのでstringsコマンドでもう一度調べると、UPXで圧縮されたファイルだとわかります。UPXって何だ？と思って調べてみると代表的な実行ファイル圧縮ソフトだそうです。こういうものがあるって教えてくれる問題みたいですね。
解凍して逆アセンブルします。

```
(gdb) disas main
Dump of assembler code for function main:
   0x0000000000401164 <+0>:	push   %rbp
   0x0000000000401165 <+1>:	mov    %rsp,%rbp
   0x0000000000401168 <+4>:	sub    $0x10,%rsp
   0x000000000040116c <+8>:	mov    $0x496658,%edi
   0x0000000000401171 <+13>:	callq  0x402080 <puts>
   0x0000000000401176 <+18>:	mov    $0x64,%edi
   0x000000000040117b <+23>:	callq  0x4099d0 <malloc>
   0x0000000000401180 <+28>:	mov    %rax,-0x8(%rbp)
   0x0000000000401184 <+32>:	mov    0x2c0ee5(%rip),%rdx        # 0x6c2070 <flag>
   0x000000000040118b <+39>:	mov    -0x8(%rbp),%rax
   0x000000000040118f <+43>:	mov    %rdx,%rsi
   0x0000000000401192 <+46>:	mov    %rax,%rdi
   0x0000000000401195 <+49>:	callq  0x400320
   0x000000000040119a <+54>:	mov    $0x0,%eax
   0x000000000040119f <+59>:	leaveq 
   0x00000000004011a0 <+60>:	retq   
End of assembler dump.
```
フラッグの場所そのまま書いてくれてますね。

```
(gdb) x/s *0x6c2070
0x496628:	"UPX...? sounds like a delivery service :)"
```