Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 11627] ファイルの概要

このコミットは、Go言語プロジェクトのビルドシステムの一部である src/sudo.bash スクリプトの修正に関するものです。sudo.bash は、Goのツール(特にプロファイリングツールやカバレッジツール)を /usr/local/bin ディレクトリにインストールする際に、sudo コマンドを使用して特権操作を行うためのシェルスクリプトです。このコミットの目的は、このスクリプトが特定の環境下で正しく動作しない問題を解決し、ツールのインストールプロセスを安定させることにあります。

コミット

  • コミットハッシュ: cdfd5b2bede93497f4c74fa0959c3d6c8445fd57
  • 作者: David Symonds dsymonds@golang.org
  • コミット日時: 2012年2月5日(日)14:50:38 +1100

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/cdfd5b2bede93497f4c74fa0959c3d6c8445fd57

元コミット内容

build: fix sudo.bash.

R=rsc, balasanjay, rsc
CC=golang-dev
https://golang.org/cl/5630051

変更の背景

このコミットの背景には、sudo.bash スクリプトがGoのツールをシステムワイドなパス(/usr/local/bin)にインストールする際に、環境変数の解決やパスの指定方法に起因する問題が発生していたことが考えられます。特に sudo コマンドは、通常のユーザー環境とは異なる環境でコマンドを実行するため、環境変数の引き継ぎやカレントディレクトリの扱いが複雑になることがあります。

元のスクリプトでは、./env.bash をソースして環境変数を設定し、$GOROOT を利用してツールのパスを解決していました。しかし、sudo を介して実行される場合、GOROOT が正しく設定されていなかったり、sudo がその環境変数を適切に引き継がなかったりする可能性がありました。これにより、cp コマンドがツールのバイナリを見つけられず、インストールが失敗する問題が発生していたと推測されます。

この修正は、GOROOT 環境変数への依存を減らし、スクリプト自身の位置からの相対パスを使用することで、sudo 環境下でも安定してツールバイナリを見つけられるようにすることを目的としています。

前提知識の解説

1. Bashスクリプト

Bashスクリプトは、Unix系OSでコマンドを実行するためのスクリプト言語です。一連のコマンドを記述し、自動化されたタスクを実行するために使用されます。

2. sudo コマンド

sudo (superuser do) コマンドは、許可されたユーザーが、別のユーザー(通常はスーパーユーザーであるroot)としてコマンドを実行するためのプログラムです。システムファイルの変更やソフトウェアのインストールなど、特権が必要な操作を行う際に利用されます。sudo はセキュリティ上の理由から、実行環境(特に環境変数)を制限することがあり、これがスクリプトの動作に影響を与えることがあります。

3. Go言語のビルドシステムと GOROOT

Go言語のプロジェクトでは、GOROOT という環境変数がGoのインストールディレクトリを指します。Goのツールチェイン(コンパイラ、リンカ、標準ライブラリなど)は、この GOROOT ディレクトリ以下に配置されます。Goのビルドプロセスでは、これらのツールが正しく参照される必要があります。

4. dirname $0

シェルスクリプト内で $0 は、実行中のスクリプト自身のパスを表します。dirname $0 は、そのパスからディレクトリ部分のみを抽出するコマンドです。これにより、スクリプトがどのディレクトリから実行されたかに関わらず、スクリプト自身の存在するディレクトリのパスを取得できます。これは、スクリプトが自身の相対的な位置にある他のファイルやディレクトリを参照する際に非常に有用です。

5. cp コマンド

cp コマンドは、ファイルをコピーするために使用されます。

6. chgrpchmod コマンド

  • chgrp: ファイルやディレクトリのグループ所有者を変更するコマンドです。
  • chmod: ファイルやディレクトリのパーミッション(読み取り、書き込み、実行権限)を変更するコマンドです。
    • g+s (setgidビット): ファイルに setgid ビットを設定すると、そのファイルが実行される際に、実行ユーザーのプライマリグループではなく、ファイルのグループ所有者の権限で実行されるようになります。これは、特定のシステムリソースへのアクセスが必要なツール(例えば、プロファイリングツールがカーネル情報にアクセスする場合など)で利用されることがあります。

技術的詳細

このコミットの技術的な詳細な変更点は以下の通りです。

1. ./env.bash の削除

- . ./env.bash

元のスクリプトでは、./env.bash をソース(実行)して、Goのビルドに必要な環境変数を設定していました。しかし、sudo コマンドでスクリプトが実行される場合、env.bash で設定された環境変数が sudo 環境に適切に引き継がれない、あるいは sudo のセキュリティポリシーによって無視される可能性がありました。この行を削除することで、環境変数の設定をスクリプト自身のロジックに直接組み込むか、あるいは環境変数に依存しないパス解決方法に切り替える必要が生じました。

2. cd $(dirname $0) の追加

+ cd $(dirname $0)

この行は、スクリプトが実行される前に、スクリプト自身の存在するディレクトリにカレントディレクトリを変更します。これにより、スクリプト内で使用されるすべての相対パスが、スクリプトの物理的な位置を基準として解決されるようになります。これは、sudo コマンドがスクリプトを異なるカレントディレクトリで実行する可能性がある場合に、パス解決の安定性を確保するために非常に重要です。

3. パス解決方法の変更

- sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
+ sudo cp ../bin/tool/$i /usr/local/bin/go$i

これがこのコミットの最も重要な変更点です。

  • 変更前: "$GOROOT"/bin/tool/$i
    • GOROOT 環境変数に依存して、Goのツールバイナリのパスを解決していました。前述の通り、sudo 環境下では GOROOT が正しく設定されない、または引き継がれない問題がありました。
  • 変更後: ../bin/tool/$i
    • sudo.bash スクリプトは src/ ディレクトリに存在します。したがって、../ はGoリポジトリのルートディレクトリを指します。
    • ../bin/tool/$i は、Goリポジトリのルートディレクトリにある bin/tool ディレクトリ内のツールバイナリを指します。
    • この変更により、スクリプトは GOROOT 環境変数に依存することなく、自身の相対的な位置からツールバイナリを見つけることができるようになりました。これにより、sudo 環境下でのパス解決の信頼性が大幅に向上しました。

4. chgrpchmod g+s の維持

これらの行は変更されていませんが、Goのプロファイリングツール (prof) やカバレッジツール (cov) が、/usr/local/bin にインストールされた後も、特定のグループ (procmod) の権限で実行されるように setgid ビットが設定されていることを示しています。これは、これらのツールがシステムレベルのプロセス情報やカバレッジデータを収集するために、特別な権限を必要とするためと考えられます。

コアとなるコードの変更箇所

--- a/src/sudo.bash
+++ b/src/sudo.bash
@@ -4,7 +4,6 @@
 # license that can be found in the LICENSE file.
 
 set -e
-. ./env.bash
 
 case "`uname`" in
 Darwin)
@@ -18,12 +17,13 @@ if [[ ! -d /usr/local/bin ]]; then
 	exit 2
 fi
 
+cd $(dirname $0)
 for i in prof cov
 do
 	# Remove old binaries if present
 	sudo rm -f /usr/local/bin/6$i
 	# Install new binaries
-	sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
+	sudo cp ../bin/tool/$i /usr/local/bin/go$i
 	sudo chgrp procmod /usr/local/bin/go$i
 	sudo chmod g+s /usr/local/bin/go$i
 done

コアとなるコードの解説

上記のdiffは、src/sudo.bash スクリプトに対する具体的な変更を示しています。

  • - . ./env.bash: この行は削除されました。これにより、外部の env.bash スクリプトに依存して環境変数を設定するのではなく、スクリプト自身の内部でパスを解決するアプローチに切り替わりました。
  • + cd $(dirname $0): この行が追加されました。スクリプトの実行開始時に、カレントディレクトリをスクリプト自身が存在するディレクトリ(src/)に変更します。これにより、以降の相対パスの参照が安定します。
  • - sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i: 変更前の行です。GOROOT 環境変数を使用してツールのパスを構築していました。
  • + sudo cp ../bin/tool/$i /usr/local/bin/go$i: 変更後の行です。../bin/tool/$i という相対パスを使用することで、GOROOT に依存せず、スクリプト自身の位置からGoのツールバイナリ(profcov)を見つけて /usr/local/bin にコピーするように修正されました。6$i から go$i への命名規則の変更も行われており、これは古いバイナリの削除と新しいバイナリのインストールを適切に行うためのものです。
  • sudo chgrp procmod /usr/local/bin/go$i: コピーされたバイナリのグループを procmod に変更します。
  • sudo chmod g+s /usr/local/bin/go$i: コピーされたバイナリに setgid ビットを設定します。これにより、procmod グループの権限で実行されるようになります。

これらの変更により、sudo.bash スクリプトは、sudo 環境下でもGoのツールバイナリを確実に特定し、システムに正しくインストールできるようになりました。

関連リンク

  • Go言語のコードレビューシステム (Gerrit) の変更リスト:
    • https://golang.org/cl/5630051
    • このリンクは、GoプロジェクトのGerritコードレビューシステムにおけるこのコミットの詳細な変更履歴や議論を確認できます。

参考にした情報源リンク

  • Go言語公式ドキュメント:
    • Go言語のビルドシステムや環境変数に関する一般的な情報については、Goの公式ドキュメントが参考になります。
    • https://go.dev/doc/
  • Bashスクリプトの基本:
    • dirname, $0, set -e など、Bashスクリプトの基本的なコマンドや構文については、Bashの公式ドキュメントやチュートリアルが参考になります。
    • https://www.gnu.org/software/bash/manual/
  • sudo コマンドの環境変数に関する挙動:
    • sudo が環境変数をどのように扱うかについては、sudo のマニュアルページ (man sudo) や関連するセキュリティドキュメントが参考になります。
  • chmodsetgid ビット:

[インデックス 11627] ファイルの概要

このコミットは、Go言語プロジェクトのビルドシステムの一部である src/sudo.bash スクリプトの修正に関するものです。このスクリプトは、Goのプロファイリングツール (prof) やカバレッジツール (cov) などのバイナリを、システム全体で利用可能なパス(具体的には /usr/local/bin)にインストールするために使用されます。この修正の主な目的は、sudo コマンドを使用してこれらのツールをインストールする際の信頼性と安定性を向上させることにあります。特に、sudo 環境下でのパス解決の問題を解決し、GOROOT 環境変数への依存を減らすことで、より堅牢なインストールプロセスを実現しています。

コミット

  • コミットハッシュ: cdfd5b2bede93497f4c74fa0959c3d6c8445fd57
  • 作者: David Symonds dsymonds@golang.org
  • コミット日時: 2012年2月5日(日)14:50:38 +1100
  • コミットメッセージ:
    build: fix sudo.bash.
    
    R=rsc, balasanjay, rsc
    CC=golang-dev
    https://golang.org/cl/5630051
    

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/cdfd5b2bede93497f4c74fa0959c3d6c8445fd57

元コミット内容

build: fix sudo.bash.

R=rsc, balasanjay, rsc
CC=golang-dev
https://golang.org/cl/5630051

変更の背景

このコミットは、Go言語のビルドプロセスにおいて、sudo.bash スクリプトがGoのツールバイナリをシステムパスにインストールする際に発生していた問題を解決するために行われました。具体的には、sudo コマンドが実行される環境下で、スクリプトがGoのインストールディレクトリ(GOROOT)を正しく認識できない、あるいは GOROOT 環境変数が sudo 環境に適切に引き継がれないという問題がありました。

sudo コマンドは、セキュリティ上の理由から、実行されるコマンドの環境変数を制限したり、カレントディレクトリをユーザーのホームディレクトリに変更したりすることがあります。これにより、元の sudo.bash スクリプトが GOROOT に基づいてツールのパスを解決しようとした際に、正しいパスを見つけられずにインストールが失敗する可能性がありました。

この修正は、GOROOT 環境変数への直接的な依存を排除し、スクリプト自身の位置からの相対パスを使用することで、sudo 環境下でもツールのバイナリを確実に特定し、インストールプロセスをより堅牢にすることを目的としています。これにより、Goのビルドとツールインストールの一貫性と信頼性が向上します。

前提知識の解説

1. Bashスクリプト

Bashスクリプトは、Unix系オペレーティングシステムでコマンドラインインターフェース(CLI)を介して実行される一連のコマンドを自動化するためのスクリプト言語です。ファイル操作、プログラムの実行、システム設定の変更など、多岐にわたるタスクに使用されます。

2. sudo コマンド

sudo (superuser do) は、Unix系システムにおいて、許可されたユーザーが別のユーザー(通常はrootユーザー)の権限でコマンドを実行するためのプログラムです。システムファイルの変更、ソフトウェアのインストール、システムサービスの管理など、特権が必要な操作を行う際に不可欠です。sudo は、セキュリティを考慮して、実行環境(特に環境変数やカレントディレクトリ)を制限することがあり、これがスクリプトの動作に影響を与えることがあります。

3. Go言語のビルドシステムと GOROOT

Go言語のビルドシステムでは、GOROOT という環境変数がGoのインストールディレクトリのルートパスを指します。Goのコンパイラ、リンカ、標準ライブラリ、および各種ツール(go fmt, go test, go build など)は、この GOROOT ディレクトリ以下に配置されます。Goのプロジェクトをビルドしたり、Goのツールを使用したりする際には、システムが GOROOT を正しく認識している必要があります。

4. dirname $0

シェルスクリプト内で $0 は、現在実行中のスクリプト自身のパス(ファイル名を含む)を表します。dirname $0 は、このパスからディレクトリ部分のみを抽出するコマンドです。例えば、/home/user/scripts/myscript.sh$0 であれば、dirname $0/home/user/scripts を返します。これにより、スクリプトがどのディレクトリから実行されたかに関わらず、スクリプト自身の物理的な位置を基準とした相対パスを構築することが可能になります。これは、スクリプトが自身の隣にある他のファイルやディレクトリを参照する際に非常に有用です。

5. cp コマンド

cp コマンドは、ファイルやディレクトリをコピーするために使用される基本的なUnixコマンドです。

6. chgrpchmod コマンド

  • chgrp (change group): ファイルやディレクトリのグループ所有者を変更するコマンドです。
  • chmod (change mode): ファイルやディレクトリのパーミッション(読み取り、書き込み、実行権限)を変更するコマンドです。
    • g+s (setgidビット): chmod コマンドでファイルに setgid ビットを設定すると、そのファイルが実行される際に、実行ユーザーのプライマリグループではなく、ファイルのグループ所有者の権限で実行されるようになります。これは、特定のシステムリソースへのアクセスが必要なツール(例えば、プロファイリングツールがカーネル情報にアクセスする場合など)で利用されることがあります。このコミットでは、Goのプロファイリングツールやカバレッジツールが、システムレベルのデータにアクセスするために procmod グループの権限を必要とするため、この設定が適用されています。

技術的詳細

このコミットにおける src/sudo.bash スクリプトへの技術的な変更点は、主に以下の3つの側面から構成されています。

1. 環境変数設定の依存関係の排除

元のスクリプトでは、./env.bash をソース(source または . コマンド)して、Goのビルドに必要な環境変数を設定していました。

- . ./env.bash

この行が削除されたことにより、sudo.bash は外部の env.bash に依存して GOROOT などの環境変数を設定することをやめました。これは、sudo コマンドが実行される際に、外部スクリプトによって設定された環境変数が sudo 環境に適切に引き継がれない、あるいは sudo のセキュリティポリシーによって無視される可能性があるためです。この変更は、スクリプトの自己完結性を高め、sudo 環境下での動作の信頼性を向上させるための重要なステップです。

2. カレントディレクトリの変更によるパス解決の安定化

スクリプトの冒頭に以下の行が追加されました。

+ cd $(dirname $0)

このコマンドは、スクリプトが実行される直前に、カレントディレクトリをスクリプト自身が存在するディレクトリ(この場合はGoリポジトリの src/ ディレクトリ)に変更します。sudo コマンドは、デフォルトでコマンドを実行するユーザーのホームディレクトリをカレントディレクトリとして使用することがあります。これにより、スクリプト内で相対パスを使用した場合に、意図しない場所を参照してしまう可能性がありました。cd $(dirname $0) を追加することで、スクリプト内のすべての相対パスが、スクリプトの物理的な位置を基準として解決されるようになり、sudo 環境下でのパス解決の安定性が大幅に向上しました。

3. GOROOT への依存を排除したパス解決

最も重要な変更は、Goツールバイナリのコピー元パスの指定方法です。

- sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
+ sudo cp ../bin/tool/$i /usr/local/bin/go$i
  • 変更前: "$GOROOT"/bin/tool/$i
    • このパスは、GOROOT 環境変数の値に依存していました。前述の通り、sudo 環境下では GOROOT が正しく設定されていない、または引き継がれないという問題がありました。
  • 変更後: ../bin/tool/$i
    • sudo.bash スクリプトはGoリポジトリの src/ ディレクトリに存在します。したがって、../ はGoリポジトリのルートディレクトリを指します。
    • ../bin/tool/$i は、Goリポジトリのルートディレクトリにある bin/tool ディレクトリ内のツールバイナリ(profcov)を指します。
    • この変更により、スクリプトは GOROOT 環境変数に依存することなく、自身の相対的な位置からツールバイナリを直接見つけることができるようになりました。これにより、sudo 環境下でのパス解決の信頼性が飛躍的に向上し、ツールのインストールがより確実に行われるようになりました。

これらの変更は、sudo 環境の特性を考慮し、スクリプトの実行環境に依存しない堅牢なパス解決メカニズムを導入することで、Goツールのインストールプロセスを安定させることに貢献しています。

コアとなるコードの変更箇所

--- a/src/sudo.bash
+++ b/src/sudo.bash
@@ -4,7 +4,6 @@
 # license that can be found in the LICENSE file.
 
 set -e
-. ./env.bash
 
 case "`uname`" in
 Darwin)
@@ -18,12 +17,13 @@ if [[ ! -d /usr/local/bin ]]; then
 	exit 2
 fi
 
+cd $(dirname $0)
 for i in prof cov
 do
 	# Remove old binaries if present
 	sudo rm -f /usr/local/bin/6$i
 	# Install new binaries
-	sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i
+	sudo cp ../bin/tool/$i /usr/local/bin/go$i
 	sudo chgrp procmod /usr/local/bin/go$i
 	sudo chmod g+s /usr/local/bin/go$i
 done

コアとなるコードの解説

上記の diff は、src/sudo.bash スクリプトに対する具体的な変更内容を示しています。

  1. - . ./env.bash:

    • この行は削除されました。これは、以前は外部の env.bash スクリプトを読み込んで GOROOT などの環境変数を設定していましたが、sudo 環境下での環境変数の引き継ぎ問題に対応するため、この依存関係を排除したことを意味します。
  2. + cd $(dirname $0):

    • この行が新しく追加されました。スクリプトが実行されると、まずこのコマンドが実行され、カレントディレクトリがスクリプト自身が存在するディレクトリ(Goリポジトリの src/ ディレクトリ)に変更されます。これにより、以降のファイルパスの参照が、スクリプトの物理的な位置を基準とした相対パスとして安定して解決されるようになります。
  3. - sudo cp "$GOROOT"/bin/tool/$i /usr/local/bin/go$i:

    • 変更前の行です。Goのツールバイナリ(profcov)を /usr/local/bin にコピーする際に、GOROOT 環境変数を使用してソースパスを構築していました。この方法では、sudo 環境下で GOROOT が正しく設定されていない場合に問題が発生する可能性がありました。
  4. + sudo cp ../bin/tool/$i /usr/local/bin/go$i:

    • 変更後の行です。../bin/tool/$i という相対パスを使用することで、GOROOT 環境変数に依存することなく、Goリポジトリのルートディレクトリにある bin/tool ディレクトリから直接ツールバイナリを見つけてコピーするように修正されました。この変更により、sudo 環境下でのパス解決の信頼性が大幅に向上しました。また、コピー先のファイル名が 6$i から go$i に変更されていますが、これは古いバイナリの削除 (sudo rm -f /usr/local/bin/6$i) と新しいバイナリのインストールを適切に行うための命名規則の変更です。
  5. sudo chgrp procmod /usr/local/bin/go$i および sudo chmod g+s /usr/local/bin/go$i:

    • これらの行は変更されていません。コピーされたツールバイナリのグループを procmod に変更し、setgid ビットを設定することで、これらのツールが procmod グループの権限で実行されるようにしています。これは、プロファイリングやカバレッジのツールがシステムレベルのデータにアクセスするために必要な特権を付与するためです。

これらの変更は、sudo コマンドの特性とGoのビルドシステムの構造を深く理解した上で、ツールのインストールプロセスをより堅牢で信頼性の高いものにするためのものです。

関連リンク

  • Go言語のコードレビューシステム (Gerrit) の変更リスト:
    • https://golang.org/cl/5630051
    • このリンクは、GoプロジェクトのGerritコードレビューシステムにおけるこのコミットの詳細な変更履歴や議論を確認できます。Goコミュニティ内でのレビュープロセスや、この変更に至るまでの背景に関する追加情報が得られる可能性があります。

参考にした情報源リンク

  • Go言語公式ドキュメント:
    • Go言語のビルドシステム、環境変数(特に GOROOT)、およびGoツールの一般的な情報については、Goの公式ドキュメントが最も信頼できる情報源です。
    • https://go.dev/doc/
  • Bashスクリプトの基本:
    • dirname, $0, set -e など、Bashスクリプトの基本的なコマンドや構文、およびシェルスクリプトのベストプラクティスについては、Bashの公式マニュアルや信頼できるオンラインチュートリアルが参考になります。
    • https://www.gnu.org/software/bash/manual/
  • sudo コマンドの環境変数に関する挙動:
    • sudo が環境変数をどのように扱うか、特にセキュリティ上の理由から環境変数を制限する挙動については、sudo のマニュアルページ (man sudo) や、Linux/Unixのセキュリティに関するドキュメントが詳細な情報を提供します。
  • chmodsetgid ビット:
  • Go言語における sudo.bash スクリプトの一般的な目的:
    • Goプロジェクトにおける sudo.bash のようなスクリプトの一般的な目的については、Goコミュニティのフォーラム、Stack Overflow、または関連するブログ記事などが参考になります。これらは、Goアプリケーションのデプロイ、システムレベルのタスク実行、Go環境の管理など、sudo を使用するシナリオについて洞察を提供します。