Add a new translation and hook up to the build:

(new)         	Makefile
	(new) -> 1.4  	fbsd-from-scratch/Makefile
	(new) -> 1.1  	fbsd-from-scratch/article.sgml
	(new) -> 1.1  	fbsd-from-scratch/stage_1.sh
	(new) -> 1.1  	fbsd-from-scratch/stage_2.sh
	(new) -> 1.1  	fbsd-from-scratch/stage_3.mk
This commit is contained in:
Hiroki Sato 2003-10-11 15:06:56 +00:00
parent 5d07ac733a
commit 8e73cebbbc
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=18398
6 changed files with 1187 additions and 1 deletions

View file

@ -14,7 +14,7 @@ SUBDIR+= dialup-firewall
SUBDIR+= diskless-x
#SUBDIR+= euro
#SUBDIR+= explaining-bsd
#SUBDIR+= fbsd-from-scratch
SUBDIR+= fbsd-from-scratch
#SUBDIR+= filtering-bridges
SUBDIR+= fonts
#SUBDIR+= formatting-media

View file

@ -0,0 +1,26 @@
#
# $FreeBSD$
#
# Article: FreeBSD From Scratch
#
# Original revision: 1.4
DOC?= article
FORMATS?= html
MAINTAINER= schweikh@FreeBSD.org
INSTALL_COMPRESSED?= gz
INSTALL_ONLY_COMPRESSED?=
# SGML content
SRCS= article.sgml stage_1.sh stage_2.sh stage_3.mk
DOC_PREFIX?= ${.CURDIR}/../../..
afterinstall:
${INSTALL_DOCS} ${.CURDIR}/stage_1.sh ${.CURDIR}/stage_2.sh \
${.CURDIR}/stage_3.mk ${DESTDIR}
.include "${DOC_PREFIX}/share/mk/doc.project.mk"

View file

@ -0,0 +1,631 @@
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
%man;
<!ENTITY % freebsd PUBLIC "-//FreeBSD//ENTITIES DocBook Miscellaneous FreeBSD Entities//EN">
%freebsd;
<!ENTITY scratch.ap "<application>FreeBSD をゼロから設定する</application>">
<!--
$FreeBSD$
Original revision: 1.1
-->
]>
<article>
<articleinfo>
<title>FreeBSD をゼロから設定するには</title>
<author>
<firstname>Jens</firstname>
<surname>Schweikhardt</surname>
<affiliation>
<address><email>schweikh@FreeBSD.org</email></address>
</affiliation>
</author>
<copyright>
<year>2002</year>
<holder>Jens Schweikhardt</holder>
</copyright>
<pubdate>$FreeBSD$</pubdate>
</articleinfo>
<abstract>
<para>この記事は、「&scratch.ap; (FreeBSD From Scratch)」という、
わたしの個人的な経験をまとめたものです。
カスタマイズした &os; システムをソースからコンパイルし、
さらに好みの ports のコンパイルして、
あなたが望む構成のシステムの、
完全に自動化されたインストールを実現します。
<command>make world</command>
がすばらしい考え方だとお思いの方にとって、
「&scratch.ap;」は、まさに <command>make world</command> を
<command>make evenmore</command> (さらにその先)
へと広げるものになることでしょう。</para>
</abstract>
<sect1 id="introduction">
<title>はじめに</title>
<para>今までに <command>make world</command>
を使ってシステムをアップグレードした経験はあるでしょうか?
もしディスクに一つのシステムしか入れていない場合は問題です。
<maketarget>installworld</maketarget> が途中で止まってしまったら、
あなたのシステムは壊れたまま、もう起動しなくなってしまうかも知れません。
あるいは、<maketarget>installworld</maketarget> が正常に終了しても、
新しいカーネルは起動に失敗してしまうかも知れません。
さて、そうなってしまったら、Fixit CD
を取り出して半年前のバックアップを戻す、
なんてはめになってしまうかも知れませんよね。</para>
<para>わたしは、<quote>アップグレードの時はディスクを初期化する</quote>
という方法がよいと考えています。パーティションではなくディスク全体のデータを
消去することで、アップグレードの手順では無視されるような古いデータが
残ってしまうことを防ぐことができます。ただ、
パーティションを全部初期化するということは、
ports/packages をすべて再コンパイル・再インストールしなければならず、
設定ファイルも注意深く作成し直さなければならないということです。
こういう作業を自動化したいと思いませんか?
そう思う人は、この先を読み進めましょう。</para>
</sect1>
<sect1 id="why">
<title>どうして「&scratch.ap;」(あるいは「~しない」)
ことが必要なのか</title>
<para>これはもっともな質問です。
すでに <application>sysinstall</application> がありますし、
カーネルとユーザランドツールをコンパイルする方法には、
もっと有名な方法が他にもあるからです。</para>
<para><application>sysinstall</application>
の問題は、「何を、どこに、
どうやってインストールするのか」が非常に限定されているという点です。</para>
<itemizedlist>
<listitem>
<para><application>sysinstall</application>
は通常、構築ずみの配布物セットと packages を
(CD, DVD, FTP などの)
別の場所からインストールする時に使われるものであり、
<literal>make buildworld</literal>
の結果をインストールできるようにはできていません。</para>
</listitem>
<listitem>
<para>現在稼働中のシステム中にあるディレクトリに、
新しいシステムをインストールすることはできません。</para>
</listitem>
<listitem>
<para><application>Vinum</application>
パーティションへのインストールはできません。</para>
</listitem>
<listitem>
<para>構築ずみの packages はインストールできますが、
ports を構築することはできません。</para>
</listitem>
<listitem>
<para>スクリプトを使ったり、
インストール後に変更するための処理を自由に入れることは困難です。</para>
</listitem>
<listitem>
<para>最後の大きな理由として、<application>sysinstall</application>
が、公式にもう積極的に使わないプログラムと考えられている、
ということがあげられます。</para>
</listitem>
</itemizedlist>
<para>システム全体を構築してインストールする方法は、
<ulink url="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/makeworld.html"
>ハンドブック</ulink>にある方法が有名です。
これはデフォルトで既存のシステムを置き換えるもので、
カーネルとモジュールだけが保存され、
システムバイナリ、ヘッダ、その他の多くのファイルは上書きされます。
使われなくなった古いファイルはそのまま残り、
動作に問題が出ることもあります。
何らかの理由でアップグレードに失敗すると、
システムを元の状態に戻することは不可能か、できても非常に困難です。</para>
<para>「&scratch.ap;」方法は、これらの問題をすべて解決できます。
考え方は単純です。
稼働中のシステムを使って空のディレクトリにシステムをインストールします。
その時、その新しいシステムのディレクトリツリーには、
新しいパーティションを適切にマウントしておaきます。
数多くある設定ファイルは、コピーできるものは適切な場所にコピーし、
それができないものには &man.mergemaster.8; を使います。
新しいシステムに対するインストール後の設定は、
古いシステムを動作させながら、新しいシステムに対して chroot して
自由に行なうことができます。具体的には、
シェルスクリプト、もしくは <command>make</command>
の実行で構成される、次の 3 段階でこれらを実現します。</para>
<orderedlist>
<listitem>
<para><filename>stage_1.sh</filename>:
新しい起動可能なシステムを空のディレクトリ以下に作成し、
必要なファイルをマージ、もしくはコピーします。
そして、新しいシステムを起動します。
</para>
</listitem>
<listitem>
<para><filename>stage_2.sh</filename>:
必要な ports をインストールします。</para>
</listitem>
<listitem>
<para><filename>stage_3.mk</filename>:
ひとつ前の段階でインストールしたソフトウェアの、
インストール後の設定を行ないます。</para>
</listitem>
</orderedlist>
<para>新しいシステムを構築するために「&scratch.ap;」方法を使い、
それが数週間、満足する程度に動作していることを確認したら、
もう一度それを使って、大元のシステムを再インストールすることができます。
これからはいつでも好きな時にシステムを更新して、
初期化・再インストールしたパーティションに切り替えるだけでよくなるわけです。</para>
<para><ulink url="http://www.linuxfromscratch.org/">Linux From Scratch</ulink>
(もしくは省略して LFS) について耳にしたり、試された方がいらっしゃるかも知れません。
LFS も同じように、稼働中のシステムを使ってシステムをゼロから構築し、
空のパーティションにインストールする方法が書かれています。
LFS が話題の中心としているのは、(カーネル、コンパイラ、デバイス、
シェル、端末データベースなどの) 各システムコンポーネントの役割と、
それらのインストールの詳細を見せることのようです。
この「&scratch.ap;」では、そのような詳細には触れません。
わたしの目的は、インストールを終わりまで自動化することであり、
システム構築時の泥くさい過程を全部説明することではありません。
&os; をそのようなレベルで掘り下げてみたい人は、
<filename>/usr/src/Makefile</filename> を読んで、
<command>make buildworld</command>
の動作を追いかけるところから始めましょう。</para>
<para>また、「&scratch.ap;」方法にも、
次のような欠点があることを心に留めておいてください。</para>
<!-- XXX: A nice idea would be to write stage2.sh using a jail
that runs into the newly installed world from stage1. Having
properly set up a network address as the jail's primary IP
address, it might even be possible to build ports in a chroot
without uninstalling anything from the 'host' system. But
keep in mind that even jails run on the 'host' kernel. -->
<itemizedlist>
<listitem>
<para>第 2 段階で ports をコンパイルしている間、
システムは通常の用途に使用することができません。
もしプロダクションサーバを運用しているなら、
第 2 段階でダウンタイムが発生することを考慮に入れなければなりません。
<filename>stage_2.sh</filename> の ports のコンパイルには、
AMD1800+、10,000rpm SCSI、1GB の RAM を搭載したシステムで、
約 4 時間かかります。</para>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="prerequisites">
<title>前提とする環境</title>
<para>「&scratch.ap;」方法を実行するには、
次のものが必要です。</para>
<itemizedlist>
<listitem>
<para>ソースと ports ツリーを含む、稼働中の &os; システム</para>
</listitem>
<listitem>
<para>新しいシステムをインストールするための、
最低 1 個の未使用パーティション</para>
</listitem>
<listitem>
<para>&man.mergemaster.8; を実行した経験。もしくは、
それを実行する勇気。</para>
</listitem>
<listitem>
<para>インターネット接続環境がない、あるいは遅い場合には、
インストールしたい ports の配布ファイル</para>
</listitem>
<listitem>
<para>Bourne シェル (&man.sh.1;)
を使ってシェルスクリプトを作成するための基礎知識</para>
</listitem>
<listitem>
<para>新しいシステムを起動する方法を、
対話的あるいは設定ファイルを使ってブートローダに
教えることができること</para>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="stage1">
<title>第 1 段階: システムのインストール</title>
<para>次に紹介するのは、わたしが作成した <filename>stage_1.sh</filename>
です。あなたが<quote>求めているシステム</quote>に合うように、
カスタマイズしてください。カスタマイズしなければならないところには、
なるべく詳細なコメントを付けてあります。重要なポイントは、
以下のとおりです。</para>
<itemizedlist>
<listitem>
<para>パーティションの配置</para>
<para>わたしは、システム全体を一つの大きな
パーティションに入れるという考え方が好きではないので、
普通は
<filename>/</filename>、
<filename>/usr</filename>、
<filename>/var</filename> の
パーティションを分割し、<filename>/tmp</filename> を
<filename>/var/tmp</filename> のシンボリックリンクにしています。
また、<filename>/home</filename> (ユーザのホームディレクトリ)、
<filename>/home/ncvs</filename> (&os; CVS リポジトリの複製),
<filename>/usr/ports</filename> (ports ツリー),
<filename>/src</filename> (チェックアウトした src ツリー)、
<filename>/share</filename> (news スプールなど、バックアップする必要がない、
その他の共有データ) といったファイルシステムを、
古いシステムと新しいシステムで共有しています。</para>
</listitem>
<listitem>
<para>その他の項目</para>
<para>これは、新しいシステムの起動後にすぐに実行したいことや、
第 2 段階の前に実行したい内容のことです。
わたしの場合は、<filename>/etc/passwd</filename> に
ログインシェルとして <filename role="package">shells/zsh</filename>
が登録してあるので、それになります。
厳密には、この「その他の項目」を実行する必要は必ずしもありません。
root ユーザでログインして、次の段階を実行できさえすればよいからです。</para>
<para>第 1 段階で単純に好みの ports をすべてインストールしないのは、
理論的、あるいは実践的な面においてブートストラップ問題と依存問題があるからです。
第 1 段階では古いカーネルが動作しているのですが、
chroot した環境では新しいバイナリとヘッダが含まれています。
たとえば、新しいシステムが (新しいヘッダに従って)
新しいシステムコールをサポートしていた場合、
configure スクリプトがそれを使おうとしてしまうかも知れません。
そうすると、古いカーネルは対応していないので異常終了してしまうでしょう。
わたしが <filename role="package">lang/perl5</filename>
をコンパイルした時には、他にも問題が発生するのを確認しています。</para>
</listitem>
</itemizedlist>
<para><filename>stage_1.sh</filename> を実行する前に、
<command>make installworld installkernel</command>
を実行するために通常行なう作業を完了させておいてください。
これらは、たとえば次のようなものです。</para>
<itemizedlist>
<listitem>
<para>カーネルコンフィグファイルの設定</para>
</listitem>
<listitem>
<para><command>make buildworld</command>
を正常終了させておくこと</para>
</listitem>
<listitem>
<para><command>make buildkernel
KERNCONF=<replaceable>whatever</replaceable></command>
を正常終了させておくこと</para>
</listitem>
</itemizedlist>
<para>初めて <filename>stage_1.sh</filename> を実行した場合は、
稼働中のシステムから新しいシステムへとコピーされる設定ファイルは
<filename>/usr/src</filename> のものと比べると古いので、
<command>mergemaster</command> がどうするかを聞いてきます。
おすすめは、ここで変更点を統合しておくことです。
もし、何度も質問に答えるのが面倒であれば、
<emphasis>稼働中の</emphasis>システムのファイルを更新しておきましょう
(ただしこれは、そうできればの話です。
<literal>-STABLE</literal> のシステムを実行していて、
<literal>-CURRENT</literal> を構築する、
もしくはその逆のようなケースでは、そうしてはいけません)。
次に <command>mergemaster</command> を実行した時、
RCS バージョン ID が <filename>/usr/src</filename>
にあるファイルと一致しているものは、処理が飛ばされるようになります。</para>
<para><filename>stage_1.sh</filename> スクリプトは
<command>set -e</command> が指定されており、
最初のコマンドが失敗 (終了コードが 0 以外) すると停止します。
そのため、エラーを見逃してしまうということはないでしょう。
次に進む前に、<filename>stage_1.sh</filename>
にあるエラーを全部修正しておいてください。</para>
<para><filename>stage_1.sh</filename> では
<command>mergemaster</command> が実行されます。
統合作業をしなければならないファイルが一つもない状態でも、
実行の終わりに次のメッセージが表示されます。</para>
<screen>*** Comparison complete
Do you wish to delete what is left of /var/tmp/temproot.stage1? [no] <userinput>no</userinput></screen>
<para><literal>no</literal> と答えるか、
単に <keycap>Enter</keycap> を押してください。
なぜかと言うと、<command>mergemaster</command>
は <filename>/var/tmp/temproot.stage1</filename>
にサイズが 0 のファイルをいくつか残すからです。
これは、後で新しいシステムに (存在しなければ) コピーされます。</para>
<para>この後、インストールされたファイルのリストがページャ
(デフォルトでは &man.more.1; です。&man.less.1; を使うこともできます)
に表示されます。</para>
<screen>*** You chose the automatic install option for files that did not
exist on your system. The following were installed for you:
/newroot/etc/defaults/rc.conf
...
/newroot/COPYRIGHT
(END)</screen>
<para><keycap>q</keycap> を入力してページャを終了します。
すると <filename>login.conf</filename> に関して、次のように表示されます。</para>
<screen>*** You installed a login.conf file, so make sure that you run
'/usr/bin/cap_mkdb /newroot/etc/login.conf'
to rebuild your login.conf database
Would you like to run it now? y or n [n]</screen>
<para>これに対する答えはどちらでも構いません。
どう答えても、スクリプトから &man.cap.mkdb.1; が実行されます。</para>
<para>ちゃんと予想どおりに動いているかチェックできるよう、
<filename>stage_1.sh</filename> で行なわれたことは、
すべて <filename>stage_1.log</filename> に記録されます。</para>
<para>次に示すのは、筆者の使っている <filename>stage_1.sh</filename> です。
特にステップ 1, 2, 5, 6 は書き換える必要があるでしょう。</para>
<warning>
<para>&man.newfs.8; コマンドには注意してください。
マウントずみのパーティションに新しいファイルシステムを作成することはできないものの、
このスクリプトはマウントされていない
<filename>/dev/da3s1a</filename>, <filename>/dev/vinum/var_a</filename>,
<filename>/dev/vinum/usr_a</filename> をすべて削除します。
ひとつ間違えれば、あなたの環境を破壊してしまう可能性がありますので、
デバイス名の変更は注意深く行なってください。</para>
</warning>
<programlisting><inlinegraphic fileref="stage_1.sh" format="linespecific"></programlisting>
<!--
<para>Download <ulink
url="stage_1.sh"><filename>stage_1.sh</filename></ulink>.</para>
-->
<para>このスクリプトを実行すると、
起動した時に次のような状態になっているシステムがインストールされます。</para>
<itemizedlist>
<listitem>
<para>稼働中のシステムと同じユーザとグループ</para>
</listitem>
<listitem>
<para>Ethernet と PPP を経由した、
ファイアウォールありのインターネット接続環境</para>
</listitem>
<listitem>
<para>正しいタイムゾーンと NTP 設定</para>
</listitem>
<listitem>
<para><filename>/etc/ttys</filename> や
<command>inetd</command> など、その他の細かな設定。</para>
</listitem>
</itemizedlist>
<para>他の部分に対する設定は、第 2 段階が終わるまで動作しません。
たとえば、プリンタや X11 の設定ファイルもコピーされますが、
プリンタは PostScript ユーティリティなど、
ベースシステムに含まれないアプリケーションを使うことが多いでしょう。
X11 はサーバ、ライブラリ、プログラムをコンパイルしないと動作しません。</para>
</sect1>
<sect1 id="stage2">
<title>第 2 段階: ports のインストール</title>
<note>
<para>この段階で ports をコンパイルするのではなく、
(コンパイルずみの) packages をインストールすることもできます。
その場合、<filename>stage_2.sh</filename> は
単に <command>pkg_add</command> コマンドを羅列するだけになるでしょう。
読者のみなさんにとって、そういうスクリプトを書くのは難しくないと思いますので、
ここではもっと柔軟で、ports
を使った伝統的な方法について考えることにします。</para>
</note>
<para>次に紹介する <filename>stage_2.sh</filename> スクリプトは、
わたしが好みの ports をインストールするために使ったものです。
これは何度でも実行でき、インストールずみの ports があれば、
飛ばして処理されます。スクリプトは <emphasis>実行せず、実行される内容だけ
を表示する (dryrun)</emphasis> オプション (<option>-n</option>)
があります。ports リストの編集や、環境変数の設定を変更しましょう。</para>
<para>ports リストは、空白で区切られた 2 個以上のキーワードからなっています。
カテゴリ、port 名に始まり、オプションとして
port をコンパイルしてインストールするためのコマンド
(デフォルトは <command>make install</command>) が続きます。
空白行と # から始まる行は無視されます。
おそらく多くの場合に考えなければならないのは、カテゴリ名と port 名だけでしょう。
ports によっては、たとえば次のように
<command>make</command> 変数を使って微調整することができます。</para>
<programlisting>www mozilla make WITHOUT_MAILNEWS=yes WITHOUT_CHATZILLA=yes install
mail procmail make BATCH=yes install</programlisting>
<para>実際には任意のシェルコマンドを指定できますので、
<command>make</command> を使う以外にも応用は可能です。</para>
<programlisting>java linux-sun-jdk13 yes | make install
news inn-stable CONFIGURE_ARGS="--enable-uucp-rnews --enable-setgid-inews" make install</programlisting>
<para><filename role="package">news/inn-stable</filename> の行は、
<literal>CONFIGURE_ARGS</literal> という シェル変数を定義した例です。
この port の <filename>Makefile</filename> は、
この指定した値を変数の初期値として、その他の必須の引数と一緒に使います。
これと</para>
<programlisting>news inn-stable make CONFIGURE_ARGS="--enable-uucp-rnews --enable-setgid-inews" install</programlisting>
<para>のようにして
<filename>make</filename> 変数をコマンドラインに設定した場合との違いは、
こちらの場合に変数そのものを完全に上書きしてしまうという点です。
どの方法を使えばいいのかについては、各 port によります。</para>
<para>インストールしたい ports が、
対話的インストールを使っていないことを確認してください。
ports は、あなたが標準入力に明示的に指定したもの以外、
標準入力を読み込む動作をしてはいけません。
もし ports がそのように作られていると、ports はヒアドキュメントにある
ports リストの次の行を読み込んで混乱してしまいます。
<filename>stage_2.sh</filename> を実行した時、
ある port が飛ばされたり、動作が止まってしまうようなことがあれば、
おそらくこれが原因でしょう。</para>
<para>次に示すのが、実際の <filename>stage_2.sh</filename> です。
これは、インストールされる port それぞれに対して
<filename>LOGDIR/category+port</filename>
という名前のログファイルを作成します。
<filename>stage_2.sh</filename> が共有パーティションになければ、
実行前に新しいシステムにこれをコピーするようにしてください。</para>
<programlisting><inlinegraphic fileref="stage_2.sh" format="linespecific"></programlisting>
<!--
<para>Download <ulink
url="stage_2.sh"><filename>stage_2.sh</filename></ulink>.</para>
-->
</sect1>
<sect1 id="stage3">
<title>第 3 段階</title>
<para>第 2 段階で、好みの ports がインストールされましたが、
ports には、設定を必要とするものがあります。
第 3 段階は、インストール後の設定を行なう段階です。
<filename>stage_2.sh</filename> の最後にこの段階を統合することもできたのですが、
わたしは port をインストールすることと初期設定を変更することが異なる工程であると考えたため、
独立した段階としています。</para>
<para>第 3 段階は、<filename>Makefile</filename> として実装しています。
これは、次のように実行することで、設定対象を簡単に選ぶことができるからです。</para>
<informalexample>
<screen>&prompt.root; <userinput>make -f stage_3.mk <replaceable>target</replaceable></userinput></screen>
</informalexample>
<para><filename>stage_2.sh</filename> の段階で、
<filename>stage_3.mk</filename> を共有パーティションに置くか、
新しいシステムのどこかにコピーするなどして、
新しいシステムが起動した時に
<filename>stage_3.mk</filename> が使えるようにしておきましょう。</para>
<programlisting><inlinegraphic fileref="stage_3.mk" format="linespecific"></programlisting>
<!--
<para>Download <ulink
url="stage_3.mk"><filename>stage_3.mk</filename></ulink>.</para>
-->
</sect1>
<sect1 id="limitations">
<title>制限事項</title>
<para>対話的で、かつ <command>make BATCH=YES install</command>
でのインストールに対応していない port
の自動インストールは難しいかも知れません。
対話的にインストールする ports には、ライセンス条項の同意を尋ねられた時に
<literal>yes</literal> と入力するだけのものがいくつかあります。
そのように入力が標準入力から読みとられる場合は、
適切な回答をインストールコマンド (通常は <command>make
install</command>) にパイプで渡すことができます
(<filename>stage_2.sh</filename> の
<filename role="package">java/linux-sun-jdk13</filename>
でとった方法がそうです)。</para>
<para>しかしこの方法は、たとえば <filename
role="package">editors/staroffice52</filename> の場合にはうまく動きません。
これは X11 が実行されていることを要求するからです。
インストール手順には多くのクリックや文字入力が必要なので、
他の ports のように自動化することはできません。
わたしは、次のようにして問題を回避しました。
最初に古いシステムで staroffice の package を作成し、</para>
<informalexample>
<screen>&prompt.root; <userinput>cd /usr/ports/editors/staroffice52</userinput>
&prompt.root; <userinput>make package</userinput>
===> Building package for staroffice-5.2_1
Creating package /usr/ports/editors/staroffice52/staroffice-5.2_1.tbz
Registering depends:.
Creating bzip'd tar ball in '/usr/ports/editors/staroffice52/staroffice-5.2_1.tbz'</screen>
</informalexample>
<para>その後、第 2 段階で次のようにしたわけです。</para>
<informalexample>
<screen>&prompt.root; <userinput>pkg_add /usr/ports/editors/staroffice52/staroffice-5.2_1.tbz</userinput></screen>
</informalexample>
<para>その他に、設定ファイルのアップグレード問題に気をつける必要があります。
一般的に、設定ファイルの書式や内容がいつ変更されるかを知ることはできません。
新しいグループが <filename>/etc/group</filename>
に追加されるかも知れませんし、<filename>/etc/passwd</filename>
に新しいフィールドが追加されるかも知れません。
このような例は、実際に過去にありました。
単純に古いシステムから新しいシステムに設定ファイルをコピーするだけで
ほとんどの場合は十分なのですが、時には不都合な場合もあります。
古いファイルを上書きする方法でシステムをアップグレードしたら、
ローカルにある設定ファイルに新しく追加されたかも知れない項目を統合する目的で
<command>mergemaster</command> を使うと思います。
しかし残念なことに、<command>mergemaster</command>
はベースシステムに存在するファイルだけで、インストールした
ports については何も処理を行なってくれません。
サードパーティ製ソフトウェアには、
リリースのたびに設定ファイルのフォーマットが変更され、
わたしをイライラさせるようなものもあります。
注意すること以外にできることはありませんが、
特にメジャーバージョンがあがった時は気を付けてください。
わたしは以前、ウェブサーバ、
ニュースサーバ、ニュースリーダのファイルを書き換えたり、
書き直すはめになったことがあります。
活発に開発が進められているソフトウェアはすべて、
設定ファイルの書式が変更されていないか確認しておきましょう。</para>
<para>わたしは
<literal>5-CURRENT</literal> から <literal>5-CURRENT</literal>
に更新するために
「&scratch.ap;」方法を数回使いましたが、
<literal>4-STABLE</literal> と <literal>5-CURRENT</literal>
の間で更新を行なった経験はありません。
異なるメジャーリリース番号の間は、非常の多数の変更が行なわれているため、
更新作業はもっと複雑なものになると思います。
(試したわけではないのですが)
<literal>4-STABLE</literal> から <literal>4-STABLE</literal>
への更新であれば、「&scratch.ap;」方法は問題なく動作するはずです。
<literal>4-STABLE</literal> のユーザは、次の点を考慮してください。</para>
<itemizedlist>
<listitem>
<para>デバイスファイルシステム
(<literal>devfs</literal>) を使ってなければ、
第 1 段階のステップ 6 で &man.MAKEDEV.8; を使い、
ハードウェア用のデバイスファイルを作成するとよいでしょう。</para>
</listitem>
</itemizedlist>
</sect1>
</article>

View file

@ -0,0 +1,233 @@
#!/bin/sh
#
# stage_1.sh - FreeBSD From Scratch, 第 1 段階: システムのインストール
# 使い方: ./stage_1.sh
#
# $FreeBSD$
# Original revision: 1.1
set -x -e
PATH=/bin:/usr/bin:/sbin:/usr/sbin
# 前提とする環境:
#
# a) "make buildworld" と "make buildkernel" が正常に終了していること。
# b) 未使用パーティションがあること (ルートファイルシステム用に少なくとも 1 個、
# 好みに応じて /usr や /var 用のものを用意する)
# 新しいシステムを作成する場所を示すルートマウントポイントを指定。
# マウントポイントとして使われるだけなので、マウントポイントのある
# ファイルシステムにファイルは置かれず、書き込みはすべてマウントした
# ファイルシステムに行なわれる。
DESTDIR=/newroot
SRC=/usr/src # src ツリーのある場所
# ---------------------------------------------------------------------------- #
# ステップ 1: $DESTDIR 以下に空のディレクトリツリーを作成
# ---------------------------------------------------------------------------- #
step_one () {
# 新しいルートファイルシステムを作成する。必須。
# デバイス名 (DEV_*) を変更すること。変更しないとシステムが壊れる危険性がある。
DEV_ROOT=/dev/da3s1a
mkdir -p ${DESTDIR}
newfs ${DEV_ROOT}
tunefs -n enable ${DEV_ROOT}
mount -o noatime ${DEV_ROOT} ${DESTDIR}
# その他のファイルシステムと初期マウントポイント。オプション。
DEV_VAR=/dev/vinum/var_a
newfs ${DEV_VAR}
tunefs -n enable ${DEV_VAR}
mkdir -m 755 ${DESTDIR}/var
mount -o noatime ${DEV_VAR} ${DESTDIR}/var
DEV_USR=/dev/vinum/usr_a
newfs ${DEV_USR}
tunefs -n enable ${DEV_USR}
mkdir -m 755 ${DESTDIR}/usr
mount -o noatime ${DEV_USR} ${DESTDIR}/usr
mkdir -m 755 -p ${DESTDIR}/usr/ports
mount /dev/vinum/ports ${DESTDIR}/usr/ports
# ここで他のすべてのディレクトリを作成。必須。
cd ${SRC}/etc; make distrib-dirs DESTDIR=${DESTDIR}
# 個人的には tmp -> var/tmp とシンボリックリンクを張るのが好み。オプション。
cd ${DESTDIR}; rmdir tmp; ln -s var/tmp
}
# ---------------------------------------------------------------------------- #
# ステップ 2: /etc ディレクトリツリーと / にファイルを追加
# ---------------------------------------------------------------------------- #
step_two () {
# 好みに応じて、このリストに追加・削除すること。ほとんどの場合は必須。
for f in \
/.profile \
/etc/group \
/etc/hosts \
/etc/inetd.conf \
/etc/ipfw.conf \
/etc/make.conf \
/etc/master.passwd \
/etc/nsswitch.conf \
/etc/ntp.conf \
/etc/printcap \
/etc/profile \
/etc/rc.conf \
/etc/resolv.conf \
/etc/start_if.xl0 \
/etc/ttys \
/etc/ppp/* \
/etc/mail/aliases \
/etc/mail/aliases.db \
/etc/mail/hal9000.mc \
/etc/mail/service.switch \
/etc/ssh/*key* \
/etc/ssh/*_config \
/etc/X11/XF86Config-4 \
/boot/splash.bmp \
/boot/loader.conf \
/boot/device.hints ; do
cp -p ${f} ${DESTDIR}${f}
done
# mergemaster の作業ファイルがあれば削除。
TEMPROOT=/var/tmp/temproot.stage1
if test -d ${TEMPROOT}; then
chflags -R 0 ${TEMPROOT}
rm -rf ${TEMPROOT}
fi
mergemaster -i -m ${SRC}/etc -t ${TEMPROOT} -D ${DESTDIR}
cap_mkdb ${DESTDIR}/etc/login.conf
pwd_mkdb -d ${DESTDIR}/etc -p ${DESTDIR}/etc/master.passwd
# mergemaster は /var/log に置かれる空ファイルを作成しないので、
# ここで作成。ただし上のループでコピーされている場合は、それを使う。
cd ${TEMPROOT}
find . -type f | sed 's,^\./,,' |
while read f; do
if test -r ${DESTDIR}/${f}; then
echo "${DESTDIR}/${f} already exists; not copied"
else
echo "Creating empty ${DESTDIR}/${f}"
cp -p ${f} ${DESTDIR}/${f}
fi
done
chflags -R 0 ${TEMPROOT}
rm -rf ${TEMPROOT}
}
# ---------------------------------------------------------------------------- #
# ステップ 3: installworld を実行する
# ---------------------------------------------------------------------------- #
step_three () {
cd ${SRC}
make installworld DESTDIR=${DESTDIR}
}
# ---------------------------------------------------------------------------- #
# ステップ 4: カーネルとモジュールをインストールする
# ---------------------------------------------------------------------------- #
step_four () {
cd ${SRC}
# installkernel ターゲットには、loader.conf と device.hints が必要。
# ステップ 2 でコピーしていなければ、次の 2 行を使ってコピーすること。
# cp sys/boot/forth/loader.conf ${DESTDIR}/boot/defaults
# cp sys/i386/conf/GENERIC.hints ${DESTDIR}/boot/device.hints
make installkernel DESTDIR=${DESTDIR} KERNCONF=HAL9000
}
# ---------------------------------------------------------------------------- #
# ステップ 5: 必須のファイルのインストールと変更
# ---------------------------------------------------------------------------- #
step_five () {
# /etc/fstab の作成。必須。自分のデバイスに合うように変更すること。
cat <<EOF >${DESTDIR}/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/da3s1b none swap sw 0 0
/dev/da4s2b none swap sw 0 0
/dev/da3s1a / ufs rw 1 1
/dev/da1s2a /src ufs rw 0 2
/dev/da2s2f /share ufs rw 0 2
/dev/vinum/var_a /var ufs rw 0 2
/dev/vinum/usr_a /usr ufs rw 0 2
/dev/vinum/home /home ufs rw 0 2
/dev/vinum/ncvs /home/ncvs ufs rw,noatime 0 2
/dev/vinum/ports /usr/ports ufs rw,noatime 0 2
#
/dev/cd0 /dvd cd9660 ro,noauto 0 0
/dev/cd1 /cdrom cd9660 ro,noauto 0 0
proc /proc procfs rw 0 0
EOF
# その他のディレクトリ。オプション。
mkdir -m 755 -p ${DESTDIR}/src; chown root:wheel ${DESTDIR}/src
mkdir -m 755 -p ${DESTDIR}/share; chown root:wheel ${DESTDIR}/share
mkdir -m 755 -p ${DESTDIR}/dvd; chown root:wheel ${DESTDIR}/dvd
mkdir -m 755 -p ${DESTDIR}/home; chown root:wheel ${DESTDIR}/home
mkdir -m 755 -p ${DESTDIR}/usr/ports; chown root:wheel ${DESTDIR}/usr/ports
# タイムゾーンの設定。ほとんどの場合は必須。
cp ${DESTDIR}/usr/share/zoneinfo/Europe/Berlin ${DESTDIR}/etc/localtime
if test -r /etc/wall_cmos_clock; then
cp -p /etc/wall_cmos_clock ${DESTDIR}/etc/wall_cmos_clock
fi
}
# ---------------------------------------------------------------------------- #
# ステップ 6: 新しいシステムにログインする時に重要な内容
# 注意: あまり多くのバイナリをこの時点でインストールしないこと。稼働している
# 古いシステムと、インストールした新しいバイナリ・ヘッダを組み合わせると、
# ブートストラップ問題に陥る可能性がある。ports は新しいシステムが起動した後に
# 再構築する方がよい。
# ---------------------------------------------------------------------------- #
step_six () {
chroot ${DESTDIR} sh -c "cd /usr/ports/shells/zsh; make clean install clean"
chroot ${DESTDIR} sh -c "cd /etc/mail; make install" # configure sendmail
# compat シンボリックリンクがないと、linux_base のファイル群が
# ルートファイルシステムに置かれてしまう。
cd ${DESTDIR}; mkdir -m 755 usr/compat
chown root:wheel usr/compat; ln -s usr/compat
mkdir -m 755 usr/compat/linux
mkdir -m 755 boot/grub
# /etc/printcap で指定したスプールディレクトリを作成。
cd ${DESTDIR}/var/spool/output/lpd; mkdir -p as od ev te lp da
touch ${DESTDIR}/var/log/lpd-errs
# 古いシステムから引き継ぎたいファイルを指定
for f in \
/var/cron/tabs/root \
/var/mail/* \
/boot/grub/*; do
cp -p ${f} ${DESTDIR}${f}
done
# 共有パーティション /home がなければ、/home をコピーした方がよいかも知れない。
# mkdir -p ${DESTDIR}/home
# cd /home; tar cf - . | (cd ${DESTDIR}/home; tar xpvf -)
# FreeBSD 5.x より perl は /usr/local/bin に置かれるようになったが、
# 多くのスクリプトは #!/usr/bin/perl でハードコードされている。
# これらを動作させるため、シンボリックリンクを作成しておく。
cd ${DESTDIR}/usr/bin; ln -s ../local/bin/perl
cd ${DESTDIR}/usr; rmdir src; ln -s ../src/current src
}
do_steps () {
step_one
step_two
step_three
step_four
step_five
step_six
}
do_steps 2>&1 | tee stage_1.log
# EOF $RCSfile: stage_1.sh,v $ vim: tabstop=2:expandtab:

View file

@ -0,0 +1,149 @@
#!/bin/sh
#
# stage_2.sh - FreeBSD From Scratch, 第 2 段階: ports のインストール
# 使い方: ./stage_2.sh
#
# $FreeBSD$
# Original revision: 1.1
DBDIR=/var/db/pkg
PORTS=/usr/ports
LOGDIR=/home/root/setup/ports.log; mkdir -p ${LOGDIR}
# 複数の port で使用される環境変数の設定
PAPERSIZE=a4; export PAPERSIZE
USA_RESIDENT=NO; export USA_RESIDENT
MYNAME=$(basename $0)
usage () {
exec >&2
echo "usage: ${MYNAME} [-hn]"
echo ""
echo " Options:"
echo " -h Print this help text."
echo " -n Dryrun: just show what would be done."
echo ""
exit 1
}
args=`getopt hn $*`
if test $? != 0; then
usage
fi
set -- $args
DRYRUN=
for i; do
case "$i" in
-n) DRYRUN=yes;;
--) break;;
*) usage;;
esac
done
cat << EOF |
lang perl5
security sudo
x11-servers XFree86-4-Server
x11 wrapper
x11 XFree86-4-libraries
x11 XFree86-4-clients
x11-fonts XFree86-4-font75dpi
x11-fonts XFree86-4-font100dpi
x11-fonts XFree86-4-fontScalable
x11-fonts urwfonts
x11-fonts webfonts
x11-toolkits open-motif
x11 rxvt
x11-wm ctwm
security openssh-askpass
astro xplanet
astro setiathome make BATCH=yes install
astro xephem
editors vim
print ghostscript-gnu make A4=yes BATCH=yes install
print a2ps-a4
print psutils-a4
print gv
print acroread5
print transfig
archivers zip
archivers unzip
java linux-sun-jdk13 yes | make install
java jdk13
www apache2
www weblint
www amaya
www mozilla make WITHOUT_MAILNEWS=yes WITHOUT_CHATZILLA=yes install
www netscape48-navigator
www checkbot
www privoxy
graphics xfig
graphics xv
graphics fxtv
lang expect
news tin
net freebsd-uucp
net cvsup-without-gui
net pathchar make NO_CHECKSUM=yes install
ftp wget
ftp ncftp3
textproc ispell
german ispell-neu
german ispell-alt
textproc docproj make JADETEX=yes HAVE_MOTIF=yes install
sysutils samefile
sysutils pstree
sysutils mkisofs
sysutils cdrtools
sysutils grub
devel ddd
devel ctags
devel ElectricFence
mail procmail make BATCH=yes install
mail metamail
mail mutt
mail spamoracle
emulators mtools
sysutils portupgrade
news inn-stable CONFIGURE_ARGS="--enable-uucp-rnews --enable-setgid-inews" make install
misc figlet-fonts
textproc gmat
EOF
while read CATEGORY NAME CMD; do
case "${CATEGORY}" in
\#*) continue;;
'') continue;;
esac
DIR="${PORTS}/${CATEGORY}/${NAME}"
if ! test -d "${DIR}"; then
echo "$DIR does not exist -- ignored"
continue
fi
cd ${DIR}
PKGNAME=`make -V PKGNAME`
if test -d "${DBDIR}/${PKGNAME}"; then
echo "${CATEGORY}/${NAME} already installed as ${PKGNAME}"
continue
fi
LOG="${LOGDIR}/${CATEGORY}+${NAME}"
echo "===> Installing ${CATEGORY}/${NAME}; logging to ${LOG}"
test -n "${CMD}" || CMD="make install"
if test -n "${DRYRUN}"; then
echo "${CMD}"
continue
fi
date "++++++++++ %v %T +++++++++" > ${LOG}
echo "CMD: ${CMD}" >> ${LOG}
(
make clean
eval "${CMD}"
# make clean # ${PORTS} 以下のディスク容量がすくなければコメントをはずす
) 2>&1 | tee -a ${LOG}
done
# StarOffice は、X11 を使った対話的インストールが必要なので、
# 古いシステム上で "make package" を実行して作成した
# package からインストールする。
#pkg_add ${PORTS}/editors/staroffice52/staroffice-*.tbz
# EOF $RCSfile: stage_2.sh,v $ vim: tabstop=4:

View file

@ -0,0 +1,147 @@
# stage_3.mk - FreeBSD From Scratch, 第 3 段階: ports をインストールした後の設定
# Usage: make -f stage_3.mk all (すべての設定を行なう)
# or make -f stage_3.mk target (target の設定を行なう)
#
# すべての target が、複数回実行しても悪影響をおよぼさないように
# 確認しておくとよい。
#
# $FreeBSD$
# Original revision: 1.1
.POSIX:
message:
@echo "Please use one of the following targets:"
@echo "config_apache"
@echo "config_inn"
@echo "config_javaplugin"
@echo "config_privoxy"
@echo "config_setiathome"
@echo "config_sgml"
@echo "config_sudo"
@echo "config_TeX"
@echo "config_tin"
@echo "config_uucp"
@echo "all -- all of the above"
all: config_apache \
config_inn \
config_javaplugin \
config_privoxy \
config_setiathome \
config_sgml \
config_sudo \
config_TeX \
config_tin \
config_uucp
config_apache:
# 1. httpd.conf の変更
perl -pi \
-e 's/#ServerName new.host.name/ServerName hal9000.s.shuttle.de/;' \
-e 's/^ServerAdmin.*/ServerAdmin schweikh\@schweikhardt.net/;' \
-e 's,/usr/local/www/cgi-bin/,/home/opt/www/cgi-bin/,;' \
/usr/local/etc/apache2/httpd.conf
# 2. ウェブページに対するシンボリックリンクの作成
cd /usr/local/www/data; \
ln -fs /home/schweikh/prj/homepage schweikhardt.net; \
ln -fs /home/opt/www/test .
config_inn:
pw usermod -n news -d /usr/local/news -s /bin/sh
# ニュースシステムの初期設定
cd /home/root/setup; \
install -C -o news -g news -m 664 active newsgroups /usr/local/news/db
# port の innd.sh は壊れていて、
#存在しない history.pag をチェックしようとする。
cd /home/root/setup; \
install -C -o root -g wheel -m 555 innd.sh /usr/local/etc/rc.d
# 格納方法の設定
cd /home/root/setup; \
printf "%s\n%s\n%s\n%s\n" \
"method tradspool {" \
" newsgroups: *" \
" class: 0" \
"}" \
>storage.conf; \
install -C -o news -g news -m 664 storage.conf /usr/local/news/etc
# newsfeeds の設定
printf "%s\n%s\n" \
"ME:*::" \
"shuttle/news2.shuttle.de:!junk,!control:B32768/512,Tf,Wfb:" \
>/usr/local/news/etc/newsfeeds
# inn.conf の設定
perl -pi \
-e 's/^(organization:\s*).*/$$1 An Open Pod Bay Door/;' \
-e 's/^(pathhost:\s*).*/$$1 hal9000.schweikhardt.net/;' \
-e 's/^(server:).*/$$1 localhost/;' \
-e 's/^(domain:).*/$$1 schweikhardt.net/;' \
-e 's/^(fromhost:).*/$$1 schweikhardt.net/;' \
-e 's,^(moderatormailer:).*,$$1 \%s\@moderators.isc.org,;' \
-e 's,/usr/local/news/spool,/share/news/spool,;' \
/usr/local/news/etc/inn.conf
config_javaplugin:
cd /usr/local/lib/netscape-linux/plugins; \
if ! test -h javaplugin.so; then \
ln -s ../../../linux-sun-jdk1.3.1/jre/plugin/i386/ns4/javaplugin.so; \
fi; \
ls -l javaplugin.so
config_privoxy:
install -C -o root -g wheel -m 644 config /usr/local/etc/privoxy
config_setiathome:
perl -pi \
-e 's,^.*seti_wrkdir.*#,seti_wrkdir=/home/nobody/setiathome #,;' \
/usr/local/etc/rc.setiathome.conf
config_sgml:
cp -p /usr/local/share/gmat/sgml/ISO_8879-1986/entities/* \
/usr/local/share/sgml/docbook/4.1
config_sudo:
if ! grep -q schweikh /usr/local/etc/sudoers; then \
echo 'schweikh ALL = (ALL) NOPASSWD: ALL' >> /usr/local/etc/sudoers; \
fi
config_TeX:
# textproc/docproj では、FreeBSD ハンドブックを JadeTeX で
# タイプセットするには、次の値を設定するよう指示されている
perl -pi \
-e 's/^% original texmf.cnf/% texmf.cnf/;' \
-e 's/^(hash_extra\s*=).*/$$1 60000/;' \
-e 's/^(pool_size\s*=).*/$$1 1000000/;' \
-e 's/^(max_strings\s*=).*/$$1 70000/;' \
-e 's/^(save_size\s*=).*/$$1 10000/;' \
/usr/local/share/texmf/web2c/texmf.cnf
config_tin:
# tin が設定したファイルを読むように設定
printf "%s\n%s\n%s\n" \
"activefile=/usr/local/news/db/active" \
"newsgroupsfile=/usr/local/news/db/newsgroups" \
"spooldir=/share/news/spool/articles" \
>/usr/local/etc/tin.defaults
config_uucp:
# UUCP が /usr/bin/rnews を見つけられるようにする
cd /usr/bin; ln -fs ../local/news/bin/rnews .
# 実際の UUCP の設定
echo nodename js2015 > /usr/local/etc/uucp/config
echo shuttle js2015 `cat uucp` > /usr/local/etc/uucp/call
printf 'port tcp\ntype tcp\n' > /usr/local/etc/uucp/port
printf "%s\n%s\n%s\n%s\n%s\n%s\n%s\n" \
"call-login *" \
"call-password *" \
"time any" \
"system shuttle" \
"address mail.s.shuttle.de" \
"commands rmail rnews" \
"port tcp" \
>/usr/local/etc/uucp/sys
cd /usr/local/etc/uucp; chown uucp:uucp *; chmod o-rwx *
# 起動後に uucico を実行する
mkdir -p /usr/local/etc/rc.d; cp uucp.sh /usr/local/etc/rc.d
# EOF $RCSfile: stage_3.mk,v $ vim: tabstop=4: