2024年6月28日金曜日

Blackhole-2ch の brew upgrade でエラー

Blackhole-2ch の brew upgrade でエラー

概要

Could not kickstart service "com.apple.audio.coreaudiod": 1: Operation not permitted

というエラーが出てアップグレードできなかったので対策方法を紹介します

環境

  • macOS 14.5
  • blackhole-2ch 0.6.0

対応方法

  • rm -rfi /opt/homebrew/Caskroom/blackhole-2ch/
  • brew reinstall blackhole-2ch

参考サイト

2024年6月27日木曜日

docker scout を Mac にインストールしてイメージのスキャンをしてみる

docker scout を Mac にインストールしてイメージのスキャンをしてみる

概要

docker scout はイメージの脆弱性をスキャンしてくれるツールです
docker のバージョンがある程度最新であればデフォルトで使えます
また dockerhub でもフリープランであれば3イメージまで scout スキャンを設定することができます

今回は Mac 上で動かして脆弱性に対応してみました

環境

  • macOS 11.7.10
  • docker 24.0.2

とりあえず使う

バージョン24であれば特にインストールは不要でいきなり使えます

  • docker scout quickview ruby:3.1.2

結果は以下の通りです

INFO New version 1.9.3 available (installed version is 0.16.1)
    ✓ Pulled
    ✓ Image stored for indexing
    ✓ Indexed 630 packages

  Your image  ruby:3.1.2                         │    7C    69H   134M   136L    11?   
  Base image  buildpack-deps:bullseye            │    6C    64H   132M   136L    11?   
  Refreshed base image  buildpack-deps:bullseye  │    1C     2H     3M   157L     3?   
                                                 │    -5    -62   -129    +21     -8   
  Updated base image  buildpack-deps:stable      │    1C     2H     3M   103L     3?   
                                                 │    -5    -62   -129    -33     -8   

What's Next?
  Learn more about vulnerabilities → docker scout cves ruby:3.1.2
  Learn more about base image update recommendations → docker scout recommendations ruby:3.1.2

脆弱性に対応してみる

  • docker scout recommendations ruby:3.1.2

これを実行すると対応方法を教えてくれます
基本はベースイメージを変更することで脆弱性に対応できるので dockerhub でベースイメージの別タグを探すと良いです

https://hub.docker.com/_/ruby/tags?page=&page_size=&ordering=&name=3.1.2 例えば 3.1.2 であれば 3.1.2-alpine3.14 にするだけでかなり減ります

  • docker scout quickview ruby:3.1.2-alpine3.14
INFO New version 1.9.3 available (installed version is 0.16.1)
    ✓ Pulled
    ✓ Image stored for indexing
    ✓ Indexed 128 packages

  Your image  ruby:3.1.2-alpine3.14  │    2C     8H     8M     0L          
  Base image  alpine:3.14            │    1C     2H     5M     0L          
  Updated base image  alpine:3.20    │    0C     0H     2M     0L     1?   
                                     │    -1     -2     -3            +1   

What's Next?
  Learn more about vulnerabilities → docker scout cves ruby:3.1.2-alpine3.14
  Learn more about base image update recommendations → docker scout recommendations ruby:3.1.2-alpine3.14

ただベースイメージを変更するとイメージ内で使用するコマンドも変わってくるのでベースイメージを変更した場合は Dockerfile などを書き換える必要がでてきます

Ruby のバージョンを上げることも検討する

3.1.2 -> 3.2.4 にすることで更に脆弱性を減らせます

  • docker scout quickview ruby:3.2.4-alpine3.20
INFO New version 1.9.3 available (installed version is 0.16.1)
    ✓ Provenance obtained from attestation
    ✓ SBOM obtained from attestation, 127 packages indexed
    ✓ Pulled

  Your image  ruby:3.2.4-alpine3.20  │    0C     0H     3M     0L     1?   
  Base image  alpine:3.20            │    0C     0H     2M     0L     1?   

What's Next?
  Learn more about vulnerabilities → docker scout cves ruby:3.2.4-alpine3.20

最後に

docker scout を試してみました
基本的に脆弱性が出たらベースイメージを変更することを検討しましょう

またイメージで使われているツールやソフトウェアの CVE もチェックできるのでソフトの脆弱性をチェックしたい場合は以下のコマンドを使いましょう

  • docker scout cves ruby:3.2.4-alpine3.20

参考サイト

2024年6月26日水曜日

Skype for mac で録音データが再生もダウンロードもできない場合の対処方法

Skype for mac で録音データが再生もダウンロードもできない場合の対処方法

概要

答え: Skype for cloud からダウンロードしましょう
Mac、iPhone の Skype では再生もダウンロードもできない状態です

環境

  • macOS 11.7.10
  • Skype for mac 8.122.0.205
  • Skype for cloud (2024/06/19時点)

状況

なぜか Mac 上だと再生もダウンロードもできません

ダウンロードしようとすると「ダウンロードに失敗しました」と表示されます

Skype for cloud

ここhttps://web.skype.com/?openPstnPage=true にログインするとブラウザで Skype が使えます

ここからだとダウンロードも再生もできました

最後に

Skype for Mac だとうまくダウンロードできない場合には Skype for cloud を試してみてください

それでもダメな場合は Windows クライアントなども試す価値はありそうです

2024年6月25日火曜日

Python で指定の cron が一日何回実行されるかカウントするスクリプト

Python で指定の cron が一日何回実行されるかカウントするスクリプト

概要

前回指定の日時にcronが実行されるかどうかチェックするスクリプトを作成しました
今回は更にそれを応用して指定の cron が一日に何回実行されるのかカウントしてみました

環境

  • macOS 11.7.10
  • Python 3.11.7
  • croniter 2.0.5

インストール

  • pipenv install croniter

サンプルスクリプト

from datetime import datetime, timedelta

from croniter import croniter


def count_run_today(cron_expression, target_date: str):
    # 指定の日付の開始、指定の日付の明日の開始時刻を取得
    target_datetime = datetime.strptime(target_date, "%Y/%m/%d")
    today_start = datetime(
        target_datetime.year, target_datetime.month, target_datetime.day
    ) - timedelta(seconds=1)
    tomorrow_start = today_start + timedelta(days=1) + timedelta(seconds=1)
    # cron オブジェクトの作成
    cron = croniter(cron_expression, today_start)
    # 当日内に実行される日時の分だけカウントする
    run_count = 0
    while True:
        # 次に実行される日時を取得
        next_run = cron.get_next(datetime)
        if today_start < next_run < tomorrow_start:
            run_count += 1
        else:
            break
    return run_count


# テスト正常系
print("正常系テスト")
print(count_run_today("0 12 * * *", "2024/06/24"))  # => 1
print(count_run_today("0 12 24 6 *", "2024/06/24"))  # => 1
print(count_run_today("*/1 * * * *", "2024/06/24"))  # => 1440
print(count_run_today("*/5 * * * *", "2024/06/24"))  # => 288
print(count_run_today("*/30 * * * *", "2024/06/24"))  # => 48
print(count_run_today("*/30 1 * * *", "2024/06/24"))  # => 2

最後に

当日分の cron が正しく全件実行されるか確認したいときに使えるスクリプトです

2024年6月24日月曜日

Python で指定の cron が当日実行されるかチェックするスクリプト

Python で指定の cron が当日実行されるかチェックするスクリプト

概要

例えば */5 * * * * は本日実行される cron で 30 12 22 6 * は本日実行されない cron というのを判定することができるスクリプトを紹介します

環境

  • macOS 11.7.10
  • Python 3.11.7
  • croniter 2.0.5

インストール

  • pipenv install croniter

サンプルスクリプト

from datetime import datetime, timedelta

from croniter import croniter


def will_run_today(cron_expression):
    # 今日の日付と今日の開始、明日の開始時刻を取得
    now = datetime.now()
    today_start = datetime(now.year, now.month, now.day) - timedelta(seconds=1)
    tomorrow_start = today_start + timedelta(days=1) + timedelta(seconds=1)
    # cron オブジェクトの作成
    cron = croniter(cron_expression, today_start)
    # 次に実行される日時を取得
    next_run = cron.get_next(datetime)
    # 次に実行される日時が今日中であればTrueを返す
    return today_start < next_run < tomorrow_start


# テスト正常系(2024/06/21(木)に実行した想定)
print("正常系テスト")
print(will_run_today("0 12 * * *"))
print(will_run_today("*/5 * * * *"))
print(will_run_today("*/1 * * * *"))
print(will_run_today("*/30 * * * *"))
print(will_run_today("*/30 5 * * *"))
print(will_run_today("*/30 5 * 6 *"))
print(will_run_today("*/30 5 * 6 *"))
print(will_run_today("59 23 21 6 *"))
print(will_run_today("59 23 * * 5"))
print(will_run_today("59 23 21 6 5"))
print(will_run_today("1 0 21 6 5"))
print(will_run_today("0 0 * * *"))
print(will_run_today("0 0 21 6 5"))
print(will_run_today("*/30 * * * 1-5"))

# テスト異常系
print("異常系テスト")
print(will_run_today("0 12 3 2 *"))
print(will_run_today("0 12 22 6 *"))
print(will_run_today("*/5 * 22 6 *"))
print(will_run_today("*/1 * * * 4"))
print(will_run_today("*/1 * * * 0,1,2,3,4,6"))
print(will_run_today("30 12 22 * *"))

おまけ: 指定の日付に実行されたかどうかチェックするように修正する

from datetime import datetime, timedelta

from croniter import croniter


def will_run_today(cron_expression, target_date: str):
    # 指定の日付の開始、指定の日付の明日の開始時刻を取得
    target_datetime = datetime.strptime(target_date, "%Y/%m/%d")
    today_start = datetime(
        target_datetime.year, target_datetime.month, target_datetime.day
    ) - timedelta(seconds=1)
    tomorrow_start = today_start + timedelta(days=1) + timedelta(seconds=1)
    # cron オブジェクトの作成
    cron = croniter(cron_expression, today_start)
    # 次に実行される日時を取得
    next_run = cron.get_next(datetime)
    # 次に実行される日時が指定日時内であればTrueを返す
    return today_start < next_run < tomorrow_start


# テスト正常系(2024/06/21(木)に実行した想定)
print("正常系テスト")
print(will_run_today("0 12 * * *", "2024/06/21"))
print(will_run_today("0 12 3 2 *", "2024/02/03"))
print(will_run_today("*/1 * * * *", "2024/01/01"))
print(will_run_today("0 0 * * *", "2024/01/01"))

# テスト異常系
print("異常系テスト")
print(will_run_today("0 12 22 6 *", "2024/06/21"))

最後に

cron が大量にありその中で本日実行されるのが何個あるのかチェックしたりするのに使えます

2024年6月21日金曜日

Slidev を docker で動かす

Slidev を docker で動かす

概要

Slidev は markdown でスライドが作成できるツールです
今回は簡単な使い方を紹介します

環境

  • macOS 11.7.10
  • docker 24.0.2
  • slidev 0.49.10

markdown 作成

適当な markdown を作成しましょう
ファイル名は slides.md にします

  • vim slides.md
# Slidevへようこそ!

開発者のためのプレゼンテーションスライド

---

# Page 2

- 📄 スライドを1つのMarkdownファイルで
- 🌈 テーマ、コードブロック、インタラクティブなコンポーネント
- 😎 詳しくはドキュメントをご覧ください!|

起動

docker run --name slidev --rm -it \
    --user node \
    -v ${PWD}:/slidev \
    -p 3030:3030 \
    -e NPM_MIRROR="https://registry.npmmirror.com" \
    tangramor/slidev:latest

マウントしているカレントに node_modules なども作成されるので注意しましょう
次回以降同じディレクトリで動作しないと再度作成されてしまいます

動作確認

http://localhost:3030/ にアクセスするとスライドが確認できます

セクションが長すぎると画面をはみ出てしまうのではみ出る場合はセクション内の文章を短くしましょう

最後に

少し記法が特殊な部分があるのでそこは対応が必要です
YAML ヘッダなどは使えます

参考サイト

2024年6月20日木曜日

Github Actions で rubygems に自動で push する (2要素認証対応あり)

Github Actions で rubygems に自動で push する (2要素認証対応あり)

概要

前回 dockerhub に push するアクションを作成しました
今回は rubygems に push するアクションを作成しました

環境

  • macOS 11.7.10
  • GithubActions v3
  • rubygems (2024/06/18時点)

gem.yml

  • vim .github/workflows/gem.yml
name: ci

on:
  workflow_dispatch:
    inputs:
      rubygems-otp-code:
        description: RubyGems OTP code
        required: true

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.2.2
      - run: bundle install

      - name: Setup git config
        run: |
          git config --global user.email "your-github-email-address@xxx.com"
          git config --global user.name "your-github-name"

      - name: git
        run: |
          git status
          git diff

      - name: Publish to RubyGems
        run: bundle exec rake release
    env:
      GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}

Rubygems の API キーの取得

設定 -> API キー

で作成できます
rubygems に push できる権限を扶養しましょう

RUBYGEMS_API_KEY の登録

リポジトリのシークレットに登録します

自分のプロジェクト -> Settings -> Secrets and variables -> Actions -> Repository secrets -> New repository secret

トラブルシューティング

There are files that need to be committed first.

ローカルの開発環境が Mac の場合 nokogiri など darwin 用のパッケージがインストールされます

     nokogiri (1.16.6-x86_64-darwin)
       racc (~> 1.4)

この状態の Gemfile.lock で Github Actions 上の Ubuntu で bundle install を実行すると linux 用の nokogiri がインストールされます

+    nokogiri (1.16.6-x86_64-linux)
+      racc (~> 1.4)

Github Actions では必ずこれがインストールされてしまうので事前に Mac 上で Linux 用のパッケージも追加してあげる必要があります

  • bundle lock --add-platform linux

You have enabled multi-factor authentication.

Rubygems で 2auth を有効にしている場合はワンタイムパスワードを入力する必要があります

env に GEM_HOST_OTP_CODE: ${{ github.event.inputs.rubygems-otp-code }} を追加することでアクション実行時にワンタイムパスワードを入力することができるのでこれで対応します

動作確認

version.rb や bundle update をして何かしら更新しましょう
そして Github に push します

今回ワークフローは手動でなので手動実行します
さらにワンタイムパスワードを入力しましょう

するとワークフローが実行されて version.rb に記載した新しいバージョンの gem が公開されていることが確認できると思います

最後に

Github Actions で rubygems に自動で push してみました
master に push されると自動で実行されます

Rubygems の API キーには有効期限があるので切れた場合は再度 Github に登録してあげましょう

参考サイト

2024年6月19日水曜日

FastAPI のデフォルトのバリデーションエラーをハンドリングするサンプルコード

FastAPI のデフォルトのバリデーションエラーをハンドリングするサンプルコード

概要

RequestValidationError をハンドリングします

環境

  • macOS 11.7.10
  • Python 3.11.6
  • fastapi 0.111.0

サンプルコード

Request と RequestValidationError のリファレンスは参考サイトに記載しています

from fastapi import FastAPI
from fastapi.exceptions import RequestValidationError
from pydantic import BaseModel, Field
from starlette.requests import Request
from starlette.responses import JSONResponse

app = FastAPI()


class Item(BaseModel):
    message: str = Field(max_length=10)


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    # print(request)
    errs = exc.errors()
    print(errs)
    return JSONResponse(
        {"error_field": errs[0]["loc"][1], "message": errs[0]["msg"]}, status_code=400
    )


@app.post("/")
async def post_msg(item: Item):
    return {
        "message": item.message,
    }

最後に

errors で取得した情報は配列なので扱いには注意しましょう

参考サイト

2024年6月18日火曜日

rq-dashboard を nginx 配下で動作させる設定のサンプル

rq-dashboard を nginx 配下で動作させる設定のサンプル

概要

compose.yaml と nginx.conf の設定ファイルを紹介します
ポイントは RQ_DASHBOARD_URL_PREFIX を設定する点です

環境

  • Ubuntu 22.04.4
  • docker 26.1.1
  • rq-dashboard 0.7.0

nginx.conf

upstream rq_dashboard {
    server 192.168.0.100:9181;
}

server {
    listen 80;
    server_name host01;

    location = /rq_dashboard {
        return 302 /rq_dashboard/;
    }

    location /rq_dashboard/ {
        proxy_set_header Host $host;
        proxy_pass http://rq_dashboard;
    }
}

compose.yaml

services:
  rq_dashboard:
    image: eoranged/rq-dashboard
    environment:
      RQ_DASHBOARD_REDIS_URL: redis://192.168.0.101:6379
      RQ_DASHBOARD_USERNAME: user01
      RQ_DASHBOARD_PASSWORD: xxx
      RQ_DASHBOARD_URL_PREFIX: /rq_dashboard
    ports:
      - 9181:9181

最後に

スラッシュなしをリダイレクトしているのはなぜかうまく Chrome がリダイレクトしてくれないので明示的にリダイレクトルールを記載しています

参考サイト

2024年6月17日月曜日

Cloudbeaver を nginx で動作させる方法

Cloudbeaver を nginx で動作させる方法

概要

rootURI を編集します
設定ファイルを置くパスがポイントです

環境

  • Ubuntu 22.04
  • docker 26.1.1
  • dbeaver 24.1.0
  • MySQL 8.0.36

dbeaver 用 compose.yaml

/opt/cloudbeaver/conf/cloudbeaver.conf に設定ファイルを配置します
dbeaver は 192.168.0.100:8978 で動作します

services:
  dbeaver:
    image: dbeaver/cloudbeaver:24.1.0
    volumes:
      - type: volume
        source: dbeaver
        target: /opt/cloudbeaver/workspace
      - type: bind
        source: /home/user01/work/cloudbeaver.conf
        target: /opt/cloudbeaver/conf/cloudbeaver.conf
    ports:
      - 8978:8978
    restart: always

volumes:
  dbeaver:

cloudbeaver.conf

少し長いですがすべて掲載しています
変更するのは冒頭の rootURI の部分だけです
それ以外はすべてデフォルトの設定です

今回は /dbeaver で受けます

{
    server: {
        serverPort: 8978,

        workspaceLocation: "workspace",
        contentRoot: "web",
        driversLocation: "drivers",

        sslConfigurationPath:"${CLOUDBEAVER_SSL_CONF_PATH:workspace/.data/ssl-config.xml}",

        rootURI: "/dbeaver",
        serviceURI: "/api/",

        productSettings: {
            # Global properties
            core.theming.theme: 'light',
            core.localization.localization: 'en',
            plugin.sql-editor.autoSave: true,
            plugin.sql-editor.disabled: false,
            # max size of the file that can be uploaded to the editor (in kilobytes)
            plugin.sql-editor.maxFileSize: 10240,
            plugin.log-viewer.disabled: false,
            plugin.log-viewer.logBatchSize: 1000,
            plugin.log-viewer.maxFailedRequests: 3,
            plugin.log-viewer.maxLogRecords: 2000,
            plugin.log-viewer.refreshTimeout: 3000,
            sql.proposals.insert.table.alias: PLAIN
        },

        expireSessionAfterPeriod: 1800000,

        develMode: false,

        enableSecurityManager: false,

        sm: {
            enableBruteForceProtection: "${CLOUDBEAVER_BRUTE_FORCE_PROTECTION_ENABLED:true}",
            maxFailedLogin: "${CLOUDBEAVER_MAX_FAILED_LOGINS:10}",
            minimumLoginTimeout: "${CLOUDBEAVER_MINIMUM_LOGIN_TIMEOUT:1}",
            blockLoginPeriod: "${CLOUDBEAVER_BLOCK_PERIOD:300}",
            passwordPolicy: {
                minLength: "${CLOUDBEAVER_POLICY_MIN_LENGTH:8}",
                requireMixedCase: "${CLOUDBEAVER_POLICY_REQUIRE_MIXED_CASE:true}",
                minNumberCount: "${CLOUDBEAVER_POLICY_MIN_NUMBER_COUNT:1}",
                minSymbolCount: "${CLOUDBEAVER_POLICY_MIN_SYMBOL_COUNT:0}"
            }
        },

        database: {
            driver: "h2_embedded_v2",
            url: "jdbc:h2:${workspace}/.data/cb.h2v2.dat",
            initialDataConfiguration: "conf/initial-data.conf",
            pool: {
                minIdleConnections: 4,
                maxIdleConnections: 10,
                maxConnections: 100,
                validationQuery: "SELECT 1"
            },
            backupEnabled: "${CLOUDBEAVER_DB_BACKUP_ENABLED:true}"
        }

    },
    app: {
        anonymousAccessEnabled: true,
        anonymousUserRole: "user",
        defaultUserTeam: "user",
        grantConnectionsAccessToAnonymousTeam: false,
        supportsCustomConnections: false,
        showReadOnlyConnectionInfo: false,
        systemVariablesResolvingEnabled: "${CLOUDBEAVER_SYSTEM_VARIABLES_RESOLVING_ENABLED:false}",

        forwardProxy: false,

        publicCredentialsSaveEnabled: true,
        adminCredentialsSaveEnabled: true,

        resourceManagerEnabled: true,

        resourceQuotas: {
            dataExportFileSizeLimit: 10000000,
            resourceManagerFileSizeLimit: 500000,
            sqlMaxRunningQueries: 100,
            sqlResultSetRowsLimit: 100000,
            sqlResultSetMemoryLimit: 2000000,
            sqlTextPreviewMaxLength: 4096,
            sqlBinaryPreviewMaxLength: 261120
        },
        enabledAuthProviders: [
            "local"
        ],

        disabledDrivers: [
            "sqlite:sqlite_jdbc",
            "h2:h2_embedded",
            "h2:h2_embedded_v2",
            "clickhouse:yandex_clickhouse"
        ],
        disabledBetaFeatures: [

        ]

    }

}

nginx.conf

location /dbeaver/ を定義します
proxy_set_header 系はそのままコピペで OK です

location = /dbeaver はリダイレクト用でなぜか自動でブラウザがリダイレクトしてくれないケースがあるので明示しておきます
末尾のスラッシュがない場合にスラッシュのある URI に移動させます

upstream dbeaver {
    server 192.168.0.100:8978;
}


server {
    listen 80;
    server_name my_nginx;

    location = /dbeaver {
        return 302 /dbeaver/;
    }

    location /dbeaver/ {
        proxy_pass http://dbeaver;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

動作確認

これで nginx と dbeaver を起動させ nginxのアドレス/dbeaver にアクセスすると画面が表示されます

最後に

DBeaver を nginx 配下で動作させる方法を紹介しました
サブディレクトリを指定する場合は dbeaver 側の rootURI も変更する必要があります

参考サイト

2024年6月14日金曜日

DBeaver でセッションタイムアウトを設定する方法

DBeaver でセッションタイムアウトを設定する方法

概要

cbadmin のセッションが切れる時間を伸ばす方法を紹介します

環境

  • Ubuntu 22.04
  • docker 26.1.1
  • dbeaver 24.1.0
  • MySQL 8.0.36

設定方法

  • 右上歯車 -> Administration -> Server configuration -> Session lifetime

単位は分です

この設定が /opt/cloudbeaver/workspace/.data/.cloudbeaver.runtime.con あたりにないのでどこに保存されているのか不明です

2024年6月13日木曜日

隠しディレクトリや隠しファイルに対して grep する方法

隠しディレクトリや隠しファイルに対して grep する方法
cd /
find . -name ".*" -type f | xargs grep -i "hoge"

2024年6月10日月曜日

OAuth2 Proxy と nginx を組み合わせる方法

OAuth2 Proxy と nginx を組み合わせる方法

概要

前回 oauth2-proxy を構築しました
今回はその構築したプロキシを使って nginx と組み合わせてみます

環境

  • Ubuntu 22.04
  • golang 1.22.3
  • oauth2-proxy 7.6
  • nginx 1.18.0

nginx.conf (default) の修正

  • vim /etc/nginx/sites-available/default

最低限設定が必要な箇所だけ紹介します
server ディレクティブを編集します

location /oauth2/location = /oauth2/auth は必須です
そして認証をかけたい部分 (今回だと location /) に auth_request と error_page お記載します

こうすることで / にアクセスされた際に oauth2-proxy に認証させることができます

server {
	listen 80 default_server;
	listen [::]:80 default_server;

	location /oauth2/ {
		proxy_pass       http://localhost:4180;
		proxy_set_header Host                    $host;
		proxy_set_header X-Real-IP               $remote_addr;
		proxy_set_header X-Auth-Request-Redirect $request_uri;
		# or, if you are handling multiple domains:
		# proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
	}
	location = /oauth2/auth {
		proxy_pass       http://localhost:4180;
		proxy_set_header Host             $host;
		proxy_set_header X-Real-IP        $remote_addr;
		proxy_set_header X-Forwarded-Uri  $request_uri;
	        # nginx auth_request includes headers but not body
	        proxy_set_header Content-Length   "";
		proxy_pass_request_body           off;
	}

	root /var/www/html;
	index index.html index.htm index.nginx-debian.html;
	server_name _;

	location / {
		auth_request /oauth2/auth;
		error_page 401 =403 /oauth2/sign_in;
		try_files $uri $uri/ =404;
	}
}

oauth2-proxy 側は

前回の設定のままで OK です

動作確認

  • sudo systemctl restart nginx

で再起動し localhost にアクセスすると認証ページに移動することを確認します

Tips

nginx は当然アクセスできる必要があるのですが auth2-proxy にもクライアントからアクセスできる必要があります
これはリダイレクト先が auth2-proxy になっているためで auth2-proxy のリダイレクト URL にブラウザからアクセスできないと認証情報が受け取れないためです
なのでクライアントには 80 と 4180 の auth2-proxy のポートも開放する必要があります

最後に

oauth2-proxy と nginx を組み合わせてみました
認証後の情報がバックエンド側のアプリでほしい場合には nginx 側でスルーするヘッダなどを設定しましょう

参考サイト

2024年6月7日金曜日

OAuth2 Proxy を Onelogin で使ってみる

OAuth2 Proxy を Onelogin で使ってみる

概要

oauth2-proxy は nginx や traefik などでホスティングした静的ページに対して認証をつけることができるツールです
今回はとりあえず単体で動かしてみました
また今回紹介する設定は localhost で動作させる設定になります

環境

  • Ubuntu 22.04
  • golang 1.22.3
  • oauth2-proxy 7.6

インストール

  • go install github.com/oauth2-proxy/oauth2-proxy/v7@latest

Onelogin のシークレットの取得

こちらの記事を参考に取得します

localhost.cfg

provider = "oidc"
redirect_url = "http://localhost:4180/oauth2/callback"
oidc_issuer_url = "https://xxxxx.onelogin.com/oidc/2"
upstreams = [
    "http://0.0.0.0"
]
email_domains = [
    "*"
]
client_id = "xxx"
client_secret = "xxx"
pass_access_token = true
cookie_secret = "hTsaC2-8_RVIU4VmTRsC_A=="
cookie_secure = false
skip_provider_button = true
# Note: use the following for testing within a container
http_address = "0.0.0.0:4180"

設定するべき項目は以下です

  • oidc_issuer_url -> Onelogin が発行する OAuth 用の URL を入力します
  • client_id -> Onelogin で取得したクライアントIDを入力します
  • client_secret -> Onelogin で取得したクライアントシークレットを入力します
  • cookie_secret -> クッキーを暗号化するための文字列を取得します

cookie_secret は以下のようなコマンドで推測されにくいランダムな文字列を設定することをオススメします

python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(16)))'

認証後は upstreams に指定している URL の情報が表示されます

oauth2-proxy の起動

  • oauth2-proxy --config ./localhost.cfg

これで localhost:4180 にアクセスすると Onelogin の認証画面になります
認証が成功すると upstreams に設定した URL のコンテンツ情報が表示されます

最後に

OAuth2 Proxy を単体で動作させてみました
まずは単体で動作させてどういう挙動になるのか確認したほうが良いかなと思います

次回は nginx と連携してみます

参考サイト

2024年6月6日木曜日

cron 情報を可視化する cronv を試してみる

cron 情報を可視化する cronv を試してみる

概要

cronv は crontab の情報から html ファイルを生成してくれるツールです

環境

  • Ubuntu 22.04
  • golang 1.22.3
  • cronv 0.4.5

インストール

  • go install -v github.com/takumakanari/cronv/cronv@0.4.5

使ってみる

  • crontab -l | cronv -o ./my_cron_schedule.html

間隔を指定する

基本は6時間分しか出力しないので24時間を指定します
-d オプションを使います

  • crontab -l | cronv -o ./my_cron_schedule.html -d 24h

開始時間を指定する

--from-date オプションを使います

  • crontab -l | cronv -o ./my_cron_schedule.html -d 24h --from-date 2024/06/05

文字列から生成する

パイプで文字列を渡せば良いだけなので crontab -l でなくても OK です

  • echo "*/5 8 * * 0,1,2,3,4 ls" | cronv -o ./my_cron_schedule.html -d 24h --from-date 2024/06/05

タイトルを指定する

生成される html の先頭のタイトルを変更します

  • echo "*/5 8 * * 0,1,2,3,4 ls" | cronv -o ./my_cron_schedule.html -d 24h --from-date 2024/06/05 --title test

動作確認

バーの数が実行される数になります
横軸は1時間になるので1時間で何回実行されるのか確認できます

最後に

cronv で crontab 情報を可視化してみました
html を生成してくるだけなので動的に変更したい場合は何かしらの仕掛けが必要になりそうです

-d を使えば表示する間隔は変更できますが例えば毎月2日に実行するようなルールでもプロットはしてしまうので毎日実行するような cron 情報しかプロットできません

参考サイト

2024年6月5日水曜日

Dbeaver を docker で動かして MySQL に接続してみる

Dbeaver を docker で動かして MySQL に接続してみる

概要

dbeaver はいろいろなデータベースに対応したクライアントツールでテーブルの一覧や好きな SQL を発行することができます
phpMyAdmin の代替として使えます

基本はマシン上で動作するクライアントアプリですが今回は docker 上で動かしてみました

環境

  • Ubuntu 22.04
  • docker 26.1.1
  • dbeaver 24.1.0
  • MySQL 8.0.36

起動

以下のコマンド一発です
起動すると 8080 ポートで起動します
エンタープライズエディションもありますがアクティベーションキーが必要になるのでコミュニティエディションを使います

  • docker run --name cloudbeaver-ee --rm -ti -p 8080:8978 -v $(pwd):/opt/cloudbeaver/workspace dbeaver/cloudbeaver:latest

cbadmin ユーザのパスワードを設定

起動するとまず初期設定をします
必ず設定しなければいけないのは管理者のパスワードです
パスワードにはポリシーがあるのでそれに沿ったパスワードにしましょう

MySQL のコネクタを作成する

管理者のパスワードを設定すると次にコネクションテンプレートというテンプレートを作成する画面になりますがそこはスルーして一度トップ画面に戻ります
そして上部のプラスボタンからコネクションを作成します

テンプレートを作成しない理由としては本当はテンプレートからコネクションを作成できるボタンがあるのですがコミュニティエディションだとそれがなかったのでテンプレートを作成する意味がないからです

いろいろなデータベースコネクタがあるので MySQL を選択します

データベースの情報を入力する

次に接続先のデータベースの情報を入力します
今回は docker 上で動作させているので localhost だとコンテナにアクセスしに行ってしまうので基本は IP や FQDN を入力することになります

IP で接続できない場合は

MySQL はデフォルトだと localhost からのみアクセスできるようになっています
今回は docker 上のコンテナの IP (ex 172.17.0.2) からのアクセスになるのでその IP からのアクセスを許可します

こちらを参考に特定の IP からでもアクセスできるユーザを作成します

Public Key Retrieval is not allowed

接続テストをした際に「Public Key Retrieval is not allowed」エラーが出る場合にはドライバの設定を変更します

DRIVER PROPERTIES タブを選択し「allowPublicKeyRetrieval」を TRUE に設定します

これで再度右上の「Test」をクリックして接続テストしてください

動作確認

コネクションが作成できたらデータベースやテーブルの一覧が表示できることを確認しましょう

よくわからないのですがコネクション作成時にデータベースを指定してもすべてのデータベース情報を取得するようです

最後に

Dbeaver を docker で動かしてみました
コミュニティエディションなので一部機能が使えなかったりするようです
閲覧するだけならこれで十分かなと思います
またダークモードや好きな SQL を発行する機能もあるので便利です

MySQL の Web クライアントで phpMyAdmin の代替になりそうなツールとして他にも ILLA Builder というツールを紹介しています

Dbeaver 自体は Java で書かれています

参考サイト

2024年6月4日火曜日

M2 mac mini 上で sd-scripts を動かして LoRA 学習させる方法

M2 mac mini 上で sd-scripts を動かして LoRA 学習させる方法

概要

前回 kohya_ss webui を使って sd-scripts が実行できる環境を用意しました
今回は kohya_ss webui を使って LoRA 学習してみたいと思います

環境

  • macOS 14.5
  • kohya_ss (24.1.4 5ed5623)
  • Python 3.10.13

画像の準備

今回は 512x512 画像を 4 枚用意しました
枚数は多ければ多いほど良いですが画像が多いとそれだけ学習時間もかかります
また M2 mac mini のスペックにも影響しており画像が多いとメモリを多大に消費するため可能な限り少なく効率の良い画像を学習させるのが良いかなと思います

作成した画像は今回は ~/Downloads/data/5_hawksnowlog というディレクトリ配下に配置します
ポイントはディレクトリ名で 学習回数_識別名 という感じで指定しないと sd-scripts が画像を発見できません

学習回数は学習させる枚数をかけた分影響するので学習回数が多いと学習にかかる時間も線形的に増えるので注意しましょう

タグ情報の準備

なくても OK ですがあったほうがいいと思います
こちらを参考に抽出/付与しましょう

また何か独自のタグをいれるとより LoRA で学習させたモデルを強調することができます

パラメータの設定

まずは LoRA タブに移動します
そして各種パラメータを設定していきます

WebUI 上でも OK です
M2 上で動作させるには以下の設定が必須です

  • Image folder (containing training images subfolders) -> ~/Downloads/data
  • Trained Model output name -> 5_hawksnowlog
  • Output directory for trained model -> model
  • Mixed precision -> no
  • Optimizer -> AdamW
  • CrossAttention -> none
  • Save precision -> float
  • Max train steps -> 200 (ここも学習時間に影響するので適宜変更

デフォルトでは見えない設定もあるのですべての項目を一度開いて設定項目名で研削すれば見つかるはずです

sd-scripts の実行には設定ファイルが必要ですが kohya_ss は webui で設定した値から自動で toml 設定ファイルを作成してくれます

最終的には実行後に以下の設定ファイルが model 配下にあれば OK です

bucket_no_upscale = true
bucket_reso_steps = 64
cache_latents = true
caption_extension = ".txt"
clip_skip = 1
dynamo_backend = "no"
enable_bucket = true
epoch = 1
gradient_accumulation_steps = 1
huber_c = 0.1
huber_schedule = "snr"
learning_rate = 0.0001
logging_dir = "log"
loss_type = "l2"
lr_scheduler = "cosine"
lr_scheduler_args = []
lr_scheduler_num_cycles = 1
lr_scheduler_power = 1
lr_warmup_steps = 160
max_bucket_reso = 2048
max_data_loader_n_workers = 0
max_grad_norm = 1
max_timestep = 1000
max_token_length = 75
max_train_steps = 200
min_bucket_reso = 256
mixed_precision = "no"
multires_noise_discount = 0.3
network_alpha = 1
network_args = []
network_dim = 8
network_module = "networks.lora"
noise_offset_type = "Original"
optimizer_args = []
optimizer_type = "AdamW"
output_dir = "model"
output_name = "5_hawksnowlog"
pretrained_model_name_or_path = "runwayml/stable-diffusion-v1-5"
prior_loss_weight = 1
resolution = "512,512"
sample_prompts = "model/prompt.txt"
sample_sampler = "euler_a"
save_every_n_epochs = 1
save_model_as = "safetensors"
save_precision = "float"
text_encoder_lr = 0.0001
train_batch_size = 1
train_data_dir = "/Users/hawksnowlog/Downloads/data"
unet_lr = 0.0001
xformers = false

実行

WebUI で実行する場合は「Start training」で OK です

安定しない場合はコマンドでも OK です
toml ファイルは webui が生成したもので大丈夫ですが値が間違っている場合は手動で toml ファイルを変更して学習を開始しましょう

  • cd kohya_ss
  • /Users/username/Documents/work/kohya_ss_3_10_13/venv/bin/python /Users/username/Documents/work/kohya_ss_3_10_13/sd-scripts/train_network.py --config_file model/config_lora-20240530-131543.toml

動作確認

4 ファイルで 5 回の学習回数でステップ数 200 にしてだいたい 30 分ほどで完了しました
かなり少なめで学習させたのでもう少し画像を増やしたり学習回数を増やしてもいいかもしれません

学習が完了すると model/5_hawksnowlog.safetensors ができています

最後に

M2 mac mini 上で Stable Diffusion のモデルを LoRA で Fine-Tuning してみました
内部的には sd-scripts という学習ツールを webui で叩いているだけなので直接 sd-scripts を触ってしまっても OK です

次回は作成した LoRA を使って sd-webui 上で LoRA の動作確認をしてみたいと思います

トラブルシューティング

libc++abi: terminating due to uncaught exception of type NSException

なぜか webui から学習が開始できなくなってしまう状況が発生しました
バックグラウンドで何か動いてしまっているのでマシンを再起動してあげれば解消しました

output_name で指定したモデルがすでにあると発生するようです、名前を変更してあげましょう

AttributeError: module 'torch' has no attribute 'compiler'

なぜか xformers ディレクトリが作成されており参照してしまっているので削除しましょう

  • rm -rf ./venv/lib/python3.10/site-packages/xformers*

参考サイト

2024年6月3日月曜日

sd-webui を使って画像のタグ情報を抽出したりタブ情報を付与する方法

sd-webui を使って画像のタグ情報を抽出したりタブ情報を付与する方法

概要

stable-diffusion-webui-wd14-tagger を使います

環境

  • macOS 14.5
  • sd-webui 1.9.4
  • Python 3.10.13
  • stable-diffusion-webui-wd14-tagger 1.2.0

インストール

例のごとく Extensions から URL を指定すれば OK です

インストールとは Apply and restart UI しましょう

タグ情報の抽出

Tagger タグが webui 上に追加されているのでそこから行います
今回は一枚の画像ではなく複数の画像に対して行うので「Batch from directory」に切り替えます

最低限入力する箇所は以下です

  • Input directory -> 画像があるディレクトリ
  • Output directory -> 画像があるディレクトリ
  • Additional tags -> 追加したいタグ

であとは「Interrogate」をクリックすればタグの抽出が行われます

タグ情報の保存

画面真ん中くらいにある保存ボタンを押せば OK です
あとは Output directory 配下に「画像ファイル名.txt」の形式でタグ情報が画像ごとに保存されます

最後に

sd-webui で画像からタグ情報を抽出してみました
タグを抽出する目的は大きく2つです

  • LoRA 学習に使える
  • 画像を生成するのにどういったプロンプトを投げればいいのか把握できる

2024年6月1日土曜日

kohya_ss webui を M2 mac mini 上で動作させる

kohya_ss webui を M2 mac mini 上で動作させる

概要

bmaltais/kohya_ss は sd-scripts という StableDiffusion の LoRA モデルや DreamBooth トレーニングを行うためのスクリプト郡を WebUI で実行できるようにしたツールです
今回は M2 mac mini 上で動作させてみました

環境

  • macOS 14.5
  • kohya_ss (24.1.4 5ed5623)
  • Python 3.10.13

インストール

  • pyenv install 3.10.13
  • git clone --recursive https://github.com/bmaltais/kohya_ss.git
  • cd kohya_ss
  • pyenv local 3.10.13
  • chmod +x ./setup.sh
  • ./setup.sh

必要なパッケージなどはすべて自動でインストールしてくれます

動作確認

  • ./gui.sh

これで localhost:7860 で起動します

最後に

sd-scripts 専用の webui ツール kohya_ss を M2 mac mini 上で動作させてみました
次回はこれを使って LoRA モデルを作成してみたいと思います

参考サイト