LAMP環境をソースからビルドしてみた(PHP編)

 先日投稿したApache編に引き続いて、今回はPHPをソースインストールしていきます。作業環境その他諸々は前回と同じなので割愛します。

PHPソースの入手

 PHPの公式サイトからソースを取得してきます。そういえば、ファイルのダウンロードといえばwgetがありましたね。なんで前回忘れてたんだろ。

$ wget https://www.php.net/distributions/php-8.1.1.tar.gz
$ wget https://www.php.net/distributions/php-8.1.1.tar.gz.asc

 前回同様署名を検証し、アーカイブを展開していきます。

$ gpg --verify php-8.1.1.tar.gz.asc
$ gzip -d php-8.1.1.tar.gz
$ tar xvf php-8.1.1.tar

依存関係の解決

 こちらも前回同様、インストールしていくうえで必要なパッケージなどを準備していく必要があります。何が必要なのかは、公式ドキュメントにすべて示されています。
PHP: Unix システムへのインストール - Manual

autoconf

 autoconfはconfigureファイルを自動で生成してくれるツールです。これからインストールするPHPのバージョンは8.1.1なので、バージョン2.64以上を選択します。とりあえず今回は最新版をインストールします。

$ wget http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.xz
$ xz -d autoconf-latest.tar.xz
$ tar xvf autoconf-latest.tar
$ cd autoconf-latest
$ ./configure
(略)
GNU M4 1.4.6 or later is required; 1.4.16 or newer is recommended.

 autoconfはM4言語のマクロなので、M4をインストールする必要があります。先にこちらをインストールしましょう。

$ cd
$ wget http://ftp.gnu.org/gnu/m4/m4-latest.tar.xz
$ xz -d m4-latest.tar.xz
$ tar xvf m4-latest.tar
$ cd m4-latest
$ ./configure
$ sudo make
$ sudo make install

 これでOK。もう一度autoconfのソースフォルダに戻って作業を再開します。

$ ./configure
$ sudo make
$ sudo make install
$ autoconf --version
autoconf (GNU Autoconf) 2.71
(略)

automake

 こちらはMakefileを自動で生成してくれるツールです。autoconfと同様の方法でインストールします。

$ wget https://ftp.gnu.org/gnu/automake/automake-1.16.5.tar.xz 
$ xz -d automake-1.16.5.tar.xz
$ tar xvf automake-1.16.5.tar
$ cd automake-1.16.5
$ ./configure
$ sudo make
$ sudo make install
$ automake --version
automake (GNU automake) 1.16.5
(略)

libtool

 各種ファイルを自動で作成してくれる上記の2ツールとは異なり、libtoolはプラットフォーム間の違いを吸収してくれるインタフェースの役割を持っています。
 インストール方法はこれまで通りです。

$ wget https://ftpmirror.gnu.org/libtool/libtool-2.4.6.tar.gz
$ gzip -d libtool-2.4.6.tar.gz
$ tar xvf libtool-2.4.6.tar
$ cd libtool-2.4.6
$ ./configure
$ sudo make
$ sudo make install
$ libtool --version
libtool --version
libtool (GNU libtool) 2.4.6
(略)

Re2c

 Re2cはLexer(lexical analyzer:字句解析器)を自動で生成するツールです。
 Lexerは与えられた文字列をトークンとして分割する役割を持ち、処理系においては後述するParserと組み合わせて利用します。

$ wget https://re2c.org/https://github.com/skvadrik/re2c/releases/download/2.2/re2c-2.2.tar.xz
$ xz -d re2c-2.2.tar.xz
$ tar xvf re2c-2.2.tar
$ cd re2c-2.2
$ ./configure
$ sudo make
$ sudo make install
$ re2c --version
re2c 2.2

Bison

 BisonはParser(構文解析器)を生成するツールです。
 Lexerと同様、Parserもソースコードの処理時に使用されますが、こちらは複数のトークンを処理し、構文木の構造を作成する役割を持ちます。

$ wget https://ftp.gnu.org/gnu/bison/bison-3.8.tar.xz
$ xz -d bison-3.8.tar.xz
$ tar xvf bison-3.8.tar
$ cd bison-3.8
$ ./configure
$ sudo make
$ sudo make install
$ bison --version
bison (GNU Bison) 3.8
(略)

Configure実行

 必要なライブラリ等がそろったので、PHPのソースディレクトリに移動して./configureを叩きます。

configure: error: in `/home/klag/php-8.1.1':
configure: error: The pkg-config script could not be found or is too old.  Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.

pkg-config

エラーで「pkg-configがない」と言われてしまったので、インストールしていきます。例によって、wgetして展開してconfigure, make, make installします。

$ wget https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz
$ gzip -d pkg-config-0.29.2.tar.gz
$ tar xvf pkg-config-0.29.2.tar 
$ cd pkg-config-0.29.2
$ ./configure --with-internal-glib
$ make
$ sudo make install
$ pkg-config --version
0.29.2

 オプションとして--with-internal-glibを指定していますが、これはglibが入っていない場合にpkg-config側にバンドルされているglibを使用してビルドを行うためのものです。

 再びPHPのconfigureを行います。

configure: error: Package requirements (libxml-2.0 >= 2.9.0) were not met:

No package 'libxml-2.0' found

libxml2

 今度はlibxml2がないとのこと。インストールしましょう。

$ wget ftp://xmlsoft.org/libxml2/libxml2-2.9.12.tar.gz
$ gzip -d libxml2-2.9.12.tar.gz
$ tar xvf libxml2-2.9.12.tar
$ cd libxml2-2.9.12
$ ./configure
$ make 
$ sudo make install

 再度configureするも、次はsqlite3がないと言われました。

configure: error: Package requirements (sqlite3 >= 3.7.7) were not met:

No package 'sqlite3' found

sqlite3

 DBはMySQLを使うのでサポートは不要なのですが、--without-sqlite3オプションをつけても同じ内容のエラーが出てしまうのでインストールしておきます。

$ wget https://www.sqlite.org/2022/sqlite-autoconf-3370200.tar.gz 
$ gzip -d sqlite-autoconf-3370200.tar.gz 
$ tar xvf sqlite-autoconf-3370200.tar
$ cd sqlite-autoconf-3370200
$ ./configure
$ make
$ sudo make install
$ sqlite3 --version
3.37.2 (略)

 これでOK。
 ここで気が付いたのですが、LAMP環境でPHPを使うにはApache2との連携を行う必要があるとのこと。
 参照:PHP: Apache 2.x (Unixシステム用) - Manual
 いままでは./configureだけを実行していたのですが、次回以降は以下のコマンドを実行していきます。

./configure --with-apxs2=/usr/local/apache2/bin/apxs --with-pdo-mysql

 APXSはApacheの拡張モジュールを管理する実行形式ファイルです。これを使ってPHPとの連携をするための設定を行ってくれるものであると思われます。
 PDOはPhp Data Objectsの略で、PHPからDBを利用する際に利用されるものです。今回はMySQL用のものを利用していきます。

 無事configureが通ったので、make, make installしていきます。
 ソースの量が結構あるのでmakeに時間がかかりました。終わったらmake installを叩きます。こちらはすぐに完了しました。

動作確認

PHPApacheの連携ができているかの確認も兼ねて、/usr/local/apache2/htdocs以下に次のような内容のphpinfo.phpを作成します。

<?php
    phpinfo();
?>

 これで(サーバのIPアドレス)/phpinfo.phpにアクセスしたところ、PHPのソース自体が表示されてしまいました。
 公式ドキュメントを確認し、Apacheが.phpファイルをPHPソースとして認識できるように以下のような設定をhttpd.confに追加しました。

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

 Apacheを再起動してページをリロードしたところ、無事phpinfoが表示されました。 f:id:KLag:20220114005510p:plain

まとめ

 前回の作業の経験から、ある程度スムーズに進むようになってきました。ただ、前回に比べてエラーが多く発生し、その解決に時間がかかってしまいました。
 また、他のアプリケーションとの連携を行う際に必要な設定に関して多少は理解が深まったと感じています。
 次回はMySQLのインストールを行っていきます。ではまた。

Cisco CatalystスイッチにSSHで接続する

かねてからCisco製品が欲しい欲しいと言ってましたが、先日ついにCatalyst 3560Xスイッチを購入しました。
2960シリーズでもよかったんですけど、L3スイッチでVLAN間ルーティングしてみるのも楽しそうだなと思ったので3560Xを選択。結果、想像以上にデカいものが届きました。

作業開始

例によってシリアルコンソールケーブルをコンソールポートに挿し込んでscreenで接続していきます。設定の度にコンソールケーブルをつないでいては面倒が過ぎるので、ここからSSHで設定ができるようにしていきます。

IPアドレスの設定

初めに、スイッチ自体のIPアドレスを設定します。管理用のインタフェースVlan1に設定すればいいらしい。

Switch>en
Switch#configure terminal
Switch(config)#interface vlan1
Switch(config-if)#ip address aaa.bbb.ccc.ddd 255.255.255.0
Switch(config-if)#no shutdown

設定を確認するときは、ユーザモードまたは特権モードでshow interface vlan1を実行すればOK。IPアドレスInternet Address is aaa.bbb.ccc.ddd/eeで表示されるはず。
お好みで他ホストからPingするなりして疎通を確認しましょう。

SSH有効化の準備

さっそくSSHサーバを有効化していきたいところですが、その前にユーザ名とドメイン名、vtyポートの設定をしておく必要があります。
ここではvtyポートを5つ作成し、その他の設定は例として適当な文字列を記載しておきます。

Switch(config)#username klag password hoge
Switch(config)#line vty 0 4
Switch(config-line)#login local
Switch(config-line)#exit
Switch(config)#ip domain-name fuga.local

SSHサーバ有効化

最後に、SSHサーバを有効化していきます。SSHバージョン2、4096bit RSA鍵を利用します。

Switch(config)#crypto key generate rsa
(略)
How many bits in the modules [512]: 4096
Switch(config)#ip ssh version 2

おまけ:SSHクライアントの設定

以上でSSHサーバは有効になりましたが、いつものようにssh klag@aaa.bbb.ccc.dddで接続しようとしたらエラー発生。内容は以下の通り。

$ ssh klag@aaa.bbb.ccc.ddd
Unable to negotiate with aaa.bbb.ccc.ddd port 22: no matching cipher found. Their offer: aes128-cbc,3des-cbc,aes192-cbc,aes256-cbc

どうやら暗号方式が異なるためにネゴシエーションに失敗しているようです。ということで、-cオプションで接続時に使用する暗号方式を指定してあげます。

$ ssh klag@aaa.bbb.ccc.ddd -c aes256-cbc

ただ、毎度毎度オプションを指定するのも面倒なので、configファイルに次のように登録しておきました。

Host Catalyst
    HostName aaa.bbb.ccc.ddd
    User klag
    Ciphers +aes256-cbc

これで無事接続できるようになりました。よかったね!

LAMP環境をソースからビルドしてみた(Apache編)

 先日、某企業様の選考エントリー課題として、「LAMP環境のソースインストール」というものをいただきました。
 僕としても初めての試みということもあり、せっかくなので今回から「LAMP環境をソースからビルドしてみた」シリーズとして連載記事にその記録を残していこうと思います。
 また、根本的な理解を深めるという側面もあるので、基本的に公式ドキュメントなどの一次情報を参考にして作業を進めていきます。(英語文献を読むのも頑張っていきたい...)
Compiling and Installing - Apache HTTP Server Version 2.4

作業環境

  • OS: Ubuntu Server 20.04 (@VBox VM)
  • RAM: 8GB
  • NIC: Bridge Adaptor

ソースコードの入手・展開

 まず初めに、Apacheのサイトでこれからビルドしていくソースコードを入手してきます。

$ curl https://dlcdn.apache.org//httpd/httpd-2.4.51.tar.gz -o httpd-2.4.51.tar.gz

 SHA256ハッシュで整合性をチェックします。

$ curl https://downloads.apache.org/httpd/httpd-2.4.51.tar.gz.sha256 -o httpd-2.4.51.tar.gz.sha256
$ sha256sum -c httpd-2.4.51.tar.gz.sha256
httpd-2.4.51.tar.gz: OK

 gzip, tarで展開して、さっそくワーキングディレクトリを移動していきます。

$ gzip -d httpd-2.4.51.tar.gz
$ tar xvf httpd-2.4.51.tar
$ cd httpd-2.4.51

依存関係の解決

 ソースをただ持ってきてmakeを叩いただけではインストールはできません。公式ドキュメントのRequirementsにも書いてある通り、Apacheを動かすために外部パッケージの設定を行っていく必要があります。

APRAPR_Util

The mission of the Apache Portable Runtime (APR) project is to create and maintain software libraries that provide a predictable and consistent interface to underlying platform-specific implementations.
引用: https://apr.apache.org/
(APRの使命は、プラットフォーム特有の実装にとらわれない一貫性を提供するライブラリを作成し、維持することです。)

 この文章からもわかる通り、APRApacheを動かすために必要なランタイムです。READMEファイルを見た限り、原子性を満たす操作やメモリ・プロセスの管理、ファイル・ネットワークの入出力などを行っているようです。
 こちらもApache本体の時と同じように、ソースとハッシュを持ってきて整合性をチェックし、展開していきます。

APR
$ curl https://dlcdn.apache.org//apr/apr-1.7.0.tar.gz -o apr-1.7.0.tar.gz
$ curl https://downloads.apache.org/apr/apr-1.7.0.tar.gz.sha256 -o apr-1.7.0.tar.gz.sha256
$ sha256sum -c apr-1.7.0.tar.gz.sha256
apr-1.7.0.tar.gz: OK
$ gzip -d apr-1.7.0.tar.gz
$ tar xvf apr-1.7.0.tar
APR-Util
$ curl https://dlcdn.apache.org//apr/apr-util-1.6.1.tar.gz -o apr-util-1.6.1.tar.gz
$ curl https://downloads.apache.org/apr/apr-util-1.6.1.tar.gz.sha256 -o apr-util-1.6.1.tar.gz.sha256
$ sha256sum apr-util-1.6.1.tar.gz.sha256
apr-util-1.6.1.tar.gz: OK
$ gzip -d apr-util-1.6.1.tar.gz
$ tar xvf apr-util-1.6.1.tar

 あとは、これらのソースを~/httpd-2.4.51/srclib内に移動すればOK。ただし、ディレクトリ名のバージョンを表す数字は消しておきます。

$ mv apr-1.7.0/ httpd-2.4.51/srclib/apr
$ mv apr-util-1.6.1/ httpd-2.4.51/srclib/apr-util

PCRE (Perl-Compatible Regular Expressions)

 名前の通り、Perl互換の正規表現を扱うためのパッケージです。github上で公開されている最新バージョンを持ってきます。

$ curl -L https://github.com/PhilipHazel/pcre2/releases/download/pcre2-10.39/pcre2-10.39.tar.gz -o pcre2-10.39.tar.gz
$ curl -L https://github.com/PhilipHazel/pcre2/releases/download/pcre2-10.39/pcre2-10.39.tar.gz.sig -o pcre2-10.39.tar.gz.sig

 PCREのパッケージはGPG鍵で署名されているので、検証は以下のように行いました。

$ gpg --verify pcre2-10.39.tar.gz.sig 
gpg: assuming signed data in 'pcre2-10.39.tar.gz'
gpg: Signature made Fri Oct 29 16:07:03 2021 UTC using RSA key 45F68D54BBE23FB3039B46E59766E084FB0F43D8
gpg: Can't check signature: No public key

 公開鍵がないと怒られたので、公開鍵を取得してきてからもう一度署名を検証します。

$ gpg --keyserver pgp.nic.ad.jp --recv-key 45F68D54BBE23FB3039B46E59766E084FB0F43D8
$ gpg --verify pcre2-10.39.tar.gz.sig
...
gpg: Good signature from "Philip Hazel <ph10@hermes.cam.ac.uk>" [unknown]
...

 検証が完了したら、いままでと同様に展開していきます。

$ gzip -d pcre2-10.39.tar.gz
$ tar xvf pcre2-10.39.tar

 展開が完了したら、PCREのREADMEに書いてある通りにインストールしていきます。/usr/local/ 以下のファイル操作でPermission Deniedされることがあるので、sudoをつけてmakeしていきます。

$ cd pcre2-10.39
$ ./configure
$ sudo make
$ sudo make install 

ANSI-Cコンパイラとビルドツール

$ make -v
GNU Make 4.2.1
(略)
$ gcc -v
(略)
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)

正確な時刻

 systemd-timesyncdをインストールしてNTPで時刻設定を行います。
 私の環境ではルータ(192.168.11.1)がNTPサーバの役割も受け持っているので、そこに同期する形で時刻を合わせていきます。

$ sudo apt install systemd-timesyncd
$ sudo vim /etc/systemd/timesyncd.conf 
(↓のようにConfファイルを編集する)
[Time]
NTP=192.168.11.1
$ sudo systemctl unmask systemctl-timesyncd
$ sudo systemctl enable systemd-timesyncd
$ sudo systemctl start systemd-timesyncd
$ sudo timedatectl set-ntp true  // NTPでの同期を有効化
$ sudo timedatectl set-timezone Asia/Tokyo // タイムゾーンをUTC+9に
$ timedatectl
(略)
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active

ソースツリーの構築とビルド(エラーとの闘い)

 ここまででインストールに必要なライブラリやパッケージの導入や、事前に済ませておくべき設定はすべて完了しました。これにてようやくApache本体のインストールに取り掛かっていきます。
 はじめに、ソースツリーをUbuntu向けに構成していきます。

$ ./configure

 実行すると作業状況などのログがダーーーーっと流れていきます。不足しているパッケージなどがある場合は最後の行に出力されます。成功した場合はバージョンやインストール先、システムのコンパイラ情報などが表示されているはず。
 無事終了したら、makeでビルドしていきます。
 これでうまくいくかと思いきや、エラー発生。APR関係の処理のあたりでexpat.hがないと怒られてしまいました。 というわけでこちらもソースからインストール。

$ curl -L https://github.com/libexpat/libexpat/releases/download/R_2_4_2/expat-2.4.2.tar.gz -o expat.tar.gz 
$ gzip -d expat.tar.gz
$ tar xvf expat.tar
$ cd expat
$ ./configure
$ sudo make
$ sudo make install

 今度こそ上手く行くかと思ったのですが、PCREまわりでエラー発生。ここでとても詰まりました。
 結論から言ってしまうと、PCRE2ではなくPCREをインストールする必要があったということがわかりました。公式サイトにEnd of lifeなどと書いてあったので、何も考えずに最新版を入れてしまったのが間違いでした。
 ということで、PCRE2をアンインストールしてからPCREを入れなおします。

$ cd pcre2-10.39
$ sudo make uninstall
$ cd
$ curl -L -o pcre-8.45.tar.gz https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz/download
$ gzip -d pcre-8.45.tar.gz
$ tar xvf pcre-8.45.tar
$ cd pcre-8.45
$ ./configure
$ sudo make
$ sudo make install

これでOK。もう一度httpdディレクトリにもどって作業を進めていきます。

$ ./configure --with-pcre=/usr/local
$ sudo make
$ sudo make install

お疲れさまでした。これにてインストールは終了です。

httpdの起動

 インストールも終わったので、さっそくApacheを動かしていきましょう。 公式ドキュメントによると、apachectlで起動できるらしい。PATHを通してからやっていきます。

$ export PATH=$PATH:/usr/local/apache2/bin
$ sudo apachectl -k start
/usr/local/apache2/bin/httpd: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory

 ライブラリが読み込めてないとのこと。調べてみたら、新たなライブラリを追加したときはldconfigでキャッシュとかリンキングをしなおしてあげる必要があるらしい。初めて使うコマンドでした。
気を取り直してもう一回。

$ sudo apachectl -k start
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using (サーバのIPv6アドレス). Set the 'ServerName' directive globally to suppress this message

 どうやらうまく動いてはいるのですが、サーバ名が指定されてないと警告が表示されました。毎度毎度このメッセージが出るのはうっとうしいので、httpd.confにサーバ名を設定します。
 あとはapachectl -k stopしてから再起動すれば、なにも表示されないでコマンドが通るはず。
 サーバにHTTPでアクセスしたら見慣れた画面とは違うページが表示されはしたものの、無事動作が確認できました。"It works!"の文字にここまで感動したのは初めてかもしれない。
f:id:KLag:20211227044259p:plain

まとめ

 sudo apt install apache2で済むようなことが、ソースコードからビルドするととても大変だということが身にしみてわかりました。これから毎日aptに感謝しながら生活したいと思います。
 それ以上に、今までLinuxを利用する中で触ってこなかった/usr/local/lib/usr/local/includeといったディレクトリにシステム全体で共有されるライブラリとかヘッダファイルが置いてあることや、単純にApache一つをとっても様々なライブラリとの依存関係があることが理解できました。
 また、今までソースからビルドする方法に関しては皆目見当がつかなかったのですが、今回の構築を通じて大まかな流れに関しては掴めたかなと思います。
 今回はここまでです。次回はここにPHPをインストールしていきたいと思います。ではまた。

Laravelバックエンドにfetch APIでDELETEリクエストを送ろうとしてハマった話

この記事は ATJ-TECH Advent Calendarの16日目です。

adventar.org

先日はレトロな駄文を失礼しました。今回はWebアプリケーション開発でハマったポイントのお話です。

実行環境

  • OS: Ubuntu 20.04 Server
  • Laravel: 8.26.1
  • PHP 8.0.12

ハマったポイント

  1. 削除ボタンがクリックされたら確認ダイアログを表示させ、OKであればDELETEメソッドでリクエストを送信する
  2. Laravel側のコントローラに定義してあるレコードの削除処理が走る
    以上のような処理を実現するため、1.の部分をfetch APIを利用して次のように実装しました。
<button onclick="confirmAndDelete('/api/hoge')">
    DELETE
</button>

function confirmAndDelete(target) {
    let conf = confirm("Delete this record?");
    if (conf) {
        fetch(target, {
            method: 'DELETE'
        });
    }
}

 これをブラウザに表示させ削除ボタンをクリックしてみましたが、登録されているレコードは削除されずに表示されたままになってしまいました。

原因解明

 Laravel側で受け取ったリクエストを全部吐き出すようなログを作成して確認してみたところ、DELETEメソッドでのリクエスト自体は受け取られていました。
 次に、ブラウザの開発者ツールからfetch APIの動作を確認してみたところ、419エラーではじかれていたことが判明しました。
 普段はform要素内に@csrfディレクティブを記述することでCSRFトークンを埋め込んでいたのですが、Javascriptを利用してDELETEリクエストを送信する場合でもトークンを持たせる必要があることまでは理解していなかったことが原因でした。

問題解決

 リクエストボディにフォームデータ_tokenとしてCSRFトークンを持たせてあげれば解決しそうではあったんですが、DELETEメソッドにはリクエストボディを持たせられない模様。
 CSRFトークンのチェックを無効化することも考えたのですが、さすがに安全性を犠牲にするのは気が向かなかったので公式ドキュメントを確認したところ、以下のような記述を見つけました。

POSTパラメータとしてCSRFトークンをチェックすることに加えて、App\Http\Middleware\VerifyCsrfTokenミドルウェアはX-CSRF-TOKENリクエストヘッダもチェックします。
参照:CSRF保護 8.x Laravel

 以上のことを参考にして、リクエストの送信前にX-CSRF-TOKENヘッダを追加するようにしたところ、無事登録されたレコードを削除することができました。
 以下変更後のコード。

<button onclick="confirmAndDelete('/api/hoge', '{{ csrf_token() }}')">
    DELETE
</button>

function confirmAndDelete(target, token) {
    let conf = confirm("Delete this record?");
    if (conf) {
+       let header = new Headers();
+       header.append("X-CSRF-TOKEN", token);
        fetch(target, {
            method: 'DELETE',
+           headers: header
        });
    }
}

2021年にもなってAMD K6を動かしてみる

この記事はATJ-TECH Advent Calendar 2021の第13日目です。
adventar.org

さて、今年もこの時期がやってまいりましたね。去年はTCUACのらぴーと君の記事に触発されて、特に何かのACに参加するわけでもなくWindows NT3.15の話をしたようなしてないような。
今年は身内でこういう企画をやる話が出たので、これ以外にも何本か記事をあげたいと思います。

さて、ここから本題。
今回の主役は家の押し入れから出てきためっちゃ古いパソコンくんです。1998年夏モデルらしい。ってことで、やっていきましょう。

スペック

  • Model: FMV DESKPOWER MVII 267
  • OS: Windows 98
  • GPU: ATI Rage 2C
  • RAM: 64MB
  • CPUソケット: Socket 7
    なんでCPUだけソケット表記なのかって?だってこいつ、押入れから引っ張り出したのは良いんですけどCPUがないんだもん。ということで、某所でSocket7対応のCPUを入手。

    はい、ここでタイトル回収です。こちら、AMD K6-2 450AFXとなっております。なんでPentiumじゃないかって?メインPCでRyzenRadeonを使ってるから元々このPCにはK6が積まれていたからです。
    参照: FMV-DESKPOWER - AzbyClub サポート : 富士通

内部を見てみる

早速カバーを開けて、中身を見ていこうと思います。

この時代のPC特有の太いケーブル(ぼくは愛着を込めて「きしめん」って呼んでます)が何より先に目に入ってきますね。
もちろんSATAなんてものは存在せず、ストレージインタフェースはIDEかフロッピーだけという仕様です。
また、拡張カードインタフェースも特徴的。PCI4発(白)、ISA3発(黒)がサポートされています。PCIe一択の今に比べ、バラエティ豊かで面白いですね。
なお、PCIスロットにはモデム(下)とグラフィックカード(上)が、ISAスロットにはサウンドカードが挿さっています。

CPU搭載・起動

では、空っぽのソケットにCPUを載せていきます。しっかりピンの位置を確認して、

こうして、

こう。
今の時代に比べるとCPUクーラが小ぶりで可愛いですね。
最大450MHz、プロセスルール0.3~0.2μmってこともあって発熱は控えめなんですかね?(教えてエロい人)
これで最低限起動に必要なものは揃ったので、フロッピードライブにWindows98の起動ディスクを挿し込んで電源を入れてみた。

富士通のロゴが出てきました。通電は問題なさそう。
しかし、次の瞬間。「Password violated. System halted!」の表示とともにフリーズしてしまいました。

BIOSパスワードの怪

この時点で疑ったのは、バックアップの電池切れかBIOSの破損。とりあえずボタン電池を交換してみましたが、症状が好転することはありませんでした。
とりあえずCMOSクリアしたいなぁってことで、ジャンパかボタンを探していたところ、マザーボードに興味深い表示が。
f:id:KLag:20211205140343j:plain

S4  | PASSWORD
------------------
ON  | CHECK
OFF | BYPASS

つまりスイッチS4をOFFにすればパスワードチェックを回避して起動できるようになるのでは...?ということでやってみます。
S1-S4はDIPスイッチで、CPUの近くにありました。さっきのファンを取り付けたときの画像の右下あたり、コネクタの近くにあります。

再挑戦

スイッチをいじったので、もう一回電源を投入。これでだめなら諦めます。
f:id:KLag:20211205175157j:plain
はい、無事BIOSまでブートできました。結構嬉しかったです。あとはここから例によってDOSブート、パテ割り、フォーマットを済ませてOSのインストールへ。
電源周りが壊れて使えなくなったHDDレコーダから摘出したIDE接続のHDDが無事動いてくれたことに多少感謝しつつ、作業を進めていきます。 f:id:KLag:20211205180710j:plain ブレッブレですが、親の顔より見たあの画面。
f:id:KLag:20211205181419j:plain 大体一時間弱で終わりました。やったね。
どうでもいいけどAMDってこの時代からCPUINFOの文字列が“AuthenticAMD”なんですね。たしかRyzenも同じように出てたような気がする。

CPU-Zで確認してみる

これだけだと「動かした」感が出ないので、みんな大好きCPU-Zで詳細を確認してみましょう。 もちろん通常版のCPU-Zがこんな化石OSで動くわけがないので、こちら↓を使っていきます。
CPU-Z Vintage Edition | News | CPUID
なんとこちら、Windows 95/98で動作する 2019年に発表された アプリケーションです。ダウンロードしてみると、解凍前サイズで1.30MBでした。ちょうど2HDフロッピーに収まりきるサイズで感動しています。
f:id:KLag:20211205183316j:plain
動かしてみるとこんな感じでした。参考程度にメインPCのCPU-Zスクリーンショットを貼り付けて、この記事を終わりにしたいと思います。
f:id:KLag:20211205183719p:plain

まとめ

案外適当に放置されてたPCでもしっかり動いてくれるんですね。電源回りもそこまで酷使されてはなさそうなので、まだまだ遊ぶ程度の用途には耐えてくれると思います。
ただ、今はキーボードしかつながっていない状態なので、とりあえずはPS/2マウスを手に入れたいと思います。

firstOrFailの例外処理でハマった話

Laravel 8においてDBにデータが存在するかどうかをチェックして、存在したらそのデータを、存在しなかったら定数を返却するような処理を書く際に一時間近くハマったので備忘録として残しておく。

環境

  • OS: Ubuntu 20.04 server
  • Laravel 8.26.1
  • PHP 8.0.12

やりたかったこと

  1. 特定の条件に当てはまるデータが存在した場合、firstOrFail()関数を用いてそのデータの特定カラム(foo)の値を返却する。
  2. 条件に当てはまらない場合、スローされた例外をキャッチして定数(-1)を返却する。

これを実現するため、以下のようなコードを作成。

try{
      $user= User::where([
           ['user_id', '=', $userId],
           他の条件…,
      ])
      ->firstOrFail();
      return $user->foo;
}catch(Exception $e){
      return -1;
}

実際にこの処理を行うAPIをブラウザから叩くと、Laravel標準の 「404 | Not Found」ページが表示された。

原因

findOrFailメソッドとfirstOrFailメソッドは、クエリの最初の結果を取得します。ただし、結果が見つからない場合は、Illuminate\Database\Eloquent\ModelNotFoundExceptionを投げます。
(中略)
ModelNotFoundExceptionをキャッチしない場合は、404 HTTPレスポンスをクライアントへ自動的に返送します。

引用: Eloquentの準備 8.x Laravel

どうやらModelNotFoundExceptionがキャッチされない限り、firstOrFailメソッドは例外発生時にApp::abort(404)と同様の動作をするらしい。

解決

きちんとModelNotFoundExceptionをキャッチするようにしたところ、想定していた通りの動作をしてくれた。

use Illuminate\Database\Eloquent\ModelNotFoundException;
...
try{
      $user= User::where([
           ['user_id', '=', $userId],
           他の条件…,
      ])
      ->firstOrFail();
      return $user->foo;
}catch(ModelNotFoundException $e){
      return -1;
}

EC2上のnginxにHTTPSで接続できるようにした話

大学の友人間でLaravelを使ったWebアプリケーションを開発することになり、開発環境としてEC2上にnginxサーバを構築しました。
この環境にHTTPSで接続できるようにしたのでメモ程度に手順を残しておきます。

Certbotのインストール

今回はLet's Encryptを利用してサーバ証明書を発行してもらうので、Certbotを使ってSSL設定を行っていきます。aptからインストールできるのは便利ですね。

$ sudo apt install certbot python3-certbot-nginx

nginxのconfファイル記述

Certbot/etc/nginx/sites-enabled下にあるファイルのserver_nameディレクティブをサーチし、一致したドメインの存在するファイルに自動で設定を適用してくれます。
なので、confファイル内にserver_nameの項目を登録していきます。

server{
    server_name exaple.com www.example.com;
    root /var/www/hogehoge/public;
    location / {
       ...
    }
}

なお、ここですでにlistenディレクティブが定義されている場合、Certbotを実行する際に「同じポートで既にlistenされてるよ」とのエラーが発生し、設定が適用されなくなってしまうので注意。
confファイルの作成が終わったら設定をリロードします。

$ sudo systemctl reload nginx

Certbotの実行

準備が完了したので、certbotを実行してSSL通信に必要な設定を反映していきます。-dオプションでconfファイルに記述したドメイン名を指定するのを忘れずに。

$ sudo certbot -d example.com -d www.example.com

あとはCertbotが渡されたドメインが実際に存在するかなどをチェックして、自動でconfファイルに追記・変更を加えてくれます。
全ての処理が完了したら、サーバとのHTTPS通信が可能になります。

参考

https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04-ja