tarballでファイルのユーザーIDとグループIDの所有権を変更しますか?

tarballでファイルのユーザーIDとグループIDの所有権を変更しますか?

正しいユーザーとグループの所有権を持たないファイルを含む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もあります。すべてのキーワードのリストについては参考資料をご覧ください。gnameuidgidman mtree 5

関連情報