正しいユーザーとグループの所有権を持たないファイルを含むtarballがあります。ファイルは所有されjenkins:jenkins
、私はそのファイルを所有したいと思いますnaftuli:othergroup
。
埋め込まれたファイルが私が所有するようにタールボールを編集する方法はありますかnaftuli:othergroup
?
私が直面している問題は、tarballの作成中にユーザーに他のユーザーとグループに対する権限がjenkins
ないことです。chown
抽出時にユーザーが言及したファイルを生成する権限が付与されるため、タールボールでユーザーIDとグループIDを編集する必要があります。
答え1
アーカイブ::タールあるいは、同様のソフトウェアがこれを行う1つの方法になります。
% touch foo
% tar cvf x foo
foo
% tar tvf x
-rw-rw-r-- 1 jdoe12 jdoe12 0 May 6 20:36 foo
% perl -MArchive::Tar -e '$t=Archive::Tar->new;$t->read("x");$t->chown("foo","root");$t->write("y")'
% tar tvf y
-rw-rw-r-- 1 root jdoe12 0 May 6 20:36 foo
%
答え2
抽出に対する権限を明示的に変更することはできませんが、tarballを作成するときに優先IDをtarballに入れることができます(tarballとして実行しなくてもroot
)。
tar cvf /tmp/tarball.tar --owner=naftuli --group othergroup files...
アカウントの詳細がソースシステムに認識されていない場合は、--owner=naftuli:3000
名前の後に必要なuidやgid(たとえば)を追加できます。
または、すでにタールボールがある場合は、Jenkinsが作成したファイルを自分(naftuli:othergroup
)で抽出することができますroot
。
答え3
Archive::Tar
アーカイブをメモリに読み込む回答を使用します。 Pythontarfile
モジュールを使用すると、このような状況を回避できます。残念ながら、私はstdin
ストリーミングでそれを見つけようとしませんでしたextractfile
。
#!/usr/bin/env python3
import tarfile
import sys
with tarfile.open(name=sys.argv[1], mode="r") as in_tar, \
tarfile.open(fileobj=sys.stdout.buffer, mode="w|") as out_tar:
for member in in_tar.getmembers():
member.uname = member.gname = "root"
if member.isfile():
with in_tar.extractfile(member) as file:
out_tar.addfile(member, file)
else:
out_tar.addfile(member)
修正する:次のGoプログラムはストリームで実行できます。
package main
import (
"archive/tar"
"io"
"log"
"os"
)
func main() {
tr := tar.NewReader(os.Stdin)
tw := tar.NewWriter(os.Stdout)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
}
hdr.Uname, hdr.Gname = "root", "root"
if err := tw.WriteHeader(hdr); err != nil {
log.Fatal(err)
}
if hdr.Typeflag == tar.TypeReg {
if _, err := io.Copy(tw, tr); err != nil {
log.Fatal(err)
}
}
}
if err := tw.Close(); err != nil {
log.Fatal(err)
}
}
答え4
macOSを使用している場合、tarバージョンにはこれを実行できる「mtree」拡張子があります。結果のtarファイルはLinuxから抽出できます(つまり、移植可能)。
macOS tar マンページのサンプルセクション:
$ cat input.mtree
#mtree
usr/bin uid=0 gid=0 mode=0755 type=dir
usr/bin/ls uid=0 gid=0 mode=0755 type=file content=myls
$ tar -cvf output.tar @input.mtree
#mtree
入力ファイルの上部の説明は必須です。数値の代わりにシンボル名を設定するオプション(/代わり)uname
もあります。すべてのキーワードのリストについては参考資料をご覧ください。gname
uid
gid
man mtree 5