X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=cmd%2Fsafcm-remote%2Fsync%2Ffiles_test.go;h=27011ac96c3e75bdd9f8fd3130e5bcceda887c20;hb=bacf1f2d844cd8b917ad0d38e0d3ba01d74dcae8;hp=22daa63fae92537239b21cb3fab375f7329ab313;hpb=f2f2bc47e8729548f3c10117f7f008b547c4afc5;p=safcm%2Fsafcm.git diff --git a/cmd/safcm-remote/sync/files_test.go b/cmd/safcm-remote/sync/files_test.go index 22daa63..27011ac 100644 --- a/cmd/safcm-remote/sync/files_test.go +++ b/cmd/safcm-remote/sync/files_test.go @@ -20,66 +20,15 @@ import ( "io/fs" "math/rand" "os" - "os/user" "path/filepath" - "reflect" "regexp" - "strconv" - "syscall" "testing" - "github.com/google/go-cmp/cmp" - "ruderich.org/simon/safcm" + ft "ruderich.org/simon/safcm/cmd/safcm-remote/sync/filetest" + "ruderich.org/simon/safcm/testutil" ) -type File struct { - Path string - Mode fs.FileMode - Data []byte -} - -func walkDir(basePath string) ([]File, error) { - var res []File - err := filepath.WalkDir(basePath, func(path string, d fs.DirEntry, err error) error { - if err != nil { - return err - } - info, err := d.Info() - if err != nil { - return err - } - rel, err := filepath.Rel(basePath, path) - if err != nil { - return err - } - - f := File{ - Path: rel, - Mode: info.Mode(), - } - if f.Mode.Type() == 0 { - x, err := os.ReadFile(path) - if err != nil { - return err - } - f.Data = x - } else if f.Mode.Type() == fs.ModeSymlink { - x, err := os.Readlink(path) - if err != nil { - return err - } - f.Data = []byte(x) - } - res = append(res, f) - return nil - }) - if err != nil { - return nil, err - } - return res, nil -} - var randFilesRegexp = regexp.MustCompile(`\d+"$`) func TestSyncFiles(t *testing.T) { @@ -98,23 +47,26 @@ func TestSyncFiles(t *testing.T) { t.Fatal(err) } - root := File{ + root := ft.File{ Path: ".", Mode: fs.ModeDir | 0700, } - user, uid, group, gid := currentUserAndGroup() + user, uid, group, gid := ft.CurrentUserAndGroup() + + skipUnlessCiRun := len(os.Getenv("SAFCM_CI_RUN")) == 0 tmpTestFilePath := "/tmp/safcm-sync-files-test-file" tests := []struct { - name string - req safcm.MsgSyncReq - prepare func() - triggers []string - expFiles []File - expResp safcm.MsgSyncResp - expDbg []string - expErr error + name string + skip bool + req safcm.MsgSyncReq + prepare func() + expTriggers []string + expFiles []ft.File + expResp safcm.MsgSyncResp + expDbg []string + expErr error }{ // NOTE: Also update MsgSyncResp in safcm test cases when @@ -125,6 +77,7 @@ func TestSyncFiles(t *testing.T) { { "basic: create", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -153,7 +106,7 @@ func TestSyncFiles(t *testing.T) { }, nil, nil, - []File{ + []ft.File{ root, { Path: "dir", @@ -208,6 +161,7 @@ func TestSyncFiles(t *testing.T) { { "basic: no change", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -235,11 +189,11 @@ func TestSyncFiles(t *testing.T) { }, }, func() { - createDirectory("dir", 0755) - createFile("dir/file", "content\n", 0644) + ft.CreateDirectory("dir", 0755) + ft.CreateFile("dir/file", "content\n", 0644) }, nil, - []File{ + []ft.File{ root, { Path: "dir", @@ -262,6 +216,7 @@ func TestSyncFiles(t *testing.T) { { "invalid File: user", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -276,7 +231,7 @@ func TestSyncFiles(t *testing.T) { }, nil, nil, - []File{ + []ft.File{ root, }, safcm.MsgSyncResp{}, @@ -285,6 +240,7 @@ func TestSyncFiles(t *testing.T) { }, { "invalid File: group", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -299,7 +255,7 @@ func TestSyncFiles(t *testing.T) { }, nil, nil, - []File{ + []ft.File{ root, }, safcm.MsgSyncResp{}, @@ -312,50 +268,39 @@ func TestSyncFiles(t *testing.T) { // don't want to modify the running system. Use this // test (and the one below for triggers) as a basic // check that absolute paths work. + // + // Use numeric IDs as not all systems use root/root; + // for example BSDs use root/wheel. "absolute paths: no change", + skipUnlessCiRun, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ "/": { Path: "/", Mode: fs.ModeDir | 0755, - User: "root", - Uid: -1, - Group: "root", - Gid: -1, + Uid: 0, + Gid: 0, OrigGroup: "group", }, "/etc": { Path: "/etc", Mode: fs.ModeDir | 0755, - User: "root", - Uid: -1, - Group: "root", - Gid: -1, + Uid: 0, + Gid: 0, OrigGroup: "group", }, "/tmp": { Path: "/tmp", Mode: fs.ModeDir | 0777 | fs.ModeSticky, - User: "root", - Uid: -1, - Group: "root", - Gid: -1, - OrigGroup: "group", - }, - "/var/tmp": { - Path: "/var/tmp", - Mode: fs.ModeDir | 0777 | fs.ModeSticky, - User: "root", - Uid: -1, - Group: "root", - Gid: -1, + Uid: 0, + Gid: 0, OrigGroup: "group", }, }, }, nil, nil, - []File{ + []ft.File{ root, }, safcm.MsgSyncResp{}, @@ -363,13 +308,13 @@ func TestSyncFiles(t *testing.T) { `4: sync remote: files: "/" (group): unchanged`, `4: sync remote: files: "/etc" (group): unchanged`, `4: sync remote: files: "/tmp" (group): unchanged`, - `4: sync remote: files: "/var/tmp" (group): unchanged`, }, nil, }, { "triggers: no change", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -406,11 +351,11 @@ func TestSyncFiles(t *testing.T) { }, }, func() { - createDirectory("dir", 0755) - createFile("dir/file", "content\n", 0644) + ft.CreateDirectory("dir", 0755) + ft.CreateFile("dir/file", "content\n", 0644) }, nil, - []File{ + []ft.File{ root, { Path: "dir", @@ -433,6 +378,7 @@ func TestSyncFiles(t *testing.T) { { "triggers: change root", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -469,17 +415,14 @@ func TestSyncFiles(t *testing.T) { }, }, func() { - err = os.Chmod(".", 0750) - if err != nil { - panic(err) - } - createDirectory("dir", 0755) - createFile("dir/file", "content\n", 0644) + ft.CreateDirectoryExists(".", 0750) + ft.CreateDirectory("dir", 0755) + ft.CreateFile("dir/file", "content\n", 0644) }, []string{ ".", }, - []File{ + []ft.File{ root, { Path: "dir", @@ -525,6 +468,7 @@ func TestSyncFiles(t *testing.T) { { "triggers: change middle", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -561,14 +505,14 @@ func TestSyncFiles(t *testing.T) { }, }, func() { - createDirectory("dir", 0750) - createFile("dir/file", "content\n", 0644) + ft.CreateDirectory("dir", 0750) + ft.CreateFile("dir/file", "content\n", 0644) }, []string{ ".", "dir", }, - []File{ + []ft.File{ root, { Path: "dir", @@ -615,6 +559,7 @@ func TestSyncFiles(t *testing.T) { { "triggers: change leaf", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -651,14 +596,14 @@ func TestSyncFiles(t *testing.T) { }, }, func() { - createDirectory("dir", 0755) + ft.CreateDirectory("dir", 0755) }, []string{ ".", "dir", "dir/file", }, - []File{ + []ft.File{ root, { Path: "dir", @@ -701,6 +646,7 @@ func TestSyncFiles(t *testing.T) { { "triggers: multiple changes", + false, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ ".": { @@ -742,7 +688,7 @@ func TestSyncFiles(t *testing.T) { "dir", "dir/file", }, - []File{ + []ft.File{ root, { Path: "dir", @@ -802,15 +748,14 @@ func TestSyncFiles(t *testing.T) { { "triggers: absolute paths", + skipUnlessCiRun, safcm.MsgSyncReq{ Files: map[string]*safcm.File{ "/": { Path: "/", Mode: fs.ModeDir | 0755, - User: "root", - Uid: -1, - Group: "root", - Gid: -1, + Uid: 0, + Gid: 0, OrigGroup: "group", TriggerCommands: []string{ "echo trigger /", @@ -819,10 +764,8 @@ func TestSyncFiles(t *testing.T) { "/tmp": { Path: "/tmp", Mode: fs.ModeDir | 0777 | fs.ModeSticky, - User: "root", - Uid: -1, - Group: "root", - Gid: -1, + Uid: 0, + Gid: 0, OrigGroup: "group", TriggerCommands: []string{ "echo trigger /tmp", @@ -840,23 +783,14 @@ func TestSyncFiles(t *testing.T) { }, }, }, - func() { - // This is slightly racy but the file name - // should be rare enough that this isn't an - // issue - _, err := os.Stat(tmpTestFilePath) - if err == nil { - t.Fatalf("%q exists, aborting", - tmpTestFilePath) - } - }, + nil, []string{ "/", "/tmp", // Don't use variable for more robust test "/tmp/safcm-sync-files-test-file", }, - []File{ + []ft.File{ root, }, safcm.MsgSyncResp{ @@ -890,60 +824,53 @@ func TestSyncFiles(t *testing.T) { } for _, tc := range tests { - // Create separate test directory for each test case - path := filepath.Join(cwd, "testdata", "files-"+tc.name) - err = os.Mkdir(path, 0700) - if err != nil { - t.Fatal(err) - } - err = os.Chdir(path) - if err != nil { - t.Fatal(err) - } + t.Run(tc.name, func(t *testing.T) { + if tc.skip { + t.SkipNow() + } - if tc.prepare != nil { - tc.prepare() - } + // Create separate test directory for each test case + path := filepath.Join(cwd, "testdata", "files-"+tc.name) + err := os.Mkdir(path, 0700) + if err != nil { + t.Fatal(err) + } + err = os.Chdir(path) + if err != nil { + t.Fatal(err) + } - s, res := prepareSync(tc.req, &testRunner{ - t: t, - name: tc.name, - }) - s.setDefaults() + if tc.prepare != nil { + tc.prepare() + } - err := s.syncFiles() - // Ugly but the simplest way to compare errors (including nil) - if fmt.Sprintf("%s", err) != fmt.Sprintf("%s", tc.expErr) { - t.Errorf("%s: err = %#v, want %#v", - tc.name, err, tc.expErr) - } - dbg := res.Wait() - // Remove random file names from result - for i, x := range dbg { - dbg[i] = randFilesRegexp.ReplaceAllString(x, `RND"`) - } - if !reflect.DeepEqual(tc.expDbg, dbg) { - t.Errorf("%s: dbg: %s", tc.name, - cmp.Diff(tc.expDbg, dbg)) - } + s, res := prepareSync(tc.req, &testRunner{ + t: t, + }) + err = s.setDefaults() + if err != nil { + t.Fatal(err) + } - files, err := walkDir(path) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(tc.expFiles, files) { - t.Errorf("%s: files: %s", tc.name, - cmp.Diff(tc.expFiles, files)) - } + err = s.syncFiles() + testutil.AssertErrorEqual(t, "err", err, tc.expErr) + dbg := res.Wait() + // Remove random file names from result + for i, x := range dbg { + dbg[i] = randFilesRegexp.ReplaceAllString(x, `RND"`) + } + testutil.AssertEqual(t, "dbg", dbg, tc.expDbg) - if !reflect.DeepEqual(tc.expResp, s.resp) { - t.Errorf("%s: resp: %s", tc.name, - cmp.Diff(tc.expResp, s.resp)) - } - if !reflect.DeepEqual(tc.triggers, s.triggers) { - t.Errorf("%s: triggers: %s", tc.name, - cmp.Diff(tc.triggers, s.triggers)) - } + files, err := ft.WalkDir(path) + if err != nil { + t.Fatal(err) + } + testutil.AssertEqual(t, "files", files, tc.expFiles) + + testutil.AssertEqual(t, "resp", s.resp, tc.expResp) + testutil.AssertEqual(t, "triggers", + s.triggers, tc.expTriggers) + }) } os.Remove(tmpTestFilePath) @@ -971,11 +898,11 @@ func TestSyncFile(t *testing.T) { t.Fatal(err) } - root := File{ + root := ft.File{ Path: ".", Mode: fs.ModeDir | 0700, } - user, uid, group, gid := currentUserAndGroup() + user, uid, group, gid := ft.CurrentUserAndGroup() tests := []struct { name string @@ -983,7 +910,7 @@ func TestSyncFile(t *testing.T) { file *safcm.File prepare func() expChanged bool - expFiles []File + expFiles []ft.File expResp safcm.MsgSyncResp expDbg []string expErr error @@ -1009,7 +936,7 @@ func TestSyncFile(t *testing.T) { }, nil, true, - []File{ + []ft.File{ root, { Path: "file", @@ -1055,7 +982,7 @@ func TestSyncFile(t *testing.T) { }, nil, true, - []File{root}, + []ft.File{root}, safcm.MsgSyncResp{ FileChanges: []safcm.FileChange{ { @@ -1091,10 +1018,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createFile("file", "content\n", 0644) + ft.CreateFile("file", "content\n", 0644) }, false, - []File{ + []ft.File{ root, { Path: "file", @@ -1123,10 +1050,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createFile("file", "content\n", 0644) + ft.CreateFile("file", "content\n", 0644) }, false, - []File{ + []ft.File{ root, { Path: "file", @@ -1153,10 +1080,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createFile("file", "content\n", 0755) + ft.CreateFile("file", "content\n", 0755) }, true, - []File{ + []ft.File{ root, { Path: "file", @@ -1206,10 +1133,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createFile("file", "old content\n", 0644) + ft.CreateFile("file", "old content\n", 0644) }, true, - []File{ + []ft.File{ root, { Path: "file", @@ -1267,7 +1194,7 @@ func TestSyncFile(t *testing.T) { }, nil, true, - []File{ + []ft.File{ root, { Path: "link", @@ -1310,10 +1237,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createFile(".link8717895732742165505", "", 0600) + ft.CreateFile(".link8717895732742165505", "", 0600) }, true, - []File{ + []ft.File{ root, { Path: ".link8717895732742165505", @@ -1365,7 +1292,7 @@ func TestSyncFile(t *testing.T) { }, nil, true, - []File{root}, + []ft.File{root}, safcm.MsgSyncResp{ FileChanges: []safcm.FileChange{ { @@ -1401,10 +1328,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createSymlink("link", "target") + ft.CreateSymlink("link", "target") }, false, - []File{ + []ft.File{ root, { Path: "link", @@ -1431,10 +1358,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createSymlink("link", "old-target") + ft.CreateSymlink("link", "old-target") }, true, - []File{ + []ft.File{ root, { Path: "link", @@ -1490,7 +1417,7 @@ func TestSyncFile(t *testing.T) { }, nil, true, - []File{ + []ft.File{ root, { Path: "dir", @@ -1535,7 +1462,7 @@ func TestSyncFile(t *testing.T) { }, nil, true, - []File{root}, + []ft.File{root}, safcm.MsgSyncResp{ FileChanges: []safcm.FileChange{ { @@ -1570,10 +1497,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createDirectory("dir", 0755) + ft.CreateDirectory("dir", 0755) }, false, - []File{ + []ft.File{ root, { Path: "dir", @@ -1598,10 +1525,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createDirectory("dir", 0500|fs.ModeSticky) + ft.CreateDirectory("dir", 0500|fs.ModeSticky) }, true, - []File{ + []ft.File{ root, { Path: "dir", @@ -1650,10 +1577,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createFile("path", "content\n", 0644) + ft.CreateFile("path", "content\n", 0644) }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -1708,10 +1635,10 @@ func TestSyncFile(t *testing.T) { Data: []byte("target"), }, func() { - createFile("path", "content\n", 0644) + ft.CreateFile("path", "content\n", 0644) }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -1766,10 +1693,10 @@ func TestSyncFile(t *testing.T) { Data: []byte("content\n"), }, func() { - createSymlink("path", "target") + ft.CreateSymlink("path", "target") }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -1823,10 +1750,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createSymlink("path", "target") + ft.CreateSymlink("path", "target") }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -1881,10 +1808,10 @@ func TestSyncFile(t *testing.T) { Data: []byte("content\n"), }, func() { - createDirectory("path", 0777) + ft.CreateDirectory("path", 0777) }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -1935,10 +1862,10 @@ func TestSyncFile(t *testing.T) { Data: []byte("target"), }, func() { - createDirectory("path", 0777) + ft.CreateDirectory("path", 0777) }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -1989,10 +1916,10 @@ func TestSyncFile(t *testing.T) { Data: []byte("content\n"), }, func() { - createFifo("path", 0666) + ft.CreateFifo("path", 0666) }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -2042,10 +1969,10 @@ func TestSyncFile(t *testing.T) { Data: []byte("target"), }, func() { - createFifo("path", 0666) + ft.CreateFifo("path", 0666) }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -2094,10 +2021,10 @@ func TestSyncFile(t *testing.T) { OrigGroup: "group", }, func() { - createFifo("path", 0666) + ft.CreateFifo("path", 0666) }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -2148,10 +2075,10 @@ func TestSyncFile(t *testing.T) { Data: []byte("target"), }, func() { - createFile("path", "target", 0644) + ft.CreateFile("path", "target", 0644) }, true, - []File{ + []ft.File{ root, { Path: "path", @@ -2211,14 +2138,14 @@ file OrigGroup: "group", }, func() { - createFile("file", `this + ft.CreateFile("file", `this is file ! `, 0644) }, true, - []File{ + []ft.File{ root, { Path: "file", @@ -2283,10 +2210,10 @@ file OrigGroup: "group", }, func() { - createFile("file", "\x00\x01\x02", 0644) + ft.CreateFile("file", "\x00\x01\x02", 0644) }, true, - []File{ + []ft.File{ root, { Path: "file", @@ -2312,7 +2239,7 @@ file Group: group, Gid: gid, }, - DataDiff: "Binary files differ, cannot show diff", + DataDiff: "Binary files differ (3 -> 4 bytes), cannot show diff", }, }, }, @@ -2338,10 +2265,10 @@ file OrigGroup: "group", }, func() { - createFile("file", "\x00\x01\x02", 0644) + ft.CreateFile("file", "\x00\x01\x02", 0644) }, true, - []File{ + []ft.File{ root, { Path: "file", @@ -2368,7 +2295,7 @@ file Gid: gid, }, DataDiff: `@@ -1,2 +1,2 @@ -- +- +content `, @@ -2397,10 +2324,10 @@ file OrigGroup: "group", }, func() { - createFile("file", "content\n", 0644) + ft.CreateFile("file", "content\n", 0644) }, true, - []File{ + []ft.File{ root, { Path: "file", @@ -2428,7 +2355,7 @@ file }, DataDiff: `@@ -1,2 +1,2 @@ -content -+ ++ `, }, @@ -2444,64 +2371,52 @@ file } for _, tc := range tests { - // Create separate test directory for each test case - path := filepath.Join(cwd, "testdata", "file-"+tc.name) - err = os.Mkdir(path, 0700) - if err != nil { - t.Fatal(err) - } - err = os.Chdir(path) - if err != nil { - t.Fatal(err) - } + t.Run(tc.name, func(t *testing.T) { + // Create separate test directory for each test case + path := filepath.Join(cwd, "testdata", "file-"+tc.name) + err := os.Mkdir(path, 0700) + if err != nil { + t.Fatal(err) + } + err = os.Chdir(path) + if err != nil { + t.Fatal(err) + } - if tc.prepare != nil { - tc.prepare() - } + if tc.prepare != nil { + tc.prepare() + } - s, res := prepareSync(tc.req, &testRunner{ - t: t, - name: tc.name, - }) - s.setDefaults() + s, res := prepareSync(tc.req, &testRunner{ + t: t, + }) + err = s.setDefaults() + if err != nil { + t.Fatal(err) + } - // Deterministic temporary symlink names - rand.Seed(0) + // Deterministic temporary symlink names + rand.Seed(0) - var changed bool - err := s.syncFile(tc.file, &changed) - // Ugly but the simplest way to compare errors (including nil) - if fmt.Sprintf("%s", err) != fmt.Sprintf("%s", tc.expErr) { - t.Errorf("%s: err = %#v, want %#v", - tc.name, err, tc.expErr) - } - dbg := res.Wait() - // Remove random file names from result - for i, x := range dbg { - dbg[i] = randFilesRegexp.ReplaceAllString(x, `RND"`) - } - if !reflect.DeepEqual(tc.expDbg, dbg) { - t.Errorf("%s: dbg: %s", tc.name, - cmp.Diff(tc.expDbg, dbg)) - } + var changed bool + err = s.syncFile(tc.file, &changed) + testutil.AssertErrorEqual(t, "err", err, tc.expErr) + dbg := res.Wait() + // Remove random file names from result + for i, x := range dbg { + dbg[i] = randFilesRegexp.ReplaceAllString(x, `RND"`) + } + testutil.AssertEqual(t, "dbg", dbg, tc.expDbg) - files, err := walkDir(path) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(tc.expFiles, files) { - t.Errorf("%s: files: %s", tc.name, - cmp.Diff(tc.expFiles, files)) - } + files, err := ft.WalkDir(path) + if err != nil { + t.Fatal(err) + } + testutil.AssertEqual(t, "files", files, tc.expFiles) - if tc.expChanged != changed { - t.Errorf("%s: changed = %#v, want %#v", - tc.name, changed, tc.expChanged) - } - if !reflect.DeepEqual(tc.expResp, s.resp) { - t.Errorf("%s: resp: %s", tc.name, - cmp.Diff(tc.expResp, s.resp)) - } + testutil.AssertEqual(t, "changed", changed, tc.expChanged) + testutil.AssertEqual(t, "resp", s.resp, tc.expResp) + }) } if !t.Failed() { @@ -2511,62 +2426,3 @@ file } } } - -// Helper functions - -func createFile(path string, data string, mode fs.FileMode) { - err := os.WriteFile(path, []byte(data), 0644) - if err != nil { - panic(err) - } - err = os.Chmod(path, mode) - if err != nil { - panic(err) - } -} -func createSymlink(path string, data string) { - err := os.Symlink(data, path) - if err != nil { - panic(err) - } -} -func createDirectory(path string, mode fs.FileMode) { - err := os.Mkdir(path, 0700) - if err != nil { - panic(err) - } - err = os.Chmod(path, mode) - if err != nil { - panic(err) - } -} -func createFifo(path string, mode fs.FileMode) { - err := syscall.Mkfifo(path, 0600) - if err != nil { - panic(err) - } - err = os.Chmod(path, mode) - if err != nil { - panic(err) - } -} - -func currentUserAndGroup() (string, int, string, int) { - u, err := user.Current() - if err != nil { - panic(err) - } - g, err := user.LookupGroupId(u.Gid) - if err != nil { - panic(err) - } - uid, err := strconv.Atoi(u.Uid) - if err != nil { - panic(err) - } - gid, err := strconv.Atoi(g.Gid) - if err != nil { - panic(err) - } - return u.Username, uid, g.Name, gid -}