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 です

2024年9月3日火曜日

unattended-upgrade でメール通知する方法

unattended-upgrade でメール通知する方法

概要

更新された際にメール通知できます

環境

  • Ubuntu 22.04

設定方法

  • sudo vim /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Mail "your-google-accout@gmail.com";

// "always", "only-on-error" or "on-change"
Unattended-Upgrade::MailReport "always";
  • sudo systemctl restart unattended-upgrades

メールサーバを設定する

Postfix + gmail を使って送信サーバを用意します
設定方法はこちらです

unattended-upgrade を設定する

設定方法はこちらです

動作確認

もし毎日実行するようにしているのであれば以下のようなメールが毎日くれば OK です

最後に

おそらくデフォルト設定の場合一日一回更新が走るのでその際に通知が来るかなと思います
うまく通知が来ない場合はメールサーバの設定や実際に更新があったかどうかを unattended-upgrade のログから確認してください

2024年9月2日月曜日

Postfix + gmail 設定方法

Postfix + gmail 設定方法

概要

Ubuntu でメール送信したい場合は .mailrc は使わずに直接 postfix を使って gmail をリレーするのが簡単です

環境

  • postfix 3.6.4
  • Ubuntu 22.04

Postfix 認証情報の作成

  • sudo vim /etc/postfix/gmail
[smtp.gmail.com]:587 your-google-account-name@gmail.com:xxx

パスワードはアプリパスワードを生成し入力します

  • sudo chmod 600 /etc/postfix/gmail
  • sudo postmap /etc/postfix/gmail

権限を変更し postfix で使える認証形式に変換します

main.cf の修正

  • sudo vim /etc/postfix/main.cf

一番下に以下を追加します
relayhost がすでに設定項目としてあるのでそこはコメントアウトしても OK です

relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/gmail
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain

Postfix 起動

  • sudo systemctl start postfix

動作確認

mailx を使っていますが mail コマンドでも OK です
本文はパイプで渡しタイトルは -s オプションを使います
最後に宛先アドレスを指定します
せっかくなので別ドメインにしています

  • printf '%s\n%s\n' "こんにちわ" "Ubuntuテストめーるです" | mailx -s "これはUbuntuからのテストメールです" your-yahoo-mail-account@ymail.ne.jp

これでメールボックスにメールが届けば OK です

最後に

Postfix で Gmail をメールリレーサーバとして使う方法を紹介しました
Ubuntu などデフォルトで Postfix が動作している環境ではリレー方式を使うのが一番簡単かなと思います

参考サイト

2024年9月1日日曜日

Windows11 に nginx をインストールする方法

Windows11 に nginx をインストールする方法

概要

インストーラはないのでダウンロードして適切な場所に配置して設定ファイルを編集します

環境

  • Windows11
  • nginx 1.27.1

ダウンロード

https://nginx.org/en/download.html ここから zip ファイルをダウンロードします

展開し C 直下に配置

ダウンロードしたファイルを展開しディレクトリをリネームし C 直下に配置します
執筆時点では nginx-1.27.1 というディレクトリ名なのでこれを nginx に変えれば OK です

C:\nginx という感じで配置します

php cgi 連携

php で起動した cgi サーバと連携する場合は以下のように C:\nginx\conf\nginx.conf を修正します
php で起動した cgi サーバと連携する箇所がそもそもコメントされているのでそこをコメントアウトして使います

location / {
    root   html;
    index  index.html index.php;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000

location ~ \.php$ {
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
    }
    root           html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

動作確認

コマンドプロンプトを起動して以下を実行しましょう

cd c:\nginx
start nginx

で localhost にアクセスできることを確認します

cgi の動作確認をしたい場合は php の cgi サーバを起動し C:\nginx\html\test.php を配置し

  • vim test.php
<?php phpinfo();

localhost/test.php にアクセスして php の情報が表示されることを確認しましょう

最後に

nginx と php の連携は連携というよりかは php で起動した fast-cgi サーバにプロキシしてその結果を nginx で表示するという感じです

参考サイト