local.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package local
  2. import (
  3. //"github.com/davecgh/go-spew/spew"
  4. "errors"
  5. "io"
  6. "io/ioutil"
  7. "log"
  8. "os"
  9. "os/exec"
  10. "path/filepath"
  11. "runtime"
  12. "strings"
  13. "github.com/gravitl/netmaker/netclient/config"
  14. "github.com/gravitl/netmaker/netclient/netclientutils"
  15. )
  16. func SetIPForwarding() error {
  17. os := runtime.GOOS
  18. var err error
  19. switch os {
  20. case "linux":
  21. err = SetIPForwardingLinux()
  22. default:
  23. err = errors.New("This OS is not supported")
  24. }
  25. return err
  26. }
  27. func SetIPForwardingLinux() error {
  28. out, err := RunCmd("sysctl net.ipv4.ip_forward", true)
  29. if err != nil {
  30. log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
  31. return err
  32. } else {
  33. s := strings.Fields(string(out))
  34. if s[2] != "1" {
  35. _, err = RunCmd("sysctl -w net.ipv4.ip_forward=1", true)
  36. if err != nil {
  37. log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
  38. return err
  39. }
  40. }
  41. }
  42. return nil
  43. }
  44. func RunCmd(command string, printerr bool) (string, error) {
  45. args := strings.Fields(command)
  46. out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
  47. if err != nil && printerr {
  48. log.Println("error running command:",command)
  49. log.Println(string(out))
  50. }
  51. return string(out), err
  52. }
  53. func RunCmds(commands []string, printerr bool) error {
  54. var err error
  55. for _, command := range commands {
  56. args := strings.Fields(command)
  57. out, err := exec.Command(args[0], args[1:]...).CombinedOutput()
  58. if err != nil && printerr {
  59. log.Println("error running command:",command)
  60. log.Println(string(out))
  61. }
  62. }
  63. return err
  64. }
  65. func FileExists(f string) bool {
  66. info, err := os.Stat(f)
  67. if os.IsNotExist(err) {
  68. return false
  69. }
  70. return !info.IsDir()
  71. }
  72. func ConfigureSystemD(network string) error {
  73. /*
  74. path, err := os.Getwd()
  75. if err != nil {
  76. log.Println(err)
  77. return err
  78. }
  79. */
  80. //binarypath := path + "/netclient"
  81. if netclientutils.IsWindows() {
  82. return nil
  83. }
  84. dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
  85. if err != nil {
  86. return err
  87. }
  88. binarypath := dir + "/netclient"
  89. _, err = os.Stat("/etc/netclient")
  90. if os.IsNotExist(err) {
  91. os.Mkdir("/etc/netclient", 744)
  92. } else if err != nil {
  93. log.Println("couldnt find or create /etc/netclient")
  94. return err
  95. }
  96. if !FileExists("/usr/local/bin/netclient") {
  97. os.Symlink("/etc/netclient/netclient", "/usr/local/bin/netclient")
  98. /*
  99. _, err = copy(binarypath, "/usr/local/bin/netclient")
  100. if err != nil {
  101. log.Println(err)
  102. return err
  103. }
  104. */
  105. }
  106. if !FileExists("/etc/netclient/netclient") {
  107. _, err = copy(binarypath, "/etc/netclient/netclient")
  108. if err != nil {
  109. log.Println(err)
  110. return err
  111. }
  112. }
  113. systemservice := `[Unit]
  114. Description=Network Check
  115. Wants=netclient.timer
  116. [Service]
  117. Type=simple
  118. ExecStart=/etc/netclient/netclient checkin -n %i
  119. [Install]
  120. WantedBy=multi-user.target
  121. `
  122. systemtimer := `[Unit]
  123. Description=Calls the Netmaker Mesh Client Service
  124. `
  125. systemtimer = systemtimer + "Requires=netclient@" + network + ".service"
  126. systemtimer = systemtimer +
  127. `
  128. [Timer]
  129. `
  130. systemtimer = systemtimer + "Unit=netclient@" + network + ".service"
  131. systemtimer = systemtimer +
  132. `
  133. OnCalendar=*:*:0/30
  134. [Install]
  135. WantedBy=timers.target
  136. `
  137. servicebytes := []byte(systemservice)
  138. timerbytes := []byte(systemtimer)
  139. if !FileExists("/etc/systemd/system/[email protected]") {
  140. err = ioutil.WriteFile("/etc/systemd/system/[email protected]", servicebytes, 0644)
  141. if err != nil {
  142. log.Println(err)
  143. return err
  144. }
  145. }
  146. if !FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
  147. err = ioutil.WriteFile("/etc/systemd/system/netclient-"+network+".timer", timerbytes, 0644)
  148. if err != nil {
  149. log.Println(err)
  150. return err
  151. }
  152. }
  153. _, _ = RunCmd("systemctl enable [email protected]", true)
  154. _, _ = RunCmd("systemctl daemon-reload", true)
  155. _, _ = RunCmd("systemctl enable netclient-" + network + ".timer", true)
  156. _, _ = RunCmd("systemctl start netclient-" + network + ".timer", true)
  157. return nil
  158. }
  159. func isOnlyService(network string) (bool, error) {
  160. isonly := false
  161. files, err := filepath.Glob("/etc/netclient/netconfig-*")
  162. if err != nil {
  163. return isonly, err
  164. }
  165. count := len(files)
  166. if count == 0 {
  167. isonly = true
  168. }
  169. return isonly, err
  170. }
  171. func RemoveSystemDServices(network string) error {
  172. //sysExec, err := exec.LookPath("systemctl")
  173. if !netclientutils.IsWindows() {
  174. fullremove, err := isOnlyService(network)
  175. if err != nil {
  176. log.Println(err)
  177. }
  178. if fullremove {
  179. _, err = RunCmd("systemctl disable [email protected]", true)
  180. }
  181. _, _ = RunCmd("systemctl daemon-reload", true)
  182. if FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
  183. _, _ = RunCmd("systemctl disable netclient-" + network + ".timer", true)
  184. }
  185. if fullremove {
  186. if FileExists("/etc/systemd/system/[email protected]") {
  187. err = os.Remove("/etc/systemd/system/[email protected]")
  188. }
  189. }
  190. if FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
  191. err = os.Remove("/etc/systemd/system/netclient-" + network + ".timer")
  192. }
  193. if err != nil {
  194. log.Println("Error removing file. Please investigate.")
  195. log.Println(err)
  196. }
  197. _, _ = RunCmd("systemctl daemon-reload", true)
  198. _, _ = RunCmd("systemctl reset-failed", true)
  199. }
  200. return nil
  201. }
  202. func WipeLocal(network string) error {
  203. cfg, err := config.ReadConfig(network)
  204. if err != nil {
  205. return err
  206. }
  207. nodecfg := cfg.Node
  208. ifacename := nodecfg.Interface
  209. home := netclientutils.GetNetclientPathSpecific()
  210. if FileExists(home + "netconfig-" + network) {
  211. _ = os.Remove(home + "netconfig-" + network)
  212. }
  213. if FileExists(home + "nettoken-" + network) {
  214. _ = os.Remove(home + "nettoken-" + network)
  215. }
  216. if FileExists(home + "secret-" + network) {
  217. _ = os.Remove(home + "secret-" + network)
  218. }
  219. if FileExists(home + "wgkey-" + network) {
  220. _ = os.Remove(home + "wgkey-" + network)
  221. }
  222. if FileExists(home + "nm-" + network + ".conf") {
  223. _ = os.Remove(home + "nm-" + network + ".conf")
  224. }
  225. if ifacename != "" {
  226. if netclientutils.IsWindows() {
  227. if err = RemoveWindowsConf(ifacename); err == nil {
  228. log.Println("removed Windows interface", ifacename)
  229. }
  230. } else {
  231. ipExec, err := exec.LookPath("ip")
  232. if err != nil {
  233. return err
  234. }
  235. out, err := RunCmd(ipExec + " link del " + ifacename, false)
  236. dontprint := strings.Contains(out, "does not exist") || strings.Contains(out, "Cannot find device")
  237. if err != nil && !dontprint {
  238. log.Println("error running command:",ipExec + " link del " + ifacename)
  239. log.Println(out)
  240. }
  241. if nodecfg.PostDown != "" {
  242. runcmds := strings.Split(nodecfg.PostDown, "; ")
  243. _ = RunCmds(runcmds, false)
  244. }
  245. }
  246. }
  247. return err
  248. }
  249. func HasNetwork(network string) bool {
  250. if netclientutils.IsWindows() {
  251. return FileExists(netclientutils.GetNetclientPathSpecific() + "netconfig-" + network)
  252. }
  253. return FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
  254. FileExists(netclientutils.GetNetclientPathSpecific()+"netconfig-"+network)
  255. }
  256. func copy(src, dst string) (int64, error) {
  257. sourceFileStat, err := os.Stat(src)
  258. if err != nil {
  259. return 0, err
  260. }
  261. if !sourceFileStat.Mode().IsRegular() {
  262. return 0, errors.New(src + " is not a regular file")
  263. }
  264. source, err := os.Open(src)
  265. if err != nil {
  266. return 0, err
  267. }
  268. defer source.Close()
  269. destination, err := os.Create(dst)
  270. if err != nil {
  271. return 0, err
  272. }
  273. defer destination.Close()
  274. nBytes, err := io.Copy(destination, source)
  275. err = os.Chmod(dst, 0755)
  276. if err != nil {
  277. log.Println(err)
  278. }
  279. return nBytes, err
  280. }