-
Notifications
You must be signed in to change notification settings - Fork 0
/
pgupgrade.go
186 lines (150 loc) · 7.47 KB
/
pgupgrade.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package postgres
import (
"context"
_ "embed"
"fmt"
"time"
"github.com/containerinfra/kube-pg-upgrade/pkg/pgupgrade"
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
)
type postgresPGUpgradeOptions struct {
namespace string
upgradeImage string
extraInitDBArgs string
newPVCDiskSize string
timeout time.Duration
// nextPostgresVersion is the current postgres version of the database
// Will attempt auto detection if empty
currentPostgresVersion string
// targetPostgresVersion is the postgres version that we will upgrade to
// Will attempt auto detection if empty
targetPostgresVersion string
// username of postgres
// Will attempt auto detection if empty
postgresUser string
sourcePVCName string
targetPVCName string
subPath string
}
func newPostgresPGUpgradeOptions() *postgresPGUpgradeOptions {
return &postgresPGUpgradeOptions{}
}
func AddPostgresStatefulSetUpgradeFlags(flagSet *flag.FlagSet, opts *postgresPGUpgradeOptions) {
flagSet.StringVarP(&opts.namespace, "namespace", "n", "", "namespace of the postgres instance. Default is the configured namespace in your kubecontext.")
flagSet.StringVar(&opts.upgradeImage, "upgrade-image", "tianon/postgres-upgrade", "Container image used to run pg_upgrade.")
// PostgreSQL settings
flagSet.StringVarP(&opts.postgresUser, "user", "u", "", "user used for initdb")
flagSet.StringVarP(&opts.targetPostgresVersion, "version", "v", "", "target postgres major version. For example: 14, 15, 16, etc..")
flagSet.StringVar(&opts.currentPostgresVersion, "current-version", "", "current version of the postgres database. Optional, will attempt auto discovery if left empty. For example: 9.6, 14, 15, 16, etc..")
flagSet.StringVarP(&opts.extraInitDBArgs, "extra-initdb-args", "i", "", "provide any additional arguments for init-db. Use the same arguments that were provided when the database was originally created. See https://www.postgresql.org/docs/current/pgupgrade.html. Otherwise will attempt to auto detect.")
// Disk settings
flagSet.StringVar(&opts.newPVCDiskSize, "size", "", "New size. Example: 10G")
flagSet.StringVar(&opts.subPath, "subpath", "", "subpath used for mounting the pvc")
flagSet.StringVar(&opts.sourcePVCName, "source-pvc-name", "", "The name of the Persistent Volume Claim with the current postgres data. Optional, will attempt auto discovery if left empty.")
flagSet.StringVar(&opts.targetPVCName, "target-pvc-name", "", "Target name of Persistent Volume Claim that will serve as the target for the upgraded postgres data. This is an optional setting, will use the source PVC name by default.")
// Other
flagSet.DurationVar(&opts.timeout, "timeout", 0*time.Second, "The length of time to wait before giving up, zero means infinite")
}
func AddPostgresPVCUpgradeFlags(flagSet *flag.FlagSet, opts *postgresPGUpgradeOptions) {
flagSet.StringVarP(&opts.namespace, "namespace", "n", "", "namespace of the postgres instance. Default is the configured namespace in your kubecontext.")
flagSet.StringVar(&opts.upgradeImage, "upgrade-image", "tianon/postgres-upgrade", "Container image used to run pg_upgrade.")
// PostgreSQL settings
flagSet.StringVarP(&opts.postgresUser, "user", "u", "", "user used for initdb")
flagSet.StringVarP(&opts.targetPostgresVersion, "version", "v", "", "target postgres major version. For example: 14, 15, 16, etc..")
flagSet.StringVar(&opts.currentPostgresVersion, "current-version", "", "current version of the postgres database. For example: 9.6, 14, 15, 16, etc..")
flagSet.StringVarP(&opts.extraInitDBArgs, "extra-initdb-args", "i", "", "provide any additional arguments for init-db. Use the same arguments that were provided when the database was originally created. See https://www.postgresql.org/docs/current/pgupgrade.html.")
// Disk settings
flagSet.StringVar(&opts.newPVCDiskSize, "size", "", "New size. Example: 10G")
flagSet.StringVar(&opts.subPath, "subpath", "", "subpath used for mounting the pvc")
flagSet.StringVar(&opts.targetPVCName, "target-pvc-name", "", "Target name of Persistent Volume Claim that will serve as the target for the upgraded postgres data. This is an optional setting, will use the source PVC name by default.")
// Other
flagSet.DurationVar(&opts.timeout, "timeout", 0*time.Second, "The length of time to wait before giving up, zero means infinite")
}
//go:embed examples/upgrade.txt
var pgUpgradeStatefulSetExamples string
// NewUpgradePostgresStatefulSetCmd
func NewUpgradePostgresStatefulSetCmd(runOptions *postgresPGUpgradeOptions) *cobra.Command {
if runOptions == nil {
runOptions = newPostgresPGUpgradeOptions()
}
var cmd = &cobra.Command{
Use: "statefulset <statefulset>",
Args: cobra.ExactArgs(1),
Aliases: []string{"sts"},
Short: ``,
Long: ``,
Example: pgUpgradeStatefulSetExamples,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithCancel(cmd.Context())
defer cancel()
if runOptions.timeout > 0 {
timeoutctx, cancelTimeout := context.WithTimeoutCause(ctx, runOptions.timeout, fmt.Errorf("upgrade did not complete within configured timeout (%s)", runOptions.timeout.String()))
defer cancelTimeout()
ctx = timeoutctx
}
upgrader, err := pgupgrade.NewPGUpgradeRunner(runOptions.namespace, pgupgrade.PGUpgradeSettings{
UpgradeImage: runOptions.upgradeImage,
InitDBUser: runOptions.postgresUser,
CurrentPostgresVersion: runOptions.currentPostgresVersion,
TargetPostgresVersion: runOptions.targetPostgresVersion,
InitDBArgs: runOptions.extraInitDBArgs,
DiskSize: runOptions.newPVCDiskSize,
TargetPVCName: runOptions.targetPVCName,
SourcePVCName: runOptions.sourcePVCName,
SubPath: runOptions.subPath,
})
if err != nil {
return err
}
return upgrader.RunPGUpgradeForDatabaseStatefulSet(ctx, args[0])
},
}
AddPostgresStatefulSetUpgradeFlags(cmd.Flags(), runOptions)
cmd.MarkFlagRequired("version")
return cmd
}
//go:embed examples/upgrade-pvc.txt
var pgUpgradePVCxamples string
// NewUpgradePostgresPVCCmd
func NewUpgradePostgresPVCCmd(runOptions *postgresPGUpgradeOptions) *cobra.Command {
if runOptions == nil {
runOptions = newPostgresPGUpgradeOptions()
}
var cmd = &cobra.Command{
Use: "pvc <name>",
Args: cobra.ExactArgs(1),
Aliases: []string{"persistent-volume-claim"},
Short: ``,
Long: ``,
Example: pgUpgradePVCxamples,
RunE: func(cmd *cobra.Command, args []string) error {
ctx, cancel := context.WithCancel(cmd.Context())
defer cancel()
if runOptions.timeout > 0 {
timeoutctx, cancelTimeout := context.WithTimeoutCause(ctx, runOptions.timeout, fmt.Errorf("upgrade did not complete within configured timeout (%s)", runOptions.timeout.String()))
defer cancelTimeout()
ctx = timeoutctx
}
upgrader, err := pgupgrade.NewPGUpgradeRunner(runOptions.namespace, pgupgrade.PGUpgradeSettings{
UpgradeImage: runOptions.upgradeImage,
InitDBUser: runOptions.postgresUser,
CurrentPostgresVersion: runOptions.currentPostgresVersion,
TargetPostgresVersion: runOptions.targetPostgresVersion,
InitDBArgs: runOptions.extraInitDBArgs,
DiskSize: runOptions.newPVCDiskSize,
TargetPVCName: runOptions.targetPVCName,
SourcePVCName: args[0],
SubPath: runOptions.subPath,
})
if err != nil {
return err
}
return upgrader.RunPGUpgradeForDatabasePVC(ctx)
},
}
AddPostgresPVCUpgradeFlags(cmd.Flags(), runOptions)
cmd.MarkFlagRequired("version")
cmd.MarkFlagRequired("current-version")
return cmd
}