@@ -33,10 +33,8 @@ const (
3333 RestoreJobType = "logical-restore"
3434
3535 // const defines restore options.
36- restoreContainerName = "retrieval_logical_restore"
37- pgDataContainerDir = "/var/lib/postgresql/pgdata"
38- dumpContainerFile = "/tmp/db.dump"
39- defaultParallelJobs = 1
36+ restoreContainerPrefix = "dblab_lr_"
37+ defaultParallelJobs = 1
4038)
4139
4240// RestoreJob defines a logical restore job.
@@ -80,10 +78,6 @@ func NewJob(cfg config.JobConfig, docker *client.Client, globalCfg *dblabCfg.Glo
8078
8179 restoreJob .setDefaults ()
8280
83- if err := restoreJob .dbMarker .CreateConfig (); err != nil {
84- return nil , errors .Wrap (err , "failed to create a DBMarker config of the database" )
85- }
86-
8781 return restoreJob , nil
8882}
8983
@@ -94,32 +88,41 @@ func (r *RestoreJob) setDefaults() {
9488 }
9589}
9690
91+ func (r * RestoreJob ) restoreContainerName () string {
92+ return restoreContainerPrefix + r .globalCfg .InstanceID
93+ }
94+
9795// Name returns a name of the job.
9896func (r * RestoreJob ) Name () string {
9997 return r .name
10098}
10199
102100// Run starts the job.
103- func (r * RestoreJob ) Run (ctx context.Context ) error {
101+ func (r * RestoreJob ) Run (ctx context.Context ) ( err error ) {
104102 log .Msg (fmt .Sprintf ("Run job: %s. Options: %v" , r .Name (), r .RestoreOptions ))
105103
106104 isEmpty , err := tools .IsEmptyDirectory (r .globalCfg .DataDir )
107105 if err != nil {
108- return errors .Wrap (err , "failed to explore the data directory" )
106+ return errors .Wrapf (err , "failed to explore the data directory %q" , r . globalCfg . DataDir )
109107 }
110108
111109 if ! isEmpty {
112110 if ! r .ForceInit {
113- return errors .New ("the data directory is not empty. Use 'forceInit' or empty the data directory" )
111+ return errors .Errorf ("the data directory %q is not empty. Use 'forceInit' or empty the data directory" ,
112+ r .globalCfg .DataDir )
114113 }
115114
116- log .Msg ("The data directory is not empty. Existing data may be overwritten." )
115+ log .Msg (fmt .Sprintf ("The data directory %q is not empty. Existing data may be overwritten." , r .globalCfg .DataDir ))
116+ }
117+
118+ if err := tools .PullImage (ctx , r .dockerClient , r .RestoreOptions .DockerImage ); err != nil {
119+ return errors .Wrap (err , "failed to scan image pulling response" )
117120 }
118121
119122 cont , err := r .dockerClient .ContainerCreate (ctx ,
120123 & container.Config {
121124 Env : []string {
122- "PGDATA=" + pgDataContainerDir ,
125+ "PGDATA=" + r . globalCfg . DataDir ,
123126 },
124127 Image : r .RestoreOptions .DockerImage ,
125128 Healthcheck : health .GetConfig (),
@@ -129,29 +132,35 @@ func (r *RestoreJob) Run(ctx context.Context) error {
129132 {
130133 Type : mount .TypeBind ,
131134 Source : r .RestoreOptions .DumpFile ,
132- Target : dumpContainerFile ,
135+ Target : r . RestoreOptions . DumpFile ,
133136 },
134137 {
135138 Type : mount .TypeBind ,
136139 Source : r .globalCfg .DataDir ,
137- Target : pgDataContainerDir ,
140+ Target : r . globalCfg . DataDir ,
138141 },
139142 },
140143 },
141144 & network.NetworkingConfig {},
142- restoreContainerName ,
145+ r . restoreContainerName () ,
143146 )
144147 if err != nil {
145- return errors .Wrap (err , "failed to create container" )
148+ return errors .Wrapf (err , "failed to create container %q" , r . restoreContainerName () )
146149 }
147150
148151 defer tools .RemoveContainer (ctx , r .dockerClient , cont .ID , tools .StopTimeout )
149152
153+ defer func () {
154+ if err != nil {
155+ tools .PrintContainerLogs (ctx , r .dockerClient , r .restoreContainerName ())
156+ }
157+ }()
158+
150159 if err := r .dockerClient .ContainerStart (ctx , cont .ID , types.ContainerStartOptions {}); err != nil {
151- return errors .Wrap (err , "failed to start a container" )
160+ return errors .Wrapf (err , "failed to start container %q" , r . restoreContainerName () )
152161 }
153162
154- log .Msg (fmt .Sprintf ("Running container: %s. ID: %v" , restoreContainerName , cont .ID ))
163+ log .Msg (fmt .Sprintf ("Running container: %s. ID: %v" , r . restoreContainerName () , cont .ID ))
155164
156165 if err := r .markDatabase (ctx , cont .ID ); err != nil {
157166 return errors .Wrap (err , "failed to mark the database" )
@@ -172,19 +181,19 @@ func (r *RestoreJob) Run(ctx context.Context) error {
172181 })
173182
174183 if err != nil {
175- return errors .Wrap (err , "failed to create an exec command" )
184+ return errors .Wrap (err , "failed to create restore command" )
176185 }
177186
178187 if len (r .Partial .Tables ) > 0 {
179188 log .Msg ("Partial restore will be run. Tables for restoring: " , strings .Join (r .Partial .Tables , ", " ))
180189 }
181190
182191 if err := r .dockerClient .ContainerExecStart (ctx , execCommand .ID , types.ExecStartCheck {Tty : true }); err != nil {
183- return errors .Wrap (err , "failed to run the exec command" )
192+ return errors .Wrap (err , "failed to run restore command" )
184193 }
185194
186195 if err := tools .InspectCommandResponse (ctx , r .dockerClient , cont .ID , execCommand .ID ); err != nil {
187- return errors .Wrap (err , "failed to exec the restore command" )
196+ return errors .Wrap (err , "failed to exec restore command" )
188197 }
189198
190199 if err := recalculateStats (ctx , r .dockerClient , cont .ID , buildAnalyzeCommand (Connection {
@@ -209,6 +218,10 @@ func (r *RestoreJob) markDatabase(ctx context.Context, contID string) error {
209218 r .dbMark .DataStateAt = dataStateAt
210219 }
211220
221+ if err := r .dbMarker .CreateConfig (); err != nil {
222+ return errors .Wrap (err , "failed to create a DBMarker config of the database" )
223+ }
224+
212225 if err := r .dbMarker .SaveConfig (r .dbMark ); err != nil {
213226 return errors .Wrap (err , "failed to mark the database" )
214227 }
@@ -217,20 +230,22 @@ func (r *RestoreJob) markDatabase(ctx context.Context, contID string) error {
217230}
218231
219232func (r * RestoreJob ) retrieveDataStateAt (ctx context.Context , contID string ) (string , error ) {
220- restoreMetaCmd := []string {"sh" , "-c" , "pg_restore -l " + dumpContainerFile + " | head -n 10" }
233+ restoreMetaCmd := []string {"sh" , "-c" , "pg_restore -l " + r .RestoreOptions .DumpFile + " | head -n 10" }
234+
235+ log .Dbg ("Running a restore metadata command: " , restoreMetaCmd )
221236
222237 execCommand , err := r .dockerClient .ContainerExecCreate (ctx , contID , types.ExecConfig {
223238 AttachStdout : true ,
224239 AttachStderr : true ,
225240 Cmd : restoreMetaCmd ,
226241 })
227242 if err != nil {
228- return "" , errors .Wrap (err , "failed to create a restore meta command" )
243+ return "" , errors .Wrap (err , "failed to create a restore metadata command" )
229244 }
230245
231246 execAttach , err := r .dockerClient .ContainerExecAttach (ctx , execCommand .ID , types.ExecStartCheck {})
232247 if err != nil {
233- return "" , errors .Wrap (err , "failed to exec a restore meta command" )
248+ return "" , errors .Wrap (err , "failed to exec a restore metadata command" )
234249 }
235250
236251 defer execAttach .Close ()
@@ -258,7 +273,7 @@ func (r *RestoreJob) buildLogicalRestoreCommand() []string {
258273 restoreCmd = append (restoreCmd , "-t" , table )
259274 }
260275
261- restoreCmd = append (restoreCmd , dumpContainerFile )
276+ restoreCmd = append (restoreCmd , r . RestoreOptions . DumpFile )
262277
263278 return restoreCmd
264279}
0 commit comments