Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Topic/test ci #8

Merged
merged 3 commits into from Sep 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/ci.yml
@@ -0,0 +1,63 @@
name: CI

on:
push:
branches:
- master
- topic/test_ci
pull_request:

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
go: [ '1.15' ]
name: Go ${{ matrix.go }} sample
steps:
- uses: actions/checkout@v2
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go }}

- name: Install Dependencies
run: |
sudo apt-get update; sudo apt-get install socat
- name: Run API test
run: |
wget https://raw.githubusercontent.com/UpdateHub/updatehub/master/doc/agent-http.yaml \
-O agent-http.yaml
docker run \
--rm \
--detach=true \
--name agent-sdk-go-mock \
-p 8080:8000 \
-v $PWD/agent-http.yaml:/api.yaml \
danielgtaylor/apisprout@sha256:6c07143937e57095d8478efc8ab7eab52b44e67c7673285f8c0a2bf4a7b137ad \
/api.yaml --validate-request
go run examples/api/main.go
- name: Run listener test
run: |
export UH_LISTENER_TEST=updatehub-statechange.sock
go build examples/listener/main.go; ./main &

while [ ! -S "$UH_LISTENER_TEST" ]; do
sleep 1
done
if [[ "$(echo "entry_point" | socat - UNIX-CONNECT:updatehub-statechange.sock)" != "" ]]; then
echo "Unexpected entry_point response"
exit 1
fi
if [[ "$(echo "download" | socat - UNIX-CONNECT:updatehub-statechange.sock)" != "cancel" ]]; then
echo "Unexpected download response"
exit 2
fi
if [[ "$(echo "error" | socat - UNIX-CONNECT:updatehub-statechange.sock)" != "" ]]; then
echo "Unexpected error response"
exit 3
fi
if [[ "$(echo "reboot" | socat - UNIX-CONNECT:updatehub-statechange.sock)" != "" ]]; then
echo "Unexpected reboot response"
exit 4
fi
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
*~
**/*
!**/*.go
!**/
agent-http.yaml
193 changes: 162 additions & 31 deletions api.go
Expand Up @@ -5,64 +5,151 @@ import (
"fmt"
"net/url"

"github.com/UpdateHub/updatehub/metadata"
"github.com/UpdateHub/updatehub/updatehub"
"github.com/parnurzeal/gorequest"
)

var DefaultHost = updatehub.DefaultSettings.ListenSocket
type ProbeResponse interface{}

const (
Updating = "updating"
NoUpdate = "no_update"
TryAgain = "try_again"
)

type APIState string

const (
Park = "park"
EntryPoint = "entry_point"
Poll = "poll"
Validation = "validation"
Download = "download"
Install = "install"
Reboot = "reboot"
DirectDownload = "direct_download"
PrepareLocalInstall = "prepare_local_install"
Error = "error"
)

type Client struct {
}

type Metadata struct {
Metadata string `json:"metadata"`
}

type Network struct {
ServerAddress string `json:"server_address"`
ListenSocket string `json:"listen_socket"`
}

type Polling struct {
Interval string `json:"interval"`
Enabled bool `json:"enabled"`
}

type Storage struct {
ReadOnly bool `json:"read_only"`
RuntimeSettings string `json:"runtime_settings"`
}

type Update struct {
DownloadDir string `json:"download_dir"`
SupportedInstallModes []string `json:"supported_install_modes"`
}

type ServerAddress struct {
Custom string `json:"custom"`
}

type DeviceAttributes struct {
Attr1 string `json:"attr1"`
Attr2 string `json:"attr2"`
}

type DeviceIdentity struct {
ID1 string `json:"id1"`
ID2 string `json:"id2"`
}

type Firmware struct {
DeviceAttributes DeviceAttributes `json:"device_attributes"`
DeviceIdentity DeviceIdentity `json:"device_identity"`
Hardware string `json:"hardware"`
PubKey string `json:"pub_key"`
Version string `json:"version"`
}

type UpdatePackage struct {
AppliedPackageUid string `json:"applied_package_uid"`
UpdgradeToInstallation string `json:"upgrade_to_installation"`
}

type Settings struct {
Firmware Metadata `json:"firmware"`
Network Network `json:"network"`
Polling Polling `json:"polling"`
Storage Storage `json:"storage"`
Update Update `json:"update"`
}

type RuntimeSettings struct {
Path string `json:"path"`
Persistent bool `json:"persistent"`
Polling PollingLog `json:"polling"`
Update UpdatePackage `json:"update"`
}

type PollingLog struct {
Last string `json:"last"`
Now bool `json:"now"`
Retries int64 `json:"retries"`
ServerAddress ServerAddress `json:"server_address"`
}

type AgentInfo struct {
Version string `json:"version"`
Config updatehub.Settings `json:"config"`
Firmware metadata.FirmwareMetadata `json:"firmware"`
Config Settings `json:"config"`
Firmware Firmware `json:"firmware"`
RuntimeSettings RuntimeSettings `json:"runtime_settings"`
State APIState `json:"state"`
Version string `json:"version"`
}

type LogEntry struct {
type Entry struct {
Data interface{} `json:"data"`
Level string `json:"level"`
Message string `json:"message"`
Time string `json:"time"`
}

type ProbeResponse struct {
UpdateAvailable bool `json:"update-available"`
TryAgainIn int `json:"try-again-in"`
type Log struct {
Entries []Entry `json:"entries"`
}

// NewClient instantiates a new updatehub agent client
func NewClient() *Client {
return &Client{}
}

// Probe default server address for update
func (c *Client) Probe() (*ProbeResponse, error) {
return c.probe("", false)
}

// ProbeCustomServer probe custom server address for update
func (c *Client) ProbeCustomServer(serverAddress string, ignoreProbeASAP bool) (*ProbeResponse, error) {
return c.probe(serverAddress, ignoreProbeASAP)
}

func (c *Client) probe(serverAddress string, ignoreProbeASAP bool) (*ProbeResponse, error) {
// Probe server address for update
func (c *Client) Probe(serverAddress string) (*ProbeResponse, error) {
var probe ProbeResponse

var req struct {
ServerAddress string `json:"server-address"`
IgnoreProbeASAP bool `json:"ignore-probe-asap"`
ServerAddress string `json:"custom_server"`
}
req.ServerAddress = serverAddress
req.IgnoreProbeASAP = ignoreProbeASAP

_, _, errs := gorequest.New().Post(buildURL("/probe")).Send(req).EndStruct(&probe)
_, body, errs := gorequest.New().Post(buildURL("/probe")).Send(req).EndStruct(&probe)
if len(errs) > 0 {
return nil, errs[0]
}

err := json.Unmarshal([]byte(body), &probe)
if err != nil {
return nil, err
}

return &probe, nil
}

Expand All @@ -79,27 +166,71 @@ func (c *Client) GetInfo() (*AgentInfo, error) {
}

// GetLogs get updatehub agent log entries
func (c *Client) GetLogs() ([]LogEntry, error) {
func (c *Client) GetLogs() (*Log, error) {
_, body, errs := gorequest.New().Get(buildURL("/log")).End()
if len(errs) > 0 {
return nil, errs[0]
}

var entries []LogEntry
var log Log

err := json.Unmarshal([]byte(body), &log)
if err != nil {
return nil, err
}

return &log, nil
}

// RemoteInstall trigger the installation of a package from a direct URL
func (c *Client) RemoteInstall(serverAddress string) (*APIState, error) {
var state APIState

var req struct {
URL string `json:"url"`
}
req.URL = serverAddress

_, body, errs := gorequest.New().Post(buildURL("/remote_install")).Send(req).EndStruct(&state)
if len(errs) > 0 {
return nil, errs[0]
}

err := json.Unmarshal([]byte(body), &state)
if err != nil {
return nil, err
}

return &state, nil
}

// LocalInstall trigger the installation of a local package
func (c *Client) LocalInstall(filePath string) (*APIState, error) {
var state APIState

var req struct {
FilePath string `json:"file"`
}
req.FilePath = filePath

_, body, errs := gorequest.New().Post(buildURL("/local_install")).Send(req).EndStruct(&state)
if len(errs) > 0 {
return nil, errs[0]
}

err := json.Unmarshal([]byte(body), &entries)
err := json.Unmarshal([]byte(body), &state)
if err != nil {
return nil, err
}

return entries, nil
return &state, nil
}

func buildURL(path string) string {
u, err := url.Parse(DefaultHost)
u, err := url.Parse("localhost:8080")
if err != nil {
panic(err)
}

return fmt.Sprintf("http://%s/%s", u.Host, path[1:])
return fmt.Sprintf("http://%s%s", u, path)
}