Google Geminiによるシェルスクリプト。(SSLの整合性確認)

Google Geminiに

「発行/別サーバからインポートしたSSL証明書の整合性確認を行うシェルスクリプト」

を書いてほしいと尋ねました。

条件は

  • コマンド [SSL証明書の入ったディレクトリ]形式
  • 証明書は
    • ドメイン名.crt.yyyymm
    • Let's Encryptのように証明書と中間証明書が結合された形式
  • 秘密鍵は
    • ドメイン名.key.yyyymm

の2つが入ったディレクトリを想定。

できあがったスクリプト

#!/bin/bash

# SSL証明書と秘密鍵の情報を表示するスクリプト
# サーバー証明書の有効期限、ドメイン名、発行局を表示します。
# また、対応する秘密鍵の存在と一致確認も行います。

# 使用法を表示する関数
usage() {
  echo "使用法: $0 <証明書と鍵が格納されているディレクトリ>"
  echo "ディレクトリには '[ドメイン名].crt.yyyymm' のような名前の証明書ファイルを配置してください。"
  echo "また、対応する秘密鍵ファイルは '[ドメイン名].key.yyyymm' の形式です。"
  echo "証明書ファイルは、サーバー証明書と中間証明書が結合された形式を想定しています。"
  exit 1
}

# 引数が指定されているか確認
if [ -z "$1" ]; then
  usage
fi

TARGET_DIR="$1"

# ディレクトリが存在するか確認
if [ ! -d "$TARGET_DIR" ]; then
  echo "エラー: ディレクトリ '$TARGET_DIR' が見つかりません。"
  exit 1
fi

# openssl コマンドが利用可能か確認
if ! command -v openssl &> /dev/null; then
    echo "エラー: openssl コマンドが見つかりません。OpenSSLをインストールしてください。"
    exit 1
fi

echo "ディレクトリ '$TARGET_DIR' 内のSSL証明書情報:"
echo "=================================================="

CERT_FILES_FOUND=0 # 処理した証明書ファイルのカウンタを初期化

# プロセス置換を使用して、CERT_FILES_FOUND が現在のシェルで更新されるようにする
while IFS= read -r -d $'\0' CERT_FILE; do
  CERT_FILES_FOUND=$((CERT_FILES_FOUND + 1)) # カウンタを増やす
  FILENAME=$(basename "$CERT_FILE")
  echo "処理中の証明書: $FILENAME"

  # --- 有効期限 ---
  EXPIRY_DATE_FULL=$(openssl x509 -noout -enddate -in "$CERT_FILE" 2>/dev/null)
  if [ $? -ne 0 ] || [ -z "$EXPIRY_DATE_FULL" ]; then
      EXPIRY_DATE_DISPLAY="有効期限の抽出エラー"
  else
      EXPIRY_DATE_DISPLAY=$(echo "$EXPIRY_DATE_FULL" | sed 's/notAfter=//')
  fi
  echo "  有効期限: $EXPIRY_DATE_DISPLAY"

  # --- ドメイン名 (サブジェクトのコモンネーム(CN) および サブジェクト代替名(SANs)) ---
  DOMAIN_NAME_DISPLAY="N/A"
  SUBJECT_CN_RAW=$(openssl x509 -noout -subject -nameopt multiline -in "$CERT_FILE" 2>/dev/null | grep 'commonName')
  SUBJECT_CN=""
  if [ $? -eq 0 ] && [ -n "$SUBJECT_CN_RAW" ]; then # grep で commonName が見つかった場合
    SUBJECT_CN=$(echo "$SUBJECT_CN_RAW" | sed -e 's/^\s*commonName\s*=\s*//' -e 's/\s*(Default)\s*$//' | head -n 1)
  fi
  
  # SANs を取得 (もしあれば最初の SAN 行のみ)
  SANS_TEXT=$(openssl x509 -noout -text -in "$CERT_FILE" 2>/dev/null | awk '/X509v3 Subject Alternative Name:/ {found=1; getline; print; exit} END{if(!found)print ""}')
  SANS_TEXT_CLEANED=$(echo "$SANS_TEXT" | sed 's/^\s*//') # 先頭の空白を削除
  SANS_LIST=""
  PRIMARY_SAN_DOMAIN=""

  if [[ "$SANS_TEXT_CLEANED" == "DNS:"* ]]; then
      # SANsリストを整形: DNS:プレフィックスを除去、空白除去、カンマ区切り、重複除去
      SANS_LIST=$(echo "$SANS_TEXT_CLEANED" | sed 's/DNS://g' | tr -d ' ' | tr ',' '\n' | awk '!seen[$0]++' | tr '\n' ',' | sed 's/,$//')
      if [ -n "$SANS_LIST" ]; then
        PRIMARY_SAN_DOMAIN=$(echo "$SANS_LIST" | cut -d',' -f1) # 最初のSANを主要ドメインとする
      fi
  fi

  if [ -n "$PRIMARY_SAN_DOMAIN" ]; then # 主要SANがある場合
      DOMAIN_NAME_DISPLAY="$PRIMARY_SAN_DOMAIN"
      # 主要SAN以外のSANがあれば表示
      OTHER_SANS=$(echo "$SANS_LIST," | sed "s/$PRIMARY_SAN_DOMAIN,//" | sed 's/,$//') 
      if [ -n "$OTHER_SANS" ]; then
          DOMAIN_NAME_DISPLAY="$PRIMARY_SAN_DOMAIN (他のSAN: $OTHER_SANS)"
      fi
      # CNが存在し、かつ主要SANと異なる場合にCNも表示
      if [ -n "$SUBJECT_CN" ] && [ "$SUBJECT_CN" != "$PRIMARY_SAN_DOMAIN" ]; then
          DOMAIN_NAME_DISPLAY="$DOMAIN_NAME_DISPLAY [CNも存在: $SUBJECT_CN]"
      fi
  elif [ -n "$SUBJECT_CN" ]; then # 主要SANが無く、CNがある場合
      DOMAIN_NAME_DISPLAY="$SUBJECT_CN"
      if [ -n "$SANS_LIST" ]; then # SANリスト自体は存在する (CNが主要となるケース)
          IS_CN_IN_SANS=0
          # SANS_LISTを配列に変換して確認しやすくする
          IFS=',' read -r -a SAN_ARRAY <<< "$SANS_LIST"
          for san_entry in "${SAN_ARRAY[@]}"; do
            if [ "$san_entry" = "$SUBJECT_CN" ]; then IS_CN_IN_SANS=1; break; fi
          done
          
          if [ $IS_CN_IN_SANS -eq 0 ]; then # CNがSANリストに含まれていない場合
             # SANリストがCNと異なる場合にのみSANリストを表示 (CNが唯一のSANである場合を除く)
             if [ "$SANS_LIST" != "$SUBJECT_CN" ]; then
                DOMAIN_NAME_DISPLAY="$SUBJECT_CN (SAN: $SANS_LIST)" # SAN -> SANs に統一すべきか検討
             fi
          else # CNがSANリストに含まれている場合、CN以外のSANがあれば表示
             OTHER_SANS_THAN_CN=""
             TEMP_SANS_LIST=""
             for san_entry in "${SAN_ARRAY[@]}"; do
                if [ "$san_entry" != "$SUBJECT_CN" ]; then
                    TEMP_SANS_LIST="${TEMP_SANS_LIST}${san_entry},"
                fi
             done
             OTHER_SANS_THAN_CN=$(echo "$TEMP_SANS_LIST" | sed 's/,$//')

             if [ -n "$OTHER_SANS_THAN_CN" ]; then
                DOMAIN_NAME_DISPLAY="$SUBJECT_CN (他のSAN: $OTHER_SANS_THAN_CN)"
             fi
          fi
      fi
  else # CNもSANも取得できなかった場合
      DOMAIN_NAME_DISPLAY="エラー: コモンネームまたはサブジェクト代替名を抽出できませんでした。"
  fi
  echo "  ドメイン名: $DOMAIN_NAME_DISPLAY"

  # --- 発行局 (サーバー証明書を発行した中間認証局) ---
  # 証明書ファイル内の最初の証明書のIssuerを取得
  ISSUER_CN_RAW=$(openssl x509 -noout -issuer -nameopt multiline -in "$CERT_FILE" 2>/dev/null | grep 'commonName')
  ISSUER_CN="N/A"
  if [ $? -eq 0 ] && [ -n "$ISSUER_CN_RAW" ]; then # grepでcommonNameが見つかったか確認
      ISSUER_CN=$(echo "$ISSUER_CN_RAW" | sed -e 's/^\s*commonName\s*=\s*//' -e 's/\s*(Default)\s*$//' | head -n 1)
  fi
  
  ISSUER_FULL_RAW=$(openssl x509 -noout -issuer -nameopt oneline,-space_eq,-show_type -in "$CERT_FILE" 2>/dev/null)
  ISSUER_FULL="N/A"
  if [ $? -eq 0 ] && [ -n "$ISSUER_FULL_RAW" ]; then
      ISSUER_FULL=$(echo "$ISSUER_FULL_RAW" | sed 's/issuer=//')
  fi

  if [ "$ISSUER_CN" != "N/A" ]; then
    echo "  発行局 (CN): $ISSUER_CN"
    echo "  発行局 (詳細): $ISSUER_FULL"
  else
    echo "  発行局 (詳細): $ISSUER_FULL (CNが見つからないか、CNの抽出エラーです)"
  fi

  # --- 秘密鍵の確認 ---
  # 証明書ファイル名から対応する秘密鍵ファイル名を推測 (例: domain.crt.yyyymm -> domain.key.yyyymm)
  KEY_FILE_CANDIDATE_NAME=$(basename "$CERT_FILE" | sed -E 's/\.crt\.([0-9]{6})$/.key.\1/')
  POTENTIAL_KEY_FILE="$TARGET_DIR/$KEY_FILE_CANDIDATE_NAME"

  if [ -f "$POTENTIAL_KEY_FILE" ]; then
    echo "  秘密鍵ファイル: $(basename "$POTENTIAL_KEY_FILE")"
    KEY_MATCH_STATUS="未確定 (エラーまたは非対応の鍵タイプ)"
    KEY_TYPE="不明"

    CERT_PUBKEY=$(openssl x509 -noout -pubkey -in "$CERT_FILE" 2>/dev/null) # 証明書から公開鍵を抽出
    KEY_IS_ENCRYPTED_OR_BAD_FORMAT=0
    PRIV_KEY_PUBKEY="" # 初期化

    # 鍵の種類を特定し、その公開鍵コンポーネントを取得 ('openssl pkey' は汎用的な鍵読み取り試行)
    if openssl pkey -in "$POTENTIAL_KEY_FILE" -noout >/dev/null 2>&1; then # まず鍵として読めるか
        if openssl rsa -in "$POTENTIAL_KEY_FILE" -noout -check >/dev/null 2>&1; then # RSA鍵か
            KEY_TYPE="RSA"
            PRIV_KEY_PUBKEY=$(openssl rsa -in "$POTENTIAL_KEY_FILE" -pubout 2>/dev/null) # RSA秘密鍵から公開鍵を抽出
        elif openssl ec -in "$POTENTIAL_KEY_FILE" -noout -check >/dev/null 2>&1; then # EC鍵か
            KEY_TYPE="EC"
            PRIV_KEY_PUBKEY=$(openssl ec -in "$POTENTIAL_KEY_FILE" -pubout 2>/dev/null) # EC秘密鍵から公開鍵を抽出
        else # その他の鍵タイプ (DSAなど) か、上記チェックをパスしないがpkeyでは読める鍵
            KEY_TYPE="その他 ('openssl pkey'で解析可能)"
            PRIV_KEY_PUBKEY=$(openssl pkey -in "$POTENTIAL_KEY_FILE" -pubout 2>/dev/null) # 汎用的に公開鍵抽出を試行
        fi
        if [ $? -ne 0 ] || [ -z "$PRIV_KEY_PUBKEY" ]; then # 公開鍵の抽出に失敗した場合
             KEY_IS_ENCRYPTED_OR_BAD_FORMAT=1 # 暗号化されているか、形式に問題がある可能性
        fi
    else # 'openssl pkey' で解析不可の場合
        KEY_IS_ENCRYPTED_OR_BAD_FORMAT=1 # 破損または暗号化の可能性が高い
        KEY_TYPE="読み取り不可または暗号化"
    fi

    if [ "$KEY_IS_ENCRYPTED_OR_BAD_FORMAT" -eq 1 ]; then
        KEY_MATCH_STATUS="鍵の読み取りエラー (暗号化、パスワード保護、または不正な形式の可能性あり)。検出された鍵タイプ: $KEY_TYPE"
    elif [ -n "$CERT_PUBKEY" ] && [ -n "$PRIV_KEY_PUBKEY" ]; then # 証明書の公開鍵と秘密鍵由来の公開鍵が両方取得できた場合
      if [ "$CERT_PUBKEY" = "$PRIV_KEY_PUBKEY" ]; then # 公開鍵同士を比較
        KEY_MATCH_STATUS="証明書と一致 ($KEY_TYPE)"
      else
        KEY_MATCH_STATUS="証明書と不一致 ($KEY_TYPE)"
      fi
    elif [ -z "$CERT_PUBKEY" ]; then # 証明書から公開鍵が取得できなかった場合
      KEY_MATCH_STATUS="証明書からの公開鍵生成エラー"
    else # 秘密鍵ファイルから公開鍵が取得できなかった場合 (鍵は読めたが公開鍵抽出に失敗)
      KEY_MATCH_STATUS="秘密鍵ファイルからの公開鍵生成エラー ($KEY_TYPE)"
    fi
    echo "    鍵の状態: $KEY_MATCH_STATUS"
  else
    echo "  秘密鍵ファイル: $(basename "$KEY_FILE_CANDIDATE_NAME") 見つかりません"
  fi
  echo "--------------------------------------------------"
done < <(find "$TARGET_DIR" -type f -name "*.crt.*[0-9][0-9][0-9][0-9][0-9][0-9]" -print0) # プロセス置換の終了

# このチェックで、ファイルが処理されたかどうかが正しく反映される
if [ "$CERT_FILES_FOUND" -eq 0 ]; then
    echo "ディレクトリ '$TARGET_DIR' 内に *.crt.*[数字6桁] のパターンに一致する証明書ファイルは見つかりませんでした。"
    echo "(例: domain.com.crt.202312)"
fi

これを `ssl-check.sh` として保存し、実行権限を付けます。

使用例

./ssl-check.sh /ディレクトリのフルパス

で実行した結果、

ディレクトリ '/hoge/' 内のSSL証明書情報:
==================================================
処理中の証明書: hoge.example.com.crt.202505
  有効期限: Aug 28 23:17:58 2025 GMT
  ドメイン名: *.hoge.example.com
  発行局 (CN): E5
  発行局 (詳細): C=US, O=Let's Encrypt, CN=E5
  秘密鍵ファイル: hoge.example.com.202505
    鍵の状態: 証明書と一致 (EC)
--------------------------------------------------

と、

  • 有効期限
  • ドメイン名
  • 自己証明でないか(発行局から発行されているか)

が明示的に分かるようになりました。

『ユミアのアトリエ』「試供品」による探索。

リグナス地方、

アルボール植物園解放後、調査団員に話しかけると、

ランダムで

  • 炸裂弾
  • 切弾

をもらうことができます。

これは、「探索ポーチ」から配備し直すことで使うことが可能です。

これを使うことにより、先んじてこういう菌糸で覆われた壁を

突破することができます。ただし、このサンプルはレシピを得ていない状態だと使うことができないため、使いどころには注意しましょう。

Geminiの学びからのフィギュア配置。

ここにより

  • 高低差を付ける
  • 余白を作る

などを学んだ結果、フィギュア棚を更に整理しました。

高さのある立像を中心にして三角形になるよう配置。

フィギュアの代償を取り入れ、額装という余白を作っていきました。

百均で購入した中華まんのスクイーズもワンポイントとして役立てています。

これにより、全体の統一感を図ることができました。

『ユミアのアトリエ』リグナス地方のメインシナリオ完了までにアクセス可能な宝物庫一覧。(ネタバレあり)

宝物庫の鍵を用いて開けられる宝物庫。

  • ノーマルクエスト
  • 開拓任務
  • キャラクタークエスト

でも必要なので、「有限の宝物庫の鍵に対し、必要と思われる宝物庫は何か?」

のまとめです。

リグナス地方のメインシナリオ完了までに得られる宝物庫の鍵は19個。

そのため、以下10個の宝物庫は十分余裕を持って開けることができます。

リグナス地方調査拠点・北

  • 宝箱1:
    • 〔特性結晶〕攻速上昇(Rank.3)
  • 宝箱2:
    • 《調合アイテム》クロース
    • 【家具】石の道(直線)
    • 【家具】石の道(曲線)
  • 宝箱3:
    • 〔特性結晶〕アイテム使用回数増加(Rank.2)

アルバーの集落・南

  • 宝箱1:
    • 《装備品》ハンターウェア
    • 【家具】花束
  • 宝箱2:
    • 《装備品》サペンニアアニュラス
    • 【家具】シーリングファン
  • 宝箱3:
    • 【家具】丸形のカーペットC
    • 《使用アイテム》樹林の治療薬

アルバーの集落・西

  • 宝箱1:
    • 《使用アイテム》ハピレスシャトル
  • 宝箱2:
    • 〔特性結晶〕攻防上昇(Rank.3)
    • 【家具】草塊
  • 宝箱3:
    • 〔特性結晶〕防速上昇(Rank.3)

[LM]大樹の爪先・北

  • 宝箱1:
    • 【家具】アーチ橋
    • 《装備品》流浪の福
  • 宝箱2:
    • 《使用アイテム》ルフト
    • 【家具】ガーデンパラソル

[LM]オブリエ大地・東

  • 宝箱1:
    • 《使用アイテム》エンハンスフルート
  • 宝箱2:
    • 【家具】巨木
    • 《調合アイテム》インゴット×3

備考

ここの宝物庫へのアクセスは炸裂弾が必要です。

[LM]残塔の入口・北※ノーマルクエストで必要な家具※

  • 宝箱1:
    • 【家具】柵・塀
    • 《使用アイテム》ルフト
  • 宝箱2:
    • 【家具】壁掛け照明E
    • 《使用アイテム》レヘルン
  • 宝箱3:
    • 【家具】普通のカーペットC
    • 《使用アイテム》プラジグ

備考

こちらのノーマルクエスト『畑荒らしを退治せよ2』で必要になります。

[LM]秘された花園・東

  • 宝箱1:
    • 《使用アイテム》フラム
  • 宝箱2:
    • 【家具】枝垂れ柳
    • 特性結晶〕防速上昇(Rank.3)
  • 宝箱3:
    • 《装備品》スカーレットスカーフ

備考

  • キャンプ場などが近くにあるものの、アクセスしやすい方法がこのランドマーク経由です。
  • また、リペアツール:木材ではしごを直してからの方が無難です。

[LM]樹海関門・北

  • 宝箱1:
    • 〔特性結晶〕アイテム使用回数増加(Rank.2)
  • 宝箱2:
    • 【家具】花の門
    • 〔特性結晶〕経験値ボーナス(Rank.2)
  • 宝箱3:
    • 《調合アイテム》アンブロイド×3

[LM]エレミトの谷・北

  • 宝箱1:
    • 【家具】ローテーブル
    • 〔特性結晶〕攻防上昇(Rank.3)
  • 宝箱2:
    • 【家具】外階段
    • 〔特性結晶〕攻速上昇(Rank.3)

[LM]地脈の樹窟・南

  • 宝箱1:
    • 【家具】スイングハンモック
    • 《調合アイテム》インゴット×3
  • 宝箱2:
    • 【家具】かわいいソファ
    • 〔特性結晶〕アイテム使用回数増加(Rank.2)
  • 宝箱3:
    • 【家具】絵画B
    • 〔特性結晶〕攻防上昇(Rank.3)

Ubuntu 24.04 aptitude updateエラー対応メモ(aptコマンドのLabel変更にによるパッケージリストの変更)

ちょっとハマったのでメモです。

環境

  • OS: Ubuntu 24.04

発生した問題

sudo aptitude update を実行した際に、特定のPPA (PHPリポジトリ) でエラーが発生し、パッケージリストの更新に失敗しました。
(※筆者の好みでaptitudeを用いています)

エラーメッセージの抜粋:

E: Repository 'https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble InRelease' changed its 'Label' value from '***** The main PPA for supported PHP versions with many PECL extensions *****' to 'PPA for PHP'
E: Failed to download some files
W: https://ppa.launchpadcontent.net/ondrej/php/ubuntu/dists/noble/InRelease を取得できませんでした:
E: 一部のインデックスファイルのダウンロードに失敗しました。無視されたか古いものを代わりに利用しています。

Ubuntu24.04をインストールしたばかりの頃に追加したリポジトリが古くなり、アップグレードができないという状態でした。

対処方法

以下の通りに実施しました。

リポジトリの Label 変更を許可

sudo apt update --allow-releaseinfo-change

変更許可後のupdate

sudo aptitude update

これにより、上記のエラーが解消され、正常にパッケージのアップグレードが成功しました。

MSI Claw用のモバイルバッテリー導入。

携帯できるSteam環境と言うことで運用しているMSI Claw。

アトリエシリーズ程度であればきちんと動き、フリーズなども特になし。

しかし、「ゲーム中のバッテリーの持ち」という課題は常につきまといます。参考までに

  • ライザのアトリエ3:1時間半程度
  • ユミアのアトリエ:1時間15分程度
  • BLUE REFLECTION(無印):1時間程度

などと、やや心許ないものがありました。それを解決するために用意したのがこちら。

Anker Prime Power Bank (27650mAh, 250W) 。

圧倒的な容量を誇り、250Wということから、ノートPCへの充電も可能なバッテリーです。(※そもそもMSI Claw自体がPC扱いなのでこれにしました)

開封した結果はこの通り。大きいです。そして、「鉄でも詰まっているのか」ぐらいの密度と重さ。(650gほど)

ケーブルを接続するとしっかり充電されます。

つなげたときでも、充電を示すマークが表していました。

Ubuntu 20.04環境でGrowi アップデート (v7.0.11 → v7.2.2) 失敗と MongoDB 切り戻しのメモ。

概要

以下の環境でGrowi v7.0.11 から v7.2.2 へのアップデートを試みたものの、サーバーのCPUハードウェア制約により断念し、データベース (MongoDB) を元の安定バージョンへ切り戻しました。

その時のメモです。

作業前の環境

  • OS: Ubuntu 20.04 LTS (Focal Fossa)
  • Growi: v7.0.11
  • Node.js: v18.20.8
  • MongoDB: v4.4.9

目指したこと

  • まずはMongoDB を Growi v7.2.2 が要求する v6.0 以上へアップデートする。

詰まったところ

Growi v7.2.2 の要求事項確認

  • Node.js: v18 以上のためOK。
  • MongoDB: v6.0 以上が必要だったため、現在の v4.4.9 アップデートが必要。

MongoDB段階的アップデート計画

MongoDB v4.4 から v6.0 へは、段階的なアップグレード (4.4 → 5.0 → 6.0 の順) が推奨されるため、まず MongoDB v5.0 へのアップデートに着手しました。

MongoDB 5.0 のGPGキー追加:

wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -

MongoDB 5.0 のリポジトリリストファイル作成:

echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list

パッケージリストの更新:

sudo aptitude update
sudo aptitude upgrade

CPUのAVX命令セット非対応問題の発覚

バージョンアップを確認するため

mongod --version

を実施しましたが、Illegal instruction (コアダンプ) というエラーが発生しました。

調査の結果、MongoDB v5.0 以降ではCPUがAVX (Advanced Vector Extensions) 命令セットをサポートしていることが必須要件となっていることが判明。

grep -q avx /proc/cpuinfo && echo "AVX supported" || echo "AVX not supported"

AVX not supportedと表示されたため、現在のサーバーでは MongoDB v5.0 及びそれ以降のバージョン (v6.0を含む) を動作させることが不可能であると結論。

そのため、目指したMongoDBのアップデートもGrowiのバージョンアップも断念。

MongoDB の切り戻し作業 (v4.4.x へ)

なので、切り戻しを行います。単にバージョンを指定してのインストールはうまくいきませんでした。

というのも依存関係の解決時に libc6 >= 2.34libssl3 (Ubuntu 22.04 Jammy のライブラリ) を要求するエラーが発生したからです。

これは、

/etc/apt/sources.list.d/

ディレクトリに最初のMongoDBのアップデート時のリポジトリが残っていたためです。

不要なMongoDBリポジトリ設定の削除

sudo rm /etc/apt/sources.list.d/mongodb-org-5.0.list
sudo rm /etc/apt/sources.list.d/mongodb-org-6.0.list

インストール済みパッケージのクリーンアップ

sudo aptitude purge mongodb-org mongodb-org-database mongodb-org-database-tools-extra mongodb-org-mongos mongodb-org-server mongodb-org-shell mongodb-org-tools mongodb-database-tools mongodb-mongosh

MongoDB v4.4 用GPGキーの再設定

wget https://www.mongodb.org/static/pgp/server-4.4.asc &&  sudo apt-key add server-4.4.asc
sudo aptitude update

MongoDB v4.4.x のインストール

apt-cache policy mongodb-org-server

インストール候補がMongoDB v4.4系であることを確認。

sudo aptitude install mongodb-org-server=4.4.29 mongodb-org-shell=4.4.29 mongodb-org-tools=4.4.29` 

動作確認

mongod --version

以下を確認。

db version v4.4.29
Build Info: {
    "version": "4.4.29",
    "gitVersion": "f4dda329a99811c707eb06d05ad023599f9be263",
    "openSSLVersion": "OpenSSL 1.1.1f  31 Mar 2020",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2004",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
systemctl status mongod

active(running)を確認。

この切り戻しにより、Growi が正常に動作することを確認しました。

MongoDB パッケージの固定 (Hold)

sudo aptitude hold mongodb-org-server mongodb-org-shell mongodb-org-tools

として、不要なアップデートを防ぐ措置を執りました。

結論

そもそもの問題として、いくらローカル環境とは言え、既にEOLを迎えているUbuntu20.04の延命措置を執ろうとしたことが誤りです。

また、OSのバージョンアップをしたとしてもCPUが対応していないと言うことが判明したことは、ハードウェアのリプレースも必要だという現実も突きつけられました。

いい機会なので、自宅のローカル環境の見直しを図ります。

Geminiによるフィギュア再配置。

2025年3月から使い始めたGoogle Gemini Advance。

画像処理能力を活かしてちょっとした検証を行いました。

模様替えで確保したフィギュアの棚。折角なので、Geminiに以下のように尋ねます。

このフィギュアの棚を、フィギュア群がさらに見栄えよくなるように配置するにはどうすればよいでしょうか。 

まず、核となる(目玉となるであろう)ライザのフィギュアを、上段と下段で指定ください。

これの結果はいささか予想外でしたが納得のいくもの。

フィギュア棚の配置について、より見栄えが良くなるような提案をさせていただきます。

核となるライザのフィギュアの配置

まず、目玉となるライザのフィギュアですが、現状の写真で特に大きく、ポーズもダイナミックな以下の2点を上下段の核として配置するのが良いでしょう。

  • 上段の核: 写真中央の赤い衣装で手を広げているライザのフィギュア。背景の緑とのコントラストも美しく、棚全体の中心として目を引きます。
  • 下段の核: 写真中央やや右、紫色の花を背景に、樽に座っているライザのフィギュア。他のフィギュアとのバランスも取りやすく、下段の安定感を出すのに適しています。

これを元に核、センターを配置。

これを撮影して更に確認。

その他のフィギュアの配置のポイント

上記の核となるフィギュアを中心に、以下の点を考慮して配置すると、より魅力的なディスプレイになるかと思います。

  • 視線の流れを意識する: フィギュアの向いている方向やポーズを活かし、見る人の視線が自然に流れるように配置します。例えば、キャラクター同士が会話しているように見せたり、ある一点を見つめているように配置したりするのも効果的です。
  • 高さと奥行きを出す: 全てのフィギュアを同じ高さに並べるのではなく、台座やアクリルスタンドなどを活用して高低差をつけたり、前後にずらして配置したりすることで、立体感と奥行きが生まれます。
  • テーマやシリーズでまとめる: 同じ作品のキャラクターや、似たような雰囲気のフィギュアを近くに配置すると、統一感が生まれます。
  • 色合いのバランスを考える: フィギュアの色や背景の色を考慮し、全体の色合いがバランス良くなるように配置します。暖色系と寒色系を効果的に組み合わせたり、同系色でまとめたりするのも良いでしょう。
  • 空間を活かす: フィギュアを詰め込みすぎず、適度な空間(余白)を残すことで、一つ一つのフィギュアが引き立ち、圧迫感を軽減できます。

これを意識して

と並べた結果、それぞれの目線が合いつつ6体も並ぶ結果に。

そして上段が埋まります。これは行けると思ったので

全体がまとまりました。

  • 中央からの三角配置
  • 両端の高さ

が合わさり、最初とは段違いの配置となりました。

こういうちょっとしたことにもAIの画像認識は役立ちます。

スタジオでの収穫。

今年も訪れた『ハリー・ポッター スタジオツアー』。

山ほど手に入れてきました。

ざっと見てこんな所。

大きなところが

  • スリザリンのクッション
  • タンブラー

となっています。

今回のワンドはホラス・スラグホーン先生。

その名前「ナメクジの角」に併せ、杖の柄の先はナメクジを想わせる意匠に、杖の身にもナメクジが這ったような模様がありました。

こちらも当然、スリザリンなので「ライザリン」と因果践む形でした。

『ユミアのアトリエ』ハウジングメモ-3-(キャラクタークエストで得られる家具:ネタバレあり)

キャラクタークエストで得られる家具のポイントです。

キャラクタークエストで得られる家具の特徴

  • それぞれのキャラクターをイメージした形容詞がつけられています。
  • 設置コストに比して快適度が上がりやすいです。(例:普通のベッドは快適度が10上がるが、これらで得られるベッドは15上がる)
  • 宝物庫の鍵を必要とする家具があります。
  • 開拓任務で必要なキャラクタークエストの家具もあります。

ヴィクトル:「クラシックな○○」

  • 納品も比較的楽で、ストーリーごとに進むのでこなしやすいです。
  • 略式調合のアイテムを納品するクエストがあります。

アイラ:「ファンシーな○○」

以下の理由で周回プレイでの罠があります。

  • 「ジャストカウンター」をクリアしないと発生しないキャラクタークエストがあります。
  • ラクーナ地方での開拓任務はこのクエストで得られる家具の設計図が必要です。

ルトガー:「ダークな○○」

  • 開拓クエストの進行をトリガーにするクエストがあります。
  • 宝物庫から得られる設計図が必要なクエストもあります。

ニーナ:「旧文明の○○」

  • 宝物庫から得られる設計図が必要なクエストがあります。
  • また、ハウジングエリアを指定して家具を設置するクエストがあります。

レイニャ:「ワイルドな○○」

  • 2つほど、アトリエで発生するクエストがありますので、見逃しやすいです。
  • 略式調合のアイテムを納品するクエストがあります。

備考

これらキャラクタークエストは、実績にも関わってくるものの、

  • 実績に関わるクエスト
  • それ以外の家具を得られるクエスト

は、独立して発生するパターンがあります。そのため、「実績は得られたのに家具がない」展開もあり得ます。

Page 1 of 255

Powered by WordPress & Theme by Anders Norén