2024年9月27日金曜日

git submodule で module 側のコミットを更新する方法

git submodule で module 側のコミットを更新する方法

概要

まず大前提として git submodule は module のコミットをハッシュを管理しています
もうちょっと砕いて言うと submodule として登録したリポジトリは常に HEAD ではなく特定のコミットハッシュと紐づいています

なので git submodule update -i をしても最新の HEAD に移動しないことがあります

今回はそんな場合に submodule 側を HEAD に移動する方法を紹介します

環境

  • git 2.46.1

更新する方法

submodule のディレクトリに入って pull します
master の HEAD のコミットハッシュと新たに紐づけを行いたい場合は以下の通りです

  • cd main_repo/submodule_repo
  • git pull origin master
  • cd …
  • git status
On branch feature/test
Your branch is up to date with 'origin/feature/test'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   submodule_repo (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

こんな感じで main_repo と submodule_repo のコミット IDの紐づけが更新される差分が出ますの状態を確認すると

git submodule コマンドで紐づいているコミットIDが確認できます

+86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 api (1.1.0-233-g61128974)

プラスマークは新たに更新されている場合に表示されます
逆にマイナスマークは紐づいているコミットIDとに齟齬がある場合に表示されます
プラスもマイナスも表示されない場合は正しいコミットIDの submodule が使われていることになります

最後に

正直 submodule はややこしいのとコミットIDの管理が面倒なので使いたくないです

参考サイト

2024年9月24日火曜日

Python3.11 以上で SSLV3_ALERT_HANDSHAKE_FAILURE が出る場合の対応方法

Python3.11 以上で SSLV3_ALERT_HANDSHAKE_FAILURE が出る場合の対応方法

概要

Cipher が変わったらしい

環境

  • Ubuntu 22.04
  • Python 3.11.10
  • requests 2.32.3

対応方法

  • pipenv install urllib3==1.26.18

最後に

requests でも python でもなく urllib3 が原因のようです

2024年9月20日金曜日

Flask でベーシック認証を実装する方法

Flask でベーシック認証を実装する方法

概要

特にライブラリを使わずに実装する方法を紹介します

環境

  • macOS 14.6.1
  • Python 3.11.10
  • Flask 3.0.3

デコレータを使う方法

from flask import Flask, Response, request

app = Flask(__name__)

# 認証情報(ユーザー名とパスワードをハードコーディング)
USERNAME = "admin"
PASSWORD = "password"


# 認証を行う関数
def check_auth(username, password):
    """ユーザー名とパスワードをチェックする"""
    return username == USERNAME and password == PASSWORD


# 認証を要求するレスポンスを返す関数
def authenticate():
    """認証を要求するレスポンスを返す"""
    return Response(
        "Could not verify your access level for that URL.\n"
        "You have to login with proper credentials",
        401,
        {"WWW-Authenticate": 'Basic realm="Login Required"'},
    )


# 認証のデコレーター
def requires_auth(f):
    """エンドポイントに認証を要求するデコレーター"""

    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not check_auth(auth.username, auth.password):
            return authenticate()
        return f(*args, **kwargs)

    return decorated


@app.route("/")
@requires_auth
def index():
    return "Hello, you are authenticated!"


if __name__ == "__main__":
    app.run(debug=True)

before_request を使ってすべてのルーティングに適用する方法

from flask import Flask, Response, request

app = Flask(__name__)

# 認証情報
USERNAME = "admin"
PASSWORD = "password"


# 認証をチェックする関数
def check_auth(username, password):
    return username == USERNAME and password == PASSWORD


# 認証が必要な場合にダイアログを表示する関数
def authenticate():
    return Response(
        "Could not verify your access level for that URL.\n"
        "You have to login with proper credentials",
        401,
        {"WWW-Authenticate": 'Basic realm="Login Required"'},
    )


# すべてのリクエストの前に認証を行う
@app.before_request
def before_request():
    if request.path == "/public":
        return  # 認証をスキップ
    auth = request.authorization
    if not auth or not check_auth(auth.username, auth.password):
        return authenticate()


# サンプルのルート
@app.route("/")
def index():
    return "Hello, you are authenticated!"


@app.route("/dashboard")
def dashboard():
    return "Welcome to your dashboard!"


if __name__ == "__main__":
    app.run(debug=True)

最後に

ライブラリを使う場合は Flask-HTTPAuth がいいかもしれまえん
Flask-BasicAuth はもうメンテナンスされていません

2024年9月19日木曜日

Windows 上に pyenv をインストールする方法

Windows 上に pyenv をインストールする方法

概要

過去に Cygwin 上でトライしましたが無理だったので今回は pyenv-win を使います

環境

  • Windows 10
  • pyenv-win 3.11

インストール

PowerShell 上で以下を実行します

Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1"

再度 PowerShell を立ち上げ直して pyenv コマンドを使えることを確認します

python インストール

  • pyenv install 3.11.9

(なぜか 3.11.10 が pyenv update しても出てこなかったです)

動作確認

  • mkdir test
  • cd test
  • pyenv local 3.11.9
  • pip install pipenv
  • pipenv install requests
  • pipenv run python -c "import requests"

でとりあえずちゃんとモジュールが読み込めることを確認しましょう

最後に

Windows 上で pyenv を使いたい場合は素直に pyenv-win を使いましょう
どこまで動くかは要検証ですが簡単なスクリプトを動かすだけならとりあえずインストールしておいてもいいのかもしれません

参考サイト

2024年9月18日水曜日

Mac 上で exif 情報を削除する方法

Mac 上で exif 情報を削除する方法

概要

exiftool コマンドを使います

環境

  • macOS 14.6.1
  • exiftool 12.76

コマンド

カレント配下の jpeg ファイルの exif をすべて削除します

for i in `ls *.jpg`; do exiftool -all= -overwrite_original ${i}; done

最後に

HEIC には使えないので注意です
HEIC を jpeg に変換するのはプレビューを使ってファイル -> 書き出しでできます

参考サイト

2024年9月17日火曜日

Siki を別 Mac へ移行する

Siki を別 Mac へ移行する

概要

毎回同じ設定をするは面倒なので前の設定を引き継ぎます

環境

  • macOS 14.6.1
  • Siki 0.31.9

移行元

  • 一旦 Siki を停止
  • cd ~/Library/Application\ Support/Siki
  • tar cvzf profile.tar.gz profile/
  • 作成した profile.tar.gz を移行先のマシンに移動する

移行先

  • 普通に Siki をインストール
  • Siki を一度起動、すぐに終了
  • cd ~/Library/Application\ Support/Siki
  • rm -rf profile
  • mv /tmp/profile.tar.gz .
  • tar xvzf profile.tar.gz
  • vim profile/config.js を編集
    • 「img_dir」「log_dir」「plugin_dir」「backup_dir」「save_dir」「user_dir」の行を削除
  • Siki 起動

最後に

これでいけるはずです

参考サイト

2024年9月16日月曜日

Mac で yt-dlp (youtube download)

Mac で yt-dlp (youtube download)

概要

音源のみをダウンロードします

環境

  • macOS 11.7.10
  • yt-dlp 2024.08.06
  • ffmpeg 7.0.1

インストール

  • brew install yt-dlp

ダウンロード

  • yt-dlp -f m4a -x 'https://www.youtube.com/watch?v=WJzSBLCaKc8'
[youtube] Extracting URL: https://www.youtube.com/watch?v=WJzSBLCaKc8
[youtube] WJzSBLCaKc8: Downloading webpage
[youtube] WJzSBLCaKc8: Downloading ios player API JSON
[youtube] WJzSBLCaKc8: Downloading web creator player API JSON
[youtube] WJzSBLCaKc8: Downloading player 5f8f5b0f
[youtube] WJzSBLCaKc8: Downloading m3u8 information
[info] WJzSBLCaKc8: Downloading 1 format(s): 140
[download] Destination: YouTubeテーマソング/ヒカキン&セイキン [WJzSBLCaKc8].m4a
[download] 100% of    4.49MiB in 00:00:00 at 5.56MiB/s
[FixupM4a] Correcting container of "YouTubeテーマソング/ヒカキン&セイキン [WJzSBLCaKc8].m4a"
[ExtractAudio] Not converting audio YouTubeテーマソング/ヒカキン&セイキン [WJzSBLCaKc8].m4a; the file is already in a common audio format

その他オプション

  • -o で出力ファイル名を指定できます

参考サイト

2024年9月14日土曜日

omnibus-gitlab で管理している Prometheus のバージョンを Python から取得する方法

omnibus-gitlab で管理している Prometheus のバージョンを Python から取得する方法

概要

前回はシェルスクリプト+ gitlab ci で取得しましたが今回は Python で取得します

GitPython というライブラリを使います

環境

  • macOS 14.6.1
  • Python 3.11.10
    • GitPython 3.1.43

サンプルコード

import re
from dataclasses import dataclass

import git


# Prometheus など各種バージョンを管理するデータクラス
@dataclass
class GitlabAlertVersion:
    prometheus_version: str = ""
    alertmanager_version: str = ""
    node_exporter_version: str = ""

    # バージョン情報をファイルに保存します
    def save_to_files(self):
        with open("prometheus_version.txt", "w") as f:
            f.write(self.prometheus_version)
        with open("alertmanager_version.txt", "w") as f:
            f.write(self.alertmanager_version)
        with open("node_exporter_version.txt", "w") as f:
            f.write(self.node_exporter_version)


# omnibus-gitlab のリポジトリをクローンしてバージョンを取得するクラス
class GitlabAlertVersionFetcher:
    def __init__(self, tag="17.1.6+ee.0"):
        self.tag = tag
        self.repo_name = "omnibus-gitlab"
        self.url = f"https://gitlab.com/gitlab-org/{self.repo_name}.git"
        self.file_names = ["prometheus", "alertmanager", "node-exporter"]

    # url に記載のリポジトリを取得
    # 今回は tag を指定しシャロークローンで取得
    def _clone(self) -> git.Repo:
        return git.Repo.clone_from(
            self.url,
            f"./{self.repo_name}",
            branch=self.tag,
            depth="1",
        )

    # 指定のファイルを git grep する
    def _grep(self, file, repo: git.Repo) -> str:
        lines = repo.git.grep(
            "Gitlab::Version.new", "--", f"config/software/{file}.rb"
        ).split("\n")
        pattern = r"\d+\.\d+\.\d+"
        for line in lines:
            match = re.search(pattern, line)
            if match:
                return match.group(0)
        else:
            raise ValueError()

    # 実行メイン関数
    # file_names に定義された各種コンポーネントのバージョンを取得
    def run(self) -> GitlabAlertVersion:
        gitlab_alert_version = GitlabAlertVersion()
        repo = self._clone()
        for file in self.file_names:
            setattr(
                gitlab_alert_version,
                f"{file.replace('-', '_')}_version",
                self._grep(file, repo),
            )
        return gitlab_alert_version


if __name__ == "__main__":
    fetcher = GitlabAlertVersionFetcher()
    version: GitlabAlertVersion = fetcher.run()
    print(version)
    version.save_to_files()

最後に

GitPython を使うと git コマンドを Python 内で使うことができます

参考サイト

2024年9月13日金曜日

Gitlab CI でセマンティクスバージョンを比較する

Gitlab CI でセマンティクスバージョンを比較する

概要

過去に前のバージョンを保存する方法を紹介しました
今回は取得したバージョン同士を比較するジョブを追加します

環境

  • Gitlab.com 17.4.0-pre
    * Runner (docker-mahcine executor ruby:3.1)

.gitlab-ci.yml

compare ジョブを追加しています
sort した結果現在のバージョンと違うバージョンが返ってきたらバージョンアップと判断しています

stages:
  - save_versions
  - fetch_versions
  - check_versions
  - compare_versions

save:
  stage: save_versions
  script:
    - |
      # バージョンファイルがすでにある場合は前回のバージョンファイルに移動する
      mkdir -p $CI_PROJECT_DIR/build/cache
      mkdir -p $CI_PROJECT_DIR/build/artifacts
      # ファイルが何もないと各種ディレクトリが破棄されるのでファイル作成
      touch $CI_PROJECT_DIR/build/cache/keep.txt
      touch $CI_PROJECT_DIR/build/artifacts/keep.txt
      if [ -f $CI_PROJECT_DIR/build/cache/prometheus.txt ]; then
        mv $CI_PROJECT_DIR/build/cache/prometheus.txt $CI_PROJECT_DIR/build/artifacts/pre_prometheus.txt
        echo "Prometheus pre version:"
        cat $CI_PROJECT_DIR/build/artifacts/pre_prometheus.txt
      fi
      if [ -f $CI_PROJECT_DIR/build/cache/alertmanager.txt ]; then
        mv $CI_PROJECT_DIR/build/cache/alertmanager.txt $CI_PROJECT_DIR/build/artifacts/pre_alertmanager.txt
        echo "Alertmanager pre version:"
        cat $CI_PROJECT_DIR/build/artifacts/pre_alertmanager.txt
      fi
      if [ -f $CI_PROJECT_DIR/build/cache/node_exporter.txt ]; then
        mv $CI_PROJECT_DIR/build/cache/node_exporter.txt $CI_PROJECT_DIR/build/artifacts/pre_node_exporter.txt
        echo "Node Exporter pre version:"
        cat $CI_PROJECT_DIR/build/artifacts/pre_node_exporter.txt
      fi
  # 前回のパイプラインを参照するために cache を使う
  cache:
    paths:
      - $CI_PROJECT_DIR/build/cache/*.txt
  # ジョブ間で結果を共有するために artifacts を使う
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt


# 任意のタグに基づいてバージョン情報を取得するジョブ
fetch:
  stage: fetch_versions
  script:
    - echo "Checking versions for the specified tag -> $TARGET_TAG"
    # GitLabソースコードをクローン
    - git clone https://gitlab.com/gitlab-org/omnibus-gitlab.git
    - cd omnibus-gitlab
    # ユーザーが指定したタグにチェックアウト
    - git checkout $TARGET_TAG
    # prometheusのバージョンを取得
    - grep 'Gitlab::Version.new' config/software/prometheus.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/prometheus.txt
    # Alertmanagerのバージョンを取得
    - grep 'Gitlab::Version.new' config/software/alertmanager.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/alertmanager.txt
    # Node Exporterのバージョンを取得
    - grep 'Gitlab::Version.new' config/software/node-exporter.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/node_exporter.txt
  # 前回のジョブの結果を使用するために artifacts を使う
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt
  # ジョブの実行にはTARGET_TAG変数が必須
  rules:
    - if: '$TARGET_TAG != null'

check:
  stage: check_versions
  script:
    - echo "Prometheus version:"
    - cat $CI_PROJECT_DIR/build/artifacts/prometheus.txt
    - echo "Alertmanager version:"
    - cat $CI_PROJECT_DIR/build/artifacts/alertmanager.txt
    - echo "Node Exporter version:"
    - cat $CI_PROJECT_DIR/build/artifacts/node_exporter.txt
    # 結果をキャッシュに保存する
    - cp $CI_PROJECT_DIR/build/artifacts/prometheus.txt $CI_PROJECT_DIR/build/cache/prometheus.txt
    - cp $CI_PROJECT_DIR/build/artifacts/alertmanager.txt $CI_PROJECT_DIR/build/cache/alertmanager.txt
    - cp $CI_PROJECT_DIR/build/artifacts/node_exporter.txt $CI_PROJECT_DIR/build/cache/node_exporter.txt
    - ls $CI_PROJECT_DIR/build/cache
    - ls $CI_PROJECT_DIR/build/artifacts
  # 次回のパイプラインに結果を残すために cache を使う
  cache:
    paths:
      - $CI_PROJECT_DIR/build/cache/*.txt
  # 前回のジョブの結果を使用するために artifacts を使う
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt

compare:
  stage: compare_versions
  script:
    - |
      # 前の Prometheus のバージョン情報を取得
      if [ -f $CI_PROJECT_DIR/build/artifacts/pre_prometheus.txt ]; then
        PREV_VERSION=$(cat $CI_PROJECT_DIR/build/artifacts/pre_prometheus.txt)
        # PREV_VERSION="0.0.0" # for test
      else
        exit 1
      fi
      # 現在の Prometheus のバージョン情報を取得
      if [ -f $CI_PROJECT_DIR/build/artifacts/prometheus.txt ]; then
        CURRENT_VERSION=$(cat $CI_PROJECT_DIR/build/artifacts/prometheus.txt)
      else
        exit 1;
      fi
      # バージョン比較のための関数
      version_gt() {
        [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" != "$1" ]
      }
      # バージョンを比較
      if version_gt "$CURRENT_VERSION" "$PREV_VERSION"; then
        echo "Version has increased from $PREV_VERSION to $CURRENT_VERSION"
      else
        echo "Version is unchanged."
        exit 0
      fi
  # 前回のジョブの結果を使用するために artifacts を使う
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt

最後に

今回はシェルスクリプトで実現していますが正しく比較したいのであれば Python などを使う方法を検討してください

2024年9月12日木曜日

Gitlab と dockerhub にある Prometheus のバージョンを比較する gitlab-ci.yml

Gitlab と dockerhub にある Prometheus のバージョンを比較する gitlab-ci.yml

概要

Gitlab 側で最新の Prometheus が使われているか定期的にチェックします

環境

  • Gitlab.com 17.4.0-pre
    * Runner (docker-mahcine executor ruby:3.1)

app.py

  • vim app.py
import re
import sys

import requests
from packaging.version import Version

image = sys.argv[1]
url = f"https://hub.docker.com/v2/repositories/prom/{image}/tags/"
response = requests.get(url)
data = response.json()
# セマンティックバージョンに一致するタグを正規表現でフィルタ
semver_pattern = re.compile(r"^v?(\d+\.\d+\.\d+)$")
# バージョンをリストに格納
versions = []
for tag in data["results"]:
    tag_name = tag["name"]
    if semver_pattern.match(tag_name):  # セマンティックバージョニングに一致
        versions.append(tag_name.lstrip("v"))
# バージョンを比較して最新を取得
latest_version = max(versions, key=lambda x: Version(x))
print(latest_version)

.gitlab-ci.yml

Gitlab のバージョンはソースコードから取得し dockerhub にあるタグのバージョンは API を使っています
取得した結果は artifacts を使ってファイルに保存して最後に比較しています

image: python:3.11.9-bullseye

stages:
  - fetch_versions
  - compare_versions

fetch_dockerhub:
  stage: fetch_versions
  before_script:
    - mkdir -p $CI_PROJECT_DIR/build/artifacts
    - pip install requests packaging
  script:
    - python app.py prometheus > $CI_PROJECT_DIR/build/artifacts/dockerhub_latest_prometheus.txt
    - python app.py alertmanager > $CI_PROJECT_DIR/build/artifacts/dockerhub_latest_alertmanager.txt
    - python app.py node-exporter > $CI_PROJECT_DIR/build/artifacts/dockerhub_latest_node_exporter.txt
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt

fetch_gitlab:
  stage: fetch_versions
  before_script:
    - mkdir -p $CI_PROJECT_DIR/build/artifacts
  script:
    - git clone https://gitlab.com/gitlab-org/omnibus-gitlab.git
    - cd omnibus-gitlab
    - git checkout $TARGET_TAG
    - grep 'Gitlab::Version.new' config/software/prometheus.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/gitlab_tagged_prometheus.txt
    - grep 'Gitlab::Version.new' config/software/alertmanager.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/gitlab_tagged_alertmanager.txt
    - grep 'Gitlab::Version.new' config/software/node-exporter.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/gitlab_tagged_node_exporter.txt
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt
  rules:
    - if: '$TARGET_TAG != null'

compare:
  stage: compare_versions
  script:
    - |
      # バージョンの比較
      DOCKERHUB_PROMETHEUS_VERSION=$(cat $CI_PROJECT_DIR/build/artifacts/dockerhub_latest_prometheus.txt)
      DOCKERHUB_ALERTMANAGER_VERSION=$(cat $CI_PROJECT_DIR/build/artifacts/dockerhub_latest_alertmanager.txt)
      DOCKERHUB_NODE_EXPORTER_VERSION=$(cat $CI_PROJECT_DIR/build/artifacts/dockerhub_latest_node_exporter.txt)
      GITLAB_TAGGED_PROMETHEUS_VERSION=$(cat $CI_PROJECT_DIR/build/artifacts/gitlab_tagged_prometheus.txt)
      GITLAB_TAGGED_ALERTMANAGER_VERSION=$(cat $CI_PROJECT_DIR/build/artifacts/gitlab_tagged_alertmanager.txt)
      GITLAB_TAGGED_NODE_EXPORTER_VERSION=$(cat $CI_PROJECT_DIR/build/artifacts/gitlab_tagged_node_exporter.txt)
      version_gt() {
        [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" != "$1" ]
      }
      if version_gt "$DOCKERHUB_PROMETHEUS_VERSION" "$GITLAB_TAGGED_PROMETHEUS_VERSION"; then
        echo "Version has increased from $GITLAB_TAGGED_PROMETHEUS_VERSION to $DOCKERHUB_PROMETHEUS_VERSION"
      else
        echo "Prometheus Version is unchanged."
      fi
      if version_gt "$DOCKERHUB_ALERTMANAGER_VERSION" "$GITLAB_TAGGED_ALERTMANAGER_VERSION"; then
        echo "Version has increased from $GITLAB_TAGGED_ALERTMANAGER_VERSION to $DOCKERHUB_ALERTMANAGER_VERSION"
      else
        echo "Alertmanager Version is unchanged."
      fi
      if version_gt "$DOCKERHUB_NODE_EXPORTER_VERSION" "$GITLAB_TAGGED_NODE_EXPORTER_VERSION"; then
        echo "Version has increased from $GITLAB_TAGGED_NODE_EXPORTER_VERSION to $DOCKERHUB_NODE_EXPORTER_VERSION"
      else
        echo "Node_Exporter Version is unchanged."
      fi
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt

最後に

Omnibus Gitlab の Prometheus のバージョンはボットが管理しているっぽいのでその仕組を使うのもありなのかもしれない

2024年9月11日水曜日

Gitlab CI で前回のパイプラインの結果を保存して次のパイプラインで使う方法

Gitlab CI で前回のパイプラインの結果を保存して次のパイプラインで使う方法

概要

cache を使います
gitlab-ci.yml の内容は前回のものを使います

環境

  • Gitlab.com 17.4.0-pre
    * Runner (docker-mahcine executor ruby:3.1)

.gitlab-ci.yml

流れとしては

  • 前回の結果があれば別ファイル名にして保存
  • 今回の結果を取得
  • 今回の結果を表示、キャッシュに保存

という感じです
ジョブ間でデータをやり取りするため artifacats も使います

stages:
  - save_versions
  - fetch_versions
  - check_versions

save:
  stage: save_versions
  script:
    - |
      # バージョンファイルがすでにある場合は前回のバージョンファイルに移動する
      mkdir -p $CI_PROJECT_DIR/build/cache
      mkdir -p $CI_PROJECT_DIR/build/artifacts
      # ファイルが何もないと各種ディレクトリが破棄されるのでファイル作成
      touch $CI_PROJECT_DIR/build/cache/keep.txt
      touch $CI_PROJECT_DIR/build/artifacts/keep.txt
      if [ -f $CI_PROJECT_DIR/build/cache/prometheus.txt ]; then
        mv $CI_PROJECT_DIR/build/cache/prometheus.txt $CI_PROJECT_DIR/build/artifacts/pre_prometheus.txt
        echo "Prometheus pre version:"
        cat $CI_PROJECT_DIR/build/artifacts/pre_prometheus.txt
      fi
      if [ -f $CI_PROJECT_DIR/build/cache/alertmanager.txt ]; then
        mv $CI_PROJECT_DIR/build/cache/alertmanager.txt $CI_PROJECT_DIR/build/artifacts/pre_alertmanager.txt
        echo "Alertmanager pre version:"
        cat $CI_PROJECT_DIR/build/artifacts/pre_alertmanager.txt
      fi
      if [ -f $CI_PROJECT_DIR/build/cache/node_exporter.txt ]; then
        mv $CI_PROJECT_DIR/build/cache/node_exporter.txt $CI_PROJECT_DIR/build/artifacts/pre_node_exporter.txt
        echo "Node Exporter pre version:"
        cat $CI_PROJECT_DIR/build/artifacts/pre_node_exporter.txt
      fi
  # 前回のパイプラインを参照するために cache を使う
  cache:
    paths:
      - $CI_PROJECT_DIR/build/cache/*.txt
  # ジョブ間で結果を共有するために artifacts を使う
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt


# 任意のタグに基づいてバージョン情報を取得するジョブ
fetch:
  stage: fetch_versions
  script:
    - echo "Checking versions for the specified tag -> $TARGET_TAG"
    # GitLabソースコードをクローン
    - git clone https://gitlab.com/gitlab-org/omnibus-gitlab.git
    - cd omnibus-gitlab
    # ユーザーが指定したタグにチェックアウト
    - git checkout $TARGET_TAG
    # prometheusのバージョンを取得
    - grep 'Gitlab::Version.new' config/software/prometheus.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/prometheus.txt
    # Alertmanagerのバージョンを取得
    - grep 'Gitlab::Version.new' config/software/alertmanager.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/alertmanager.txt
    # Node Exporterのバージョンを取得
    - grep 'Gitlab::Version.new' config/software/node-exporter.rb | sed -n "s/.*'\(.*\)'.*/\1/p" > $CI_PROJECT_DIR/build/artifacts/node_exporter.txt
  # 前回のジョブの結果を使用するために artifacts を使う
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt
  # ジョブの実行にはTARGET_TAG変数が必須
  rules:
    - if: '$TARGET_TAG != null'

check:
  stage: check_versions
  script:
    - echo "Prometheus version:"
    - cat $CI_PROJECT_DIR/build/artifacts/prometheus.txt
    - echo "Alertmanager version:"
    - cat $CI_PROJECT_DIR/build/artifacts/alertmanager.txt
    - echo "Node Exporter version:"
    - cat $CI_PROJECT_DIR/build/artifacts/node_exporter.txt
    # 結果をキャッシュに保存する
    - cp $CI_PROJECT_DIR/build/artifacts/prometheus.txt $CI_PROJECT_DIR/build/cache/prometheus.txt
    - cp $CI_PROJECT_DIR/build/artifacts/alertmanager.txt $CI_PROJECT_DIR/build/cache/alertmanager.txt
    - cp $CI_PROJECT_DIR/build/artifacts/node_exporter.txt $CI_PROJECT_DIR/build/cache/node_exporter.txt
    - ls $CI_PROJECT_DIR/build/cache
    - ls $CI_PROJECT_DIR/build/artifacts
  # 次回のパイプラインに結果を残すために cache を使う
  cache:
    paths:
      - $CI_PROJECT_DIR/build/cache/*.txt
  # 前回のジョブの結果を使用するために artifacts を使う
  artifacts:
    paths:
      - $CI_PROJECT_DIR/build/artifacts/*.txt

最後に

artifacts は結果を保存してダウンロードできますが次回のパイプラインでは使えません
cache は結果を保存してダウンロードはできませんが次回のパイプラインで使えます

どちらもサブディレクトリを使う場合は対象のファイルが一つでもないと次のジョブ実行時にサブディレクトリがないので注意しましょう

参考サイト

2024年9月10日火曜日

omnibus-gitlab に記載されている Promethues のバージョンを定期的に取得する gitlab-ci のサンプル

omnibus-gitlab に記載されている Promethues のバージョンを定期的に取得する gitlab-ci のサンプル

概要

clone して grep します
変数でタグを指定できるようにしているのでもう少し工夫すればタグを自動で取得したり複数のタグのバージョンを取得できたりできるはずです

環境

  • Gitlab.com 17.4.0-pre
    * Runner (docker-mahcine executor ruby:3.1)

.gitlab-ci.yml

stages:
  - fetch_versions

# 任意のタグに基づいてバージョン情報を取得するジョブ
get_versions:
  stage: fetch_versions
  script:
    - echo "Checking versions for the specified tag -> $TARGET_TAG"
    # GitLabソースコードをクローン
    - git clone https://gitlab.com/gitlab-org/omnibus-gitlab.git
    - cd omnibus-gitlab
    # ユーザーが指定したタグにチェックアウト
    - git checkout $TARGET_TAG
    # Prometheusのバージョンを取得
    - echo "Prometheus version:"
    - grep 'Gitlab::Version.new' config/software/prometheus.rb | sed -n "s/.*'\(.*\)'.*/\1/p"
    # Alertmanagerのバージョンを取得
    - echo "Alertmanager version:"
    - grep 'Gitlab::Version.new' config/software/alertmanager.rb | sed -n "s/.*'\(.*\)'.*/\1/p"
    # Node Exporterのバージョンを取得
    - echo "Node Exporter version:"
    - grep 'Gitlab::Version.new' config/software/node-exporter.rb | sed -n "s/.*'\(.*\)'.*/\1/p"
  # ジョブの実行にはTARGET_TAG変数が必須
  rules:
    - if: '$TARGET_TAG != null'

変数

注意事項

script 内でコロンを使う場合はコロンの後ろにスペースがあると「This GitLab CI configuration is invalid: jobs:get_versions:script config should be a string or a nested array of strings up to 10 levels deep.」と言われて怒られるので注意しましょう

最後に

シャローンクローンにしたりすればもっと速くなると思います
定期実行にするのも良いと思います

前回の実行からバージョンが上がったら通知するようにしたら便利かもしれません

Wordpress でショートコードを使ってデータベースの情報を取得する方法

Wordpress でショートコードを使ってデータベースの情報を取得する方法

概要

ショートコードを使えばサーバサイドにある functions.php を呼び出せるのでデータベースにある情報を表示することができます

環境

  • macOS 14.6.1
  • MySQL 9.0
  • Wordpress 6.6.1
  • docker 27.2.0

functions.php

function get_first_user_by_db() {
    global $wpdb;
    $result = $wpdb->get_results("SELECT user_login FROM wp_users LIMIT 1");
    foreach($result as $row) {
        return $row->user_login;
    }
}

add_shortcode ( 'first_user_name', 'get_first_user_by_db' );

ショートコード

[first_user_name]

動作確認

mysql> select user_login from wp_users limit 1;
+------------+
| user_login |
+------------+
| test       |
+------------+
1 row in set (0.00 sec)

おまけ: wordpress のテーブル一覧

mysql> show tables;
+-----------------------+
| Tables_in_wordpress   |
+-----------------------+
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_termmeta           |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+
12 rows in set (0.00 sec)

最後に

functions.php を使えばデータベースにある情報もサイトに表示することができます
他のデータベースにアクセスしたい場合は wordpress で使用しているユーザが他のデータベースにアクセスできるように権限設定する必要があります

functions.php は正直何でもできるのでこれだけ極めても Wordpress を使いこなせるようになると思います

参考サイト

2024年9月9日月曜日

Wordpress のショートコードに引数を設定する方法

Wordpress のショートコードに引数を設定する方法

概要

$atts を受取れるようにします

環境

  • macOS 14.6.1
  • MySQL 9.0
  • Wordpress 6.6.1
  • docker 27.2.0

functions.php

function say($atts) {
    /** デフォルト値の設定 
     * shortcode_atts を使うことでショートコードにkey,valueな属性を付与することができる
     * 以下では message という属性を定義している
     * ショートコード側の引数で message=hoge という引数が与えられるとそれが優先される
     * extract は与えられた連想配列から変数を生成するPHPの組み込み関数
     */
    extract(shortcode_atts(array(
      'message' => 'Hello'), $atts));
    return $message;
}

add_shortcode( 'say_something', 'say' );

動作確認

ショートコードを生成し message という引数の値をいろいろと変えてみましょう

最後に

Wordpress のショートコード用の関数で引数を受け取る方法を紹介しました
これで同じようなコンポーネントは functions.php で定義しデータだけを変数で与えることでコンポーネントの使い回しができるようになります

ショートコード用の関数には他にも content という引数が受け取れます
これは [sc]content[/sc] という感じでショートコードのタグで囲われたコンテンツの内容を受け取ることができます

参考サイト

2024年9月8日日曜日

Alembic で does not provide a MetaData object or sequence of objects to the context.

Alembic で does not provide a MetaData object or sequence of objects to the context.

概要

autogenerate オプションを付与すると発生するエラーになります
対策を紹介します

環境

  • Ubuntu 22.04
  • Python 3.10.2
  • alembic 1.13.2

env.py に metadata を追加する

DeclarativeBase or declarative_base で作成された Base クラスを import しその metadata を参照します
ポイントはちゃんとマイグレーションする際の context.configure にも metadata 情報を渡す点です

  • vim env.py
from app.models import Base
target_metadata = Base.metadata
def run_migrations_online() -> None:
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    configuration = config.get_section(config.config_ini_section)
    if configuration is None:
        raise ValueError()
    connectable = engine_from_config(
        configuration=configuration,
        prefix="sqlalchemy.",
        poolclass=pool.NullPool,
    )

    with connectable.connect() as connection:
        context.configure(
            connection=connection,
            target_metadata=target_metadata,  # <= ここでちゃんと設定するのが重要
        )

        with context.begin_transaction():
            context.run_migrations()

最後に

あとは普通にマイグレーションできるか確認すれば OK です
almbic や sqlalchemy を最新にすると発生することがあるようです

2024年9月7日土曜日

Mac に Roblox をインストールする方法

Mac に Roblox をインストールする方法

概要

少し Mac のバージョンが古いですが Apple Sillicon Mac でも同じ手順でインストール可能です

環境

  • macOS 11.7.10
  • Roblox

アカウントの作成

まずはアカウントから作成します
こちらから作成します

好きなユーザ名とパスワードを設定します
ユーザ名が少し曲があり推測しやすい名前は登録できないので注意しましょう
登録時にメールアドレスは不要なのであとで登録します

アカウントが登録できたらメールアドレスを設定します
確認用のメールがくるので URL をクリックすればメールアドレスの登録は完了です

インストール

Roblox.dmg をダウンロードしてインストールするだけです
Roblox.dmg はいろんなダウンロード方法がありそうですがログインした画面のままやる方法を紹介します

まずは適当なゲームを選択します

そしてプレイボタンを押します

もし Roblox がインストールされていない場合はダウンロードボタンが表示されるのでそこから Roblox.dmg をダウンロードできます

Roblox.dmg を展開してインストール

ダブルクリックしてインストールを開始します
展開すると RobloxPlayerInstaller.app があるのでこれを実行すれば OK です

インストールが完了すると Rolblox が自動で起動します
先ほど作成したアカウントでログインしましょう

動作確認

ログインが完了するとゲームの一覧が表示されるのであとはプレイしたいゲームをダウンロードしてプレイしましょう

もしかしたらサーバ側にゲーム情報があるのでダウンロードは不要っぽいです
読み込めればゲームが始まります

最後に

Mac に Roblox をインストールしゲームを開始する方法を紹介しました
かなり簡単にできる印象です
コントローラなども設定すればできると思います
ゲーム自体のインストールは不要っぽいですが描画などはそれなりのスペックを要するのでゲームをプレイする際はそれなりのスペックのマシンを使いましょう

2024年9月6日金曜日

Wordpress のショートコード (functions.php) 超入門

Wordpress のショートコード (functions.php) 超入門

概要

Wordpress にショートコードという PHP の関数を呼び出す機能があるらしいので使ってみました

環境

  • macOS 14.6.1
  • MySQL 9.0
  • Wordpress 6.6.1
  • docker 27.2.0

functions.php の編集

今回はテーマ配下の functions.php を使います

  • vim wordpress/wp-content/themes/twentytwentyfour/functions.php
/** original functions **/
function say() {
    return 'Hello!!';
}

add_shortcode( 'say_hello', 'say' );

add_shortcode を使って追加できます
add_action ではないので注意です

ショートコードの追加

ポストを編集しショートコードを追加します
[say_hello] と記載します

動作確認

保存しプレビューを表示してみましょう

ちゃんと return の内容が反映されていることが確認できます
スタイルなど当てていないので左端にあります

最後に

Wordpress のショートコードに入門してみました
js や css と違いサーバサイド側のデータを表示したいときに使えるかなと思います

2024年9月5日木曜日

docker で wordpress

docker で wordpress

概要

たぶんこれが一番簡単です

環境

  • macOS 14.6.1
  • MySQL 9.0
  • Wordpress 6.6.1
  • docker 27.2.0

compose.yaml

services:
   db:
     image: mysql:9.0
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:6.6.1
     volumes:
       - ./wordpress:/var/www/html
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

compose.yaml と同じ wordpress ディレクトリを作成しておきましょう

起動

  • docker compose up -d
[+] Running 33/2
 ✔ wordpress Pulled                                                                                                                                                   41.3s 
 ✔ db Pulled                                                                                                                                                          65.8s 
[+] Running 4/4
 ✔ Network wordpress_default        Created                                                                                                                            0.0s 
 ✔ Volume "wordpress_db_data"       Created                                                                                                                            0.0s 
 ✔ Container wordpress-db-1         Started                                                                                                                            0.5s 
 ✔ Container wordpress-wordpress-1  Started

動作確認

localhost:8000 にアクセスすると wordpress の設定画面に遷移します

最後に

mysql のパスワードはテストなので適当です
プロダクションで使う場合はちゃんとしたパスワードにしましょう

参考サイト

2024年9月4日水曜日

Windows11 に Wordpress をインストールする

Windows11 に Wordpress をインストールする

概要

Windows11 上に wsl なしで wordpress を構築する流れを紹介します

環境

  • Windows11
  • Wordpress 6.6.1

1. PHP のインストール

こちら

2. nginx のインストール

こちら

3. MySQL のインストール

これはインストーラがあるのでインストーラを使うと簡単です
ここでアーキテクチャなどを指定してインストーラをダウンロードします

基本は指示に従えば OK です
Workspace などは自由にインストールしてください
最低限コマンドラインインタフェースがあればいいかなと思います

3.1 wordpress 用データベースの作成

作成しましょう
名前は何でも OK です
専用のユーザを作ってもいいですがこの記事では localhost でしか使わないので root ユーザで進めます

なおデータベース名は「wordpress」として進めます

4 Wordpress のダウンロード

ここからダウンロードします
執筆時点では wordpress-6.6.1-ja.zip でした

ダウンロードした wordpress を展開し C:\nginx\html\wordpress に配置します

4.1 wp-config.php の編集

C:\nginx\html\wordpress\wp-config-sample.php があるのでこれを wp-config.php にリネームなりコピーして作成します

そして接続先データベースの設定を行います
以下はデータベースの設定部分のみ抜粋しているので設定ファイル内の該当部分を探して設定してください

  • vim wp-config.php
define( 'DB_NAME', 'wordpress' ); 
define( 'DB_USER', 'root' ); 
define( 'DB_PASSWORD', 'xxxxxxxx' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );

動作確認

nginx と cgi サーバを起動します
コマンドプロンプトで以下を実行します

cd c:\nginx
start nginx
cd c:\php
start php-cgi -b 127.0.0.1:9000

これで localhost/wordpress/wp-admin にアクセスすると wordpress の初期設定画面にアクセスできるので設定を進めれば OK です

最後に

wordpress にインストーラはないので nginx 配下に配置することで動作します
最低限必要なコンポーネント (php, nginx, mysql) がいくつかあるのでそれらのインストールと設定もしっかりしましょう

今回の手順ではすべてのコンポーネントを Windows11 上にインストールしましたが面倒であれば WSL2 + docker で簡単に構築できるのでその方法でも OK です