diff --git a/Fula.podspec b/Fula.podspec index e619f2d..5dd6425 100644 --- a/Fula.podspec +++ b/Fula.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Fula' # Name for your pod - s.version = '1.43.0' + s.version = '1.44.0' s.summary = 'Go-fula for iOS' s.homepage = 'https://github.com/functionland/go-fula' diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 7b0ab59..eff9dba 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -396,6 +396,9 @@ func (bl *FxBlockchain) serve(w http.ResponseWriter, r *http.Request) { actionEraseBlData: func(from peer.ID, w http.ResponseWriter, r *http.Request) { bl.handleEraseBlData(r.Context(), from, w, r) }, + actionFetchContainerLogs: func(from peer.ID, w http.ResponseWriter, r *http.Request) { + bl.handleFetchContainerLogs(r.Context(), from, w, r) + }, } // Look up the function in the map and call it diff --git a/blockchain/blox.go b/blockchain/blox.go index 67bfa01..0a9e5e2 100644 --- a/blockchain/blox.go +++ b/blockchain/blox.go @@ -208,6 +208,43 @@ func (bl *FxBlockchain) GetAccount(ctx context.Context, to peer.ID) ([]byte, err } +func (bl *FxBlockchain) FetchContainerLogs(ctx context.Context, to peer.ID, r wifi.FetchContainerLogsRequest) ([]byte, error) { + + if bl.allowTransientConnection { + ctx = network.WithUseTransient(ctx, "fx.blockchain") + } + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(r); err != nil { + return nil, err + } + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://"+to.String()+".invalid/"+actionFetchContainerLogs, &buf) + if err != nil { + return nil, err + } + resp, err := bl.c.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + b, err := io.ReadAll(resp.Body) + switch { + case err != nil: + return nil, err + case resp.StatusCode != http.StatusAccepted: + // Attempt to parse the body as JSON. + if jsonErr := json.Unmarshal(b, &apiError); jsonErr != nil { + // If we can't parse the JSON, return the original body in the error. + return nil, fmt.Errorf("unexpected response: %d %s", resp.StatusCode, string(b)) + } + // Return the parsed error message and description. + return nil, fmt.Errorf("unexpected response: %d %s - %s", resp.StatusCode, apiError.Message, apiError.Description) + default: + return b, nil + } +} + func (bl *FxBlockchain) DeleteWifi(ctx context.Context, to peer.ID, r wifi.DeleteWifiRequest) ([]byte, error) { if bl.allowTransientConnection { @@ -281,3 +318,41 @@ func (bl *FxBlockchain) DisconnectWifi(ctx context.Context, to peer.ID, r wifi.D return b, nil } } + +func (bl *FxBlockchain) handleFetchContainerLogs(ctx context.Context, from peer.ID, w http.ResponseWriter, r *http.Request) { + log := log.With("action", actionFetchContainerLogs, "from", from) + + // Parse the JSON body of the request into the DeleteWifiRequest struct + var req wifi.FetchContainerLogsRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + log.Error("failed to decode request: %v", err) + http.Error(w, "failed to decode request", http.StatusBadRequest) + return + } + log.Debugw("handleFetchContainerLogs received", "req", req) + + out := wifi.FetchContainerLogsResponse{ + Status: true, + Msg: "", + } + res, err := wifi.FetchContainerLogs(ctx, req) + if err != nil { + out = wifi.FetchContainerLogsResponse{ + Status: false, + Msg: err.Error(), + } + } else { + out = wifi.FetchContainerLogsResponse{ + Status: true, + Msg: res, + } + } + + w.WriteHeader(http.StatusOK) + if err := json.NewEncoder(w).Encode(out); err != nil { + log.Error("failed to write response: %v", err) + http.Error(w, "failed to write response", http.StatusInternalServerError) + return + } + +} diff --git a/blockchain/interface.go b/blockchain/interface.go index dbc0cca..dedb92f 100644 --- a/blockchain/interface.go +++ b/blockchain/interface.go @@ -35,15 +35,16 @@ const ( actionManifestRemoveStored = "fula-manifest-remove_storing_manifest" //Hardware - actionBloxFreeSpace = "blox-free-space" - actionEraseBlData = "erase-blockchain-data" - actionWifiRemoveall = "wifi-removeall" - actionReboot = "reboot" - actionPartition = "partition" - actionDeleteFulaConfig = "delete-fula-config" - actionDeleteWifi = "delete-wifi" - actionDisconnectWifi = "disconnect-wifi" - actionGetAccount = "get-account" + actionBloxFreeSpace = "blox-free-space" + actionEraseBlData = "erase-blockchain-data" + actionWifiRemoveall = "wifi-removeall" + actionReboot = "reboot" + actionPartition = "partition" + actionDeleteFulaConfig = "delete-fula-config" + actionDeleteWifi = "delete-wifi" + actionDisconnectWifi = "disconnect-wifi" + actionGetAccount = "get-account" + actionFetchContainerLogs = "fetch-container-logs" ) type LinkWithLimit struct { @@ -354,6 +355,7 @@ type Blockchain interface { Partition(context.Context, peer.ID) ([]byte, error) DeleteFulaConfig(context.Context, peer.ID) ([]byte, error) GetAccount(context.Context, peer.ID) ([]byte, error) + FetchContainerLogs(context.Context, peer.ID, wifi.FetchContainerLogsRequest) ([]byte, error) } var requestTypes = map[string]reflect.Type{ @@ -381,15 +383,16 @@ var requestTypes = map[string]reflect.Type{ actionTransferToMumbai: reflect.TypeOf(TransferToFulaRequest{}), //Hardware - actionBloxFreeSpace: reflect.TypeOf(wifi.BloxFreeSpaceRequest{}), - actionEraseBlData: reflect.TypeOf(wifi.EraseBlDataRequest{}), - actionWifiRemoveall: reflect.TypeOf(wifi.WifiRemoveallRequest{}), - actionReboot: reflect.TypeOf(wifi.RebootRequest{}), - actionPartition: reflect.TypeOf(wifi.PartitionRequest{}), - actionDeleteFulaConfig: reflect.TypeOf(wifi.DeleteFulaConfigRequest{}), - actionDeleteWifi: reflect.TypeOf(wifi.DeleteWifiRequest{}), - actionDisconnectWifi: reflect.TypeOf(wifi.DeleteWifiRequest{}), - actionGetAccount: reflect.TypeOf(GetAccountRequest{}), + actionBloxFreeSpace: reflect.TypeOf(wifi.BloxFreeSpaceRequest{}), + actionEraseBlData: reflect.TypeOf(wifi.EraseBlDataRequest{}), + actionWifiRemoveall: reflect.TypeOf(wifi.WifiRemoveallRequest{}), + actionReboot: reflect.TypeOf(wifi.RebootRequest{}), + actionPartition: reflect.TypeOf(wifi.PartitionRequest{}), + actionDeleteFulaConfig: reflect.TypeOf(wifi.DeleteFulaConfigRequest{}), + actionDeleteWifi: reflect.TypeOf(wifi.DeleteWifiRequest{}), + actionDisconnectWifi: reflect.TypeOf(wifi.DeleteWifiRequest{}), + actionGetAccount: reflect.TypeOf(GetAccountRequest{}), + actionFetchContainerLogs: reflect.TypeOf(wifi.FetchContainerLogsRequest{}), } var responseTypes = map[string]reflect.Type{ @@ -417,13 +420,14 @@ var responseTypes = map[string]reflect.Type{ actionTransferToMumbai: reflect.TypeOf(TransferToFulaResponse{}), //Hardware - actionBloxFreeSpace: reflect.TypeOf(wifi.BloxFreeSpaceResponse{}), - actionEraseBlData: reflect.TypeOf(wifi.EraseBlDataResponse{}), - actionWifiRemoveall: reflect.TypeOf(wifi.WifiRemoveallResponse{}), - actionReboot: reflect.TypeOf(wifi.RebootResponse{}), - actionPartition: reflect.TypeOf(wifi.PartitionResponse{}), - actionDeleteFulaConfig: reflect.TypeOf(wifi.DeleteFulaConfigResponse{}), - actionDeleteWifi: reflect.TypeOf(wifi.DeleteWifiResponse{}), - actionDisconnectWifi: reflect.TypeOf(wifi.DeleteWifiResponse{}), - actionGetAccount: reflect.TypeOf(GetAccountResponse{}), + actionBloxFreeSpace: reflect.TypeOf(wifi.BloxFreeSpaceResponse{}), + actionEraseBlData: reflect.TypeOf(wifi.EraseBlDataResponse{}), + actionWifiRemoveall: reflect.TypeOf(wifi.WifiRemoveallResponse{}), + actionReboot: reflect.TypeOf(wifi.RebootResponse{}), + actionPartition: reflect.TypeOf(wifi.PartitionResponse{}), + actionDeleteFulaConfig: reflect.TypeOf(wifi.DeleteFulaConfigResponse{}), + actionDeleteWifi: reflect.TypeOf(wifi.DeleteWifiResponse{}), + actionDisconnectWifi: reflect.TypeOf(wifi.DeleteWifiResponse{}), + actionGetAccount: reflect.TypeOf(GetAccountResponse{}), + actionFetchContainerLogs: reflect.TypeOf(wifi.FetchContainerLogsResponse{}), } diff --git a/mobile/blockchain.go b/mobile/blockchain.go index 57d4e85..476c7c8 100644 --- a/mobile/blockchain.go +++ b/mobile/blockchain.go @@ -189,3 +189,10 @@ func (c *Client) GetAccount() ([]byte, error) { ctx := context.TODO() return c.bl.GetAccount(ctx, c.bloxPid) } + +// GetAccount requests blox at Config.BloxAddr to get the balance of the account. +// the addr must be a valid multiaddr that includes peer ID. +func (c *Client) FetchContainerLogs(ContainerName string, TailCount string) ([]byte, error) { + ctx := context.TODO() + return c.bl.FetchContainerLogs(ctx, c.bloxPid, wifi.FetchContainerLogsRequest{ContainerName: ContainerName, TailCount: TailCount}) +} diff --git a/wap/pkg/wifi/properties.go b/wap/pkg/wifi/properties.go index e1ddfde..463b623 100644 --- a/wap/pkg/wifi/properties.go +++ b/wap/pkg/wifi/properties.go @@ -6,6 +6,7 @@ import ( "crypto/sha256" "encoding/base64" "fmt" + "io" "os/exec" "strconv" "strings" @@ -28,6 +29,15 @@ type BloxFreeSpaceResponse struct { UsedPercentage float32 `json:"used_percentage"` } +type FetchContainerLogsResponse struct { + Status bool `json:"status"` + Msg string `json:"msg"` +} +type FetchContainerLogsRequest struct { + ContainerName string + TailCount string +} + type DockerInfo struct { Image string `json:"image"` Version string `json:"version"` @@ -42,6 +52,13 @@ type Config struct { // other fields } +type SyncInfo struct { + Best string + Target string + Finalized string + Speed string +} + const ( B = 1 KB = 1024 * B @@ -203,3 +220,28 @@ func GetContainerInfo(containerName string) (DockerInfo, error) { return info, nil } + +func FetchContainerLogs(ctx context.Context, req FetchContainerLogsRequest) (string, error) { + cli, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation(), client.WithHost("unix:///var/run/docker.sock")) + if err != nil { + return "", fmt.Errorf("creating Docker client: %w", err) + } + + options := types.ContainerLogsOptions{ + ShowStdout: true, + ShowStderr: true, + Tail: req.TailCount, // Adjust the number of lines as needed + } + logs, err := cli.ContainerLogs(ctx, req.ContainerName, options) + if err != nil { + return "", fmt.Errorf("getting container logs: %w", err) + } + defer logs.Close() + + logBytes, err := io.ReadAll(logs) + if err != nil { + return "", fmt.Errorf("reading container logs: %w", err) + } + + return string(logBytes), nil +} diff --git a/wap/props.json b/wap/props.json index 96751b5..828c5db 100644 --- a/wap/props.json +++ b/wap/props.json @@ -1 +1 @@ -{"connection":"9a:09:32:25:44:e8","country_code":"GB","password":"hhio618123.","ssid":"9a:09:32:25:44:e8"} \ No newline at end of file +{"connection":"9a:09:32:25:44:e8","country_code":"GB","password":".","ssid":"9a:09:32:25:44:e8"} \ No newline at end of file