docker.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. package service
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/base64"
  6. "encoding/binary"
  7. json2 "encoding/json"
  8. "fmt"
  9. model2 "github.com/IceWhaleTech/CasaOS/service/model"
  10. types2 "github.com/IceWhaleTech/CasaOS/types"
  11. "github.com/containerd/containerd"
  12. "github.com/containerd/containerd/cio"
  13. "github.com/containerd/containerd/namespaces"
  14. "github.com/containerd/containerd/oci"
  15. "syscall"
  16. "github.com/IceWhaleTech/CasaOS/model"
  17. "github.com/IceWhaleTech/CasaOS/pkg/docker"
  18. command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
  19. "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
  20. loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
  21. //"github.com/containerd/containerd/oci"
  22. "github.com/docker/docker/api/types"
  23. "github.com/docker/docker/api/types/container"
  24. "github.com/docker/docker/api/types/filters"
  25. "github.com/docker/docker/api/types/mount"
  26. "github.com/docker/docker/api/types/network"
  27. client2 "github.com/docker/docker/client"
  28. "github.com/docker/go-connections/nat"
  29. "io"
  30. "io/ioutil"
  31. "log"
  32. "os"
  33. "strconv"
  34. "strings"
  35. "time"
  36. )
  37. type DockerService interface {
  38. DockerPullImage(imageName string, m model2.AppNotify) error
  39. IsExistImage(imageName string) bool
  40. DockerContainerCreate(imageName string, containerDbId string, m model.CustomizationPostData, net string) (containerId string, err error)
  41. DockerContainerStart(name string) error
  42. DockerContainerStats(name string) (string, error)
  43. DockerListByName(name string) (*types.Container, error)
  44. DockerListByImage(image, version string) (*types.Container, error)
  45. DockerContainerInfo(name string) (*types.ContainerJSON, error)
  46. DockerImageRemove(name string) error
  47. DockerContainerRemove(name string) error
  48. DockerContainerStop(id string) error
  49. DockerContainerUpdate(m model.CustomizationPostData, id string) (err error)
  50. DockerContainerLog(name string) (string, error)
  51. DockerContainerCommit(name string)
  52. DockerNetworkModelList() []types.NetworkResource
  53. DockerImageInfo(image string)
  54. }
  55. type dockerService struct {
  56. rootDir string
  57. log loger2.OLog
  58. }
  59. func DockerPs() {
  60. cli, _ := client2.NewClientWithOpts(client2.FromEnv)
  61. containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
  62. if err != nil {
  63. os.Exit(5)
  64. }
  65. for _, container := range containers {
  66. fmt.Printf("%s %s\n", container.ID[:10], container.Image)
  67. }
  68. }
  69. //创建默认网络
  70. func DockerNetwork() {
  71. cli, _ := client2.NewClientWithOpts(client2.FromEnv)
  72. defer cli.Close()
  73. d, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{})
  74. for _, resource := range d {
  75. if resource.Name == docker.NETWORKNAME {
  76. return
  77. }
  78. }
  79. cli.NetworkCreate(context.Background(), docker.NETWORKNAME, types.NetworkCreate{})
  80. }
  81. //拉取镜像
  82. func DockerPull() {
  83. cli, _ := client2.NewClientWithOpts(client2.FromEnv)
  84. defer cli.Close()
  85. authConfig := types.AuthConfig{
  86. Username: "cn-north-4@M4OW0IULZ3U6PCQPBUZC",
  87. Password: "7390181a1565f90927bbd98038436b57d6ebc66a3828d7a11dfda42b9c19d91d",
  88. }
  89. encodedJSON, err := json2.Marshal(authConfig)
  90. fmt.Println(err)
  91. authStr := base64.URLEncoding.EncodeToString(encodedJSON)
  92. reader, err := cli.ImagePull(context.Background(), "swr.cn-north-4.myhuaweicloud.com/root/swr-demo-2048:latest", types.ImagePullOptions{RegistryAuth: authStr})
  93. buf := new(bytes.Buffer)
  94. buf.ReadFrom(reader)
  95. fmt.Println(buf.String())
  96. }
  97. //拉取镜像
  98. func DockerEx() {
  99. cli, _ := client2.NewClientWithOpts(client2.FromEnv)
  100. defer cli.Close()
  101. importResponse, err := cli.ImageImport(context.Background(), types.ImageImportSource{
  102. Source: strings.NewReader("source"),
  103. SourceName: "image_source",
  104. }, "repository_name:imported", types.ImageImportOptions{
  105. Tag: "imported",
  106. Message: "A message",
  107. Changes: []string{"change1", "change2"},
  108. })
  109. response, err := ioutil.ReadAll(importResponse)
  110. if err != nil {
  111. fmt.Println(err)
  112. }
  113. importResponse.Close()
  114. println(string(response))
  115. if string(response) != "response" {
  116. fmt.Println("expected response to contain 'response', got %s", string(response))
  117. }
  118. }
  119. //func DockerContainerSize() {
  120. // cli, err := client2.NewClientWithOpts(client2.FromEnv)
  121. // //but := bytes.Buffer{}
  122. // d, err := cli.ContainerExecCreate(context.Background(), "c3adcef92bae648890941ac00e6c4024d7f2959c2e629f0b581d6a19d77b5eda")
  123. // fmt.Println(d)
  124. // st, _ := ioutil.ReadAll(d.Body)
  125. // fmt.Println(string(st))
  126. // if err != nil {
  127. // fmt.Print(err)
  128. // }
  129. //
  130. //}
  131. func (ds *dockerService) DockerImageInfo(image string) {
  132. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  133. //but := bytes.Buffer{}
  134. d, b, err := cli.ImageInspectWithRaw(context.Background(), image)
  135. st, _ := json2.Marshal(d.Config)
  136. fmt.Println(string(st))
  137. fmt.Println("换行")
  138. fmt.Println(string(b))
  139. if err != nil {
  140. fmt.Print(err)
  141. }
  142. }
  143. func MsqlExec(container string) error {
  144. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  145. ctx := context.Background()
  146. // 执行/bin/bash命令
  147. ir, err := cli.ContainerExecCreate(ctx, container, types.ExecConfig{
  148. AttachStdin: false,
  149. AttachStdout: true,
  150. AttachStderr: true,
  151. Cmd: []string{"date"},
  152. Tty: true,
  153. Env: []string{"aaa=ddd"},
  154. })
  155. err = cli.ContainerExecStart(ctx, ir.ID, types.ExecStartCheck{})
  156. fmt.Println(err)
  157. return err
  158. }
  159. func Exec(container, row, col string) (hr types.HijackedResponse, err error) {
  160. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  161. ctx := context.Background()
  162. // 执行/bin/bash命令
  163. ir, err := cli.ContainerExecCreate(ctx, container, types.ExecConfig{
  164. AttachStdin: true,
  165. AttachStdout: true,
  166. AttachStderr: true,
  167. Env: []string{"COLUMNS=" + col, "LINES=" + row},
  168. Cmd: []string{"/bin/bash"},
  169. Tty: true,
  170. })
  171. if err != nil {
  172. return
  173. }
  174. // 附加到上面创建的/bin/bash进程中
  175. hr, err = cli.ContainerExecAttach(ctx, ir.ID, types.ExecStartCheck{Detach: false, Tty: true})
  176. if err != nil {
  177. return
  178. }
  179. return
  180. }
  181. func DockerLog() {
  182. //cli, err := client2.NewClientWithOpts(client2.FromEnv)
  183. //ctx := context.Background()
  184. //ir, err := cli.ContainerLogs(ctx, "79c6fa382c330b9149e2d28d24f4d2c231cdb8cfc0710c2d268ccee13c5b24f8", types.ContainerLogsOptions{})
  185. //str, err := ioutil.ReadAll(ir)
  186. //fmt.Println(string(str))
  187. //fmt.Println(err)
  188. ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  189. defer cancel()
  190. client, _ := client2.NewClientWithOpts(client2.FromEnv)
  191. reader, err := client.ContainerLogs(ctx, "79c6fa382c330b9149e2d28d24f4d2c231cdb8cfc0710c2d268ccee13c5b24f8", types.ContainerLogsOptions{})
  192. if err != nil {
  193. log.Fatal(err)
  194. }
  195. _, err = io.Copy(os.Stdout, reader)
  196. if err != nil && err != io.EOF {
  197. log.Fatal(err)
  198. }
  199. }
  200. func DockerLogs() {
  201. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  202. i, err := cli.ContainerLogs(context.Background(), "79c6fa382c330b9149e2d28d24f4d2c231cdb8cfc0710c2d268ccee13c5b24f8", types.ContainerLogsOptions{
  203. ShowStderr: true,
  204. ShowStdout: true,
  205. Timestamps: false,
  206. Follow: true,
  207. Tail: "40",
  208. })
  209. if err != nil {
  210. log.Fatal(err)
  211. }
  212. hdr := make([]byte, 8)
  213. for {
  214. _, err := i.Read(hdr)
  215. if err != nil {
  216. log.Fatal(err)
  217. }
  218. var w io.Writer
  219. switch hdr[0] {
  220. case 1:
  221. w = os.Stdout
  222. default:
  223. w = os.Stderr
  224. }
  225. count := binary.BigEndian.Uint32(hdr[4:])
  226. dat := make([]byte, count)
  227. _, err = i.Read(dat)
  228. fmt.Fprint(w, string(dat))
  229. }
  230. defer i.Close()
  231. }
  232. //正式内容
  233. //检查镜像是否存在
  234. func (ds *dockerService) IsExistImage(imageName string) bool {
  235. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  236. if err != nil {
  237. return false
  238. }
  239. defer cli.Close()
  240. filter := filters.NewArgs()
  241. filter.Add("reference", imageName)
  242. list, err := cli.ImageList(context.Background(), types.ImageListOptions{Filters: filter})
  243. if err == nil && len(list) > 0 {
  244. return true
  245. }
  246. return false
  247. }
  248. //安装镜像
  249. func (ds *dockerService) DockerPullImage(imageName string, m model2.AppNotify) error {
  250. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  251. if err != nil {
  252. return err
  253. }
  254. defer cli.Close()
  255. out, err := cli.ImagePull(context.Background(), imageName, types.ImagePullOptions{})
  256. if err != nil {
  257. return err
  258. }
  259. defer out.Close()
  260. if err != nil {
  261. return err
  262. }
  263. buf := make([]byte, 256)
  264. for {
  265. n, err := out.Read(buf)
  266. if err != nil {
  267. if err != io.EOF {
  268. fmt.Println("read error:", err)
  269. }
  270. break
  271. }
  272. m.Type = types2.NOTIFY_TYPE_INSTALL_LOG
  273. m.State = 0
  274. m.Speed = 70
  275. m.Message = string(buf[:n])
  276. MyService.Notify().UpdateLog(m)
  277. }
  278. return err
  279. }
  280. //param imageName 镜像名称
  281. //param containerDbId 数据库的id
  282. //param port 容器内部主端口
  283. //param mapPort 容器主端口映射到外部的端口
  284. //param tcp 容器其他tcp端口
  285. //param udp 容器其他udp端口
  286. func (ds *dockerService) DockerContainerCreate(imageName string, containerDbId string, m model.CustomizationPostData, net string) (containerId string, err error) {
  287. if len(net) == 0 {
  288. net = "oasis"
  289. }
  290. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  291. if err != nil {
  292. return "", err
  293. }
  294. defer cli.Close()
  295. ports := make(nat.PortSet)
  296. portMaps := make(nat.PortMap)
  297. // ports[nat.Port(fmt.Sprint(m.PortMap)+"/tcp")] = struct{}{}
  298. // if net != "host" {
  299. // portMaps[nat.Port(fmt.Sprint(m.Port)+"/tcp")] = []nat.PortBinding{{HostIP: "", HostPort: m.PortMap}}
  300. // }
  301. for _, portMap := range m.Ports {
  302. if portMap.Protocol == "tcp" {
  303. tContainer, _ := strconv.Atoi(portMap.ContainerPort)
  304. if tContainer > 0 {
  305. ports[nat.Port(portMap.ContainerPort+"/tcp")] = struct{}{}
  306. if net != "host" {
  307. portMaps[nat.Port(portMap.ContainerPort+"/tcp")] = []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: portMap.CommendPort}}
  308. }
  309. }
  310. } else if portMap.Protocol == "both" {
  311. tContainer, _ := strconv.Atoi(portMap.ContainerPort)
  312. if tContainer > 0 {
  313. ports[nat.Port(portMap.ContainerPort+"/tcp")] = struct{}{}
  314. if net != "host" {
  315. portMaps[nat.Port(portMap.ContainerPort+"/tcp")] = []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: portMap.CommendPort}}
  316. }
  317. }
  318. uContainer, _ := strconv.Atoi(portMap.ContainerPort)
  319. if uContainer > 0 {
  320. ports[nat.Port(portMap.ContainerPort+"/udp")] = struct{}{}
  321. if net != "host" {
  322. portMaps[nat.Port(portMap.ContainerPort+"/udp")] = []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: portMap.CommendPort}}
  323. }
  324. }
  325. } else {
  326. uContainer, _ := strconv.Atoi(portMap.ContainerPort)
  327. if uContainer > 0 {
  328. ports[nat.Port(portMap.ContainerPort+"/udp")] = struct{}{}
  329. if net != "host" {
  330. portMaps[nat.Port(portMap.ContainerPort+"/udp")] = []nat.PortBinding{{HostIP: "0.0.0.0", HostPort: portMap.CommendPort}}
  331. }
  332. }
  333. }
  334. }
  335. var envArr []string
  336. for _, e := range m.Envs {
  337. if len(e.Value) > 0 {
  338. if e.Value == "port_map" {
  339. envArr = append(envArr, e.Name+"="+m.PortMap)
  340. continue
  341. }
  342. envArr = append(envArr, e.Name+"="+e.Value)
  343. }
  344. }
  345. res := container.Resources{}
  346. if m.CpuShares > 0 {
  347. res.CPUShares = m.CpuShares
  348. }
  349. if m.Memory > 0 {
  350. res.Memory = m.Memory << 20
  351. }
  352. for _, p := range m.Devices {
  353. if len(p.Path) > 0 {
  354. res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath})
  355. }
  356. }
  357. // volumes bind
  358. volumes := []mount.Mount{}
  359. for _, v := range m.Volumes {
  360. path := v.Path
  361. if len(path) == 0 {
  362. path = docker.GetDir(containerDbId, v.ContainerPath)
  363. if len(path) == 0 {
  364. continue
  365. }
  366. }
  367. err := file.IsNotExistMkDir(path)
  368. if err != nil {
  369. ds.log.Error("mkdir error", err)
  370. continue
  371. }
  372. volumes = append(volumes, mount.Mount{
  373. Type: mount.TypeBind,
  374. Source: path,
  375. Target: v.ContainerPath,
  376. })
  377. }
  378. rp := container.RestartPolicy{}
  379. if len(m.Restart) > 0 {
  380. rp.Name = m.Restart
  381. }
  382. config := &container.Config{
  383. Image: imageName,
  384. Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin},
  385. Env: envArr,
  386. }
  387. hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net)}
  388. //if net != "host" {
  389. config.ExposedPorts = ports
  390. hostConfig.PortBindings = portMaps
  391. //}
  392. containerDb, err := cli.ContainerCreate(context.Background(),
  393. config,
  394. hostConfig,
  395. &network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{net: {NetworkID: "", Aliases: []string{}}}},
  396. nil,
  397. containerDbId)
  398. if err != nil {
  399. return "", err
  400. }
  401. return containerDb.ID, err
  402. }
  403. //删除容器
  404. func (ds *dockerService) DockerContainerRemove(name string) error {
  405. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  406. if err != nil {
  407. return err
  408. }
  409. defer cli.Close()
  410. err = cli.ContainerRemove(context.Background(), name, types.ContainerRemoveOptions{})
  411. //路径处理
  412. path := docker.GetDir(name, "/config")
  413. if !file.CheckNotExist(path) {
  414. file.RMDir(path)
  415. }
  416. if err != nil {
  417. return err
  418. }
  419. return err
  420. }
  421. //删除镜像
  422. func (ds *dockerService) DockerImageRemove(name string) error {
  423. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  424. if err != nil {
  425. return err
  426. }
  427. defer cli.Close()
  428. imageList, err := cli.ImageList(context.Background(), types.ImageListOptions{})
  429. imageId := ""
  430. Loop:
  431. for _, ig := range imageList {
  432. for _, i := range ig.RepoTags {
  433. if i == name {
  434. imageId = ig.ID
  435. break Loop
  436. }
  437. }
  438. }
  439. _, err = cli.ImageRemove(context.Background(), imageId, types.ImageRemoveOptions{})
  440. return err
  441. }
  442. func DockerImageRemove(name string) error {
  443. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  444. if err != nil {
  445. return err
  446. }
  447. defer cli.Close()
  448. imageList, err := cli.ImageList(context.Background(), types.ImageListOptions{})
  449. imageId := ""
  450. Loop:
  451. for _, ig := range imageList {
  452. fmt.Println(ig.RepoDigests)
  453. fmt.Println(ig.Containers)
  454. for _, i := range ig.RepoTags {
  455. if i == name {
  456. imageId = ig.ID
  457. break Loop
  458. }
  459. }
  460. }
  461. _, err = cli.ImageRemove(context.Background(), imageId, types.ImageRemoveOptions{})
  462. return err
  463. }
  464. //停止镜像
  465. func (ds *dockerService) DockerContainerStop(id string) error {
  466. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  467. if err != nil {
  468. return err
  469. }
  470. defer cli.Close()
  471. err = cli.ContainerStop(context.Background(), id, nil)
  472. return err
  473. }
  474. //启动容器
  475. func (ds *dockerService) DockerContainerStart(name string) error {
  476. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  477. if err != nil {
  478. return err
  479. }
  480. defer cli.Close()
  481. err = cli.ContainerStart(context.Background(), name, types.ContainerStartOptions{})
  482. return err
  483. }
  484. //查看日志
  485. func (ds *dockerService) DockerContainerLog(name string) (string, error) {
  486. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  487. if err != nil {
  488. return "", err
  489. }
  490. defer cli.Close()
  491. body, err := cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{ShowStderr: true, ShowStdout: true})
  492. if err != nil {
  493. return "", err
  494. }
  495. defer body.Close()
  496. content, err := ioutil.ReadAll(body)
  497. if err != nil {
  498. return "", err
  499. }
  500. return string(content), nil
  501. }
  502. func DockerContainerStats1() error {
  503. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  504. if err != nil {
  505. return err
  506. }
  507. defer cli.Close()
  508. dss, err := cli.ContainerStats(context.Background(), "dockermysql", false)
  509. if err != nil {
  510. return err
  511. }
  512. defer dss.Body.Close()
  513. sts, err := ioutil.ReadAll(dss.Body)
  514. if err != nil {
  515. return err
  516. }
  517. fmt.Println(string(sts))
  518. return nil
  519. }
  520. //获取容器状态
  521. func (ds *dockerService) DockerContainerStats(name string) (string, error) {
  522. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  523. if err != nil {
  524. return "", err
  525. }
  526. defer cli.Close()
  527. dss, err := cli.ContainerStats(context.Background(), name, false)
  528. if err != nil {
  529. return "", err
  530. }
  531. defer dss.Body.Close()
  532. sts, err := ioutil.ReadAll(dss.Body)
  533. if err != nil {
  534. return "", err
  535. }
  536. return string(sts), nil
  537. }
  538. //备份容器
  539. func (ds *dockerService) DockerContainerCommit(name string) {
  540. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  541. if err != nil {
  542. fmt.Println(err)
  543. }
  544. defer cli.Close()
  545. d, err := cli.ContainerInspect(context.Background(), name)
  546. dss, err := cli.ContainerCommit(context.Background(), name, types.ContainerCommitOptions{Reference: "test", Config: d.Config})
  547. if err != nil {
  548. fmt.Println(err)
  549. }
  550. fmt.Println(dss)
  551. }
  552. func (ds *dockerService) DockerListByName(name string) (*types.Container, error) {
  553. cli, _ := client2.NewClientWithOpts(client2.FromEnv)
  554. defer cli.Close()
  555. filter := filters.NewArgs()
  556. filter.Add("name", name)
  557. containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{Filters: filter})
  558. if err != nil {
  559. return &types.Container{}, err
  560. }
  561. return &containers[0], nil
  562. }
  563. func (ds *dockerService) DockerListByImage(image, version string) (*types.Container, error) {
  564. cli, _ := client2.NewClientWithOpts(client2.FromEnv)
  565. defer cli.Close()
  566. filter := filters.NewArgs()
  567. filter.Add("ancestor", image+":"+version)
  568. containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{Filters: filter})
  569. if err != nil {
  570. return nil, err
  571. }
  572. if len(containers) == 0 {
  573. return nil, nil
  574. }
  575. return &containers[0], nil
  576. }
  577. //获取容器详情
  578. func (ds *dockerService) DockerContainerInfo(name string) (*types.ContainerJSON, error) {
  579. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  580. if err != nil {
  581. return &types.ContainerJSON{}, err
  582. }
  583. defer cli.Close()
  584. d, err := cli.ContainerInspect(context.Background(), name)
  585. if err != nil {
  586. return &types.ContainerJSON{}, err
  587. }
  588. return &d, nil
  589. }
  590. //更新容器
  591. //param shares cpu优先级
  592. //param containerDbId 数据库的id
  593. //param port 容器内部主端口
  594. //param mapPort 容器主端口映射到外部的端口
  595. //param tcp 容器其他tcp端口
  596. //param udp 容器其他udp端口
  597. func (ds *dockerService) DockerContainerUpdate(m model.CustomizationPostData, id string) (err error) {
  598. cli, err := client2.NewClientWithOpts(client2.FromEnv)
  599. if err != nil {
  600. return err
  601. }
  602. defer cli.Close()
  603. //重启策略
  604. rp := container.RestartPolicy{
  605. Name: "",
  606. MaximumRetryCount: 0,
  607. }
  608. if len(m.Restart) > 0 {
  609. rp.Name = m.Restart
  610. }
  611. res := container.Resources{}
  612. if m.Memory > 0 {
  613. res.Memory = m.Memory * 1024 * 1024
  614. res.MemorySwap = -1
  615. }
  616. if m.CpuShares > 0 {
  617. res.CPUShares = m.CpuShares
  618. }
  619. for _, p := range m.Devices {
  620. res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath})
  621. }
  622. _, err = cli.ContainerUpdate(context.Background(), id, container.UpdateConfig{RestartPolicy: rp, Resources: res})
  623. if err != nil {
  624. return err
  625. }
  626. return
  627. }
  628. //获取网络列表
  629. func (ds *dockerService) DockerNetworkModelList() []types.NetworkResource {
  630. cli, _ := client2.NewClientWithOpts(client2.FromEnv)
  631. defer cli.Close()
  632. networks, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{})
  633. return networks
  634. }
  635. func NewDcokerService(log loger2.OLog) DockerService {
  636. return &dockerService{rootDir: command2.ExecResultStr(`source ./shell/helper.sh ;GetDockerRootDir`), log: log}
  637. }
  638. // ---------------------------------------test------------------------------------
  639. //func ServiceCreate() {
  640. // cli, err := client2.NewClientWithOpts(client2.FromEnv)
  641. // r, err := cli.ServiceCreate(context.Background(), swarm.ServiceSpec{}, types.ServiceCreateOptions{})
  642. // if err != nil {
  643. // fmt.Println("error", err)
  644. // }
  645. //
  646. //
  647. //}
  648. func Containerd() {
  649. // create a new client connected to the default socket path for containerd
  650. cli, err := containerd.New("/run/containerd/containerd.sock")
  651. if err != nil {
  652. fmt.Println("111")
  653. fmt.Println(err)
  654. }
  655. defer cli.Close()
  656. // create a new context with an "example" namespace
  657. ctx := namespaces.WithNamespace(context.Background(), "default")
  658. // pull the redis image from DockerHub
  659. image, err := cli.Pull(ctx, "docker.io/library/busybox:latest", containerd.WithPullUnpack)
  660. if err != nil {
  661. fmt.Println("222")
  662. fmt.Println(err)
  663. }
  664. // create a container
  665. container, err := cli.NewContainer(
  666. ctx,
  667. "test1",
  668. containerd.WithImage(image),
  669. containerd.WithNewSnapshot("redis-server-snapshot1", image),
  670. containerd.WithNewSpec(oci.WithImageConfig(image)),
  671. )
  672. if err != nil {
  673. fmt.Println("333")
  674. fmt.Println(err)
  675. }
  676. defer container.Delete(ctx, containerd.WithSnapshotCleanup)
  677. // create a task from the container
  678. task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))
  679. if err != nil {
  680. fmt.Println("444")
  681. fmt.Println(err)
  682. }
  683. defer task.Delete(ctx)
  684. // make sure we wait before calling start
  685. exitStatusC, err := task.Wait(ctx)
  686. if err != nil {
  687. fmt.Println(err)
  688. }
  689. // call start on the task to execute the redis server
  690. if err = task.Start(ctx); err != nil {
  691. fmt.Println("555")
  692. fmt.Println(err)
  693. }
  694. fmt.Println("执行完成等待")
  695. // sleep for a lil bit to see the logs
  696. time.Sleep(3 * time.Second)
  697. // kill the process and get the exit status
  698. if err = task.Kill(ctx, syscall.SIGTERM); err != nil {
  699. fmt.Println("666")
  700. fmt.Println(err)
  701. }
  702. // wait for the process to fully exit and print out the exit status
  703. status := <-exitStatusC
  704. code, _, err := status.Result()
  705. if err != nil {
  706. fmt.Println("777")
  707. fmt.Println(err)
  708. }
  709. fmt.Printf("redis-server exited with status: %d\n", code)
  710. }