local.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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")
  29. if err != nil {
  30. log.Println(err)
  31. log.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
  32. return err
  33. } else {
  34. s := strings.Fields(string(out))
  35. if s[2] != "1" {
  36. _, err = RunCmd("sysctl -w net.ipv4.ip_forward=1")
  37. if err != nil {
  38. log.Println(err)
  39. log.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
  40. return err
  41. }
  42. }
  43. }
  44. return nil
  45. }
  46. func RunCmd(command string) (string, error) {
  47. args := strings.Fields(command)
  48. out, err := exec.Command(args[0], args[1:]...).Output()
  49. return string(out), err
  50. }
  51. func RunCmds(commands []string) error {
  52. var err error
  53. for _, command := range commands {
  54. args := strings.Fields(command)
  55. out, err := exec.Command(args[0], args[1:]...).Output()
  56. if string(out) != "" {
  57. log.Println(string(out))
  58. }
  59. if err != nil {
  60. return err
  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. _, err = RunCmd("systemctl enable [email protected]")
  154. if err != nil {
  155. log.Println("Error enabling [email protected]. Please investigate.")
  156. log.Println(err)
  157. }
  158. _, err = RunCmd("systemctl daemon-reload")
  159. if err != nil {
  160. log.Println("Error reloading system daemons. Please investigate.")
  161. log.Println(err)
  162. }
  163. _, err = RunCmd("systemctl enable netclient-" + network + ".timer")
  164. if err != nil {
  165. log.Println("Error enabling netclient.timer. Please investigate.")
  166. log.Println(err)
  167. }
  168. _, err = RunCmd("systemctl start netclient-" + network + ".timer")
  169. if err != nil {
  170. log.Println("Error starting netclient-" + network + ".timer. Please investigate.")
  171. log.Println(err)
  172. }
  173. return nil
  174. }
  175. func isOnlyService(network string) (bool, error) {
  176. isonly := false
  177. files, err := filepath.Glob("/etc/netclient/netconfig-*")
  178. if err != nil {
  179. return isonly, err
  180. }
  181. count := len(files)
  182. if count == 0 {
  183. isonly = true
  184. }
  185. return isonly, err
  186. }
  187. func RemoveSystemDServices(network string) error {
  188. //sysExec, err := exec.LookPath("systemctl")
  189. if !netclientutils.IsWindows() {
  190. fullremove, err := isOnlyService(network)
  191. if err != nil {
  192. log.Println(err)
  193. }
  194. if fullremove {
  195. _, err = RunCmd("systemctl disable [email protected]")
  196. if err != nil {
  197. log.Println("Error disabling [email protected]. Please investigate.")
  198. log.Println(err)
  199. }
  200. }
  201. _, err = RunCmd("systemctl daemon-reload")
  202. if err != nil {
  203. log.Println("Error stopping netclient-" + network + ".timer. Please investigate.")
  204. log.Println(err)
  205. }
  206. _, err = RunCmd("systemctl disable netclient-" + network + ".timer")
  207. if err != nil {
  208. log.Println("Error disabling netclient-" + network + ".timer. Please investigate.")
  209. log.Println(err)
  210. }
  211. if fullremove {
  212. if FileExists("/etc/systemd/system/[email protected]") {
  213. err = os.Remove("/etc/systemd/system/[email protected]")
  214. }
  215. }
  216. if FileExists("/etc/systemd/system/netclient-" + network + ".timer") {
  217. err = os.Remove("/etc/systemd/system/netclient-" + network + ".timer")
  218. }
  219. if err != nil {
  220. log.Println("Error removing file. Please investigate.")
  221. log.Println(err)
  222. }
  223. _, err = RunCmd("systemctl daemon-reload")
  224. if err != nil {
  225. log.Println("Error reloading system daemons. Please investigate.")
  226. log.Println(err)
  227. }
  228. _, err = RunCmd("systemctl reset-failed")
  229. if err != nil {
  230. log.Println("Error reseting failed system services. Please investigate.")
  231. log.Println(err)
  232. }
  233. return err
  234. }
  235. return nil
  236. }
  237. func WipeLocal(network string) error {
  238. cfg, err := config.ReadConfig(network)
  239. if err != nil {
  240. return err
  241. }
  242. nodecfg := cfg.Node
  243. ifacename := nodecfg.Interface
  244. home := netclientutils.GetNetclientPathSpecific()
  245. if FileExists(home + "netconfig-" + network) {
  246. _ = os.Remove(home + "netconfig-" + network)
  247. }
  248. if FileExists(home + "nettoken-" + network) {
  249. _ = os.Remove(home + "nettoken-" + network)
  250. }
  251. if FileExists(home + "secret-" + network) {
  252. _ = os.Remove(home + "secret-" + network)
  253. }
  254. if FileExists(home + "wgkey-" + network) {
  255. _ = os.Remove(home + "wgkey-" + network)
  256. }
  257. if FileExists(home + "nm-" + network + ".conf") {
  258. _ = os.Remove(home + "nm-" + network + ".conf")
  259. }
  260. if ifacename != "" {
  261. if netclientutils.IsWindows() {
  262. if err := RemoveWindowsConf(ifacename); err == nil {
  263. log.Println("removed Windows interface", ifacename)
  264. }
  265. } else {
  266. ipExec, err := exec.LookPath("ip")
  267. if err != nil {
  268. return err
  269. }
  270. out, err := RunCmd(ipExec + " link del " + ifacename)
  271. if err != nil {
  272. log.Println(out, err)
  273. }
  274. if nodecfg.PostDown != "" {
  275. runcmds := strings.Split(nodecfg.PostDown, "; ")
  276. err = RunCmds(runcmds)
  277. if err != nil {
  278. log.Println("Error encountered running PostDown: " + err.Error())
  279. }
  280. }
  281. }
  282. }
  283. return err
  284. }
  285. func HasNetwork(network string) bool {
  286. if netclientutils.IsWindows() {
  287. return FileExists(netclientutils.GetNetclientPathSpecific() + "netconfig-" + network)
  288. }
  289. return FileExists("/etc/systemd/system/netclient-"+network+".timer") ||
  290. FileExists(netclientutils.GetNetclientPathSpecific()+"netconfig-"+network)
  291. }
  292. func copy(src, dst string) (int64, error) {
  293. sourceFileStat, err := os.Stat(src)
  294. if err != nil {
  295. return 0, err
  296. }
  297. if !sourceFileStat.Mode().IsRegular() {
  298. return 0, errors.New(src + " is not a regular file")
  299. }
  300. source, err := os.Open(src)
  301. if err != nil {
  302. return 0, err
  303. }
  304. defer source.Close()
  305. destination, err := os.Create(dst)
  306. if err != nil {
  307. return 0, err
  308. }
  309. defer destination.Close()
  310. nBytes, err := io.Copy(destination, source)
  311. err = os.Chmod(dst, 0755)
  312. if err != nil {
  313. log.Println(err)
  314. }
  315. return nBytes, err
  316. }