docker.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. package docker
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "gadmin/config"
  7. "gadmin/internal/admin/consts"
  8. "gadmin/internal/gorm/model"
  9. "gadmin/internal/gorm/query"
  10. "io"
  11. "net"
  12. "os"
  13. "strings"
  14. "time"
  15. "github.com/docker/docker/api/types"
  16. "github.com/docker/docker/client"
  17. "github.com/sirupsen/logrus"
  18. )
  19. // api文档
  20. // https://pkg.go.dev/github.com/docker/docker/client#Client.ContainerExecStart
  21. type PushDeployStopInput struct {
  22. Ctx context.Context
  23. Deploy *model.ServerDeploy
  24. Log *model.ServerDeployLog
  25. StopType int64
  26. }
  27. type PushDeployTaskInput struct {
  28. Ctx context.Context
  29. Deploy *model.ServerDeploy
  30. Log *model.ServerDeployLog
  31. DeployServ []string `json:"deployServ" form:"deployServ"` // 部署服务选项
  32. }
  33. type ReadDeployLogInput struct {
  34. Ctx context.Context
  35. Deploy *model.ServerDeploy
  36. LogFile string
  37. }
  38. type GraveProcessInput struct {
  39. Ctx context.Context
  40. Deploy *model.ServerDeploy
  41. }
  42. func getDeployScript(serverType string, publishType int32) (deployScript string) {
  43. var name string
  44. switch publishType {
  45. case consts.DeployPublishTypeStop:
  46. name = "stop"
  47. default:
  48. name = "deployment"
  49. }
  50. url := os.Getenv("DEPLOY_SH_URL")
  51. if os.Getenv("ADMIN_IS_LOCAL") == "1" {
  52. deployScript = url + serverType + "_" + name + "_local.sh"
  53. return
  54. }
  55. if os.Getenv("GIN_MODE") == "release" {
  56. deployScript = url + serverType + "_" + name + "_release.sh"
  57. return
  58. }
  59. if os.Getenv("GIN_MODE") == "debug" {
  60. deployScript = url + serverType + "_" + name + "_debug.sh"
  61. return
  62. }
  63. return
  64. }
  65. func findTemplate(packs []string, startServ []string, stopServ []string) []string {
  66. if len(packs) > 0 {
  67. return packs
  68. }
  69. if len(startServ) > 0 {
  70. return startServ
  71. }
  72. if len(stopServ) > 0 {
  73. return stopServ
  74. }
  75. return nil
  76. }
  77. func ParseDeployServArgs(serverType string, deployServ []string, isStartMpRoom int32) (string, string, string) {
  78. var packs []string
  79. var startServ []string
  80. var stopServ []string
  81. // _ = consts.DeployTypeLogin:
  82. //stopServ需要consts.DeployPackChapter
  83. if containsAll(deployServ) {
  84. serverType2 := strings.ToUpper(serverType)
  85. DownloadKey := fmt.Sprintf("DEPLOY_%v_DOWNLOAD", serverType2)
  86. StartKey := fmt.Sprintf("DEPLOY_%v_START", serverType2)
  87. StopKey := fmt.Sprintf("DEPLOY_%v_STOP", serverType2)
  88. tmp := os.Getenv(DownloadKey)
  89. if len(tmp) > 0 {
  90. packs = strings.Split(tmp, ",")
  91. }
  92. tmp = os.Getenv(StartKey)
  93. if len(tmp) > 0 {
  94. startServ = strings.Split(tmp, ",")
  95. }
  96. tmp = os.Getenv(StopKey)
  97. if len(tmp) > 0 {
  98. stopServ = strings.Split(tmp, ",")
  99. }
  100. // 允许只设一个的情况,找到这一个,并给其他赋值
  101. templateList := findTemplate(packs, startServ, stopServ)
  102. if len(templateList) == 0 {
  103. logrus.Errorln("parseDeployServArgs findTemplate found nil")
  104. return "", "", ""
  105. }
  106. if len(packs) == 0 {
  107. packs = templateList
  108. }
  109. if len(startServ) == 0 {
  110. startServ = templateList
  111. }
  112. if len(stopServ) == 0 {
  113. stopServ = templateList
  114. }
  115. if isStartMpRoom != consts.INTTRUE {
  116. tmps := make([]string, 0, len(startServ))
  117. for _, v := range startServ {
  118. if v == consts.DeployPackMPRoom {
  119. continue
  120. }
  121. tmps = append(tmps, v)
  122. }
  123. startServ = tmps
  124. }
  125. // switch serverType {
  126. // case consts.DeployTypeLogin:
  127. // packs = strings.Split(os.Getenv("DEPLOY_LOGIN_DOWNLOAD"), ",")
  128. // if len(packs) == 0 {
  129. // packs = append(packs, consts.DeployServLoginGroup...)
  130. // }
  131. // startServ = strings.Split(os.Getenv("DEPLOY_LOGIN_START"), ",")
  132. // if len(startServ) == 0 {
  133. // startServ = packs
  134. // }
  135. // stopServ = strings.Split(os.Getenv("DEPLOY_LOGIN_STOP"), ",")
  136. // if len(stopServ) == 0 {
  137. // stopServ = packs
  138. // }
  139. // case consts.DeployTypeGrave:
  140. // packs = strings.Split(os.Getenv("DEPLOY_GRAVE_DOWNLOAD"), ",")
  141. // if len(packs) == 0 {
  142. // packs = append(packs, consts.DeployServGraveGroup...)
  143. // }
  144. // startServ = strings.Split(os.Getenv("DEPLOY_GRAVE_START"), ",")
  145. // if len(startServ) == 0 {
  146. // startServ = packs
  147. // }
  148. // stopServ = strings.Split(os.Getenv("DEPLOY_GRAVE_STOP"), ",")
  149. // if len(stopServ) == 0 {
  150. // stopServ = packs
  151. // }
  152. // if isStartMpRoom != consts.INTTRUE {
  153. // tmps := make([]string, 0, len(startServ))
  154. // for _, v := range startServ {
  155. // if v == consts.DeployPackMPRoom {
  156. // continue
  157. // }
  158. // tmps = append(tmps, v)
  159. // }
  160. // startServ = tmps
  161. // }
  162. // // if isStartMpRoom == consts.StartDeployIsMPRoom {
  163. // // startServ = append(startServ, consts.DeployServGraveGroup...)
  164. // // } else {
  165. // // startServ = append(startServ, consts.DeployServGraveGroupNoMPRoom...)
  166. // // }
  167. // // stopServ = append(stopServ, consts.DeployServGraveGroup...)
  168. // // stopServ = append(stopServ, consts.DeployPackChapter)
  169. // // case consts.DeployTypeGate:
  170. // // startServ = append(startServ, consts.DeployServGateGroup...)
  171. // default:
  172. // // 处理未知的 serverType
  173. // logrus.Errorf("parseDeployServArgs containsAll default serverType:%+v, deployServ:%+v", serverType, deployServ)
  174. // return "", "", ""
  175. // }
  176. } else {
  177. startServ = append(startServ, deployServ...)
  178. stopServ = append(startServ, deployServ...)
  179. packs = append(packs, deployServ...)
  180. }
  181. return strings.Join(packs, ","), strings.Join(startServ, ","), strings.Join(stopServ, ",")
  182. }
  183. // // supplementGate 追加网关服务
  184. // func supplementGate(serv []string) []string {
  185. // gates := strings.Split(os.Getenv("DEPLOY_GRAVE_GATE"), ",")
  186. // lst := make([]string, 0, len(serv)+len(gates))
  187. // for _, v := range serv {
  188. // if v == "gate" {
  189. // for _, v2 := range gates {
  190. // if len(v2) > 0 {
  191. // lst = append(lst, v2)
  192. // }
  193. // }
  194. // } else {
  195. // lst = append(lst, v)
  196. // }
  197. // }
  198. // return lst
  199. // }
  200. func containsAll(arr []string) bool {
  201. for _, val := range arr {
  202. if val == "all" {
  203. return true
  204. }
  205. }
  206. return false
  207. }
  208. func PushDeployTask(in PushDeployTaskInput) (err error) {
  209. defer func() {
  210. var (
  211. ql = query.Use(config.DB).ServerDeployLog
  212. status = consts.DeployStatusIng
  213. errMsg = ""
  214. )
  215. if err != nil {
  216. status = consts.DeployStatusErr
  217. errMsg = err.Error()
  218. }
  219. _, err = query.Use(config.DB).ServerDeployLog.WithContext(in.Ctx).Where(ql.ID.Eq(in.Log.ID)).Updates(model.ServerDeployLog{
  220. ErrorMsg: errMsg,
  221. Status: status,
  222. EndAt: time.Now(),
  223. })
  224. if err != nil {
  225. logrus.Warningf("PushDeployTask ServerDeployLog Updates err:%+v", err)
  226. }
  227. }()
  228. packs, startServ, stopServ := ParseDeployServArgs(in.Deploy.ServerType, in.DeployServ, in.Deploy.IsMproom)
  229. if len(packs) == 0 || len(startServ) == 0 || len(stopServ) == 0 {
  230. err = errors.New("download pack is nil")
  231. logrus.Warningln("PushDeployTask ParseDeployServArgs list is nil")
  232. return
  233. }
  234. logrus.Infof("ParseDeployServArgs %+v", packs)
  235. cli, err := newStrictClient(in.Ctx, in.Deploy.DockerAddr, in.Deploy.CaPem, in.Deploy.CertPem, in.Deploy.KeyPem, in.Deploy.ContainerName)
  236. defer cli.Close()
  237. if err != nil {
  238. logrus.Warningf("PushDeployTask newStrictClient err:%+v", err)
  239. return
  240. }
  241. var (
  242. sh = "rm -rf deployment.sh && curl %s >> deployment.sh && chmod +x deployment.sh && ./deployment.sh %s %s %s %s %s %s %s %s %s"
  243. execSh = fmt.Sprintf(sh,
  244. getDeployScript(in.Deploy.ServerType, in.Log.PublishType), //curl
  245. in.Deploy.ContainerName, //appName
  246. in.Log.Version, //version
  247. in.Log.TraceID, //traceID
  248. os.Getenv("DEPLOY_ORIGIN_URL"), //originURL
  249. os.Getenv("DEPLOY_NOTIFY_URL"), //notifyURL
  250. os.Getenv("DEPLOY_MODE"), //mode
  251. packs, //packLstStr
  252. startServ, //serverListStr
  253. stopServ, //stopServerListStr
  254. )
  255. )
  256. logrus.Infof("ContainerExecCreate execSh:%+v", execSh)
  257. execResp, err := cli.ContainerExecCreate(in.Ctx, in.Deploy.ContainerName,
  258. types.ExecConfig{
  259. AttachStdin: true,
  260. AttachStdout: true,
  261. Cmd: []string{"sh", "-c", execSh},
  262. },
  263. )
  264. logrus.Infof("ContainerExecCreate execResp:%+v", execResp)
  265. resp, err := cli.ContainerExecAttach(in.Ctx, execResp.ID,
  266. types.ExecStartCheck{
  267. Detach: false,
  268. Tty: false,
  269. },
  270. )
  271. if err != nil {
  272. logrus.Warningf("ContainerExecAttach err:%+v", err)
  273. return
  274. }
  275. defer resp.Close()
  276. return
  277. }
  278. func PushDeployStop(in PushDeployStopInput) (err error) {
  279. defer func() {
  280. var (
  281. ql = query.Use(config.DB).ServerDeployLog
  282. status = consts.DeployStatusIng
  283. errMsg = ""
  284. )
  285. if err != nil {
  286. status = consts.DeployStatusErr
  287. errMsg = err.Error()
  288. }
  289. _, err = query.Use(config.DB).ServerDeployLog.WithContext(in.Ctx).Where(ql.DeployID.Eq(in.Log.ID)).Updates(model.ServerDeployLog{
  290. ErrorMsg: errMsg,
  291. Status: status,
  292. EndAt: time.Now(),
  293. })
  294. if err != nil {
  295. logrus.Warningf("PushDeployStop ServerDeployLog Updates err:%+v", err)
  296. }
  297. }()
  298. cli, err := newStrictClient(in.Ctx, in.Deploy.DockerAddr, in.Deploy.CaPem, in.Deploy.CertPem, in.Deploy.KeyPem, in.Deploy.ContainerName)
  299. defer cli.Close()
  300. if err != nil {
  301. logrus.Warningf("PushDeployStop newStrictClient err:%+v", err)
  302. return
  303. }
  304. stopCmd := fmt.Sprintf("rm -rf stop.sh && curl %s >> stop.sh && chmod +x stop.sh && ./stop.sh %s %v %s %s",
  305. getDeployScript(in.Deploy.ServerType, in.Log.PublishType),
  306. in.Deploy.ContainerName,
  307. in.StopType,
  308. in.Log.TraceID,
  309. os.Getenv("DEPLOY_NOTIFY_URL"),
  310. )
  311. logrus.Infof("PushDeployStop stopCmd:%+v", stopCmd)
  312. execResp, err := cli.ContainerExecCreate(in.Ctx, in.Deploy.ContainerName,
  313. types.ExecConfig{
  314. AttachStdin: true,
  315. AttachStdout: true,
  316. Cmd: []string{"sh", "-c", stopCmd},
  317. },
  318. )
  319. if err != nil {
  320. logrus.Errorf("PushDeployStop ContainerExecCreate err:%+v", err)
  321. return
  322. }
  323. logrus.Infof("PushDeployStop ContainerExecCreate execResp:%+v", execResp)
  324. resp, err := cli.ContainerExecAttach(in.Ctx, execResp.ID,
  325. types.ExecStartCheck{
  326. Detach: false,
  327. Tty: false,
  328. },
  329. )
  330. if err != nil {
  331. logrus.Errorf("PushDeployStop ContainerExecAttach err:%+v", err)
  332. return
  333. }
  334. defer resp.Close()
  335. return
  336. }
  337. func GetContainer(ctx context.Context, dockerAddr, caPem, certPem, keyPem, containerName string) (cr *types.Container, err error) {
  338. key := config.UKey("GetContainer", dockerAddr)
  339. if foo, found := config.Cache.Get(key); found {
  340. containers, ok := foo.([]types.Container)
  341. if !ok {
  342. err = errors.New("GetContainer 缓存数据断言失败!")
  343. }
  344. for _, container := range containers {
  345. if container.Names[0] == "/"+containerName {
  346. cr = &container
  347. break
  348. }
  349. }
  350. return
  351. }
  352. var cli client.APIClient
  353. if caPem == "" {
  354. cli, err = newAPIClient(dockerAddr)
  355. if err != nil {
  356. logrus.Warningf("newAPIClient err:%+v", err)
  357. return
  358. }
  359. } else {
  360. cli, err = newTLSAPIClient(dockerAddr, caPem, certPem, keyPem)
  361. if err != nil {
  362. logrus.Warningf("newTLSAPIClient err:%+v", err)
  363. return
  364. }
  365. }
  366. defer cli.Close()
  367. containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true})
  368. if err != nil {
  369. return
  370. }
  371. for _, container := range containers {
  372. if container.Names[0] == "/"+containerName {
  373. cr = &container
  374. break
  375. }
  376. }
  377. // 只保证在遍历列表时够用就行
  378. config.Cache.Set(key, containers, time.Second*3)
  379. return
  380. }
  381. func GetContainerList(ctx context.Context, dockerAddr, caPem, certPem, keyPem string) (containers []types.Container, err error) {
  382. var cli client.APIClient
  383. if caPem == "" {
  384. cli, err = newAPIClient(dockerAddr)
  385. if err != nil {
  386. logrus.Warningf("newAPIClient err:%+v", err)
  387. return
  388. }
  389. } else {
  390. cli, err = newTLSAPIClient(dockerAddr, caPem, certPem, keyPem)
  391. if err != nil {
  392. logrus.Warningf("newTLSAPIClient err:%+v", err)
  393. return
  394. }
  395. }
  396. defer cli.Close()
  397. containers, err = cli.ContainerList(ctx, types.ContainerListOptions{All: true})
  398. if err != nil {
  399. return
  400. }
  401. return
  402. }
  403. func newStrictClient(ctx context.Context, dockerAddr, caPem, certPem, keyPem, containerName string) (cli client.APIClient, err error) {
  404. if caPem == "" {
  405. cli, err = newAPIClient(dockerAddr)
  406. if err != nil {
  407. logrus.Warningf("newAPIClient err:%+v", err)
  408. return
  409. }
  410. } else {
  411. cli, err = newTLSAPIClient(dockerAddr, caPem, certPem, keyPem)
  412. if err != nil {
  413. logrus.Warningf("newTLSAPIClient err:%+v", err)
  414. return
  415. }
  416. }
  417. containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true})
  418. if err != nil {
  419. return
  420. }
  421. verify := false
  422. for _, container := range containers {
  423. if container.Names[0] == "/"+containerName {
  424. verify = true
  425. if "running" != container.State {
  426. err = errors.New(fmt.Sprintf("容器没有运行,当前状态:%v", container.State))
  427. return
  428. }
  429. break
  430. }
  431. }
  432. if !verify {
  433. err = errors.New(fmt.Sprintf("docker中没有找到容器:%v", containerName))
  434. return
  435. }
  436. return
  437. }
  438. func ReadDeployLog(in ReadDeployLogInput) (b []byte, err error) {
  439. if in.LogFile == "" {
  440. err = errors.New("没有找到日志路径")
  441. return
  442. }
  443. cli, err := newStrictClient(in.Ctx, in.Deploy.DockerAddr, in.Deploy.CaPem, in.Deploy.CertPem, in.Deploy.KeyPem, in.Deploy.ContainerName)
  444. defer cli.Close()
  445. if err != nil {
  446. logrus.Warningf("ReadDeployLog newStrictClient err:%+v", err)
  447. return
  448. }
  449. var sh = `cat %s`
  450. execResp, err := cli.ContainerExecCreate(in.Ctx, in.Deploy.ContainerName,
  451. types.ExecConfig{
  452. AttachStdin: true,
  453. AttachStdout: true,
  454. Cmd: []string{"sh", "-c", fmt.Sprintf(sh, in.LogFile)},
  455. },
  456. )
  457. logrus.Infof("readDeploymentLog ContainerExecCreate execResp:%+v", execResp)
  458. resp, err := cli.ContainerExecAttach(in.Ctx, execResp.ID,
  459. types.ExecStartCheck{
  460. Detach: false,
  461. Tty: false,
  462. },
  463. )
  464. if err != nil {
  465. logrus.Warningf("readDeploymentLog ContainerExecAttach err:%+v", err)
  466. return
  467. }
  468. defer resp.Close()
  469. return io.ReadAll(resp.Reader)
  470. }
  471. // 获取容器内运行的进程
  472. func GetGraveProcess(in GraveProcessInput) (b []byte, err error) {
  473. logrus.Infof("GetGraveProcess Start...")
  474. cli, err := newStrictClient(in.Ctx, in.Deploy.DockerAddr, in.Deploy.CaPem, in.Deploy.CertPem, in.Deploy.KeyPem, in.Deploy.ContainerName)
  475. defer cli.Close()
  476. if err != nil {
  477. logrus.Warningf("GetGraveProcess newStrictClient err:%+v", err)
  478. return
  479. }
  480. cmd := fmt.Sprintf("ps -aux | grep %s | grep -v grep | grep -v deployment", in.Deploy.ContainerName)
  481. execConfig := types.ExecConfig{
  482. Cmd: []string{"sh", "-c", cmd},
  483. AttachStdout: true,
  484. AttachStderr: true,
  485. }
  486. execRes, err := cli.ContainerExecCreate(in.Ctx, in.Deploy.ContainerName, execConfig)
  487. if err != nil {
  488. logrus.WithField("method", "GetGraveProcess").Errorf("ContainerExecCreate Err:%+v", execRes)
  489. return nil, err
  490. }
  491. execStartCheck := types.ExecStartCheck{}
  492. hr, err := cli.ContainerExecAttach(in.Ctx, execRes.ID, execStartCheck)
  493. if err != nil {
  494. logrus.WithField("method", "GetGraveProcess").Errorf("ContainerExecAttach Err: %+v", err)
  495. return
  496. }
  497. defer hr.Close()
  498. //输出
  499. data, err := io.ReadAll(hr.Reader)
  500. if err != nil {
  501. logrus.WithField("method", "GetGraveProcess").Errorf("io.ReadAll Err: %+v", err)
  502. return
  503. }
  504. logrus.Infof("GetGraveProcess end.")
  505. return data, nil
  506. }
  507. func RetryGraveProcess(in GraveProcessInput, maxRetry, retry int) (b []byte, err error) {
  508. cli, err := newStrictClient(in.Ctx, in.Deploy.DockerAddr, in.Deploy.CaPem, in.Deploy.CertPem, in.Deploy.KeyPem, in.Deploy.ContainerName)
  509. if err != nil {
  510. logrus.Warningf("GetGraveProcess newStrictClient err:%+v", err)
  511. if maxRetry > 0 && retry < maxRetry {
  512. time.Sleep(time.Second * 2)
  513. retry++
  514. return RetryGraveProcess(in, maxRetry, retry)
  515. }
  516. return
  517. }
  518. var sh = `ps -aux | grep grave | grep -v grep | grep -v deployment`
  519. execResp, err := cli.ContainerExecCreate(in.Ctx, in.Deploy.ContainerName,
  520. types.ExecConfig{
  521. AttachStdin: true,
  522. AttachStdout: true,
  523. Cmd: []string{"sh", "-c", sh},
  524. },
  525. )
  526. logrus.Infof("GetGraveProcess ContainerExecCreate execResp:%+v", execResp)
  527. resp, err := cli.ContainerExecAttach(in.Ctx, execResp.ID,
  528. types.ExecStartCheck{
  529. Detach: false,
  530. Tty: false,
  531. },
  532. )
  533. if err != nil {
  534. logrus.Warningf("GetGraveProcess ContainerExecAttach err:%+v", err)
  535. if maxRetry > 0 && retry < maxRetry {
  536. time.Sleep(time.Second * 2)
  537. retry++
  538. return RetryGraveProcess(in, maxRetry, retry)
  539. }
  540. return
  541. }
  542. defer resp.Close()
  543. defer cli.Close()
  544. return io.ReadAll(resp.Reader)
  545. }
  546. func AuthZPluginTLS() {
  547. const (
  548. testDaemonHTTPSAddr = "tcp://119.91.150.156:13375"
  549. cacertPath = "/root/certs/119.91.150.156/pem/ca.pem"
  550. //serverCertPath = "../../testdata/https/server-cert.pem"
  551. //serverKeyPath = "../../testdata/https/server-key.pem"
  552. clientCertPath = "/root/certs/119.91.150.156/pem/client-cert.pem"
  553. clientKeyPath = "/root/certs/119.91.150.156/pem/client-key.pem"
  554. )
  555. ctx := context.Background()
  556. c, err := newTLSAPIClient(testDaemonHTTPSAddr, cacertPath, clientCertPath, clientKeyPath)
  557. defer c.Close()
  558. if err != nil {
  559. logrus.Warningf("newTLSAPIClient err:%+v", err)
  560. return
  561. }
  562. list, err := c.ContainerList(context.Background(), types.ContainerListOptions{})
  563. if err != nil {
  564. logrus.Warningf("ContainerList err:%+v", err)
  565. return
  566. }
  567. for i, container := range list {
  568. logrus.Warningf("ContainerList i:%v container:%+v \n\n", i, container)
  569. }
  570. //listImages(c)
  571. //
  572. vers, err := c.ServerVersion(ctx)
  573. if err != nil {
  574. logrus.Warningf("ServerVersion err:%+v", err)
  575. return
  576. }
  577. logrus.Warningf("ServerVersion vers:%+v", vers)
  578. //var sh = "rm -rf deployment.sh && curl http://mysql.facms.cn/sh/deployment.sh >> deployment.sh && chmod +x deployment.sh && ./deployment.sh %s %s %s"
  579. //var traceID = character.Md5Content([]byte(character.RandStringRunes(32)))
  580. //
  581. //execResp, err := c.ContainerExecCreate(ctx, "gadmin",
  582. // types.ExecConfig{
  583. // AttachStdin: true,
  584. // AttachStdout: true,
  585. // Cmd: []string{"sh", "-c", fmt.Sprintf(sh, "test123", "v1.6.2", traceID)},
  586. // },
  587. //)
  588. //
  589. //logrus.Infof("ContainerExecCreate execResp:%+v", execResp)
  590. //
  591. //resp, err := c.ContainerExecAttach(ctx, execResp.ID,
  592. // types.ExecStartCheck{
  593. // Detach: false,
  594. // Tty: false,
  595. // },
  596. //)
  597. //if err != nil {
  598. // logrus.Warningf("ContainerExecAttach err:%+v", err)
  599. // return
  600. //}
  601. //
  602. //defer resp.Close()
  603. //r, err := io.ReadAll(resp.Reader)
  604. //logrus.Warningf("ContainerExecAttach2 resCh got:%+v", string(r))
  605. //var (
  606. // waitCh = make(chan struct{})
  607. // resCh = make(chan struct {
  608. // content string
  609. // err error
  610. // }, 1)
  611. //)
  612. //
  613. //go func() {
  614. // close(waitCh)
  615. // defer close(resCh)
  616. // r, err := io.ReadAll(resp.Reader)
  617. //
  618. // resCh <- struct {
  619. // content string
  620. // err error
  621. // }{
  622. // content: string(r),
  623. // err: err,
  624. // }
  625. //}()
  626. //
  627. //<-waitCh
  628. //select {
  629. //case <-time.After(3 * time.Second):
  630. // logrus.Fatal("failed to read the content in time")
  631. //case got := <-resCh:
  632. //
  633. // logrus.Warningf("ContainerExecAttach resCh got:%+v", got)
  634. // //assert.NilError(t, got.err)
  635. // //
  636. // //// NOTE: using Contains because no-tty's stream contains UX information
  637. // //// like size, stream type.
  638. // //assert.Assert(t, is.Contains(got.content, expected))
  639. //}
  640. }
  641. func newTLSAPIClient(host, cacertPath, certPath, keyPath string) (client.APIClient, error) {
  642. dialer := &net.Dialer{
  643. KeepAlive: 30 * time.Second,
  644. Timeout: 30 * time.Second,
  645. }
  646. return client.NewClientWithOpts(
  647. client.WithTLSClientConfig(cacertPath, certPath, keyPath),
  648. client.WithDialContext(dialer.DialContext),
  649. client.WithHost(host),
  650. client.WithAPIVersionNegotiation(),
  651. )
  652. }
  653. func newAPIClient(host string) (client.APIClient, error) {
  654. dialer := &net.Dialer{
  655. KeepAlive: 30 * time.Second,
  656. Timeout: 30 * time.Second,
  657. }
  658. return client.NewClientWithOpts(
  659. client.WithDialContext(dialer.DialContext),
  660. client.WithHost(host),
  661. client.WithAPIVersionNegotiation(),
  662. )
  663. }