-
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.
On Windows, the admin-helper service can be installed automatically with the command 'admin-helper install-daemon' and uninstalled with 'admin-helper uninstall-daemon'. It will launch the admin-helper in daemon mode and provide an HTTP API available on the named pipe crc-admin-helper. Only members of the Hyper-V administrators group can use it.
- Loading branch information
1 parent
94fb5bc
commit c5cfd48
Showing
104 changed files
with
25,655 additions
and
4 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
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.