mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-21 14:11:56 +00:00
cmd/nardump: support symlinks, add basic test
Signed-off-by: phanirithvij <phanirithvij2000@gmail.com>
This commit is contained in:
parent
0655dd7b3d
commit
ad2b075d4f
@ -100,14 +100,13 @@ func (nw *narWriter) writeDir(dirPath string) error {
|
|||||||
sub := path.Join(dirPath, ent.Name())
|
sub := path.Join(dirPath, ent.Name())
|
||||||
var err error
|
var err error
|
||||||
switch {
|
switch {
|
||||||
case mode.IsRegular():
|
|
||||||
err = nw.writeRegular(sub)
|
|
||||||
case mode.IsDir():
|
case mode.IsDir():
|
||||||
err = nw.writeDir(sub)
|
err = nw.writeDir(sub)
|
||||||
|
case mode.IsRegular():
|
||||||
|
err = nw.writeRegular(sub)
|
||||||
|
case mode&os.ModeSymlink != 0:
|
||||||
|
err = nw.writeSymlink(sub)
|
||||||
default:
|
default:
|
||||||
// TODO(bradfitz): symlink, but requires fighting io/fs a bit
|
|
||||||
// to get at Readlink or the osFS via fs. But for now
|
|
||||||
// we don't need symlinks because they're not in Go's archive.
|
|
||||||
return fmt.Errorf("unsupported file type %v at %q", sub, mode)
|
return fmt.Errorf("unsupported file type %v at %q", sub, mode)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -143,6 +142,23 @@ func (nw *narWriter) writeRegular(path string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (nw *narWriter) writeSymlink(path string) error {
|
||||||
|
nw.str("(")
|
||||||
|
nw.str("type")
|
||||||
|
nw.str("symlink")
|
||||||
|
nw.str("target")
|
||||||
|
// broken symlinks are valid in a nar
|
||||||
|
// given we do os.chdir(dir) and os.dirfs(".") above
|
||||||
|
// readlink now resolves relative links even if they are broken
|
||||||
|
link, err := os.Readlink(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nw.str(link)
|
||||||
|
nw.str(")")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (nw *narWriter) str(s string) {
|
func (nw *narWriter) str(s string) {
|
||||||
if err := writeString(nw.w, s); err != nil {
|
if err := writeString(nw.w, s); err != nil {
|
||||||
panic(writeNARError{err})
|
panic(writeNARError{err})
|
||||||
|
52
cmd/nardump/nardump_test.go
Normal file
52
cmd/nardump/nardump_test.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setupTmpdir sets up a known golden layout, covering all allowed file/folder types in a nar
|
||||||
|
func setupTmpdir(t *testing.T) string {
|
||||||
|
tmpdir := t.TempDir()
|
||||||
|
pwd, _ := os.Getwd()
|
||||||
|
os.Chdir(tmpdir)
|
||||||
|
defer os.Chdir(pwd)
|
||||||
|
os.MkdirAll("sub/dir", 0755)
|
||||||
|
os.Symlink("brokenfile", "brokenlink")
|
||||||
|
os.Symlink("sub/dir", "dirl")
|
||||||
|
os.Symlink("/abs/nonexistentdir", "dirb")
|
||||||
|
os.Create("sub/dir/file1")
|
||||||
|
f, _ := os.Create("file2m")
|
||||||
|
_ = f.Truncate(2 * 1024 * 1024)
|
||||||
|
f.Close()
|
||||||
|
os.Symlink("../file2m", "sub/goodlink")
|
||||||
|
return tmpdir
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteNar(t *testing.T) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
// Skip test on Windows as the Nix package manager is not supported on this platform
|
||||||
|
t.Skip("nix package manager is not available on Windows")
|
||||||
|
}
|
||||||
|
dir := setupTmpdir(t)
|
||||||
|
t.Run("nar", func(t *testing.T) {
|
||||||
|
// obtained via `nix-store --dump /tmp/... | sha256sum` of the above test dir
|
||||||
|
expected := "727613a36f41030e93a4abf2649c3ec64a2757ccff364e3f6f7d544eb976e442"
|
||||||
|
h := sha256.New()
|
||||||
|
os.Chdir(dir)
|
||||||
|
err := writeNAR(h, os.DirFS("."))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
hash := fmt.Sprintf("%x", h.Sum(nil))
|
||||||
|
if expected != hash {
|
||||||
|
t.Fatal("sha256sum of nar not matched", hash, expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user