-
Notifications
You must be signed in to change notification settings - Fork 241
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement CrcApiServer, which is the run as the crc daemon
The CrcApiServer listens on a unix socket and handles requests of the format {"command": "command_to_run, "args": "args_for_cmd"} the args field in the json object is optional. It reads the request from the connection and runs a handler function to serve the request based on the command field. This commit also includes implementation of a few of the handlers. Fixes #796
- Loading branch information
1 parent
c3cc33d
commit c36a879
Showing
5 changed files
with
221 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/code-ready/crc/pkg/crc/api" | ||
"github.com/code-ready/crc/pkg/crc/constants" | ||
"github.com/code-ready/crc/pkg/crc/logging" | ||
"github.com/spf13/cobra" | ||
"os" | ||
) | ||
|
||
func init() { | ||
rootCmd.AddCommand(daemonCmd) | ||
} | ||
|
||
var daemonCmd = &cobra.Command{ | ||
Use: "daemon", | ||
Short: "Run the crc daemon", | ||
Long: "Run the crc daemon", | ||
Hidden: true, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
runDaemon() | ||
}, | ||
} | ||
|
||
func runDaemon() { | ||
// Remove if an old socket is present | ||
os.Remove(constants.DaemonSocketPath) | ||
crcApiServer, err := api.CreateApiServer(constants.DaemonSocketPath) | ||
if err != nil { | ||
logging.Fatal("Failed to launch daemon", err) | ||
} | ||
crcApiServer.Serve() | ||
} |
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,93 @@ | ||
package api | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"net" | ||
|
||
"github.com/code-ready/crc/pkg/crc/logging" | ||
) | ||
|
||
type ArgsType map[string]string | ||
type handlerFunc func(ArgsType) string | ||
|
||
type CrcApiServer struct { | ||
listener net.Listener | ||
handlers map[string]handlerFunc // relates commands to handler func | ||
} | ||
|
||
// commandRequest struct is used to decode the json request from tray | ||
type commandRequest struct { | ||
Command string `json:"command"` | ||
Args map[string]string `json:"args,omitempty"` | ||
} | ||
|
||
func CreateApiServer(socketPath string) (CrcApiServer, error) { | ||
listener, err := net.Listen("unix", socketPath) | ||
if err != nil { | ||
logging.Error("Failed to create socket: ", err.Error()) | ||
return CrcApiServer{}, err | ||
} | ||
apiServer := CrcApiServer{ | ||
listener: listener, | ||
handlers: map[string]handlerFunc{ | ||
"start": startHandler, | ||
"stop": stopHandler, | ||
"status": statusHandler, | ||
"delete": deleteHandler, | ||
"version": versionHandler, | ||
"webconsoleurl": webconsoleURLHandler, | ||
}, | ||
} | ||
return apiServer, nil | ||
} | ||
|
||
func (api CrcApiServer) Serve() { | ||
for { | ||
conn, err := api.listener.Accept() | ||
if err != nil { | ||
logging.Error("Error establishing communication: ", err.Error()) | ||
continue | ||
} | ||
go api.handleConnection(conn) | ||
} | ||
} | ||
|
||
func (api CrcApiServer) handleConnection(conn net.Conn) { | ||
defer conn.Close() | ||
inBuffer := make([]byte, 1024) | ||
var req commandRequest | ||
numBytes, err := conn.Read(inBuffer) | ||
if err != nil || numBytes == 0 || numBytes == cap(inBuffer) { | ||
logging.Error("Error reading from socket") | ||
return | ||
} | ||
logging.Debug("Received Request:", string(inBuffer[0:numBytes])) | ||
err = json.Unmarshal(inBuffer[0:numBytes], &req) | ||
if err != nil { | ||
logging.Error("Error decoding request: ", err.Error()) | ||
return | ||
} | ||
|
||
if handler, ok := api.handlers[req.Command]; ok { | ||
result := handler(req.Args) | ||
writeStringToSocket(conn, result) | ||
} else { | ||
writeStringToSocket(conn, fmt.Sprintf("Unknown command supplied: %s", req.Command)) | ||
} | ||
} | ||
|
||
func writeStringToSocket(socket net.Conn, msg string) { | ||
var outBuffer bytes.Buffer | ||
_, err := outBuffer.WriteString(msg) | ||
if err != nil { | ||
logging.Error("Failed writing string to buffer", err.Error()) | ||
return | ||
} | ||
_, err = socket.Write(outBuffer.Bytes()) | ||
if err != nil { | ||
logging.Error("Failed writing string to socket", err.Error()) | ||
return | ||
} | ||
} |
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,87 @@ | ||
package api | ||
|
||
import ( | ||
"encoding/json" | ||
"io/ioutil" | ||
|
||
"github.com/code-ready/crc/cmd/crc/cmd/config" | ||
crcConfig "github.com/code-ready/crc/pkg/crc/config" | ||
"github.com/code-ready/crc/pkg/crc/constants" | ||
"github.com/code-ready/crc/pkg/crc/logging" | ||
"github.com/code-ready/crc/pkg/crc/machine" | ||
"github.com/code-ready/crc/pkg/crc/validation" | ||
"github.com/code-ready/crc/pkg/crc/version" | ||
) | ||
|
||
func statusHandler(_ ArgsType) string { | ||
statusConfig := machine.ClusterStatusConfig{Name: constants.DefaultName} | ||
clusterStatus, _ := machine.Status(statusConfig) | ||
return encodeStructToJson(clusterStatus) | ||
} | ||
|
||
func stopHandler(_ ArgsType) string { | ||
stopConfig := machine.StopConfig{ | ||
Name: constants.DefaultName, | ||
Debug: true, | ||
} | ||
commandResult, _ := machine.Stop(stopConfig) | ||
return encodeStructToJson(commandResult) | ||
} | ||
|
||
func startHandler(_ ArgsType) string { | ||
startConfig := machine.StartConfig{ | ||
Name: constants.DefaultName, | ||
BundlePath: crcConfig.GetString(config.Bundle.Name), | ||
VMDriver: crcConfig.GetString(config.VMDriver.Name), | ||
Memory: crcConfig.GetInt(config.Memory.Name), | ||
CPUs: crcConfig.GetInt(config.CPUs.Name), | ||
NameServer: crcConfig.GetString(config.NameServer.Name), | ||
GetPullSecret: getPullSecretFileContent, | ||
Debug: true, | ||
} | ||
status, _ := machine.Start(startConfig) | ||
return encodeStructToJson(status) | ||
} | ||
|
||
func versionHandler(_ ArgsType) string { | ||
v := &machine.VersionResult{ | ||
CrcVersion: version.GetCRCVersion(), | ||
CommitSha: version.GetCommitSha(), | ||
OpenshiftVersion: version.GetBundleVersion(), | ||
Success: true, | ||
} | ||
return encodeStructToJson(v) | ||
} | ||
|
||
func getPullSecretFileContent() (string, error) { | ||
data, err := ioutil.ReadFile(crcConfig.GetString(config.PullSecretFile.Name)) | ||
if err != nil { | ||
return "", err | ||
} | ||
pullsecret := string(data) | ||
if err := validation.ImagePullSecret(pullsecret); err != nil { | ||
return "", err | ||
} | ||
return pullsecret, nil | ||
} | ||
|
||
func deleteHandler(_ ArgsType) string { | ||
delConfig := machine.DeleteConfig{Name: constants.DefaultName} | ||
r, _ := machine.Delete(delConfig) | ||
return encodeStructToJson(r) | ||
} | ||
|
||
func webconsoleURLHandler(_ ArgsType) string { | ||
consoleConfig := machine.ConsoleConfig{Name: constants.DefaultName} | ||
r, _ := machine.GetConsoleURL(consoleConfig) | ||
return encodeStructToJson(r) | ||
} | ||
|
||
func encodeStructToJson(v interface{}) string { | ||
s, err := json.Marshal(v) | ||
if err != nil { | ||
logging.Error(err.Error()) | ||
return "Failed" | ||
} | ||
return string(s) | ||
} |
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