@@ -22,6 +22,7 @@ import (
2222 "archive/tar"
2323 "bytes"
2424 "context"
25+ "fmt"
2526 "io"
2627 "io/ioutil"
2728 "os"
@@ -32,6 +33,7 @@ import (
3233
3334 _ "crypto/sha256"
3435
36+ "github.com/containerd/containerd/testutil"
3537 "github.com/containerd/continuity/fs"
3638 "github.com/containerd/continuity/fs/fstest"
3739 "github.com/pkg/errors"
@@ -182,6 +184,50 @@ func TestSymlinks(t *testing.T) {
182184 }
183185}
184186
187+ func TestTarWithXattr (t * testing.T ) {
188+ testutil .RequiresRoot (t )
189+
190+ fileXattrExist := func (f1 , xattrKey , xattrValue string ) func (string ) error {
191+ return func (root string ) error {
192+ values , err := getxattr (filepath .Join (root , f1 ), xattrKey )
193+ if err != nil {
194+ return err
195+ }
196+ if xattrValue != string (values ) {
197+ return fmt .Errorf ("file xattrs expect to be %s, actually get %s" , xattrValue , values )
198+ }
199+ return nil
200+ }
201+ }
202+
203+ tests := []struct {
204+ name string
205+ key string
206+ value string
207+ err error
208+ }{
209+ {
210+ name : "WithXattrsUser" ,
211+ key : "user.key" ,
212+ value : "value" ,
213+ },
214+ {
215+ // security related xattrs need root permission to test
216+ name : "WithXattrSelinux" ,
217+ key : "security.selinux" ,
218+ value : "unconfined_u:object_r:default_t:s0\x00 " ,
219+ },
220+ }
221+ for _ , at := range tests {
222+ tc := TarContext {}.WithUIDGID (os .Getuid (), os .Getgid ()).WithModTime (time .Now ().UTC ()).WithXattrs (map [string ]string {
223+ at .key : at .value ,
224+ })
225+ w := TarAll (tc .File ("/file" , []byte {}, 0755 ))
226+ validator := fileXattrExist ("file" , at .key , at .value )
227+ t .Run (at .name , makeWriterToTarTest (w , nil , validator , at .err ))
228+ }
229+ }
230+
185231func TestBreakouts (t * testing.T ) {
186232 tc := TarContext {}.WithUIDGID (os .Getuid (), os .Getgid ()).WithModTime (time .Now ().UTC ())
187233 expected := "unbroken"
0 commit comments