Skip to content

Commit 9b37a50

Browse files
committed
simplify IO by using only internal buffers
1 parent 54de053 commit 9b37a50

File tree

6 files changed

+352
-197
lines changed

6 files changed

+352
-197
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ This key is intentionally absent from pg2s3's environment in order to require us
4848

4949
| Variable | Description |
5050
| ------------------------- | ----------- |
51-
| `PG2S3_AGE_PUBLIC_KEY` | Public key generated by [age](https://github.com/FiloSottile/age) |
51+
| `PG2S3_AGE_PUBLIC_KEY` | Public key for backup encryption |
5252

5353
## Usage
5454
The pg2s3 command-line tool offers three commands:

cmd/cli/main.go

+30-39
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,44 @@ import (
99
"strconv"
1010
"strings"
1111

12+
"filippo.io/age"
1213
"github.com/theandrew168/pg2s3"
1314
"golang.org/x/term"
1415
)
1516

16-
// TODO: move env var names to package constants?
17-
1817
func main() {
1918
log.SetFlags(0)
2019

20+
usage := "usage: pg2s3 backup|restore|prune"
21+
if len(os.Args) < 2 {
22+
log.Fatalln(usage)
23+
}
24+
2125
client, err := pg2s3.New(
22-
requireEnv("PG2S3_PG_CONNECTION_URI"),
23-
requireEnv("PG2S3_S3_ENDPOINT"),
24-
requireEnv("PG2S3_S3_ACCESS_KEY_ID"),
25-
requireEnv("PG2S3_S3_SECRET_ACCESS_KEY"),
26-
requireEnv("PG2S3_S3_BUCKET_NAME"))
26+
requireEnv(pg2s3.EnvPGConnectionURI),
27+
requireEnv(pg2s3.EnvS3Endpoint),
28+
requireEnv(pg2s3.EnvS3AccessKeyID),
29+
requireEnv(pg2s3.EnvS3SecretAccessKey),
30+
requireEnv(pg2s3.EnvS3BucketName))
2731
if err != nil {
2832
log.Fatalln(err)
2933
}
3034

31-
prefix := requireEnv("PG2S3_BACKUP_PREFIX")
32-
retention, err := strconv.Atoi(requireEnv("PG2S3_BACKUP_RETENTION"))
35+
prefix := requireEnv(pg2s3.EnvBackupPrefix)
36+
retention, err := strconv.Atoi(requireEnv(pg2s3.EnvBackupRetention))
3337
if err != nil {
3438
log.Fatalln(err)
3539
}
3640

37-
usage := "usage: pg2s3 backup|restore|prune"
38-
if len(os.Args) < 2 {
39-
log.Fatalln(usage)
41+
// validate public key (if provided)
42+
publicKey := os.Getenv(pg2s3.EnvAgePublicKey)
43+
if publicKey != "" {
44+
_, err = age.ParseX25519Recipient(publicKey)
45+
if err != nil {
46+
log.Fatalln(err)
47+
}
4048
}
4149

42-
// TODO: verify connection to PG
43-
// TODO: verify connection to S3
44-
// TODO: verify age public key (if provided)
45-
4650
cmd := os.Args[1]
4751
switch cmd {
4852
case "backup":
@@ -91,39 +95,32 @@ func confirm(message string) bool {
9195
}
9296

9397
func backup(client *pg2s3.Client, prefix string) error {
94-
publicKey := os.Getenv("PG2S3_AGE_PUBLIC_KEY")
98+
publicKey := os.Getenv(pg2s3.EnvAgePublicKey)
9599

96100
// generate name for backup
97101
name, err := pg2s3.GenerateBackupName(prefix)
98102
if err != nil {
99103
return err
100104
}
101105

102-
// generate path for backup
103-
path := pg2s3.GenerateBackupPath(name)
104-
105106
// create backup
106-
err = client.CreateBackup(path)
107+
backup, err := client.CreateBackup()
107108
if err != nil {
108109
return err
109110
}
110-
defer os.Remove(path)
111111

112112
// encrypt backup (if applicable)
113113
if publicKey != "" {
114-
agePath := path + ".age"
115-
err := client.EncryptBackup(agePath, path, publicKey)
114+
backup, err = client.EncryptBackup(backup, publicKey)
116115
if err != nil {
117116
return err
118117
}
119118

120119
name = name + ".age"
121-
path = agePath
122120
}
123-
defer os.Remove(path)
124121

125122
// upload backup
126-
err = client.UploadBackup(name, path)
123+
err = client.UploadBackup(name, backup)
127124
if err != nil {
128125
return err
129126
}
@@ -133,7 +130,7 @@ func backup(client *pg2s3.Client, prefix string) error {
133130
}
134131

135132
func restore(client *pg2s3.Client) error {
136-
publicKey := os.Getenv("PG2S3_AGE_PUBLIC_KEY")
133+
publicKey := os.Getenv(pg2s3.EnvAgePublicKey)
137134

138135
// list all backups
139136
backups, err := client.ListBackups()
@@ -148,34 +145,28 @@ func restore(client *pg2s3.Client) error {
148145
// determine latest backup
149146
latest := backups[0]
150147

151-
// generate path for backup
152-
path := pg2s3.GenerateBackupPath(latest)
153-
154148
// download backup
155-
err = client.DownloadBackup(path, latest)
149+
backup, err := client.DownloadBackup(latest)
156150
if err != nil {
157151
return err
158152
}
159-
defer os.Remove(path)
160153

161154
// decrypt backup (if applicable)
162155
if publicKey != "" {
163-
fmt.Println("enter age private key:")
156+
fmt.Print("enter private key: ")
164157
input, err := term.ReadPassword(int(os.Stdin.Fd()))
165158
if err != nil {
166159
return err
167160
}
168161

162+
fmt.Println()
169163
privateKey := string(input)
170164

171-
agePath := path
172-
path = strings.TrimSuffix(path, ".age")
173-
err = client.DecryptBackup(path, agePath, privateKey)
165+
backup, err = client.DecryptBackup(backup, privateKey)
174166
if err != nil {
175167
return err
176168
}
177169
}
178-
defer os.Remove(path)
179170

180171
// confirm restore before applying
181172
message := fmt.Sprintf("restore %s", latest)
@@ -184,7 +175,7 @@ func restore(client *pg2s3.Client) error {
184175
}
185176

186177
// restore backup
187-
err = client.RestoreBackup(path)
178+
err = client.RestoreBackup(backup)
188179
if err != nil {
189180
return err
190181
}

go.mod

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@ go 1.17
44

55
require (
66
filippo.io/age v1.0.0
7+
github.com/jackc/pgx/v4 v4.13.0
78
github.com/minio/minio-go/v7 v7.0.14
89
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b
910
)
1011

1112
require (
1213
github.com/dustin/go-humanize v1.0.0 // indirect
1314
github.com/google/uuid v1.1.1 // indirect
15+
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
16+
github.com/jackc/pgconn v1.10.0 // indirect
17+
github.com/jackc/pgio v1.0.0 // indirect
18+
github.com/jackc/pgpassfile v1.0.0 // indirect
19+
github.com/jackc/pgproto3/v2 v2.1.1 // indirect
20+
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
21+
github.com/jackc/pgtype v1.8.1 // indirect
1422
github.com/json-iterator/go v1.1.10 // indirect
1523
github.com/klauspost/cpuid v1.3.1 // indirect
1624
github.com/minio/md5-simd v1.1.0 // indirect
@@ -23,6 +31,6 @@ require (
2331
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
2432
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
2533
golang.org/x/sys v0.0.0-20210903071746-97244b99971b // indirect
26-
golang.org/x/text v0.3.3 // indirect
34+
golang.org/x/text v0.3.6 // indirect
2735
gopkg.in/ini.v1 v1.57.0 // indirect
2836
)

0 commit comments

Comments
 (0)