fix(gitpush): log a failed removal of the temporary key directory and simplify the refspec check
1 file · +10 -2
M internal/adapters/gitpush/gitpush.go +10 -2
| @@ -18,6 +18,7 @@ import ( | |||
| 18 | 18 | ||
| 19 | 19 | "bnema.dev/ermite/internal/domain" | |
| 20 | 20 | "bnema.dev/ermite/internal/ports" | |
| 21 | + | "github.com/bnema/zerowrap" | |
| 21 | 22 | "golang.org/x/crypto/ssh" | |
| 22 | 23 | ) | |
| 23 | 24 | ||
| @@ -52,7 +53,7 @@ func quote(s string) string { return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") | |||
| 52 | 53 | // Empty sources, wildcards, force prefixes and revision expressions never reach git. | |
| 53 | 54 | func validRefspec(s string) bool { | |
| 54 | 55 | a, b, ok := strings.Cut(s, ":") | |
| 55 | - | if !ok || a != b || !(strings.HasPrefix(a, "refs/heads/") || strings.HasPrefix(a, "refs/tags/")) { | |
| 56 | + | if !ok || a != b || !strings.HasPrefix(a, "refs/heads/") && !strings.HasPrefix(a, "refs/tags/") { | |
| 56 | 57 | return false | |
| 57 | 58 | } | |
| 58 | 59 | if strings.ContainsAny(a, "+*?[:\\^~ ") || strings.Contains(a, "..") || strings.Contains(a, "@{") || strings.Contains(a, "//") || strings.HasSuffix(a, "/") || strings.HasSuffix(a, ".") { | |
| @@ -104,7 +105,14 @@ func (p *Pusher) Push(parent context.Context, req ports.MirrorPush) (result port | |||
| 104 | 105 | if e != nil { | |
| 105 | 106 | return result, internal("create temporary mirror directory") | |
| 106 | 107 | } | |
| 107 | - | defer os.RemoveAll(dir) | |
| 108 | + | defer func() { | |
| 109 | + | // The directory holds the private key: a leftover is reported, and resetRunDir wipes it at | |
| 110 | + | // the next start. | |
| 111 | + | if e := os.RemoveAll(dir); e != nil { | |
| 112 | + | log := zerowrap.FromCtx(parent) | |
| 113 | + | log.Warn().Err(e).Msg("remove the temporary mirror key directory") | |
| 114 | + | } | |
| 115 | + | }() | |
| 108 | 116 | block, e := ssh.MarshalPrivateKey(req.PrivateKey, "") | |
| 109 | 117 | if e != nil { | |
| 110 | 118 | return result, internal("encode mirror private key") | |
| @@ -18,6 +18,7 @@ import ( | |||||
| 18 | 18 | ||||
| 19 | "bnema.dev/ermite/internal/domain" | 19 | "bnema.dev/ermite/internal/domain" | ||
| 20 | "bnema.dev/ermite/internal/ports" | 20 | "bnema.dev/ermite/internal/ports" | ||
| 21 | + | "github.com/bnema/zerowrap" | |||
| 21 | "golang.org/x/crypto/ssh" | 22 | "golang.org/x/crypto/ssh" | ||
| 22 | ) | 23 | ) | ||
| 23 | 24 | ||||
| @@ -52,7 +53,7 @@ func quote(s string) string { return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") | |||||
| 52 | // Empty sources, wildcards, force prefixes and revision expressions never reach git. | 53 | // Empty sources, wildcards, force prefixes and revision expressions never reach git. | ||
| 53 | func validRefspec(s string) bool { | 54 | func validRefspec(s string) bool { | ||
| 54 | a, b, ok := strings.Cut(s, ":") | 55 | a, b, ok := strings.Cut(s, ":") | ||
| 55 | - | if !ok || a != b || !(strings.HasPrefix(a, "refs/heads/") || strings.HasPrefix(a, "refs/tags/")) { | 56 | + | if !ok || a != b || !strings.HasPrefix(a, "refs/heads/") && !strings.HasPrefix(a, "refs/tags/") { |
| 56 | return false | 57 | return false | ||
| 57 | } | 58 | } | ||
| 58 | if strings.ContainsAny(a, "+*?[:\\^~ ") || strings.Contains(a, "..") || strings.Contains(a, "@{") || strings.Contains(a, "//") || strings.HasSuffix(a, "/") || strings.HasSuffix(a, ".") { | 59 | if strings.ContainsAny(a, "+*?[:\\^~ ") || strings.Contains(a, "..") || strings.Contains(a, "@{") || strings.Contains(a, "//") || strings.HasSuffix(a, "/") || strings.HasSuffix(a, ".") { | ||
| @@ -104,7 +105,14 @@ func (p *Pusher) Push(parent context.Context, req ports.MirrorPush) (result port | |||||
| 104 | if e != nil { | 105 | if e != nil { | ||
| 105 | return result, internal("create temporary mirror directory") | 106 | return result, internal("create temporary mirror directory") | ||
| 106 | } | 107 | } | ||
| 107 | - | defer os.RemoveAll(dir) | 108 | + | defer func() { |
| 109 | + | // The directory holds the private key: a leftover is reported, and resetRunDir wipes it at | |||
| 110 | + | // the next start. | |||
| 111 | + | if e := os.RemoveAll(dir); e != nil { | |||
| 112 | + | log := zerowrap.FromCtx(parent) | |||
| 113 | + | log.Warn().Err(e).Msg("remove the temporary mirror key directory") | |||
| 114 | + | } | |||
| 115 | + | }() | |||
| 108 | block, e := ssh.MarshalPrivateKey(req.PrivateKey, "") | 116 | block, e := ssh.MarshalPrivateKey(req.PrivateKey, "") | ||
| 109 | if e != nil { | 117 | if e != nil { | ||
| 110 | return result, internal("encode mirror private key") | 118 | return result, internal("encode mirror private key") | ||