Golang实现一个批量自动化执行树莓派指令的软件(5)模块整合

简介

基于上篇 Golang实现一个批量自动化执行树莓派指令的软件(4)上传 已经实现了ssh的基本操作模块了,这里我们将这些模块进行整合。

环境描述

运行环境 : Windows, 基于Golang, 暂时没有使用什么不可跨平台接口, 理论上支持Linux/MacOS
目标终端:树莓派DebianOS(主要做用它测试)

实现

接口定义

go 复制代码
/* SFTPClient接口,整合Downloader和Uploader */
type ISFTPClient interface {
	IDownloader
	IUploader

	Cancel() error
	Destroy() error
}

/* 整合所有ssh的基本操作模块 */
type ISSHUtil interface {
	Commander() ICommander
	SFTFClient() ISFTPClient
	Cancel() error
	Destroy() error
}

接口实现

sftpclient.go

go 复制代码
package sshutil

import (
	"fmt"
	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
)

type SFTPClient struct {
	IDownloader
	IUploader
	sftpClient *sftp.Client
}

func NewSFTPClient(sshClient *ssh.Client) (*SFTPClient, error) {
	var (
		sftpClient = &SFTPClient{}
		err        error
	)
	sftpClient.sftpClient, err = sftp.NewClient(sshClient)
	if nil != err {
		return nil, err
	}
	if sftpClient.IDownloader, err = newDownloader(sftpClient.sftpClient); nil != err {
		sftpClient.Destroy()
		return nil, err
	}
	if sftpClient.IUploader, err = newUploader(sftpClient.sftpClient); nil != err {
		sftpClient.Destroy()
		return nil, err
	}

	return sftpClient, nil
}

func (s *SFTPClient) Cancel() (err error) {
	if nil != s.IDownloader {
		if err = s.IDownloader.(*downloader).Cancel(); nil != err {
			fmt.Println("downloader cancel fail, ", err.Error())
		}
	}
	if nil != s.IUploader {
		if err = s.IUploader.(*uploader).Cancel(); nil != err {
			fmt.Println("uploader cancel fail, ", err.Error())
		}
	}
	err = nil
	return
}

func (s *SFTPClient) Destroy() (err error) {
	if nil != s.IDownloader {
		if err = s.IDownloader.(*downloader).Destroy(); nil != err {
			fmt.Println("downloader cancel fail, ", err.Error())
		}
		s.IDownloader = nil
	}
	if nil != s.IUploader {
		if err = s.IUploader.(*uploader).Destroy(); nil != err {
			fmt.Println("uploader destroy fail, ", err.Error())
		}
		s.IUploader = nil
	}
	if nil != s.sftpClient {
		if err = s.sftpClient.Close(); nil != err {
			fmt.Println("sftp client destroy fail, ", err.Error())
		}
		s.sftpClient = nil
	}
	err = nil
	return
}

sshutil.go

go 复制代码
package sshutil

import (
	"fmt"
	"golang.org/x/crypto/ssh"
	"net"
	"time"
)

type SSHUtil struct {
	commander  *Commander
	sftpClient *SFTPClient

	cfg SSHConfig
}

func NewSSHUtil(cfg SSHConfig) (*SSHUtil, error) {
	var (
		sshUtil = &SSHUtil{}
		err     error
	)
	sshUtil.cfg = cfg
	sshUtil.cfg.sshClientConfig = &ssh.ClientConfig{
		User: cfg.User,
		Auth: []ssh.AuthMethod{ssh.Password(cfg.Password)}, // 密码
		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
			return nil
		},
		Timeout: time.Duration(cfg.Timeout) * time.Second,
	}

	sshUtil.commander, err = NewCommander(sshUtil.cfg)
	if nil != err {
		sshUtil.Destroy()
		return nil, err
	}

	sshUtil.sftpClient, err = NewSFTPClient(sshUtil.commander.sshClient)
	if nil != err {
		sshUtil.Destroy()
		return nil, err
	}

	return sshUtil, err
}

func (s *SSHUtil) Commander() ICommander {
	return s.commander
}

func (s *SSHUtil) SFTFClient() ISFTPClient {
	return s.sftpClient
}

func (s *SSHUtil) Cancel() (err error) {
	if nil != s.commander {
		if err = s.commander.Cancel(); nil != err {
			fmt.Println("commander cancel fail, ", err.Error())
		}
	}

	if nil != s.sftpClient {
		if err = s.sftpClient.Cancel(); nil != err {
			fmt.Println("sftp client cancel fail, ", err.Error())
		}
	}

	err = nil
	return
}

func (s *SSHUtil) Destroy() (err error) {
	if nil != s.sftpClient {
		if err = s.sftpClient.Destroy(); nil != err {
			fmt.Println("sftp client destroy fail, ", err.Error())
		}
		s.sftpClient = nil
	}

	if nil != s.commander {
		if err = s.commander.Destroy(); nil != err {
			fmt.Println("commander destroy fail, ", err.Error())
		}
		s.commander = nil
	}

	err = nil
	return
}

测试用例

代码源

https://gitee.com/grayhsu/ssh_remote_access

其他

参考

相关推荐
就叫_这个吧2 小时前
Java递归方法实现面包屑导航
java·开发语言
fīɡЙtīиɡ ℡2 小时前
AI 应用系统设计
java·开发语言·人工智能
聪明蛋子哟3 小时前
Stagehand v3多语言SDK:Python/Go/Rust/Java下的浏览器自动化统一方案
python·golang·rust
今天AI了吗4 小时前
Python 基础语法(一):常量、变量、输入输出与运算符
开发语言·数据库·人工智能·python·sql·深度学习·机器学习
TELL5215 小时前
selenium webdriver 第二次初始化的异常
开发语言·python
动词ing5 小时前
【C语言】自定义函数+指针入门
c语言·开发语言·算法
重生之后端学习5 小时前
283. 移动零[简单]✅
开发语言·数据结构·算法·leetcode·职场和发展
动词ing6 小时前
【C语言】结构体+文件基础
c语言·开发语言·数据结构
caimouse6 小时前
ReactOS 窗口系统分析(7):分层窗口与绘制辅助 — layered.c + draw.c
c语言·开发语言
丰锋ff7 小时前
基于 Qt 的智慧社区物业管理系统
开发语言·qt