|
| 1 | +package route |
| 2 | + |
| 3 | +import ( |
| 4 | + "encoding/json" |
| 5 | + "encoding/xml" |
| 6 | + "strconv" |
| 7 | + "time" |
| 8 | + |
| 9 | + "github.com/IceWhaleTech/CasaOS/model" |
| 10 | + "github.com/IceWhaleTech/CasaOS/model/system_app" |
| 11 | + "github.com/IceWhaleTech/CasaOS/pkg/config" |
| 12 | + "github.com/IceWhaleTech/CasaOS/pkg/docker" |
| 13 | + "github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper" |
| 14 | + "github.com/IceWhaleTech/CasaOS/pkg/utils/file" |
| 15 | + "github.com/IceWhaleTech/CasaOS/pkg/utils/port" |
| 16 | + "github.com/IceWhaleTech/CasaOS/service" |
| 17 | + model2 "github.com/IceWhaleTech/CasaOS/service/model" |
| 18 | + uuid "github.com/satori/go.uuid" |
| 19 | +) |
| 20 | + |
| 21 | +func InitFunction() { |
| 22 | + go checkSystemApp() |
| 23 | +} |
| 24 | + |
| 25 | +var syncIsExistence = false |
| 26 | + |
| 27 | +func installSyncthing(appId string) { |
| 28 | + |
| 29 | + var appInfo model.ServerAppList |
| 30 | + m := model.CustomizationPostData{} |
| 31 | + var dockerImage string |
| 32 | + var dockerImageVersion string |
| 33 | + |
| 34 | + appInfo = service.MyService.OAPI().GetServerAppInfo(appId) |
| 35 | + |
| 36 | + dockerImage = appInfo.Image |
| 37 | + |
| 38 | + if len(appInfo.ImageVersion) == 0 { |
| 39 | + dockerImageVersion = "latest" |
| 40 | + } |
| 41 | + |
| 42 | + if appInfo.NetworkModel != "host" { |
| 43 | + for i := 0; i < len(appInfo.Ports); i++ { |
| 44 | + if p, _ := strconv.Atoi(appInfo.Ports[i].ContainerPort); port.IsPortAvailable(p, appInfo.Ports[i].Protocol) { |
| 45 | + appInfo.Ports[i].CommendPort = strconv.Itoa(p) |
| 46 | + } else { |
| 47 | + if appInfo.Ports[i].Protocol == "tcp" { |
| 48 | + if p, err := port.GetAvailablePort("tcp"); err == nil { |
| 49 | + appInfo.Ports[i].CommendPort = strconv.Itoa(p) |
| 50 | + } |
| 51 | + } else if appInfo.Ports[i].Protocol == "upd" { |
| 52 | + if p, err := port.GetAvailablePort("udp"); err == nil { |
| 53 | + appInfo.Ports[i].CommendPort = strconv.Itoa(p) |
| 54 | + } |
| 55 | + } |
| 56 | + } |
| 57 | + |
| 58 | + if appInfo.Ports[i].Type == 0 { |
| 59 | + appInfo.PortMap = appInfo.Ports[i].CommendPort |
| 60 | + } |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + for i := 0; i < len(appInfo.Devices); i++ { |
| 65 | + if !file.CheckNotExist(appInfo.Devices[i].ContainerPath) { |
| 66 | + appInfo.Devices[i].Path = appInfo.Devices[i].ContainerPath |
| 67 | + } |
| 68 | + } |
| 69 | + if len(appInfo.Tip) > 0 { |
| 70 | + appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip) |
| 71 | + } |
| 72 | + |
| 73 | + for i := 0; i < len(appInfo.Volumes); i++ { |
| 74 | + appInfo.Volumes[i].Path = docker.GetDir("", appInfo.Volumes[i].ContainerPath) |
| 75 | + } |
| 76 | + appInfo.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20 |
| 77 | + |
| 78 | + id := uuid.NewV4().String() |
| 79 | + |
| 80 | + installLog := model2.AppNotify{} |
| 81 | + |
| 82 | + // step:下载镜像 |
| 83 | + err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog) |
| 84 | + if err != nil { |
| 85 | + //pull image error |
| 86 | + return |
| 87 | + } |
| 88 | + |
| 89 | + for !service.MyService.Docker().IsExistImage(dockerImage + ":" + dockerImageVersion) { |
| 90 | + time.Sleep(time.Second) |
| 91 | + } |
| 92 | + |
| 93 | + m.CpuShares = 50 |
| 94 | + m.Envs = appInfo.Envs |
| 95 | + m.Memory = int64(appInfo.MaxMemory) |
| 96 | + m.Origin = "system" |
| 97 | + m.PortMap = appInfo.PortMap |
| 98 | + m.Ports = appInfo.Ports |
| 99 | + m.Restart = "" |
| 100 | + m.Volumes = appInfo.Volumes |
| 101 | + |
| 102 | + containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, id, m, appInfo.NetworkModel) |
| 103 | + |
| 104 | + if err != nil { |
| 105 | + // create container error |
| 106 | + return |
| 107 | + } |
| 108 | + |
| 109 | + //step:start container |
| 110 | + err = service.MyService.Docker().DockerContainerStart(id) |
| 111 | + if err != nil { |
| 112 | + //start container error |
| 113 | + return |
| 114 | + } |
| 115 | + |
| 116 | + portsStr, _ := json.Marshal(appInfo.Ports) |
| 117 | + envsStr, _ := json.Marshal(appInfo.Envs) |
| 118 | + volumesStr, _ := json.Marshal(appInfo.Volumes) |
| 119 | + devicesStr, _ := json.Marshal(appInfo.Devices) |
| 120 | + //step: 保存数据到数据库 |
| 121 | + md := model2.AppListDBModel{ |
| 122 | + CustomId: id, |
| 123 | + Title: appInfo.Title, |
| 124 | + //ScreenshotLink: appInfo.ScreenshotLink, |
| 125 | + Slogan: appInfo.Tagline, |
| 126 | + Description: appInfo.Description, |
| 127 | + //Tags: appInfo.Tags, |
| 128 | + Icon: appInfo.Icon, |
| 129 | + Version: dockerImageVersion, |
| 130 | + ContainerId: containerId, |
| 131 | + Image: dockerImage, |
| 132 | + Index: appInfo.Index, |
| 133 | + PortMap: appInfo.PortMap, |
| 134 | + Label: appInfo.Title, |
| 135 | + EnableUPNP: false, |
| 136 | + Ports: string(portsStr), |
| 137 | + Envs: string(envsStr), |
| 138 | + Volumes: string(volumesStr), |
| 139 | + Position: true, |
| 140 | + NetModel: appInfo.NetworkModel, |
| 141 | + Restart: m.Restart, |
| 142 | + CpuShares: 50, |
| 143 | + Memory: int64(appInfo.MaxMemory), |
| 144 | + Devices: string(devicesStr), |
| 145 | + Origin: m.Origin, |
| 146 | + CreatedAt: strconv.FormatInt(time.Now().Unix(), 10), |
| 147 | + UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10), |
| 148 | + } |
| 149 | + service.MyService.App().SaveContainer(md) |
| 150 | + |
| 151 | + checkSystemApp() |
| 152 | +} |
| 153 | + |
| 154 | +// check if the system application is installed |
| 155 | +func checkSystemApp() { |
| 156 | + list := service.MyService.App().GetSystemAppList() |
| 157 | + for _, v := range *list { |
| 158 | + if v.Image == "linuxserver/syncthing" { |
| 159 | + syncIsExistence = true |
| 160 | + if config.SystemConfigInfo.SyncPort != v.Port { |
| 161 | + config.SystemConfigInfo.SyncPort = v.Port |
| 162 | + } |
| 163 | + var paths []model.PathMap |
| 164 | + json.Unmarshal([]byte(v.Volumes), &paths) |
| 165 | + path := "" |
| 166 | + for _, i := range paths { |
| 167 | + if i.ContainerPath == "/config" { |
| 168 | + path = docker.GetDir(v.CustomId, i.ContainerPath) + "config.xml" |
| 169 | + for i := 0; i < 10; i++ { |
| 170 | + if file.CheckNotExist(path) { |
| 171 | + time.Sleep(1 * time.Second) |
| 172 | + } else { |
| 173 | + break |
| 174 | + } |
| 175 | + } |
| 176 | + break |
| 177 | + } |
| 178 | + } |
| 179 | + content := file.ReadFullFile(path) |
| 180 | + syncConfig := &system_app.SyncConfig{} |
| 181 | + xml.Unmarshal(content, &syncConfig) |
| 182 | + config.SystemConfigInfo.SyncKey = syncConfig.Key |
| 183 | + } |
| 184 | + } |
| 185 | + if !syncIsExistence { |
| 186 | + installSyncthing("44") |
| 187 | + } |
| 188 | +} |
0 commit comments