66package logical
77
88import (
9+ "archive/tar"
910 "bufio"
1011 "bytes"
1112 "context"
1213 "fmt"
14+ "io"
1315 "io/fs"
1416 "os"
1517 "path"
@@ -22,7 +24,6 @@ import (
2224 "github.com/docker/docker/api/types/container"
2325 "github.com/docker/docker/api/types/mount"
2426 "github.com/docker/docker/client"
25- "github.com/docker/docker/pkg/archive"
2627 "github.com/pkg/errors"
2728
2829 "gitlab.com/postgres-ai/database-lab/v3/internal/provision/resources"
@@ -655,35 +656,58 @@ func (r *RestoreJob) prepareDB(ctx context.Context, contID, dbName string) error
655656}
656657
657658func (r * RestoreJob ) prepareArchive (ctx context.Context , contID string , tempFile * os.File , dstPath string ) error {
658- srcInfo , err := archive . CopyInfoSourcePath (tempFile . Name (), false )
659+ archiveReader , err := createTarArchive (tempFile , dstPath )
659660 if err != nil {
660661 return err
661662 }
662663
663- srcArchive , err := archive .TarResource (srcInfo )
664- if err != nil {
665- return err
664+ dstDir := filepath .Dir (dstPath )
665+ if err := r .dockerClient .CopyToContainer (ctx , contID , dstDir , archiveReader , container.CopyToContainerOptions {
666+ AllowOverwriteDirWithFile : true ,
667+ CopyUIDGID : true ,
668+ }); err != nil {
669+ log .Err (err )
670+
671+ return errors .Wrap (err , "failed to copy auxiliary file" )
666672 }
667673
668- defer func () { _ = srcArchive .Close () }()
674+ return nil
675+ }
676+
677+ // createTarArchive creates a tar archive from a file for the given destination path.
678+ func createTarArchive (tempFile * os.File , dstPath string ) (io.Reader , error ) {
679+ var buf bytes.Buffer
680+ tarWriter := tar .NewWriter (& buf )
669681
670- dstDir , preparedArchive , err := archive . PrepareArchiveCopy ( srcArchive , srcInfo , archive. CopyInfo { Path : dstPath } )
682+ fileInfo , err := tempFile . Stat ( )
671683 if err != nil {
672- return err
684+ return nil , errors . Wrap ( err , "failed to stat file" )
673685 }
674686
675- defer func () { _ = preparedArchive .Close () }()
687+ header := & tar.Header {
688+ Name : filepath .Base (dstPath ),
689+ Mode : int64 (fileInfo .Mode ()),
690+ Size : fileInfo .Size (),
691+ ModTime : fileInfo .ModTime (),
692+ }
676693
677- if err := r .dockerClient .CopyToContainer (ctx , contID , dstDir , preparedArchive , container.CopyToContainerOptions {
678- AllowOverwriteDirWithFile : true ,
679- CopyUIDGID : true ,
680- }); err != nil {
681- log .Err (err )
694+ if err := tarWriter .WriteHeader (header ); err != nil {
695+ return nil , errors .Wrap (err , "failed to write tar header" )
696+ }
682697
683- return errors .Wrap (err , "failed to copy auxiliary file" )
698+ if _ , err := tempFile .Seek (0 , 0 ); err != nil {
699+ return nil , errors .Wrap (err , "failed to seek file" )
684700 }
685701
686- return nil
702+ if _ , err := io .Copy (tarWriter , tempFile ); err != nil {
703+ return nil , errors .Wrap (err , "failed to copy file to tar" )
704+ }
705+
706+ if err := tarWriter .Close (); err != nil {
707+ return nil , errors .Wrap (err , "failed to close tar writer" )
708+ }
709+
710+ return & buf , nil
687711}
688712
689713// formatDBName extracts a database name from a file name and adjusts it.
0 commit comments