Add tarstream
This commit is contained in:
parent
6295c3f1a4
commit
c3378d4327
4 changed files with 174 additions and 1 deletions
15
distbuild/pkg/dist/state.go
vendored
Normal file
15
distbuild/pkg/dist/state.go
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package dist
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
||||||
|
"gitlab.com/slon/shad-go/distbuild/pkg/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cluster struct {
|
||||||
|
sourceFiles map[build.ID]map[proto.WorkerID]struct{}
|
||||||
|
artifacts map[build.ID]map[proto.WorkerID]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) FindOptimalWorkers(task build.ID, sources, deps []build.ID) []proto.WorkerID {
|
||||||
|
|
||||||
|
}
|
|
@ -18,13 +18,15 @@ type JobResult struct {
|
||||||
Error *string
|
Error *string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WorkerID string
|
||||||
|
|
||||||
type HeartbeatRequest struct {
|
type HeartbeatRequest struct {
|
||||||
// WorkerID задаёт персистентный идентификатор данного воркера.
|
// WorkerID задаёт персистентный идентификатор данного воркера.
|
||||||
//
|
//
|
||||||
// WorkerID так же выступает в качестве endpoint-а, к которому можно подключиться по HTTP.
|
// WorkerID так же выступает в качестве endpoint-а, к которому можно подключиться по HTTP.
|
||||||
//
|
//
|
||||||
// В наших тестов, идентификатор будет иметь вид "localhost:%d".
|
// В наших тестов, идентификатор будет иметь вид "localhost:%d".
|
||||||
WorkerID string
|
WorkerID WorkerID
|
||||||
|
|
||||||
// ProcessID задаёт эфемерный идентификатор текущего процесса воркера.
|
// ProcessID задаёт эфемерный идентификатор текущего процесса воркера.
|
||||||
//
|
//
|
||||||
|
|
96
distbuild/pkg/tarstream/stream.go
Normal file
96
distbuild/pkg/tarstream/stream.go
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
package tarstream
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Send(dir string, w io.Writer) error {
|
||||||
|
tw := tar.NewWriter(w)
|
||||||
|
|
||||||
|
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rel, err := filepath.Rel(dir, path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if rel == "." {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.IsDir() {
|
||||||
|
return tw.WriteHeader(&tar.Header{
|
||||||
|
Name: rel,
|
||||||
|
Typeflag: tar.TypeDir,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
h := &tar.Header{
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Name: rel,
|
||||||
|
Size: info.Size(),
|
||||||
|
Mode: int64(info.Mode()),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tw.WriteHeader(h); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(tw, f)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tw.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Receive(dir string, r io.Reader) error {
|
||||||
|
tr := tar.NewReader(r)
|
||||||
|
|
||||||
|
for {
|
||||||
|
h, err := tr.Next()
|
||||||
|
if err == io.EOF {
|
||||||
|
return nil
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
absPath := filepath.Join(dir, h.Name)
|
||||||
|
|
||||||
|
if h.Typeflag == tar.TypeDir {
|
||||||
|
if err := os.Mkdir(absPath, 0777); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
writeFile := func() error {
|
||||||
|
f, err := os.OpenFile(absPath, os.O_CREATE|os.O_WRONLY, os.FileMode(h.Mode))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(f, tr)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := writeFile(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
distbuild/pkg/tarstream/stream_test.go
Normal file
60
distbuild/pkg/tarstream/stream_test.go
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package tarstream
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTarStream(t *testing.T) {
|
||||||
|
tmpDir, err := ioutil.TempDir("", "tarstream")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Logf("running inside %s", tmpDir)
|
||||||
|
|
||||||
|
from := filepath.Join(tmpDir, "from")
|
||||||
|
to := filepath.Join(tmpDir, "to")
|
||||||
|
|
||||||
|
require.NoError(t, os.Mkdir(from, 0777))
|
||||||
|
require.NoError(t, os.Mkdir(to, 0777))
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
require.NoError(t, os.Mkdir(filepath.Join(from, "a"), 0777))
|
||||||
|
require.NoError(t, os.MkdirAll(filepath.Join(from, "b", "c", "d"), 0777))
|
||||||
|
require.NoError(t, ioutil.WriteFile(filepath.Join(from, "a", "x.bin"), []byte("xxx"), 0777))
|
||||||
|
require.NoError(t, ioutil.WriteFile(filepath.Join(from, "b", "c", "y.txt"), []byte("yyy"), 0666))
|
||||||
|
|
||||||
|
require.NoError(t, Send(from, &buf))
|
||||||
|
|
||||||
|
require.NoError(t, Receive(to, &buf))
|
||||||
|
|
||||||
|
checkDir := func(path string) {
|
||||||
|
st, err := os.Stat(path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, st.IsDir())
|
||||||
|
}
|
||||||
|
|
||||||
|
checkDir(filepath.Join(to, "a"))
|
||||||
|
checkDir(filepath.Join(to, "b", "c", "d"))
|
||||||
|
|
||||||
|
checkFile := func(path string, content []byte, mode os.FileMode) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
st, err := os.Stat(path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, mode.String(), st.Mode().String())
|
||||||
|
|
||||||
|
b, err := ioutil.ReadFile(path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, content, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkFile(filepath.Join(from, "a", "x.bin"), []byte("xxx"), 0755)
|
||||||
|
checkFile(filepath.Join(from, "b", "c", "y.txt"), []byte("yyy"), 0644)
|
||||||
|
}
|
Loading…
Reference in a new issue