mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-12-01 22:31:15 +00:00
Fix bug where db file is posible moved outside of docker volume (#496)
#494 introduced a bug, where a migration function can remove the sqlite3 file outside of the mounted docker volume. that would result in a data lose after a container recreate. this fix it by only rename the file if in same folder else just use the old path as fallback and put warnings into the log Co-authored-by: Anbraten <anton@ju60.de>
This commit is contained in:
parent
06800cb61e
commit
f02789c74a
1 changed files with 73 additions and 23 deletions
|
@ -17,6 +17,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -46,41 +47,90 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupStore(c *cli.Context) (store.Store, error) {
|
func setupStore(c *cli.Context) (store.Store, error) {
|
||||||
if err := migrateSqlFile(c); err != nil {
|
datasource := c.String("datasource")
|
||||||
log.Fatal().Err(err).Msg("could not migrate legacy sqlite file")
|
driver := c.String("driver")
|
||||||
|
|
||||||
|
if strings.ToLower(driver) == "sqlite3" {
|
||||||
|
if new, err := fallbackSqlite3File(datasource); err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("fallback to old sqlite3 file failed")
|
||||||
|
} else {
|
||||||
|
datasource = new
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := &datastore.Opts{
|
opts := &datastore.Opts{
|
||||||
Driver: c.String("driver"),
|
Driver: driver,
|
||||||
Config: c.String("datasource"),
|
Config: datasource,
|
||||||
}
|
}
|
||||||
log.Trace().Msgf("setup datastore: %#v", opts)
|
log.Trace().Msgf("setup datastore: %#v", opts)
|
||||||
return datastore.New(opts)
|
return datastore.New(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Remove this once we are sure users aren't attempting to migrate from Drone to Woodpecker (possibly never)
|
// TODO: convert it to a check and fail hard only function in v0.16.0 to be able to remove it in v0.17.0
|
||||||
func migrateSqlFile(c *cli.Context) error {
|
// TODO: add it to the "how to migrate from drone docs"
|
||||||
// default config for docker containers
|
func fallbackSqlite3File(path string) (string, error) {
|
||||||
if c.String("datasource") == "/var/lib/woodpecker/woodpecker.sqlite" {
|
const dockerDefaultPath = "/var/lib/woodpecker/woodpecker.sqlite"
|
||||||
_, err := os.Stat("/var/lib/drone/drone.sqlite")
|
const dockerDefaultDir = "/var/lib/woodpecker/drone.sqlite"
|
||||||
if err == nil {
|
const dockerOldPath = "/var/lib/drone/drone.sqlite"
|
||||||
return os.Rename("/var/lib/drone/drone.sqlite", "/var/lib/woodpecker/woodpecker.sqlite")
|
const standaloneDefault = "woodpecker.sqlite"
|
||||||
} else if !os.IsNotExist(err) {
|
const standaloneOld = "drone.sqlite"
|
||||||
return err
|
|
||||||
}
|
// custom location was set, use that one
|
||||||
|
if path != dockerDefaultPath && path != standaloneDefault {
|
||||||
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// default config for standalone installations
|
// file is at new default("/var/lib/woodpecker/woodpecker.sqlite")
|
||||||
if c.String("datasource") == "woodpecker.sqlite" {
|
_, err := os.Stat(dockerDefaultPath)
|
||||||
_, err := os.Stat("drone.sqlite")
|
if err != nil && !os.IsNotExist(err) {
|
||||||
if err == nil {
|
return "", err
|
||||||
return os.Rename("drone.sqlite", "woodpecker.sqlite")
|
}
|
||||||
} else if err != nil && !os.IsNotExist(err) {
|
if err == nil {
|
||||||
return err
|
return dockerDefaultPath, nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// file is at new default("woodpecker.sqlite")
|
||||||
|
_, err = os.Stat(standaloneDefault)
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
return standaloneDefault, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// woodpecker run in standalone mode, file is in same folder but not renamed
|
||||||
|
_, err = os.Stat(standaloneOld)
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
// rename in same folder should be fine as it should be same docker volume
|
||||||
|
log.Warn().Msgf("found sqlite3 file at '%s' and moved to '%s'", standaloneOld, standaloneDefault)
|
||||||
|
return standaloneDefault, os.Rename(standaloneOld, standaloneDefault)
|
||||||
|
}
|
||||||
|
|
||||||
|
// file is in new folder but not renamed
|
||||||
|
_, err = os.Stat(dockerDefaultDir)
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
// rename in same folder should be fine as it should be same docker volume
|
||||||
|
log.Warn().Msgf("found sqlite3 file at '%s' and moved to '%s'", dockerDefaultDir, dockerDefaultPath)
|
||||||
|
return dockerDefaultPath, os.Rename(dockerDefaultDir, dockerDefaultPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// file is still at old location
|
||||||
|
_, err = os.Stat(dockerOldPath)
|
||||||
|
if err == nil {
|
||||||
|
// TODO: use log.Fatal()... in next version
|
||||||
|
log.Error().Msgf("found sqlite3 file at deprecated path '%s', please move it to '%s' and update your volume path if necessary", dockerOldPath, dockerDefaultPath)
|
||||||
|
return dockerOldPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// file does not exist at all
|
||||||
|
log.Warn().Msgf("no sqlite3 file found, will create one at '%s'", path)
|
||||||
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupQueue(c *cli.Context, s store.Store) queue.Queue {
|
func setupQueue(c *cli.Context, s store.Store) queue.Queue {
|
||||||
|
|
Loading…
Reference in a new issue