123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914 |
- package service
- import (
- "bytes"
- "context"
- "encoding/base64"
- "encoding/binary"
- json2 "encoding/json"
- "fmt"
- "reflect"
- "syscall"
- model2 "github.com/IceWhaleTech/CasaOS/service/model"
- types2 "github.com/IceWhaleTech/CasaOS/types"
- "github.com/containerd/containerd"
- "github.com/containerd/containerd/cio"
- "github.com/containerd/containerd/namespaces"
- "github.com/containerd/containerd/oci"
- "github.com/pkg/errors"
- "github.com/IceWhaleTech/CasaOS/model"
- "github.com/IceWhaleTech/CasaOS/pkg/docker"
- command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
- "github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
- "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
- loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
- //"github.com/containerd/containerd/oci"
- "io"
- "io/ioutil"
- "log"
- "os"
- "strconv"
- "strings"
- "time"
- "github.com/docker/docker/api/types"
- "github.com/docker/docker/api/types/container"
- "github.com/docker/docker/api/types/filters"
- "github.com/docker/docker/api/types/mount"
- "github.com/docker/docker/api/types/network"
- client2 "github.com/docker/docker/client"
- "github.com/docker/go-connections/nat"
- )
- type DockerService interface {
- DockerPullImage(imageName string, m model2.AppNotify) error
- IsExistImage(imageName string) bool
- DockerContainerCreate(imageName string, m model.CustomizationPostData, net string) (containerId string, err error)
- DockerContainerCopyCreate(info *types.ContainerJSON) (containerId string, err error)
- DockerContainerStart(name string) error
- DockerContainerStats(name string) (string, error)
- DockerListByName(name string) (*types.Container, error)
- DockerListByImage(image, version string) (*types.Container, error)
- DockerContainerInfo(name string) (*types.ContainerJSON, error)
- DockerImageRemove(name string) error
- DockerContainerRemove(name string, update bool) error
- DockerContainerStop(id string) error
- DockerContainerUpdateName(name, id string) (err error)
- DockerContainerUpdate(m model.CustomizationPostData, id string) (err error)
- DockerContainerLog(name string) (string, error)
- DockerContainerCommit(name string)
- DockerContainerList() []types.Container
- DockerNetworkModelList() []types.NetworkResource
- DockerImageInfo(image string) (types.ImageInspect, error)
- GetNetWorkNameByNetWorkID(id string) (string, error)
- ContainerExecShell(container_id string) string
- }
- type dockerService struct {
- rootDir string
- log loger2.OLog
- }
- func (ds *dockerService) DockerContainerList() []types.Container {
- cli, err := client2.NewClientWithOpts(client2.FromEnv, client2.WithTimeout(time.Second*5))
- if err != nil {
- return nil
- }
- defer cli.Close()
- containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
- if err != nil {
- return containers
- }
- return containers
- }
- func (ds *dockerService) ContainerExecShell(container_id string) string {
- cli, _ := client2.NewClientWithOpts(client2.FromEnv)
- exec, err := cli.ContainerExecCreate(context.Background(), container_id, types.ExecConfig{
- User: "1000:1000",
- Cmd: []string{"echo -e \"hellow\nworld\" >> /a.txt"},
- })
- if err != nil {
- os.Exit(5)
- }
- err = cli.ContainerExecStart(context.Background(), exec.ID, types.ExecStartCheck{})
- if err != nil {
- fmt.Println("exec script error ", err)
- }
- return exec.ID
- }
- //创建默认网络
- func DockerNetwork() {
- cli, _ := client2.NewClientWithOpts(client2.FromEnv)
- defer cli.Close()
- d, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{})
- for _, resource := range d {
- if resource.Name == docker.NETWORKNAME {
- return
- }
- }
- cli.NetworkCreate(context.Background(), docker.NETWORKNAME, types.NetworkCreate{})
- }
- //根据网络id获取网络名
- func (ds *dockerService) GetNetWorkNameByNetWorkID(id string) (string, error) {
- cli, _ := client2.NewClientWithOpts(client2.FromEnv)
- defer cli.Close()
- filter := filters.NewArgs()
- filter.Add("id", id)
- d, err := cli.NetworkList(context.Background(), types.NetworkListOptions{Filters: filter})
- if err == nil && len(d) > 0 {
- return d[0].Name, nil
- }
- return "", err
- }
- //拉取镜像
- func DockerPull() {
- cli, _ := client2.NewClientWithOpts(client2.FromEnv)
- defer cli.Close()
- authConfig := types.AuthConfig{}
- encodedJSON, err := json2.Marshal(authConfig)
- fmt.Println(err)
- authStr := base64.URLEncoding.EncodeToString(encodedJSON)
- reader, err := cli.ImagePull(context.Background(), "swr.cn-north-4.myhuaweicloud.com/root/swr-demo-2048:latest", types.ImagePullOptions{RegistryAuth: authStr})
- buf := new(bytes.Buffer)
- buf.ReadFrom(reader)
- fmt.Println(buf.String())
- }
- //拉取镜像
- func DockerEx() {
- cli, _ := client2.NewClientWithOpts(client2.FromEnv)
- defer cli.Close()
- importResponse, err := cli.ImageImport(context.Background(), types.ImageImportSource{
- Source: strings.NewReader("source"),
- SourceName: "image_source",
- }, "repository_name:imported", types.ImageImportOptions{
- Tag: "imported",
- Message: "A message",
- Changes: []string{"change1", "change2"},
- })
- response, err := ioutil.ReadAll(importResponse)
- if err != nil {
- fmt.Println(err)
- }
- importResponse.Close()
- println(string(response))
- if string(response) != "response" {
- fmt.Printf("expected response to contain 'response', got %s", string(response))
- }
- }
- //func DockerContainerSize() {
- // cli, err := client2.NewClientWithOpts(client2.FromEnv)
- // //but := bytes.Buffer{}
- // d, err := cli.ContainerExecCreate(context.Background(), "c3adcef92bae648890941ac00e6c4024d7f2959c2e629f0b581d6a19d77b5eda")
- // fmt.Println(d)
- // st, _ := ioutil.ReadAll(d.Body)
- // fmt.Println(string(st))
- // if err != nil {
- // fmt.Print(err)
- // }
- //
- //}
- func (ds *dockerService) DockerImageInfo(image string) (types.ImageInspect, error) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return types.ImageInspect{}, err
- }
- inspect, _, err := cli.ImageInspectWithRaw(context.Background(), image)
- if err != nil {
- return inspect, err
- }
- return inspect, nil
- }
- func MsqlExec(container string) error {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- ctx := context.Background()
- // 执行/bin/bash命令
- ir, err := cli.ContainerExecCreate(ctx, container, types.ExecConfig{
- AttachStdin: false,
- AttachStdout: true,
- AttachStderr: true,
- Cmd: []string{"date"},
- Tty: true,
- Env: []string{"aaa=ddd"},
- })
- err = cli.ContainerExecStart(ctx, ir.ID, types.ExecStartCheck{})
- fmt.Println(err)
- return err
- }
- func Exec(container, row, col string) (hr types.HijackedResponse, err error) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- ctx := context.Background()
- // 执行/bin/bash命令
- ir, err := cli.ContainerExecCreate(ctx, container, types.ExecConfig{
- AttachStdin: true,
- AttachStdout: true,
- AttachStderr: true,
- Env: []string{"COLUMNS=" + col, "LINES=" + row},
- Cmd: []string{"/bin/bash"},
- Tty: true,
- })
- if err != nil {
- return
- }
- // 附加到上面创建的/bin/bash进程中
- hr, err = cli.ContainerExecAttach(ctx, ir.ID, types.ExecStartCheck{Detach: false, Tty: true})
- if err != nil {
- return
- }
- return
- }
- func DockerLog() {
- //cli, err := client2.NewClientWithOpts(client2.FromEnv)
- //ctx := context.Background()
- //ir, err := cli.ContainerLogs(ctx, "79c6fa382c330b9149e2d28d24f4d2c231cdb8cfc0710c2d268ccee13c5b24f8", types.ContainerLogsOptions{})
- //str, err := ioutil.ReadAll(ir)
- //fmt.Println(string(str))
- //fmt.Println(err)
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- client, _ := client2.NewClientWithOpts(client2.FromEnv)
- reader, err := client.ContainerLogs(ctx, "79c6fa382c330b9149e2d28d24f4d2c231cdb8cfc0710c2d268ccee13c5b24f8", types.ContainerLogsOptions{})
- if err != nil {
- log.Fatal(err)
- }
- _, err = io.Copy(os.Stdout, reader)
- if err != nil && err != io.EOF {
- log.Fatal(err)
- }
- }
- func DockerLogs() {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- i, err := cli.ContainerLogs(context.Background(), "79c6fa382c330b9149e2d28d24f4d2c231cdb8cfc0710c2d268ccee13c5b24f8", types.ContainerLogsOptions{
- ShowStderr: true,
- ShowStdout: true,
- Timestamps: false,
- Follow: true,
- Tail: "40",
- })
- if err != nil {
- log.Fatal(err)
- }
- defer i.Close()
- hdr := make([]byte, 8)
- for {
- _, err := i.Read(hdr)
- if err != nil {
- log.Fatal(err)
- }
- var w io.Writer
- switch hdr[0] {
- case 1:
- w = os.Stdout
- default:
- w = os.Stderr
- }
- count := binary.BigEndian.Uint32(hdr[4:])
- dat := make([]byte, count)
- _, err = i.Read(dat)
- fmt.Fprint(w, string(dat))
- }
- }
- //正式内容
- //检查镜像是否存在
- func (ds *dockerService) IsExistImage(imageName string) bool {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return false
- }
- defer cli.Close()
- filter := filters.NewArgs()
- filter.Add("reference", imageName)
- list, err := cli.ImageList(context.Background(), types.ImageListOptions{Filters: filter})
- if err == nil && len(list) > 0 {
- return true
- }
- return false
- }
- //安装镜像
- func (ds *dockerService) DockerPullImage(imageName string, m model2.AppNotify) error {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- out, err := cli.ImagePull(context.Background(), imageName, types.ImagePullOptions{})
- if err != nil {
- return err
- }
- defer out.Close()
- if err != nil {
- return err
- }
- buf := make([]byte, 256)
- for {
- n, err := out.Read(buf)
- if err != nil {
- if err != io.EOF {
- fmt.Println("read error:", err)
- }
- break
- }
- if !reflect.DeepEqual(m, model2.AppNotify{}) {
- m.Type = types2.NOTIFY_TYPE_INSTALL_LOG
- m.State = 0
- m.Message = string(buf[:n])
- MyService.Notify().UpdateLog(m)
- }
- }
- return err
- }
- func (ds *dockerService) DockerContainerCopyCreate(info *types.ContainerJSON) (containerId string, err error) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return "", err
- }
- defer cli.Close()
- container, err := cli.ContainerCreate(context.Background(), info.Config, info.HostConfig, &network.NetworkingConfig{info.NetworkSettings.Networks}, nil, info.Name)
- if err != nil {
- return "", err
- }
- return container.ID, err
- }
- //param imageName 镜像名称
- //param containerDbId 数据库的id
- //param port 容器内部主端口
- //param mapPort 容器主端口映射到外部的端口
- //param tcp 容器其他tcp端口
- //param udp 容器其他udp端口
- func (ds *dockerService) DockerContainerCreate(imageName string, m model.CustomizationPostData, net string) (containerId string, err error) {
- if len(net) == 0 {
- net = "bridge"
- }
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return "", err
- }
- defer cli.Close()
- ports := make(nat.PortSet)
- portMaps := make(nat.PortMap)
- // ports[nat.Port(fmt.Sprint(m.PortMap)+"/tcp")] = struct{}{}
- // if net != "host" {
- // portMaps[nat.Port(fmt.Sprint(m.Port)+"/tcp")] = []nat.PortBinding{{HostIP: "", HostPort: m.PortMap}}
- // }
- //port := ""
- for _, portMap := range m.Ports {
- // if portMap.CommendPort == m.PortMap && portMap.Protocol == "tcp" || portMap.Protocol == "both" {
- // port = portMap.ContainerPort
- // }
- if portMap.Protocol == "tcp" {
- tContainer, _ := strconv.Atoi(portMap.ContainerPort)
- if tContainer > 0 {
- ports[nat.Port(portMap.ContainerPort+"/tcp")] = struct{}{}
- if net != "host" {
- portMaps[nat.Port(portMap.ContainerPort+"/tcp")] = []nat.PortBinding{{HostPort: portMap.CommendPort}}
- }
- }
- } else if portMap.Protocol == "both" {
- tContainer, _ := strconv.Atoi(portMap.ContainerPort)
- if tContainer > 0 {
- ports[nat.Port(portMap.ContainerPort+"/tcp")] = struct{}{}
- if net != "host" {
- portMaps[nat.Port(portMap.ContainerPort+"/tcp")] = []nat.PortBinding{{HostPort: portMap.CommendPort}}
- }
- }
- uContainer, _ := strconv.Atoi(portMap.ContainerPort)
- if uContainer > 0 {
- ports[nat.Port(portMap.ContainerPort+"/udp")] = struct{}{}
- if net != "host" {
- portMaps[nat.Port(portMap.ContainerPort+"/udp")] = []nat.PortBinding{{HostPort: portMap.CommendPort}}
- }
- }
- } else {
- uContainer, _ := strconv.Atoi(portMap.ContainerPort)
- if uContainer > 0 {
- ports[nat.Port(portMap.ContainerPort+"/udp")] = struct{}{}
- if net != "host" {
- portMaps[nat.Port(portMap.ContainerPort+"/udp")] = []nat.PortBinding{{HostPort: portMap.CommendPort}}
- }
- }
- }
- }
- var envArr []string
- for _, e := range m.Envs {
- if strings.HasPrefix(e.Value, "$") {
- envArr = append(envArr, e.Name+"="+env_helper.ReplaceDefaultENV(e.Value, MyService.System().GetTimeZone()))
- continue
- }
- if len(e.Value) > 0 {
- if e.Value == "port_map" {
- envArr = append(envArr, e.Name+"="+m.PortMap)
- continue
- }
- envArr = append(envArr, e.Name+"="+e.Value)
- }
- }
- res := container.Resources{}
- if m.CpuShares > 0 {
- res.CPUShares = m.CpuShares
- }
- if m.Memory > 0 {
- res.Memory = m.Memory << 20
- }
- for _, p := range m.Devices {
- if len(p.Path) > 0 {
- res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath, CgroupPermissions: "rwm"})
- }
- }
- hostConfingBind := []string{}
- // volumes bind
- volumes := []mount.Mount{}
- for _, v := range m.Volumes {
- path := v.Path
- if len(path) == 0 {
- path = docker.GetDir(m.Label, v.Path)
- if len(path) == 0 {
- continue
- }
- }
- path = strings.ReplaceAll(path, "$AppID", m.Label)
- //reg1 := regexp.MustCompile(`([^<>/\\\|:""\*\?]+\.\w+$)`)
- //result1 := reg1.FindAllStringSubmatch(path, -1)
- //if len(result1) == 0 {
- err = file.IsNotExistMkDir(path)
- if err != nil {
- ds.log.Error("mkdir error", err)
- continue
- }
- //}
- // else {
- // err = file.IsNotExistCreateFile(path)
- // if err != nil {
- // ds.log.Error("mkdir error", err)
- // continue
- // }
- // }
- volumes = append(volumes, mount.Mount{
- Type: mount.TypeBind,
- Source: path,
- Target: v.ContainerPath,
- })
- hostConfingBind = append(hostConfingBind, v.Path+":"+v.ContainerPath)
- }
- rp := container.RestartPolicy{}
- if len(m.Restart) > 0 {
- rp.Name = m.Restart
- }
- // healthTest := []string{}
- // if len(port) > 0 {
- // healthTest = []string{"CMD-SHELL", "curl -f http://localhost:" + port + m.Index + " || exit 1"}
- // }
- // health := &container.HealthConfig{
- // Test: healthTest,
- // StartPeriod: 0,
- // Retries: 1000,
- // }
- // fmt.Print(health)
- if len(m.HostName) == 0 {
- m.HostName = m.Label
- }
- config := &container.Config{
- Image: imageName,
- Labels: map[string]string{"origin": m.Origin, m.Origin: m.Origin, "casaos": "casaos"},
- Env: envArr,
- // Healthcheck: health,
- Hostname: m.HostName,
- Cmd: m.Cmd,
- }
- config.Labels["web"] = m.PortMap
- config.Labels["icon"] = m.Icon
- config.Labels["desc"] = m.Description
- config.Labels["index"] = m.Index
- config.Labels["custom_id"] = m.CustomId
- //config.Labels["order"] = strconv.Itoa(MyService.App().GetCasaOSCount() + 1)
- hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net), Privileged: m.Privileged, CapAdd: m.CapAdd}
- //if net != "host" {
- config.ExposedPorts = ports
- hostConfig.PortBindings = portMaps
- //}
- containerDb, err := cli.ContainerCreate(context.Background(),
- config,
- hostConfig,
- &network.NetworkingConfig{EndpointsConfig: map[string]*network.EndpointSettings{net: {NetworkID: "", Aliases: []string{}}}},
- nil,
- m.Label)
- if err != nil {
- return "", err
- }
- return containerDb.ID, err
- }
- //删除容器
- func (ds *dockerService) DockerContainerRemove(name string, update bool) error {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- err = cli.ContainerRemove(context.Background(), name, types.ContainerRemoveOptions{})
- //路径处理
- if !update {
- path := docker.GetDir(name, "/config")
- if !file.CheckNotExist(path) {
- file.RMDir(path)
- }
- }
- if err != nil {
- return err
- }
- return err
- }
- //删除镜像
- func (ds *dockerService) DockerImageRemove(name string) error {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- imageList, err := cli.ImageList(context.Background(), types.ImageListOptions{})
- imageId := ""
- Loop:
- for _, ig := range imageList {
- for _, i := range ig.RepoTags {
- if i == name {
- imageId = ig.ID
- break Loop
- }
- }
- }
- _, err = cli.ImageRemove(context.Background(), imageId, types.ImageRemoveOptions{})
- return err
- }
- func DockerImageRemove(name string) error {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- imageList, err := cli.ImageList(context.Background(), types.ImageListOptions{})
- imageId := ""
- Loop:
- for _, ig := range imageList {
- fmt.Println(ig.RepoDigests)
- fmt.Println(ig.Containers)
- for _, i := range ig.RepoTags {
- if i == name {
- imageId = ig.ID
- break Loop
- }
- }
- }
- _, err = cli.ImageRemove(context.Background(), imageId, types.ImageRemoveOptions{})
- return err
- }
- //停止镜像
- func (ds *dockerService) DockerContainerStop(id string) error {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- err = cli.ContainerStop(context.Background(), id, nil)
- return err
- }
- //启动容器
- func (ds *dockerService) DockerContainerStart(name string) error {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- err = cli.ContainerStart(context.Background(), name, types.ContainerStartOptions{})
- return err
- }
- //查看日志
- func (ds *dockerService) DockerContainerLog(name string) (string, error) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return "", err
- }
- defer cli.Close()
- body, err := cli.ContainerLogs(context.Background(), name, types.ContainerLogsOptions{ShowStderr: true, ShowStdout: true})
- if err != nil {
- return "", err
- }
- defer body.Close()
- content, err := ioutil.ReadAll(body)
- if err != nil {
- return "", err
- }
- return string(content), nil
- }
- func DockerContainerStats1() error {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- dss, err := cli.ContainerStats(context.Background(), "dockermysql", false)
- if err != nil {
- return err
- }
- defer dss.Body.Close()
- sts, err := ioutil.ReadAll(dss.Body)
- if err != nil {
- return err
- }
- fmt.Println(string(sts))
- return nil
- }
- //获取容器状态
- func (ds *dockerService) DockerContainerStats(name string) (string, error) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return "", err
- }
- defer cli.Close()
- dss, err := cli.ContainerStats(context.Background(), name, false)
- if err != nil {
- return "", err
- }
- defer dss.Body.Close()
- sts, err := ioutil.ReadAll(dss.Body)
- if err != nil {
- return "", err
- }
- return string(sts), nil
- }
- //备份容器
- func (ds *dockerService) DockerContainerCommit(name string) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- fmt.Println(err)
- }
- defer cli.Close()
- d, err := cli.ContainerInspect(context.Background(), name)
- dss, err := cli.ContainerCommit(context.Background(), name, types.ContainerCommitOptions{Reference: "test", Config: d.Config})
- if err != nil {
- fmt.Println(err)
- }
- fmt.Println(dss)
- }
- func (ds *dockerService) DockerListByName(name string) (*types.Container, error) {
- cli, _ := client2.NewClientWithOpts(client2.FromEnv)
- defer cli.Close()
- filter := filters.NewArgs()
- filter.Add("name", name)
- containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{Filters: filter})
- if err != nil {
- return &types.Container{}, err
- }
- if len(containers) == 0 {
- return &types.Container{}, errors.New("not found")
- }
- return &containers[0], nil
- }
- func (ds *dockerService) DockerListByImage(image, version string) (*types.Container, error) {
- cli, _ := client2.NewClientWithOpts(client2.FromEnv)
- defer cli.Close()
- filter := filters.NewArgs()
- filter.Add("ancestor", image+":"+version)
- containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{Filters: filter})
- if err != nil {
- return nil, err
- }
- if len(containers) == 0 {
- return nil, nil
- }
- return &containers[0], nil
- }
- //获取容器详情
- func (ds *dockerService) DockerContainerInfo(name string) (*types.ContainerJSON, error) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return &types.ContainerJSON{}, err
- }
- defer cli.Close()
- d, err := cli.ContainerInspect(context.Background(), name)
- if err != nil {
- return &types.ContainerJSON{}, err
- }
- return &d, nil
- }
- //更新容器
- //param shares cpu优先级
- //param containerDbId 数据库的id
- //param port 容器内部主端口
- //param mapPort 容器主端口映射到外部的端口
- //param tcp 容器其他tcp端口
- //param udp 容器其他udp端口
- func (ds *dockerService) DockerContainerUpdate(m model.CustomizationPostData, id string) (err error) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- //重启策略
- rp := container.RestartPolicy{
- Name: "",
- MaximumRetryCount: 0,
- }
- if len(m.Restart) > 0 {
- rp.Name = m.Restart
- }
- res := container.Resources{}
- if m.Memory > 0 {
- res.Memory = m.Memory * 1024 * 1024
- res.MemorySwap = -1
- }
- if m.CpuShares > 0 {
- res.CPUShares = m.CpuShares
- }
- for _, p := range m.Devices {
- res.Devices = append(res.Devices, container.DeviceMapping{PathOnHost: p.Path, PathInContainer: p.ContainerPath, CgroupPermissions: "rwm"})
- }
- _, err = cli.ContainerUpdate(context.Background(), id, container.UpdateConfig{RestartPolicy: rp, Resources: res})
- if err != nil {
- return err
- }
- return
- }
- //更新容器名称
- //param name 容器名称
- //param id 老的容器名称
- func (ds *dockerService) DockerContainerUpdateName(name, id string) (err error) {
- cli, err := client2.NewClientWithOpts(client2.FromEnv)
- if err != nil {
- return err
- }
- defer cli.Close()
- err = cli.ContainerRename(context.Background(), id, name)
- if err != nil {
- return err
- }
- return
- }
- //获取网络列表
- func (ds *dockerService) DockerNetworkModelList() []types.NetworkResource {
- cli, _ := client2.NewClientWithOpts(client2.FromEnv)
- defer cli.Close()
- networks, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{})
- return networks
- }
- func NewDockerService(log loger2.OLog) DockerService {
- return &dockerService{rootDir: command2.ExecResultStr(`source ./shell/helper.sh ;GetDockerRootDir`), log: log}
- }
- // ---------------------------------------test------------------------------------
- //func ServiceCreate() {
- // cli, err := client2.NewClientWithOpts(client2.FromEnv)
- // r, err := cli.ServiceCreate(context.Background(), swarm.ServiceSpec{}, types.ServiceCreateOptions{})
- // if err != nil {
- // fmt.Println("error", err)
- // }
- //
- //
- //}
- func Containerd() {
- // create a new client connected to the default socket path for containerd
- cli, err := containerd.New("/run/containerd/containerd.sock")
- if err != nil {
- fmt.Println("111")
- fmt.Println(err)
- }
- defer cli.Close()
- // create a new context with an "example" namespace
- ctx := namespaces.WithNamespace(context.Background(), "default")
- // pull the redis image from DockerHub
- image, err := cli.Pull(ctx, "docker.io/library/busybox:latest", containerd.WithPullUnpack)
- if err != nil {
- fmt.Println("222")
- fmt.Println(err)
- }
- // create a container
- container, err := cli.NewContainer(
- ctx,
- "test1",
- containerd.WithImage(image),
- containerd.WithNewSnapshot("redis-server-snapshot1", image),
- containerd.WithNewSpec(oci.WithImageConfig(image)),
- )
- if err != nil {
- fmt.Println(err)
- }
- defer container.Delete(ctx, containerd.WithSnapshotCleanup)
- // create a task from the container
- task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))
- if err != nil {
- fmt.Println(err)
- }
- defer task.Delete(ctx)
- // make sure we wait before calling start
- exitStatusC, err := task.Wait(ctx)
- if err != nil {
- fmt.Println(err)
- }
- // call start on the task to execute the redis server
- if err = task.Start(ctx); err != nil {
- fmt.Println(err)
- }
- fmt.Println("执行完成等待")
- // sleep for a lil bit to see the logs
- time.Sleep(3 * time.Second)
- // kill the process and get the exit status
- if err = task.Kill(ctx, syscall.SIGTERM); err != nil {
- fmt.Println(err)
- }
- // wait for the process to fully exit and print out the exit status
- status := <-exitStatusC
- code, _, err := status.Result()
- if err != nil {
- fmt.Println(err)
- }
- fmt.Printf("redis-server exited with status: %d\n", code)
- }
|