お知らせ

現在サイトのリニューアル作業中のため、全体的にページの表示が乱れています。

幾らか詰まった箇所があったので、その備忘録も兼ねて書いておく

前提条件

  • Ubuntu Desktop 20.04.6 LTS -> Ubuntu Desktop 22.04.2 LTS
  • ターゲットは物理マシンでモニタとキーボードは未接続
    • 作業はリモートで実施

実行マシンのスペック

デバイス 製品 諸元
CPU AMD Athlon 200GE 2C4T 3.2GHz Vega3 TDP35W
MEM G.SKILL F4-2666C19D-16GNT DDR4-2666 8GB * 2
SSD Crucial P1 CT500P1SSD8JP NVMe SSD 500GB
ネット回線 フレッツ光ネクストスーパーハイスピードタイプ隼 実効速度 360Mbps

手順

この作業では設定ファイルが勝手に更新されることはない

アップデート方法

事前にSSHを2本立てておくと作業しやすい

  1. SSHの認証鍵がRSA1の場合、ED25519など強力な鍵に置き換えておく
    1. これをしないと再起動後SSHで繋がらなくなる
  2. 次のコマンドを叩く
sudo apt update -y && sudo apt upgrade -y && sudo do-release-upgrade
  1. 続行するのでyを選択。1022への穴あけはしなくて良いが、もう一本SSHを繋いでおくと便利

  2. 設定更新などの作業が発生するため時間は1-2h程度見ておくと良い。問題なければy

    時間に余裕があるかどうかを確認してから進む

  3. <はい>を選択

  4. Dで差分を確認した後、修正の必要があればZで直す。Zを選ぶとシェルが起動し、シェルを終了するとこのダイアログに戻ってくるのでNで進む。また、これは設定ファイルの変更分出てくる

    差分を確認し、修正の必要性を判断しつつ進む

  5. 数時間かかることはないのでy

    まともな回線であればyを選べると思う

  6. 後は放置してれば再起動のダイアログが出てくるので、再起動すれば完了。壁紙がクラゲになるだけかと思ったらDockの位置とかUIが地味に変わっていた
    アップデート後のデスクトップ。クラゲが印象的だ

トラブルシューティング

手順通りやっていれば遭遇しないが、ハマりポイントだったので残しておく

Software Updateでアップグレードできない

日本語表示だと「ソフトウェアの更新」になるが、アップグレードボタンを押してもダイアログが消えるだけで何も起きない

このダイアログは役に立たなかった

これは次のコマンドを叩くことで回避出来る

sudo apt update -y && sudo apt upgrade -y && sudo do-release-upgrade

再起動後にRLoginから接続しようとするとエラーになる

SSH2 User Auth Failure "publickey" Status=0004
Send Disconnect Message...
publickey(ssh-rsa)

上記のエラーが出る場合、SSH認証鍵をRSA1を超える強度のものにする必要がある。XRDPがあればXRDPから復旧できるが、ない場合はモニタとキーボードを繋いでどうにかするしかない

参考までに/var/log/auth.logには以下のログが出る状態

sshd[7330]: userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]

アップグレード所感

セキュリティ面に改善がされているのは良かった(SSHの話)。またGUI周りのパフォーマンスが良くなったのか、キビキビ動くようになった気がする

後はこんなしょぼいスペックも中々ないだろうなというので貼っておく。主にAthlon 200geの部分の話

Athlon 200GEでもインストール速度に不満が出ることはなかった

投稿日:
ジャンル::生活の知恵

蓋を湯煎したり、瓶の底を叩いたり、蓋を叩いたり、あらゆる手を尽くしても開かなかったザワークラウト瓶詰めの蓋を楽に開ける方法があったので書き残しておきます。

本記事ではマイナスドライバーを使います。

対象物

定番とも言えるザワークラウトの瓶詰めです。

ザワークラウトの瓶

開け方

まず瓶の蓋側面に「∅」みたいな感じのマークがあるので探します。

「∅」みたいな感じのマークを探す

次に「∅」の下にある隙間にマイナスドライバーを差し込み、テコの原理で「カパッ」と音がするまで蓋を持ち上げます。ここまでくれば後は蓋を回すだけで開くようになります。

「∅」の下にある隙間にマイナスドライバーを差し込み、テコの原理で「カパッ」と音がするまで蓋を持ち上げる

関連商品

ヘングステンベルグのザワークラウトはカルディで売ってますし、行くのが面倒な場合はAmazonからも買えます

VisualStudio 2022でGitの署名コミットをしようとしたらエラーを吐いたのでその対処法

前提条件

  • Gpg4winをインストールしている
  • cmdから署名コミットができる
  • 最低限以下の設定がある
[user]
	name = your-name
	email = your@example.com
	signingkey = XXXXXXXXXXXXX
[commit]
	gpgsign = true

確認環境

下記のgpgはGpg4winにバンドルされているものです

Env Ver
Visual Studio Community 2022 (64 bit) Version 17.5.1
Git 2.40.0.windows.1
gpg 2.3.4

エラー内容

このエラーをコピーしようとするとVisualStudioがクラッシュしたので頑張って写経しました

Git failed with a fatal error.
Git failed with a fatal error.
hint: core.useBuiltinFSMonitor=true is deprecated; please set core.fsmonitor=ture instead
hint: Disable this message with "git config advice.useBuiltinFSMonitorConfig false"
error: cannot spawn gpg: No such file or directory
error: gpg failed wqrite commit object

対処方法

GitのGlobal Config設定変更で対処する

  1. 次のコマンドを流す
    1. git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"
    2. gpg.exeのパスは環境に応じて書き換えること

参考までにWindowsのGlobal Configは%USERPROFILE%.gitconfigにあるのでファイルを編集して対応する場合は、下記内容を追記することで対応できる

[gpg]
	program = "C:\\Program Files (x86)\\GnuPG\\bin\\gpg.exe"

この記事ではGitHub ActionsのCustom actionをJavaScriptで実装するJavaScript actionをTypeScriptとSWCを使って実装した方法を書いてます。

モチベーション

  • GitHub ActionsのWorkflowsを共通化したい
  • TypeScriptでロジックを書きたい
  • SWCを使いたい(nccはtscを使うので避けたい
  • github-scriptは一定以上のボリュームがあるものには向かない
    • これを使いつつUTを書いたりするとなると結構面倒になると思う

今回作るもの

Custom actionのうちJavaScript actionを作成します。
実装コードはTypeScript、トランスパイラはSWC、バンドラはwebpackを利用します。
バンドラを利用するのは、node_modules/をGitで管理したくないためです。
ビルド成果物であるdist/は実行時に必要なため、Gitで管理します。
(CI上でビルドしてキャッシュさせておくことも出来ると思いますが、今回は扱いません)

確認環境

Env Ver
@actions/core 1.10.0
@actions/github 5.1.1
@swc/cli 0.1.57
@swc/core 1.3.26
swc-loader 0.2.3
typescript 4.9.5
webpack 5.75.0
webpack-cli 5.0.1

サンプルコード

Custom Actions本体

Custom action本体のサンプルコードです。以下に一式があります。
https://github.com/Lycolia/typescript-code-examples/tree/main/swc-ts-custom-actions

ディレクトリ構成

dist/配下を叩くため、ここはGit管理に含めます。バンドルするのでnode_modules/はGit管理から外して問題ありません。

├─dist/
│ └─index.js        # Custom Actionsとして実行するファイル本体
├─node_modules/
├─src/
│ └─index.ts        # TypeScript実装
├─action.yaml       # Custom Actionsの定義
├─package-lock.json
├─package.json
├─swcrc-base.js     # SWCの設定
├─tsconfig.json     # tscの設定
└─webpack.config.js # webpackの設定
swcrc-base.js

SWCの設定例。特にJavaScript actionのための設定はなく、CLI向けのトランスパイルが出来る設定ならおk。
ファイル名は何でも大丈夫ですが、この場では.swcrcにしないことで、直接SWCで利用しないことを判りやすくするために違う名前にしています。

module.exports = {
    module: {
        type: 'commonjs',
    },
    jsc: {
        target: 'es2020',
        parser: {
            syntax: 'typescript',
            tsx: false,
            decorators: false,
            dynamicImport: false,
        },
        baseUrl: '.',
        paths: {
            'src/*': ['src/*'],
        },
    },
};
webpack.config.js

SWCを使って.tsファイルをバンドルするための設定。これがないとimportの解決ができずにコケます。
node_modules/配下をGit管理に含める場合は不要かもしれませんが、それをするのは微妙だと思います。

const path = require('path');
const swcrcBase = require(path.resolve(__dirname, 'swcrc-base'));

module.exports = {
    // エントリポイント
    entry: path.resolve(__dirname, 'src/index.ts'),
    // 出力設定
    output: {
        // クリーンアップ後に出力
        clean: true,
        // 出力ファイル名
        filename: 'index.js',
        // 出力パス
        path: path.resolve(__dirname, 'dist'),
    },
    // 設定必須なので何か指定しておく
    mode: 'production',
    // 指定してないとNode.jsのネイティブAPIが呼べない
    target: ['node'],
    module: {
        // swc-loaderの設定
        rules: [
            {
                test: /\.ts$/,
                exclude: /(node_modules)/,
                use: {
                    loader: 'swc-loader',
                    // swcrcの設定
                    options: {
                        ...swcrcBase,
                    },
                },
            },
        ],
    },
    resolve: {
        // import時のファイル拡張子を省略してる場合にパスを解決するための設定
        extensions: ['', '.ts', '.js'],
    },
};
src/index.ts

最低限これだけ確認できれば応用して実装できるだろうという程度のサンプルコード。

@actions/*系の使い方は以下のリンクから確認できます。
actions/toolkit: The GitHub ToolKit for developing GitHub Actions.

import * as core from '@actions/core';
import * as github from '@actions/github';

const githubToken = core.getInput('GITHUB_TOKEN', { required: true });
const octokit = github.getOctokit(githubToken);

console.log('octokit', octokit);
console.log('context', github.context);
core.setOutput('RESULT_MESSAGE', 'test result message');
action.yaml

実装の参考例として引数と出力を定義してます。特に不要な場合は書かなくてもいいです。
Node.jsのバージョンを詳細に指定したい場合は、composite action にすれば可能だとは思いますが、試してない。
composite actionにしてnvmか何かでインストールしてやれば恐らく可能。

構文は以下のページで確認できます。
GitHub Actions のメタデータ構文 - GitHub Docs

name: example
description: custom actions example
inputs:
  GITHUB_TOKEN:
    description: 'Repogitory GITHUB_TOKEN'
    required: true
outputs:
  RESULT_MESSAGE:
    description: 'Result message'
on:
  workflow_call:
runs:
  using: node16
  main: dist/index.js

Custom actionを使う側

Custom actionを使うWorkflowのサンプルコードです。以下にソースがあります。
https://github.com/Lycolia/custom-actions-usage-example

.github/workflows/example.yaml

usesのところにはリポジトリの組織名と、リポジトリ名、action.yamlが配置されているディレクトリまでのパスを書きます。ルートディレクトリにある場合はパスを書かなくてOK
最後に@sha-hashでコミットハッシュかタグを付けてやれば呼べるようになります。
動作確認中はハッシュが頻繁に変わるので、最新のハッシュを取得してきて設定されるようにしておくと便利かもしれません。

name: run example
on:
  workflow_dispatch:
jobs:
  example:
    runs-on: ubuntu-latest
    steps:
      - name: run custom actions
        id: test
        uses: org-name/repo-name/path/to/file@sha-hash
        with:
          # Custom action側で定義されている引数(input)の設定
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: show custom actions output
        # Custom action側で定義されている出力(output)の取得
        run: echo ${{ steps.test.outputs.RESULT_MESSAGE }}

参考資料

FocalboardというNotionクローンがあるらしく試してみた結果のメモ。
外部に公開することは一切考慮していません。ローカルマシンでの個人利用を想定しています。

確認環境

Env Ver
Ubuntu 20.04.4 LTS
WSL2 1.0.3.0
Focalboard 0.15.0
MySQL Ver 15.1 Distrib 10.3.37-MariaDB

前提条件

  • MySQLはセットアップ済み

手順

基本的なセットアップ

wget https://github.com/mattermost/focalboard/releases/download/v0.15.0/focalboard-server-linux-amd64.tar.gz
tar -xvzf focalboard-server-linux-amd64.tar.gz
sudo mv focalboard /var/lib/

cat <<'EOF' | sudo tee /etc/nginx/conf.d/focalboard.conf
upstream focalboard {
   server localhost:15001;
   keepalive 32;
}

server {
   server_name  focalboard.test;
   access_log   /var/log/nginx/focalboard.access.log;
   error_log    /var/log/nginx/focalboard.error.log;

   location ~ /ws/* {
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
       client_max_body_size 50M;
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       client_body_timeout 60;
       send_timeout 300;
       lingering_timeout 5;
       proxy_connect_timeout 1d;
       proxy_send_timeout 1d;
       proxy_read_timeout 1d;
       proxy_pass http://focalboard;
   }

   location / {
       client_max_body_size 50M;
       proxy_set_header Connection "";
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Frame-Options SAMEORIGIN;
       proxy_buffers 256 16k;
       proxy_buffer_size 16k;
       proxy_read_timeout 600s;
       proxy_cache_revalidate on;
       proxy_cache_min_uses 2;
       proxy_cache_use_stale timeout;
       proxy_cache_lock on;
       proxy_http_version 1.1;
       proxy_pass http://focalboard;
   }
}
EOF

sudo cat << 'EOF' | sudo tee /etc/init.d/focalboard
#!/bin/sh
## BEGIN INIT INFO
# Provides:          focalboard
# Required-Start:    $syslog $network
# Required-Stop:     $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: A self-hosted Git service written in Go.
# Description:       A self-hosted Git service written in Go.
## END INIT INFO

. /lib/lsb/init-functions

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="Focalboard server"
NAME=focalboard
SERVICEVERBOSE=yes
PIDFILE=/run/$NAME.pid
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/1/KILL/5}"

do_start()
{
    start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \
        --background --chdir /var/lib/focalboard \
        --exec /var/lib/focalboard/bin/focalboard-server
}

do_stop()
{
    kill -9 $(cat /run/focalboard.pid)
    # does not work
    #start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PIDFILE --name $NAME --oknodo
    rm -f $PIDFILE
}

do_status()
{
    if [ -f $PIDFILE ]; then
        if kill -0 $(cat "$PIDFILE"); then
            echo "$NAME is running, PID is $(cat $PIDFILE)"
        else
            echo "$NAME process is dead, but pidfile exists"
        fi
    else
        echo "$NAME is not running"
    fi
}

case "$1" in
    start)
        log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        ;;
    stop)
        log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        ;;
    status)
        do_status
        ;;
    restart)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        do_start
        ;;
    *)
        log_daemon_msg "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
        exit 2
        ;;
esac

exit 0
EOF

sudo chmod 755 /etc/init.d/focalboard
sudo update-rc.d focalboard defaults

mysql -u XXX -pYYY

DBの作成

CREATE DATABASE boards;
GRANT ALL on boards.* to 'boardsuser'@'localhost' identified by 'boardsuser-password';
exit

DBとportの変更

nano /var/lib/focalboard/config.json

portdbtypeを以下の内容に書き換え

    "port": 15001,
    "dbtype": "mysql",

起動

以下を叩き http://focalboard.test/ にアクセスできればOK

sudo service focalboard start

感想

Notionっぽいけどかなりしょぼい
ボードが作れてmdが書ける程度
2カラムレイアウト作るとか、画像をドラッグで移動するとかはできない
表組みへの画像挿入は「画像添付 -> 表のmdを書く -> HTMLからblob URLを貼る」で可能だが、見切れるので微妙

今のところ実用性はあまりないかも

参考