From d3c696d89a293b25334136367eb9926e6f32d0e7 Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Mon, 31 Mar 2025 12:42:59 +0300 Subject: [PATCH 1/9] improve publishes --- README.md | 4 +- cmd/gcx/main.go | 121 +++++++++++++++++++++++++++++++--- internal/helpers/path.go | 17 +++++ internal/helpers/path_test.go | 48 ++++++++++++++ 4 files changed, 179 insertions(+), 11 deletions(-) create mode 100644 internal/helpers/path.go create mode 100644 internal/helpers/path_test.go diff --git a/README.md b/README.md index ff7ff2e..82b1e00 100644 --- a/README.md +++ b/README.md @@ -134,13 +134,15 @@ archives: # Artifact publishing configuration blobs: - provider: s3 + name: s3-storage bucket: your-bucket-name directory: "releases/{{.Version}}" region: us-west-1 endpoint: https://s3.example.com - provider: ssh - server: "storage.example.com" + name: stage-server + server: "stage.example.com" user: "deployer" key_path: "~/.ssh/deploy_key" directory: "/var/www/releases/{{.Version}}" diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index 2374ddd..0bd549b 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -23,6 +23,7 @@ import ( "github.com/melbahja/goph" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" + "github.com/sxwebdev/gcx/internal/helpers" "github.com/urfave/cli/v2" "gopkg.in/yaml.v3" ) @@ -77,6 +78,7 @@ type ArchiveTemplateData struct { type BlobConfig struct { Provider string `yaml:"provider"` + Name string `yaml:"name"` // S3 config fields Bucket string `yaml:"bucket,omitempty"` Region string `yaml:"region,omitempty"` @@ -96,6 +98,7 @@ type DeployConfig struct { Server string `yaml:"server,omitempty"` User string `yaml:"user,omitempty"` KeyPath string `yaml:"key_path,omitempty"` + KeyRaw string `yaml:"key_raw,omitempty"` Commands []string `yaml:"commands"` // Alert configuration Alerts AlertConfig `yaml:"alerts,omitempty"` @@ -128,11 +131,12 @@ func (c *BlobConfig) ToS3Config() *S3Config { } // ToSSHConfig converts BlobConfig to SSHConfig if provider is ssh -func (c *BlobConfig) ToSSHConfig() *SSHConfig { +func (c *BlobConfig) ToSSHConfig() *SSHPublishConfig { if c.Provider != "ssh" { return nil } - return &SSHConfig{ + return &SSHPublishConfig{ + Name: c.Name, Server: c.Server, User: c.User, KeyPath: c.KeyPath, @@ -162,22 +166,71 @@ type S3Config struct { Endpoint string } -type SSHConfig struct { +type SSHPublishConfig struct { + Name string Server string User string KeyPath string + KeyRaw string Directory string } +// Validate checks if the SSHConfig is valid +func (c *SSHPublishConfig) Validate() error { + if c.Name == "" { + return fmt.Errorf("name is required") + } + if c.Server == "" { + return fmt.Errorf("server is required") + } + if c.User == "" { + return fmt.Errorf("user is required") + } + if c.KeyPath == "" && c.KeyRaw == "" { + return fmt.Errorf("either key_path or key_raw is required") + } + if c.KeyPath != "" && c.KeyRaw != "" { + return fmt.Errorf("only one of key_path or key_raw should be provided") + } + if c.Directory == "" { + return fmt.Errorf("directory is required") + } + return nil +} + // Internal config types for type safety type SSHDeployConfig struct { Name string Server string User string KeyPath string + KeyRaw string Commands []string } +// Validate checks if the SSHCSSHDeployConfigonfig is valid +func (c *SSHDeployConfig) Validate() error { + if c.Name == "" { + return fmt.Errorf("name is required") + } + if c.Server == "" { + return fmt.Errorf("server is required") + } + if c.User == "" { + return fmt.Errorf("user is required") + } + if c.KeyPath == "" && c.KeyRaw == "" { + return fmt.Errorf("either key_path or key_raw is required") + } + if c.KeyPath != "" && c.KeyRaw != "" { + return fmt.Errorf("only one of key_path or key_raw should be provided") + } + if len(c.Commands) == 0 { + return fmt.Errorf("at least one command is required") + } + return nil +} + // loadConfig reads the YAML configuration from the specified file. func loadConfig(configPath string) (*Config, error) { data, err := os.ReadFile(configPath) @@ -521,7 +574,7 @@ func buildBinaries(cfg *Config) error { } // publishArtifacts uploads artifacts to configured destinations -func publishArtifacts(cfg *Config) error { +func publishArtifacts(cfg *Config, publishName string) error { // Determine the artifacts directory (default is "dist") artifactsDir := cfg.OutDir if artifactsDir == "" { @@ -535,8 +588,29 @@ func publishArtifacts(cfg *Config) error { "Version": tag, } + var blobs []BlobConfig + + // If publishName is specified, execute only that publish + if publishName != "" { + var found bool + for _, config := range cfg.Blobs { + if config.Name == publishName { + blobs = append(blobs, config) + found = true + } + } + if !found { + return fmt.Errorf("publish configuration '%s' not found", publishName) + } + } else { + // Otherwise, execute all publish configurations + blobs = cfg.Blobs + } + // Process each blob configuration - for _, blob := range cfg.Blobs { + for _, blob := range blobs { + fmt.Println("Publishing to:", blob.Name) + switch blob.Provider { case "s3": if err := publishToS3(blob.ToS3Config(), artifactsDir, tmplData); err != nil { @@ -637,11 +711,16 @@ func publishToS3(cfg *S3Config, artifactsDir string, tmplData map[string]string) } // publishToSSH uploads artifacts to remote server via SSH -func publishToSSH(cfg *SSHConfig, artifactsDir string, tmplData map[string]string) error { +func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[string]string) error { if cfg == nil { return fmt.Errorf("ssh configuration is required for ssh provider") } + // Validate SSH configuration + if err := cfg.Validate(); err != nil { + return fmt.Errorf("invalid SSH configuration: %w", err) + } + // Process template for the publish directory tmpl, err := template.New("directory").Parse(cfg.Directory) if err != nil { @@ -654,9 +733,21 @@ func publishToSSH(cfg *SSHConfig, artifactsDir string, tmplData map[string]strin remoteDir := dirBuffer.String() // Create SSH client - auth, err := goph.Key(cfg.KeyPath, "") - if err != nil { - return fmt.Errorf("failed to load SSH key: %w", err) + var auth goph.Auth + if cfg.KeyRaw != "" { + auth, err = goph.RawKey(cfg.KeyRaw, "") + if err != nil { + return fmt.Errorf("failed to load SSH key: %w", err) + } + } else { + path, err := helpers.ExpandPath(cfg.KeyPath) + if err != nil { + return fmt.Errorf("failed to expand key path: %w", err) + } + auth, err = goph.Key(path, "") + if err != nil { + return fmt.Errorf("failed to load SSH key: %w", err) + } } client, err := goph.New(cfg.User, cfg.Server, auth) @@ -952,6 +1043,11 @@ func executeSSHDeploy(cfg *SSHDeployConfig) error { return fmt.Errorf("ssh configuration is required for ssh provider") } + // Validate SSH configuration + if err := cfg.Validate(); err != nil { + return fmt.Errorf("invalid SSH configuration: %w", err) + } + // Create SSH client auth, err := goph.Key(cfg.KeyPath, "") if err != nil { @@ -1015,6 +1111,11 @@ func main() { Usage: "Path to the YAML configuration file", Value: "gcx.yaml", }, + &cli.StringFlag{ + Name: "name", + Aliases: []string{"n"}, + Usage: "Name of the publish configuration to execute", + }, }, Action: func(c *cli.Context) error { configPath := c.String("config") @@ -1022,7 +1123,7 @@ func main() { if err != nil { return fmt.Errorf("error loading configuration: %w", err) } - return publishArtifacts(cfg) + return publishArtifacts(cfg, c.String("name")) }, }, { diff --git a/internal/helpers/path.go b/internal/helpers/path.go new file mode 100644 index 0000000..0fdd7d9 --- /dev/null +++ b/internal/helpers/path.go @@ -0,0 +1,17 @@ +package helpers + +import ( + "os/user" + "strings" +) + +func ExpandPath(path string) (string, error) { + if strings.HasPrefix(path, "~/") { + usr, err := user.Current() + if err != nil { + return "", err + } + return strings.Replace(path, "~", usr.HomeDir, 1), nil + } + return path, nil +} diff --git a/internal/helpers/path_test.go b/internal/helpers/path_test.go new file mode 100644 index 0000000..5d6408e --- /dev/null +++ b/internal/helpers/path_test.go @@ -0,0 +1,48 @@ +package helpers_test + +import ( + "os/user" + "testing" + + "github.com/sxwebdev/gcx/internal/helpers" +) + +func TestExpandPath(t *testing.T) { + // get current user's home directory for constructing expected outputs. + usr, err := user.Current() + if err != nil { + t.Fatalf("failed to get current user: %v", err) + } + + tests := []struct { + input string + expected string + }{ + { + input: "~/folder", + expected: usr.HomeDir + "/folder", + }, + { + input: "~/", + expected: usr.HomeDir + "/", + }, + { + input: "/absolute/path", + expected: "/absolute/path", + }, + { + input: "relative/path", + expected: "relative/path", + }, + } + + for _, tt := range tests { + got, err := helpers.ExpandPath(tt.input) + if err != nil { + t.Errorf("ExpandPath(%q) returned error: %v", tt.input, err) + } + if got != tt.expected { + t.Errorf("ExpandPath(%q) = %q; want %q", tt.input, got, tt.expected) + } + } +} From 09186887bdd328b078b20576b8864f9ed514a136 Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Mon, 31 Mar 2025 13:33:04 +0300 Subject: [PATCH 2/9] more logs --- README.md | 2 +- cmd/gcx/main.go | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 82b1e00..8dea849 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ You can download the pre-built binary from the [releases](https://github.com/sxw ### Install from source ```bash -go install github.com/sxwebdev/gcx@latest +go install github.com/sxwebdev/gcx/cmd/gcx@latest ``` ### Install via script diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index 0bd549b..25b9a84 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -744,6 +744,9 @@ func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[strin if err != nil { return fmt.Errorf("failed to expand key path: %w", err) } + + fmt.Println("use key path:", path) + auth, err = goph.Key(path, "") if err != nil { return fmt.Errorf("failed to load SSH key: %w", err) From 1dac5946fb4446efb97d8a46e36579d94efab69b Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Mon, 31 Mar 2025 15:05:39 +0300 Subject: [PATCH 3/9] update client --- cmd/gcx/main.go | 10 +++++++++- go.mod | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index 25b9a84..eca9bda 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -25,6 +25,7 @@ import ( "github.com/minio/minio-go/v7/pkg/credentials" "github.com/sxwebdev/gcx/internal/helpers" "github.com/urfave/cli/v2" + "golang.org/x/crypto/ssh" "gopkg.in/yaml.v3" ) @@ -753,7 +754,14 @@ func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[strin } } - client, err := goph.New(cfg.User, cfg.Server, auth) + client, err := goph.NewConn(&goph.Config{ + Auth: auth, + User: cfg.User, + Addr: cfg.Server, + Port: 22, + Timeout: goph.DefaultTimeout, + Callback: ssh.InsecureIgnoreHostKey(), + }) if err != nil { return fmt.Errorf("failed to create SSH client: %w", err) } diff --git a/go.mod b/go.mod index 5e7b39f..1da08fd 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/melbahja/goph v1.4.0 github.com/minio/minio-go/v7 v7.0.89 github.com/urfave/cli/v2 v2.27.6 + golang.org/x/crypto v0.36.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -30,7 +31,6 @@ require ( github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - golang.org/x/crypto v0.36.0 // indirect golang.org/x/net v0.38.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect From 07aae3fcee83736381042ace0ca7c3f480f00e43 Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Mon, 31 Mar 2025 16:10:22 +0300 Subject: [PATCH 4/9] revert --- cmd/gcx/main.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index eca9bda..25b9a84 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -25,7 +25,6 @@ import ( "github.com/minio/minio-go/v7/pkg/credentials" "github.com/sxwebdev/gcx/internal/helpers" "github.com/urfave/cli/v2" - "golang.org/x/crypto/ssh" "gopkg.in/yaml.v3" ) @@ -754,14 +753,7 @@ func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[strin } } - client, err := goph.NewConn(&goph.Config{ - Auth: auth, - User: cfg.User, - Addr: cfg.Server, - Port: 22, - Timeout: goph.DefaultTimeout, - Callback: ssh.InsecureIgnoreHostKey(), - }) + client, err := goph.New(cfg.User, cfg.Server, auth) if err != nil { return fmt.Errorf("failed to create SSH client: %w", err) } From 6484e0c0d82ae0eb7bd66496cd13ba096d3fcd11 Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Tue, 1 Apr 2025 08:14:26 +0300 Subject: [PATCH 5/9] fix --- cmd/gcx/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index 25b9a84..b3232e6 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -775,10 +775,10 @@ func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[strin continue } localFilePath := filepath.Join(artifactsDir, file.Name()) - remotePath := filepath.Join(remoteDir, file.Name()) - log.Printf("Uploading %s to %s:%s", localFilePath, cfg.Server, remotePath) + // remotePath := filepath.Join(remoteDir, file.Name()) + log.Printf("Uploading %s to %s:%s", localFilePath, cfg.Server, remoteDir) - if err := client.Upload(localFilePath, remotePath); err != nil { + if err := client.Upload(localFilePath, remoteDir); err != nil { return fmt.Errorf("failed to upload file %s: %w", localFilePath, err) } } From df31858f523f89230f5f69f5a4dc391a1d8f8a6a Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Tue, 1 Apr 2025 08:37:15 +0300 Subject: [PATCH 6/9] revert fix --- cmd/gcx/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index b3232e6..25b9a84 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -775,10 +775,10 @@ func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[strin continue } localFilePath := filepath.Join(artifactsDir, file.Name()) - // remotePath := filepath.Join(remoteDir, file.Name()) - log.Printf("Uploading %s to %s:%s", localFilePath, cfg.Server, remoteDir) + remotePath := filepath.Join(remoteDir, file.Name()) + log.Printf("Uploading %s to %s:%s", localFilePath, cfg.Server, remotePath) - if err := client.Upload(localFilePath, remoteDir); err != nil { + if err := client.Upload(localFilePath, remotePath); err != nil { return fmt.Errorf("failed to upload file %s: %w", localFilePath, err) } } From 0fdf11d512d907c35b8a713e590b9d62b60a5889 Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Tue, 1 Apr 2025 09:17:47 +0300 Subject: [PATCH 7/9] added known_hosts creationsupport --- cmd/gcx/main.go | 37 +++++++++++++++++++++++++++++++++++++ go.mod | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index 25b9a84..c44ce0d 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -732,6 +732,43 @@ func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[strin } remoteDir := dirBuffer.String() + // Check if known_hosts file exists and create it if it doesn't + knownHostsPath, err := helpers.ExpandPath("~/.ssh/known_hosts") + if err != nil { + return fmt.Errorf("failed to expand known hosts path: %w", err) + } + + if _, err := os.Stat(knownHostsPath); os.IsNotExist(err) { + // Create ~/.ssh directory if it doesn't exist + sshDir := filepath.Dir(knownHostsPath) + if err := os.MkdirAll(sshDir, 0o700); err != nil { + return fmt.Errorf("failed to create .ssh directory: %w", err) + } + + // Create empty known_hosts file + if err := os.WriteFile(knownHostsPath, []byte{}, 0o600); err != nil { + return fmt.Errorf("failed to create known_hosts file: %w", err) + } + + // Run ssh-keyscan to add the server to known_hosts + cmd := exec.Command("ssh-keyscan", "-H", cfg.Server) + output, err := cmd.Output() + if err != nil { + return fmt.Errorf("ssh-keyscan failed: %w", err) + } + + // Append the output to the known_hosts file + f, err := os.OpenFile(knownHostsPath, os.O_APPEND|os.O_WRONLY, 0o600) + if err != nil { + return fmt.Errorf("failed to open known_hosts file: %w", err) + } + defer f.Close() + + if _, err := f.Write(output); err != nil { + return fmt.Errorf("failed to write to known_hosts file: %w", err) + } + } + // Create SSH client var auth goph.Auth if cfg.KeyRaw != "" { diff --git a/go.mod b/go.mod index 1da08fd..5e7b39f 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/melbahja/goph v1.4.0 github.com/minio/minio-go/v7 v7.0.89 github.com/urfave/cli/v2 v2.27.6 - golang.org/x/crypto v0.36.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -31,6 +30,7 @@ require ( github.com/rs/xid v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect + golang.org/x/crypto v0.36.0 // indirect golang.org/x/net v0.38.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect From 5243411a51a5d9a984ceb096f8112f4a84e150c7 Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Tue, 1 Apr 2025 11:45:04 +0300 Subject: [PATCH 8/9] added insecure_ignore_host_key --- README.md | 3 ++ cmd/gcx/main.go | 81 +++++++++++++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 8dea849..caa466a 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ blobs: server: "stage.example.com" user: "deployer" key_path: "~/.ssh/deploy_key" + insecure_ignore_host_key: false directory: "/var/www/releases/{{.Version}}" # Deployment configuration @@ -154,6 +155,7 @@ deploys: server: "prod.example.com" user: "deployer" key_path: "~/.ssh/deploy_key" + insecure_ignore_host_key: false commands: - systemctl stop myapp - cp /var/www/releases/myapp/latest/myapp /usr/local/bin/ @@ -171,6 +173,7 @@ deploys: server: "staging.example.com" user: "deployer" key_path: "~/.ssh/deploy_key" + insecure_ignore_host_key: true commands: - docker-compose -f /opt/myapp/docker-compose.yml down - cp /var/www/releases/myapp/latest/myapp /opt/myapp/ diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index c44ce0d..81b5495 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -84,9 +84,10 @@ type BlobConfig struct { Region string `yaml:"region,omitempty"` Endpoint string `yaml:"endpoint,omitempty"` // SSH config fields - Server string `yaml:"server,omitempty"` - User string `yaml:"user,omitempty"` - KeyPath string `yaml:"key_path,omitempty"` + Server string `yaml:"server,omitempty"` + User string `yaml:"user,omitempty"` + KeyPath string `yaml:"key_path,omitempty"` + InsecureIgnoreHostKey bool `yaml:"insecure_ignore_host_key,omitempty"` // Common fields Directory string `yaml:"directory"` } @@ -95,11 +96,12 @@ type DeployConfig struct { Name string `yaml:"name"` Provider string `yaml:"provider"` // SSH config fields - Server string `yaml:"server,omitempty"` - User string `yaml:"user,omitempty"` - KeyPath string `yaml:"key_path,omitempty"` - KeyRaw string `yaml:"key_raw,omitempty"` - Commands []string `yaml:"commands"` + Server string `yaml:"server,omitempty"` + User string `yaml:"user,omitempty"` + KeyPath string `yaml:"key_path,omitempty"` + KeyRaw string `yaml:"key_raw,omitempty"` + InsecureIgnoreHostKey bool `yaml:"insecure_ignore_host_key,omitempty"` + Commands []string `yaml:"commands"` // Alert configuration Alerts AlertConfig `yaml:"alerts,omitempty"` } @@ -136,11 +138,12 @@ func (c *BlobConfig) ToSSHConfig() *SSHPublishConfig { return nil } return &SSHPublishConfig{ - Name: c.Name, - Server: c.Server, - User: c.User, - KeyPath: c.KeyPath, - Directory: c.Directory, + Name: c.Name, + Server: c.Server, + User: c.User, + KeyPath: c.KeyPath, + InsecureIgnoreHostKey: c.InsecureIgnoreHostKey, + Directory: c.Directory, } } @@ -150,11 +153,13 @@ func (c *DeployConfig) ToSSHDeployConfig() *SSHDeployConfig { return nil } return &SSHDeployConfig{ - Name: c.Name, - Server: c.Server, - User: c.User, - KeyPath: c.KeyPath, - Commands: c.Commands, + Name: c.Name, + Server: c.Server, + User: c.User, + KeyPath: c.KeyPath, + KeyRaw: c.KeyRaw, + InsecureIgnoreHostKey: c.InsecureIgnoreHostKey, + Commands: c.Commands, } } @@ -167,12 +172,13 @@ type S3Config struct { } type SSHPublishConfig struct { - Name string - Server string - User string - KeyPath string - KeyRaw string - Directory string + Name string + Server string + User string + KeyPath string + KeyRaw string + InsecureIgnoreHostKey bool + Directory string } // Validate checks if the SSHConfig is valid @@ -200,12 +206,13 @@ func (c *SSHPublishConfig) Validate() error { // Internal config types for type safety type SSHDeployConfig struct { - Name string - Server string - User string - KeyPath string - KeyRaw string - Commands []string + Name string + Server string + User string + KeyPath string + KeyRaw string + InsecureIgnoreHostKey bool + Commands []string } // Validate checks if the SSHCSSHDeployConfigonfig is valid @@ -790,9 +797,17 @@ func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[strin } } - client, err := goph.New(cfg.User, cfg.Server, auth) - if err != nil { - return fmt.Errorf("failed to create SSH client: %w", err) + var client *goph.Client + if cfg.InsecureIgnoreHostKey { + client, err = goph.NewUnknown(cfg.User, cfg.Server, auth) + if err != nil { + return fmt.Errorf("failed to create insecure SSH client: %w", err) + } + } else { + client, err = goph.New(cfg.User, cfg.Server, auth) + if err != nil { + return fmt.Errorf("failed to create SSH client: %w", err) + } } defer client.Close() From 50d97b3c9c13995a5ed80f76dd6e25865d4d8114 Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Tue, 1 Apr 2025 12:01:34 +0300 Subject: [PATCH 9/9] fix deploy --- cmd/gcx/main.go | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/cmd/gcx/main.go b/cmd/gcx/main.go index 81b5495..b092849 100644 --- a/cmd/gcx/main.go +++ b/cmd/gcx/main.go @@ -789,8 +789,6 @@ func publishToSSH(cfg *SSHPublishConfig, artifactsDir string, tmplData map[strin return fmt.Errorf("failed to expand key path: %w", err) } - fmt.Println("use key path:", path) - auth, err = goph.Key(path, "") if err != nil { return fmt.Errorf("failed to load SSH key: %w", err) @@ -1104,14 +1102,36 @@ func executeSSHDeploy(cfg *SSHDeployConfig) error { } // Create SSH client - auth, err := goph.Key(cfg.KeyPath, "") - if err != nil { - return fmt.Errorf("failed to load SSH key: %w", err) + var auth goph.Auth + var err error + if cfg.KeyRaw != "" { + auth, err = goph.RawKey(cfg.KeyRaw, "") + if err != nil { + return fmt.Errorf("failed to load SSH key: %w", err) + } + } else { + path, err := helpers.ExpandPath(cfg.KeyPath) + if err != nil { + return fmt.Errorf("failed to expand key path: %w", err) + } + + auth, err = goph.Key(path, "") + if err != nil { + return fmt.Errorf("failed to load SSH key: %w", err) + } } - client, err := goph.New(cfg.User, cfg.Server, auth) - if err != nil { - return fmt.Errorf("failed to create SSH client: %w", err) + var client *goph.Client + if cfg.InsecureIgnoreHostKey { + client, err = goph.NewUnknown(cfg.User, cfg.Server, auth) + if err != nil { + return fmt.Errorf("failed to create insecure SSH client: %w", err) + } + } else { + client, err = goph.New(cfg.User, cfg.Server, auth) + if err != nil { + return fmt.Errorf("failed to create SSH client: %w", err) + } } defer client.Close()