windows.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package local
  2. import (
  3. "fmt"
  4. "io"
  5. "io/ioutil"
  6. "log"
  7. "net/http"
  8. "os"
  9. "strings"
  10. "github.com/gravitl/netmaker/netclient/netclientutils"
  11. )
  12. func IsWindowsWGInstalled() bool {
  13. out, err := RunCmd("wg help", true)
  14. if err != nil {
  15. return false
  16. }
  17. return strings.Contains(out, "Available subcommand")
  18. }
  19. func ApplyWindowsConf(confPath string) error {
  20. if _, err := RunCmd("wireguard.exe /installtunnelservice " + confPath, true); err != nil {
  21. return err
  22. }
  23. return nil
  24. }
  25. func RemoveWindowsConf(ifacename string) error {
  26. if _, err := RunCmd("wireguard.exe /uninstalltunnelservice " + ifacename, true); err != nil {
  27. return err
  28. }
  29. return nil
  30. }
  31. func writeServiceConfig() error {
  32. serviceConfigPath := netclientutils.GetNetclientPathSpecific() + "winsw.xml"
  33. scriptString := fmt.Sprintf(`<service>
  34. <id>netclient</id>
  35. <name>Netclient</name>
  36. <description>Connects Windows nodes to one or more Netmaker networks.</description>
  37. <executable>%v</executable>
  38. <log mode="roll"></log>
  39. </service>
  40. `, strings.Replace(netclientutils.GetNetclientPathSpecific()+"netclient.exe", `\\`, `\`, -1))
  41. if !FileExists(serviceConfigPath) {
  42. err := ioutil.WriteFile(serviceConfigPath, []byte(scriptString), 0644)
  43. if err != nil {
  44. return err
  45. }
  46. netclientutils.Log("wrote the daemon config file to the Netclient directory")
  47. }
  48. return nil
  49. }
  50. // == Daemon ==
  51. func StopWindowsDaemon() {
  52. netclientutils.Log("no networks detected, stopping Windows, Netclient daemon")
  53. // stop daemon, will not overwrite
  54. RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe stop`, true)
  55. }
  56. func RemoveWindowsDaemon() {
  57. // uninstall daemon, will not restart or start another
  58. RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe uninstall`, true)
  59. netclientutils.Log("uninstalled Windows, Netclient daemon")
  60. }
  61. func copyWinswOver() error {
  62. input, err := ioutil.ReadFile(".\\winsw.exe")
  63. if err != nil {
  64. netclientutils.Log("failed to find winsw.exe")
  65. return err
  66. }
  67. if err = ioutil.WriteFile(netclientutils.GetNetclientPathSpecific()+"winsw.exe", input, 0644); err != nil {
  68. netclientutils.Log("failed to copy winsw.exe to " + netclientutils.GetNetclientPath())
  69. return err
  70. }
  71. if err = os.Remove(".\\winsw.exe"); err != nil {
  72. netclientutils.Log("failed to cleanup local winsw.exe, feel free to delete it")
  73. return err
  74. }
  75. netclientutils.Log("finished copying winsw.exe")
  76. return nil
  77. }
  78. func downloadWinsw() error {
  79. fullURLFile := "https://github.com/winsw/winsw/releases/download/v2.11.0/WinSW-x64.exe"
  80. fileName := "winsw.exe"
  81. // Create the file
  82. file, err := os.Create(fileName)
  83. if err != nil {
  84. netclientutils.Log("could not create file on OS for Winsw")
  85. return err
  86. }
  87. client := http.Client{
  88. CheckRedirect: func(r *http.Request, via []*http.Request) error {
  89. r.URL.Opaque = r.URL.Path
  90. return nil
  91. },
  92. }
  93. // Put content on file
  94. netclientutils.Log("downloading service tool...")
  95. resp, err := client.Get(fullURLFile)
  96. if err != nil {
  97. netclientutils.Log("could not GET Winsw")
  98. return err
  99. }
  100. defer resp.Body.Close()
  101. _, err = io.Copy(file, resp.Body)
  102. if err != nil {
  103. netclientutils.Log("could not mount winsw.exe")
  104. return err
  105. }
  106. defer file.Close()
  107. netclientutils.Log("finished downloading Winsw")
  108. return nil
  109. }
  110. func CreateAndRunWindowsDaemon() error {
  111. if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.xml") {
  112. if err := writeServiceConfig(); err != nil {
  113. return err
  114. }
  115. }
  116. if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.exe") {
  117. netclientutils.Log("performing first time daemon setup")
  118. if !FileExists(".\\winsw.exe") {
  119. err := downloadWinsw()
  120. if err != nil {
  121. return err
  122. }
  123. }
  124. err := copyWinswOver()
  125. if err != nil {
  126. return err
  127. }
  128. netclientutils.Log("finished daemon setup")
  129. }
  130. // install daemon, will not overwrite
  131. RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe install`, true)
  132. // start daemon, will not restart or start another
  133. RunCmd(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe start`, true)
  134. netclientutils.Log(strings.Replace(netclientutils.GetNetclientPathSpecific(), `\\`, `\`, -1) + `winsw.exe start`)
  135. return nil
  136. }
  137. func Cleanup() {
  138. if !FileExists(netclientutils.GetNetclientPathSpecific() + "winsw.xml") {
  139. writeServiceConfig()
  140. }
  141. StopWindowsDaemon()
  142. RemoveWindowsDaemon()
  143. os.RemoveAll(netclientutils.GetNetclientPath())
  144. log.Println("Netclient on Windows, uninstalled")
  145. }