Skip to content
This repository was archived by the owner on Oct 29, 2023. It is now read-only.

Commit fac69a3

Browse files
author
dataclouder
committed
Implemets Issue #33: Add support for MySQL upgrade
Version 1.10.0 adds command 'admin upgrade from_sandbox to_sandbox' Also added upgrade test.
1 parent 57dedd0 commit fac69a3

16 files changed

+967
-19
lines changed

Diff for: .build/COMPATIBLE_VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.9.0
1+
1.10.0

Diff for: .build/VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.9.0
1+
1.10.0

Diff for: .build/create-version-source-file.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package main
22

33
import (
4-
"bufio"
4+
//"bufio"
55
"fmt"
66
"github.com/datacharmer/dbdeployer/common"
77
"os"
@@ -25,7 +25,6 @@ func main() {
2525
if !common.DirExists(templates_dir) {
2626
common.Exit(1, "Directory .build/ not found")
2727
}
28-
2928
}
3029
version_dest_file := "common/version.go"
3130

@@ -51,6 +50,7 @@ func main() {
5150
"Timestamp": time.Now().Format("2006-01-02 15:04"),
5251
}
5352
version_code := common.Tprintf(template, data)
53+
/*
5454
file, err := os.Open(version_dest_file)
5555
if err != nil {
5656
common.Exit(1, fmt.Sprintf("error opening file %s", version_dest_file))
@@ -61,5 +61,7 @@ func main() {
6161
if err != nil {
6262
common.Exit(1, fmt.Sprintf("error writing to file %s", version_dest_file))
6363
}
64-
fmt.Printf("Written %d bytes into %s\n", written, version_dest_file)
64+
*/
65+
common.WriteString(version_code, version_dest_file)
66+
// fmt.Printf("Written %d bytes into %s\n", written, version_dest_file)
6567
}

Diff for: .build/set_version.sh

100644100755
File mode changed.

Diff for: .travis.yml

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ language: go
22

33
go:
44
- "1.10.x"
5-
- master
65

76
os: linux
87

Diff for: Changelog

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
1.10.0 27-Aug-2018
2+
- Fixed Issue#32 "Error log was not created in data directory"
3+
- Added command 'dbdeployer admin upgrade sandbox1 sandbox2' (Issue#33)
14
1.9.0 12-Aug-2018
25
- Implemented Issue#31 "Add feature to extract and merge a mysql-shell
36
tarball into a regular one"

Diff for: README.md

+46-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[DBdeployer](https://github.com/datacharmer/dbdeployer) is a tool that deploys MySQL database servers easily.
44
This is a port of [MySQL-Sandbox](https://github.com/datacharmer/mysql-sandbox), originally written in Perl, and re-designed from the ground up in [Go](https://golang.org). See the [features comparison](https://github.com/datacharmer/dbdeployer/blob/master/docs/features.md) for more detail.
55

6-
Documentation updated for version 1.9.0 (14-Aug-2018 08:30 UTC)
6+
Documentation updated for version 1.10.0 (26-Aug-2018 21:57 UTC)
77

88
[![Build Status](https://travis-ci.org/datacharmer/dbdeployer.svg "Travis CI status")](https://travis-ci.org/datacharmer/dbdeployer)
99

@@ -15,7 +15,7 @@ Get the one for your O.S. from [dbdeployer releases](https://github.com/datachar
1515

1616
For example:
1717

18-
$ VERSION=1.9.0
18+
$ VERSION=1.10.0
1919
$ OS=linux
2020
$ origin=https://github.com/datacharmer/dbdeployer/releases/download/$VERSION
2121
$ wget $origin/dbdeployer-$VERSION.$OS.tar.gz
@@ -50,7 +50,7 @@ For example:
5050
The program doesn't have any dependencies. Everything is included in the binary. Calling *dbdeployer* without arguments or with ``--help`` will show the main help screen.
5151

5252
$ dbdeployer --version
53-
dbdeployer version 1.9.0
53+
dbdeployer version 1.10.0
5454

5555

5656
$ dbdeployer -h
@@ -819,25 +819,62 @@ The lock can also be reverted using
819819

820820
$ dbdeployer admin unlock sandbox_name
821821

822+
## Sandbox upgrade
823+
824+
dbdeployer 1.10.0 introduces upgrades:
825+
826+
$ dbdeployer admin upgrade -h
827+
Upgrades a sandbox to a newer version.
828+
The sandbox with the new version must exist already.
829+
The data directory of the old sandbox will be moved to the new one.
830+
831+
Usage:
832+
dbdeployer admin upgrade sandbox_name newer_sandbox [flags]
833+
834+
Examples:
835+
dbdeployer admin upgrade msb_8_0_11 msb_8_0_12
836+
837+
Flags:
838+
-h, --help help for upgrade
839+
840+
841+
842+
To perform an upgrade, the following conditions myst be met:
843+
844+
* Both sandboxes must be **single** deployments.
845+
* The older version must be one major version behind (5.6.x to 5.7.x, or 5.7.x to 8.0.x, but not 5.6.x to 8.0.x) or same major version but different revision (e.g. 5.7.22 to 5.7.23)
846+
* The newer version must have been already deployed.
847+
* The newer version must have mysql_upgrade in its base directory (e.g $SANDBOX_BINARY/5.7.23/bin)
848+
849+
dbdeployer checks all the conditions, then
850+
851+
1. stops both databases;
852+
2. renames the data directory of the newer version;
853+
3. moves the data directory of the older version under the newer sandbox;
854+
4. restarts the newer version;
855+
5. runs mysql_upgrade.
856+
857+
The older version is, at this point, not operational anymore, and can be deleted.
858+
822859
## Compiling dbdeployer
823860

824861
Should you need to compile your own binaries for dbdeployer, follow these steps:
825862

826863
1. Make sure you have go installed in your system, and that the ``$GOPATH`` variable is set.
827864
2. Run ``go get -u github.com/datacharmer/dbdeployer``. This will import all the code that is needed to build dbdeployer.
828865
3. Change directory to ``$GOPATH/src/github.com/datacharmer/dbdeployer``.
829-
4. Run ``./build.sh {linux|OSX} 1.9.0``
830-
5. If you need the docs enabled binaries (see the section "Generating additional documentation") run ``MKDOCS=1 ./build.sh {linux|OSX} 1.9.0``
866+
4. Run ``./build.sh {linux|OSX} 1.10.0``
867+
5. If you need the docs enabled binaries (see the section "Generating additional documentation") run ``MKDOCS=1 ./build.sh {linux|OSX} 1.10.0``
831868

832869
## Generating additional documentation
833870

834871
Between this file and [the API API list](https://github.com/datacharmer/dbdeployer/blob/master/docs/API/API-1.1.md), you have all the existing documentation for dbdeployer.
835872
Should you need additional formats, though, dbdeployer is able to generate them on-the-fly. Tou will need the docs-enabled binaries: in the distribution list, you will find:
836873

837-
* dbdeployer-1.9.0-docs.linux.tar.gz
838-
* dbdeployer-1.9.0-docs.osx.tar.gz
839-
* dbdeployer-1.9.0.linux.tar.gz
840-
* dbdeployer-1.9.0.osx.tar.gz
874+
* dbdeployer-1.10.0-docs.linux.tar.gz
875+
* dbdeployer-1.10.0-docs.osx.tar.gz
876+
* dbdeployer-1.10.0.linux.tar.gz
877+
* dbdeployer-1.10.0.osx.tar.gz
841878

842879
The executables containing ``-docs`` in their name have the same capabilities of the regular ones, but in addition they can run the *hidden* command ``tree``, with alias ``docs``.
843880

Diff for: build.sh

+5
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ case $target in
109109
(set -x
110110
env GOOS=darwin GOARCH=386 go build $docs_flags -o $executable .
111111
)
112+
if [ "$?" != "0" ]
113+
then
114+
echo "ERROR during build!"
115+
exit 1
116+
fi
112117
tar -c $executable | gzip -c > ${executable}.tar.gz
113118
build_sort Darwin
114119
;;

Diff for: cmd/admin.go

+126
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,121 @@ func UnlockSandbox(cmd *cobra.Command, args []string) {
152152
}
153153
}
154154

155+
func UpgradeSandbox(sandbox_dir, old_sandbox, new_sandbox string) {
156+
var possible_upgrades = map[string]string{
157+
"5.0" : "5.1",
158+
"5.1" : "5.5",
159+
"5.5" : "5.6",
160+
"5.6" : "5.7",
161+
"5.7" : "8.0",
162+
"8.0" : "8.0",
163+
}
164+
err := os.Chdir(sandbox_dir)
165+
if err != nil {
166+
common.Exit(1, fmt.Sprintf("Error: can't change directory to %s", sandbox_dir))
167+
}
168+
scripts := []string{"start", "stop", "my"}
169+
for _, dir := range []string{old_sandbox, new_sandbox} {
170+
if !common.DirExists(dir) {
171+
common.Exit(1, fmt.Sprintf("Error: Directory %s not found in %s", dir, sandbox_dir))
172+
}
173+
for _, script := range scripts {
174+
if !common.ExecExists( dir + "/" + script) {
175+
common.Exit(1, fmt.Sprintf("Error: script %s not found in %s", script, dir),
176+
"The upgrade only works between SINGLE deployments")
177+
}
178+
}
179+
}
180+
new_sbdesc := common.ReadSandboxDescription(new_sandbox)
181+
old_sbdesc := common.ReadSandboxDescription(old_sandbox)
182+
mysql_upgrade := new_sbdesc.Basedir + "/bin/mysql_upgrade"
183+
if !common.ExecExists(mysql_upgrade) {
184+
common.WriteString("", new_sandbox + "/no_upgrade")
185+
common.Exit(0, fmt.Sprintf("mysql_upgrade not found in %s. Upgrade is not possible", new_sbdesc.Basedir))
186+
}
187+
new_version_list := common.VersionToList(new_sbdesc.Version)
188+
new_major := new_version_list[0]
189+
new_minor := new_version_list[1]
190+
new_rev := new_version_list[2]
191+
old_version_list := common.VersionToList(old_sbdesc.Version)
192+
old_major := old_version_list[0]
193+
old_minor := old_version_list[1]
194+
old_rev := old_version_list[2]
195+
new_upgrade_version := fmt.Sprintf("%d.%d", new_version_list[0], new_version_list[1])
196+
old_upgrade_version := fmt.Sprintf("%d.%d", old_version_list[0], old_version_list[1])
197+
if old_major == 10 || new_major == 10 {
198+
common.Exit(1, "Upgrade from and to MariaDB is not supported")
199+
}
200+
if common.GreaterOrEqualVersion(old_sbdesc.Version, new_version_list) {
201+
common.Exit(1, fmt.Sprintf("Version %s must be greater than %s", new_upgrade_version, old_upgrade_version))
202+
}
203+
can_be_upgraded := false
204+
if old_major < new_major {
205+
can_be_upgraded = true
206+
} else {
207+
if old_major == new_major && old_minor < new_minor {
208+
can_be_upgraded = true
209+
} else {
210+
if old_major == new_major && old_minor == new_minor && old_rev < new_rev {
211+
can_be_upgraded = true
212+
}
213+
}
214+
}
215+
if !can_be_upgraded {
216+
common.Exit(1, fmt.Sprintf("Version %s can only be upgraded to %s or to the same version with a higher revision", old_upgrade_version, possible_upgrades[old_upgrade_version]))
217+
}
218+
new_sandbox_old_data := new_sandbox + "/data-" + new_sandbox
219+
if common.DirExists(new_sandbox_old_data) {
220+
common.Exit(1, fmt.Sprintf("Sandbox %s is already the upgrade from an older version", new_sandbox))
221+
}
222+
err, _ = common.Run_cmd(old_sandbox + "/stop")
223+
if err != nil {
224+
common.Exit(1, fmt.Sprintf("Error while stopping sandbox %s", old_sandbox))
225+
}
226+
err, _ = common.Run_cmd(new_sandbox + "/stop")
227+
if err != nil {
228+
common.Exit(1, fmt.Sprintf("Error while stopping sandbox %s", new_sandbox))
229+
}
230+
mv_args := []string{new_sandbox + "/data", new_sandbox_old_data}
231+
err, _ = common.Run_cmd_with_args("mv", mv_args)
232+
if err != nil {
233+
common.Exit(1, fmt.Sprintf("Error while moving data directory in sandbox %s", new_sandbox))
234+
}
235+
236+
mv_args = []string{old_sandbox + "/data", new_sandbox + "/data" }
237+
err, _ = common.Run_cmd_with_args("mv", mv_args)
238+
if err != nil {
239+
common.Exit(1, fmt.Sprintf("Error while moving data directory from sandbox %s to %s", old_sandbox, new_sandbox))
240+
}
241+
fmt.Printf("Data directory %s/data moved to %s/data \n", old_sandbox, new_sandbox)
242+
243+
err, _ = common.Run_cmd(new_sandbox + "/start")
244+
if err != nil {
245+
common.Exit(1, fmt.Sprintf("Error while starting sandbox %s", new_sandbox))
246+
}
247+
upgrade_args := []string{"sql_upgrade"}
248+
err, _ = common.Run_cmd_with_args(new_sandbox + "/my", upgrade_args)
249+
if err != nil {
250+
common.Exit(1, fmt.Sprintf("Error while running mysql_upgrade in %s", new_sandbox))
251+
}
252+
fmt.Println("")
253+
fmt.Printf("The data directory from %s/data is preserved in %s\n", new_sandbox, new_sandbox_old_data)
254+
fmt.Printf("The data directory from %s/data is now used in %s/data\n", old_sandbox, new_sandbox)
255+
fmt.Printf("%s is not operational and can be deleted\n", old_sandbox)
256+
}
257+
258+
func RunUpgradeSandbox(cmd *cobra .Command, args []string) {
259+
if len(args) < 2 {
260+
common.Exit(1,
261+
"'upgrade' requires the name of two sandboxes ",
262+
"Example: dbdeployer admin upgrade msb_5_7_23 msb_8_0_12")
263+
}
264+
old_sandbox := args[0]
265+
new_sandbox := args[1]
266+
sandbox_dir := GetAbsolutePathFromFlag(cmd, "sandbox-home")
267+
UpgradeSandbox(sandbox_dir, old_sandbox, new_sandbox)
268+
}
269+
155270
var (
156271
adminCmd = &cobra.Command{
157272
Use: "admin",
@@ -177,10 +292,21 @@ Users can still delete locked sandboxes manually.`,
177292
Long: `Removes lock, allowing deletion of a given sandbox`,
178293
Run: UnlockSandbox,
179294
}
295+
adminUpgradeCmd = &cobra.Command{
296+
Use: "upgrade sandbox_name newer_sandbox",
297+
Short: "Upgrades a sandbox to a newer version",
298+
Long: `Upgrades a sandbox to a newer version.
299+
The sandbox with the new version must exist already.
300+
The data directory of the old sandbox will be moved to the new one.`,
301+
Example: "dbdeployer admin upgrade msb_8_0_11 msb_8_0_12",
302+
Run: RunUpgradeSandbox,
303+
}
304+
180305
)
181306

182307
func init() {
183308
rootCmd.AddCommand(adminCmd)
184309
adminCmd.AddCommand(adminLockCmd)
185310
adminCmd.AddCommand(adminUnlockCmd)
311+
adminCmd.AddCommand(adminUpgradeCmd)
186312
}

Diff for: common/fileutil.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ func WriteStrings(lines []string, filename string, termination string) error {
159159

160160
w := bufio.NewWriter(file)
161161
for _, line := range lines {
162-
fmt.Fprintln(w, line+termination)
162+
//fmt.Fprintln(w, line+termination)
163+
fmt.Fprintf(w, "%s", line+termination)
163164
}
164165
return w.Flush()
165166
}

Diff for: common/version.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
package common
1717

1818
// This file was generated during build. Do not edit.
19-
// Build time: 2018-08-15 05:55
19+
// Build time: 2018-08-26 23:55
2020

21-
var VersionDef string = "1.9.0" // 2018-08-12
21+
var VersionDef string = "1.10.0" // 2018-08-26
2222

2323
// Compatible version is the version used to mark compatible archives (templates, configuration).
2424
// It is usually major.minor.0, except when we are at version 0.x, when
2525
// every revision may bring incompatibility
26-
var CompatibleVersion string = "1.9.0" // 2018-08-12
26+
var CompatibleVersion string = "1.10.0" // 2018-08-26

0 commit comments

Comments
 (0)