diff --git a/engine/configs/config.example.logical_generic.yml b/engine/configs/config.example.logical_generic.yml index 74295189e8fade019d4aadc2d215054b658bc4a2..d4d9006dd00f4a66231adc8452c94021cf7d2d98 100644 --- a/engine/configs/config.example.logical_generic.yml +++ b/engine/configs/config.example.logical_generic.yml @@ -193,6 +193,7 @@ retrieval: <<: *db_container # The dump file will be automatically created on this location and then used to restore. # Ensure that there is enough disk space. + # If you specify dumpLocation outside the mountDir, add this location as a volume to the DLE container. dumpLocation: "/var/lib/dblab/dblab_pool/dump" # Source of data. @@ -267,6 +268,7 @@ retrieval: options: <<: *db_container # The location of the archive files (or directories, for directory-format archives) to be restored. + # If you specify dumpLocation outside the mountDir, add this location as a volume to the DLE container. dumpLocation: "/var/lib/dblab/dblab_pool/dump" # Use parallel jobs to restore faster. diff --git a/engine/configs/config.example.logical_rds_iam.yml b/engine/configs/config.example.logical_rds_iam.yml index f66310756a15df99bfda4cc60ac60aa3e98abeae..ba327e0b752e524fafd63d67ff006937012f2156 100644 --- a/engine/configs/config.example.logical_rds_iam.yml +++ b/engine/configs/config.example.logical_rds_iam.yml @@ -192,6 +192,7 @@ retrieval: <<: *db_container # The dump file will be automatically created on this location and then used to restore. # Ensure that there is enough disk space. + # If you specify dumpLocation outside the mountDir, add this location as a volume to the DLE container. dumpLocation: "/var/lib/dblab/dblab_pool/dump" # Source of data. @@ -262,6 +263,7 @@ retrieval: options: <<: *db_container # The location of the archive file (or directory, for a directory-format archive) to be restored. + # If you specify dumpLocation outside the mountDir, add this location as a volume to the DLE container. dumpLocation: "/var/lib/dblab/dblab_pool/dump" # Use parallel jobs to restore faster. diff --git a/engine/internal/retrieval/engine/postgres/logical/dump.go b/engine/internal/retrieval/engine/postgres/logical/dump.go index 3d9d5e076abfbbf2d7d04970fbbbd5b9a62ca7c5..4250363deabb70f74b367057dbde11952367c62e 100644 --- a/engine/internal/retrieval/engine/postgres/logical/dump.go +++ b/engine/internal/retrieval/engine/postgres/logical/dump.go @@ -16,6 +16,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/mount" "github.com/docker/docker/client" "github.com/jackc/pgx/v4" "github.com/pkg/errors" @@ -632,6 +633,21 @@ func (d *DumpJob) buildHostConfig(ctx context.Context) (*container.HostConfig, e return nil, err } + if d.DumpOptions.DumpLocation != "" && !isAlreadyMounted(hostConfig.Mounts, d.DumpOptions.DumpLocation) { + hostConfig.Mounts = append(hostConfig.Mounts, + mount.Mount{ + Type: mount.TypeBind, + Source: d.DumpOptions.DumpLocation, + Target: d.DumpOptions.DumpLocation, + BindOptions: &mount.BindOptions{ + Propagation: mount.PropagationRShared, + }, + }, + ) + + log.Dbg("Mount dump location", d.DumpOptions.DumpLocation) + } + hostConfig.NetworkMode = d.getContainerNetworkMode() return hostConfig, nil diff --git a/engine/internal/retrieval/engine/postgres/logical/logical.go b/engine/internal/retrieval/engine/postgres/logical/logical.go index dc70709c5a0114e02392d7bd0ddd0e72b163f175..155a999c01a7c6565599055720e59e23078957f9 100644 --- a/engine/internal/retrieval/engine/postgres/logical/logical.go +++ b/engine/internal/retrieval/engine/postgres/logical/logical.go @@ -7,6 +7,8 @@ package logical import ( "strconv" + + "github.com/docker/docker/api/types/mount" ) func buildAnalyzeCommand(conn Connection, parallelJobs int) []string { @@ -20,3 +22,13 @@ func buildAnalyzeCommand(conn Connection, parallelJobs int) []string { return analyzeCmd } + +func isAlreadyMounted(mounts []mount.Mount, dir string) bool { + for _, mountPoint := range mounts { + if mountPoint.Source == dir { + return true + } + } + + return false +} diff --git a/engine/internal/retrieval/engine/postgres/logical/restore.go b/engine/internal/retrieval/engine/postgres/logical/restore.go index 6497c8db41e05339b73fe5a31b03ab362a1d1de7..fdc59092f907b55ea43b3ada14370d50eeb4749b 100644 --- a/engine/internal/retrieval/engine/postgres/logical/restore.go +++ b/engine/internal/retrieval/engine/postgres/logical/restore.go @@ -20,6 +20,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/mount" "github.com/docker/docker/client" "github.com/docker/docker/pkg/archive" "github.com/pkg/errors" @@ -126,7 +127,7 @@ func NewJob(cfg config.JobConfig, global *global.Config, engineProps *global.Eng } if err := restoreJob.Reload(cfg.Spec.Options); err != nil { - return nil, errors.Wrap(err, "failed to unmarshal configuration options") + return nil, errors.Wrap(err, "failed to load configuration options") } restoreJob.setDefaults() @@ -205,7 +206,7 @@ func (r *RestoreJob) Run(ctx context.Context) (err error) { return errors.Wrap(err, "failed to scan image pulling response") } - hostConfig, err := cont.BuildHostConfig(ctx, r.dockerClient, r.fsPool.DataDir(), r.RestoreOptions.ContainerConfig) + hostConfig, err := r.buildHostConfig(ctx) if err != nil { return errors.Wrap(err, "failed to build container host config") } @@ -293,6 +294,30 @@ func (r *RestoreJob) Run(ctx context.Context) (err error) { return nil } +func (r *RestoreJob) buildHostConfig(ctx context.Context) (*container.HostConfig, error) { + hostConfig, err := cont.BuildHostConfig(ctx, r.dockerClient, r.fsPool.DataDir(), r.RestoreOptions.ContainerConfig) + if err != nil { + return nil, fmt.Errorf("failed to build container host config: %w", err) + } + + if r.RestoreOptions.DumpLocation != "" && !isAlreadyMounted(hostConfig.Mounts, r.RestoreOptions.DumpLocation) { + hostConfig.Mounts = append(hostConfig.Mounts, + mount.Mount{ + Type: mount.TypeBind, + Source: r.RestoreOptions.DumpLocation, + Target: r.RestoreOptions.DumpLocation, + BindOptions: &mount.BindOptions{ + Propagation: mount.PropagationRShared, + }, + }, + ) + + log.Dbg("Mount dump location", r.RestoreOptions.DumpLocation) + } + + return hostConfig, nil +} + func (r *RestoreJob) getDBList(ctx context.Context, contID string) (map[string]DumpDefinition, error) { if len(r.Databases) > 0 { return r.Databases, nil diff --git a/engine/internal/retrieval/engine/postgres/tools/tools.go b/engine/internal/retrieval/engine/postgres/tools/tools.go index 932d787392d7c134ce7255a4b4cc9c8fa7eb0112..df1f357c655cd037f4c2f3a97dfad7cd08fcf634 100644 --- a/engine/internal/retrieval/engine/postgres/tools/tools.go +++ b/engine/internal/retrieval/engine/postgres/tools/tools.go @@ -147,8 +147,6 @@ func AddVolumesToHostConfig(ctx context.Context, docker *client.Client, hostConf } hostConfig.Mounts = GetMountsFromMountPoints(dataDir, inspection.Mounts) - - log.Dbg(hostConfig.Mounts) } else { hostConfig.Mounts = append(hostConfig.Mounts, mount.Mount{ Type: mount.TypeBind, @@ -157,6 +155,8 @@ func AddVolumesToHostConfig(ctx context.Context, docker *client.Client, hostConf }) } + log.Dbg(hostConfig.Mounts) + return nil }