-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from guillaumerose/daemon
Add daemon mode for Windows
- Loading branch information
Showing
105 changed files
with
25,657 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
.DS_Store | ||
/admin-helper | ||
/admin-helper.exe | ||
/crc-admin-helper | ||
/crc-admin-helper.exe | ||
.idea | ||
dist | ||
out | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"net/http" | ||
|
||
"github.com/code-ready/admin-helper/pkg/api" | ||
"github.com/code-ready/admin-helper/pkg/hosts" | ||
"github.com/kardianos/service" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var InstallDaemon = &cobra.Command{ | ||
Use: "install-daemon", | ||
Short: "Install the daemon", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
svc, err := svc() | ||
if err != nil { | ||
return err | ||
} | ||
if err := svc.Install(); err != nil { | ||
return err | ||
} | ||
return svc.Start() | ||
}, | ||
} | ||
|
||
var UninstallDaemon = &cobra.Command{ | ||
Use: "uninstall-daemon", | ||
Short: "Uninstall the daemon", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
svc, err := svc() | ||
if err != nil { | ||
return err | ||
} | ||
if err := svc.Stop(); err != nil { | ||
log.Println(err) | ||
} | ||
return svc.Uninstall() | ||
}, | ||
} | ||
|
||
var Daemon = &cobra.Command{ | ||
Use: "daemon", | ||
Short: "Run as a daemon", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return daemon() | ||
}, | ||
} | ||
|
||
func daemon() error { | ||
svc, err := svc() | ||
if err != nil { | ||
return err | ||
} | ||
return svc.Run() | ||
} | ||
|
||
func svc() (service.Service, error) { | ||
svcConfig := &service.Config{ | ||
Name: "CodeReadyContainersAdminHelper", | ||
DisplayName: "CodeReadyContainers Admin Helper", | ||
Description: "Perform administrative tasks for the user", | ||
Arguments: []string{"daemon"}, | ||
} | ||
prg := &program{} | ||
return service.New(prg, svcConfig) | ||
} | ||
|
||
type program struct{} | ||
|
||
func (p *program) Start(s service.Service) error { | ||
go func() { | ||
logger, err := s.Logger(nil) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
ln, err := listen() | ||
if err != nil { | ||
_ = logger.Error(err) | ||
return | ||
} | ||
hosts, err := hosts.New() | ||
if err != nil { | ||
_ = logger.Error(err) | ||
return | ||
} | ||
if err := http.Serve(ln, api.Mux(hosts)); err != nil { | ||
_ = logger.Error(err) | ||
return | ||
} | ||
}() | ||
return nil | ||
} | ||
|
||
func (p *program) Stop(s service.Service) error { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// +build !windows | ||
|
||
package main | ||
|
||
import "net" | ||
|
||
func listen() (net.Listener, error) { | ||
return net.Listen("unix", "daemon.sock") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
|
||
"github.com/Microsoft/go-winio" | ||
) | ||
|
||
func listen() (net.Listener, error) { | ||
// see https://github.com/moby/moby/blob/46cdcd206c56172b95ba5c77b827a722dab426c5/daemon/listeners/listeners_windows.go | ||
// allow Administrators and SYSTEM, plus whatever additional users or groups were specified | ||
sddl := "D:P(A;;GA;;;BA)(A;;GA;;;SY)" | ||
sid, err := winio.LookupSidByName("crc-users") | ||
if err != nil { | ||
return nil, err | ||
} | ||
sddl += fmt.Sprintf("(A;;GRGW;;;%s)", sid) | ||
|
||
return winio.ListenPipe(`\\.\pipe\crc-admin-helper`, &winio.PipeConfig{ | ||
SecurityDescriptor: sddl, // Administrators and system | ||
MessageMode: true, // Use message mode so that CloseWrite() is supported | ||
InputBufferSize: 65536, // Use 64KB buffers to improve performance | ||
OutputBufferSize: 65536, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// +build windows | ||
|
||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"net" | ||
"net/http" | ||
"time" | ||
|
||
"github.com/Microsoft/go-winio" | ||
) | ||
|
||
func main() { | ||
client := &http.Client{ | ||
Transport: &http.Transport{ | ||
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { | ||
return winio.DialPipeContext(ctx, `\\.\pipe\crc-admin-helper`) | ||
}, | ||
}, | ||
Timeout: 5 * time.Second, | ||
} | ||
|
||
res, err := client.Get("http://unix/version") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
bin, err := ioutil.ReadAll(res.Body) | ||
defer res.Body.Close() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
fmt.Println(string(bin)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package api | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
|
||
"github.com/code-ready/admin-helper/pkg/constants" | ||
"github.com/code-ready/admin-helper/pkg/hosts" | ||
"github.com/code-ready/admin-helper/pkg/types" | ||
) | ||
|
||
func Mux(hosts *hosts.Hosts) http.Handler { | ||
mux := http.NewServeMux() | ||
mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { | ||
_, _ = fmt.Fprint(w, constants.Version) | ||
}) | ||
mux.HandleFunc("/add", func(w http.ResponseWriter, r *http.Request) { | ||
if r.Method != http.MethodPost { | ||
http.Error(w, "post only", http.StatusBadRequest) | ||
return | ||
} | ||
var req types.AddRequest | ||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { | ||
http.Error(w, err.Error(), http.StatusBadRequest) | ||
return | ||
} | ||
if err := hosts.Add(req.IP, req.Hosts); err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
w.WriteHeader(http.StatusOK) | ||
}) | ||
mux.HandleFunc("/remove", func(w http.ResponseWriter, r *http.Request) { | ||
if r.Method != http.MethodPost { | ||
http.Error(w, "post only", http.StatusBadRequest) | ||
return | ||
} | ||
var req types.RemoveRequest | ||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { | ||
http.Error(w, err.Error(), http.StatusBadRequest) | ||
return | ||
} | ||
if err := hosts.Remove(req.Hosts); err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
w.WriteHeader(http.StatusOK) | ||
}) | ||
mux.HandleFunc("/clean", func(w http.ResponseWriter, r *http.Request) { | ||
if r.Method != http.MethodPost { | ||
http.Error(w, "post only", http.StatusBadRequest) | ||
return | ||
} | ||
var req types.CleanRequest | ||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { | ||
http.Error(w, err.Error(), http.StatusBadRequest) | ||
return | ||
} | ||
if err := hosts.Clean(req.Domains); err != nil { | ||
http.Error(w, err.Error(), http.StatusInternalServerError) | ||
return | ||
} | ||
w.WriteHeader(http.StatusOK) | ||
}) | ||
return mux | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package api | ||
|
||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/code-ready/admin-helper/pkg/client" | ||
"github.com/code-ready/admin-helper/pkg/constants" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestMux(t *testing.T) { | ||
ts := httptest.NewServer(Mux(nil)) | ||
defer ts.Close() | ||
|
||
client := client.New(http.DefaultClient, ts.URL) | ||
version, err := client.Version() | ||
assert.NoError(t, err) | ||
assert.Equal(t, constants.Version, version) | ||
} |
Oops, something went wrong.