Merge pull request #11330 from ndeloof/watch_tar

watch: remove requirements for tar binary and for sync target to be rw
This commit is contained in:
Guillaume Lours 2024-01-09 16:58:38 +01:00 committed by GitHub
commit 8d81b87513
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 19 deletions

View File

@ -47,6 +47,7 @@ type LowLevelClient interface {
ContainersForService(ctx context.Context, projectName string, serviceName string) ([]moby.Container, error) ContainersForService(ctx context.Context, projectName string, serviceName string) ([]moby.Container, error)
Exec(ctx context.Context, containerID string, cmd []string, in io.Reader) error Exec(ctx context.Context, containerID string, cmd []string, in io.Reader) error
Untar(ctx context.Context, id string, reader io.ReadCloser) error
} }
type Tar struct { type Tar struct {
@ -84,39 +85,24 @@ func (t *Tar) Sync(ctx context.Context, service types.ServiceConfig, paths []Pat
if len(pathsToDelete) != 0 { if len(pathsToDelete) != 0 {
deleteCmd = append([]string{"rm", "-rf"}, pathsToDelete...) deleteCmd = append([]string{"rm", "-rf"}, pathsToDelete...)
} }
copyCmd := []string{"tar", "-v", "-C", "/", "-x", "-f", "-"}
var eg multierror.Group var eg multierror.Group
writers := make([]*io.PipeWriter, len(containers))
for i := range containers { for i := range containers {
containerID := containers[i].ID containerID := containers[i].ID
r, w := io.Pipe() tarReader := tarArchive(pathsToCopy)
writers[i] = w
eg.Go(func() error { eg.Go(func() error {
if len(deleteCmd) != 0 { if len(deleteCmd) != 0 {
if err := t.client.Exec(ctx, containerID, deleteCmd, nil); err != nil { if err := t.client.Exec(ctx, containerID, deleteCmd, nil); err != nil {
return fmt.Errorf("deleting paths in %s: %w", containerID, err) return fmt.Errorf("deleting paths in %s: %w", containerID, err)
} }
} }
if err := t.client.Exec(ctx, containerID, copyCmd, r); err != nil {
if err := t.client.Untar(ctx, containerID, tarReader); err != nil {
return fmt.Errorf("copying files to %s: %w", containerID, err) return fmt.Errorf("copying files to %s: %w", containerID, err)
} }
return nil return nil
}) })
} }
multiWriter := newLossyMultiWriter(writers...)
tarReader := tarArchive(pathsToCopy)
defer func() {
_ = tarReader.Close()
multiWriter.Close()
}()
_, err = io.Copy(multiWriter, tarReader)
if err != nil {
return err
}
multiWriter.Close()
return eg.Wait().ErrorOrNil() return eg.Wait().ErrorOrNil()
} }

View File

@ -419,6 +419,12 @@ func (t tarDockerClient) Exec(ctx context.Context, containerID string, cmd []str
return nil return nil
} }
func (t tarDockerClient) Untar(ctx context.Context, id string, archive io.ReadCloser) error {
return t.s.apiClient().CopyToContainer(ctx, id, "/", archive, moby.CopyToContainerOptions{
CopyUIDGID: true,
})
}
func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Project, serviceName string, build api.BuildOptions, batch []fileEvent, syncer sync.Syncer) error { func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Project, serviceName string, build api.BuildOptions, batch []fileEvent, syncer sync.Syncer) error {
pathMappings := make([]sync.PathMapping, len(batch)) pathMappings := make([]sync.PathMapping, len(batch))
restartService := false restartService := false