Skip to content

Commit

Permalink
More work
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulh committed Oct 9, 2023
1 parent 394e440 commit 068a0b1
Show file tree
Hide file tree
Showing 13 changed files with 644 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ debian/calaos-container.postrm.debhelper
debian/calaos-container.substvars
debian/debhelper-build-stamp
debian/files
calaos-os.releases
calaos-container.dev.toml
15 changes: 14 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ GOCMD=go
GOTEST=$(GOCMD) test
GOVET=$(GOCMD) vet
BINARY_NAME=calaos-container
BINARY_NAME_TOOL=calaos-os
VERSION?=1.0.0

TOP_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))

GREEN := $(shell tput -Txterm setaf 2)
YELLOW := $(shell tput -Txterm setaf 3)
WHITE := $(shell tput -Txterm setaf 7)
CYAN := $(shell tput -Txterm setaf 6)
RESET := $(shell tput -Txterm sgr0)

.PHONY: all test build
.ONESHELL:

all: build

Expand All @@ -27,7 +31,16 @@ help: ## Show this help.
}' $(MAKEFILE_LIST)

## Build:
build: ## Build the project and put the output binary in bin/
build: build-server build-tools ## Build the project and put the output binary in bin/
@mkdir -p bin

build-tools:
@mkdir -p bin
@cd cmd/calaos-os
$(GOCMD) build -v -o $(TOP_DIR)/bin/$(BINARY_NAME_TOOL) .
@cd $(TOP_DIR)

build-server:
@mkdir -p bin
$(GOCMD) build -v -o bin/$(BINARY_NAME) .

Expand Down
15 changes: 15 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ func NewApp() (a *AppServer, err error) {
return a.apiNetIntfList(c)
})

//Force an update check
api.Get("/update/check", func(c *fiber.Ctx) error {
return a.apiUpdateCheck(c)
})

//Get available updates
api.Get("/update/available", func(c *fiber.Ctx) error {
return a.apiUpdateAvail(c)
})

//Get currently installed images
api.Get("/update/images", func(c *fiber.Ctx) error {
return a.apiUpdateImages(c)
})

return
}

Expand Down
37 changes: 37 additions & 0 deletions app/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package app

import (
"github.com/calaos/calaos-container/config"
"github.com/calaos/calaos-container/models"
"github.com/gofiber/fiber/v2"
)

func (a *AppServer) apiUpdateCheck(c *fiber.Ctx) (err error) {

err = models.CheckUpdates()
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": true,
"msg": err.Error(),
})
}

return c.Status(fiber.StatusOK).JSON(models.NewVersions)
}

func (a *AppServer) apiUpdateAvail(c *fiber.Ctx) (err error) {
return c.Status(fiber.StatusOK).JSON(models.NewVersions)
}

func (a *AppServer) apiUpdateImages(c *fiber.Ctx) (err error) {

m, err := models.LoadFromDisk(config.Config.String("general.version_file"))
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": true,
"msg": err.Error(),
})
}

return c.Status(fiber.StatusOK).JSON(m)
}
11 changes: 10 additions & 1 deletion calaos-container.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
[general]
#Port to listen for Web
port = 8000
address = "127.0.0.1"
address = "127.0.0.1"

# URL for releases
url_releases = "https://releases.calaos.fr/v4/images"
#url_releases = "https://releases.calaos.fr/v4/images-dev"

version_file = "/etc/calaos-os.releases"

#duration between update checks
update_time = "12h"
230 changes: 230 additions & 0 deletions cmd/calaos-os/api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
package api

import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"

"github.com/calaos/calaos-container/models/images"
)

const (
CalaosCtHost = "localhost:8000"
)

type apiOptions struct {
timeout time.Duration
insecure bool
proxy func(*http.Request) (*url.URL, error)
transport func(*http.Transport)
}

// Optional parameter, used to configure timeouts on API calls.
func SetTimeout(timeout time.Duration) func(*apiOptions) {
return func(opts *apiOptions) {
opts.timeout = timeout
}
}

// Optional parameter for testing only. Bypasses all TLS certificate validation.
func SetInsecure() func(*apiOptions) {
return func(opts *apiOptions) {
opts.insecure = true
}
}

// Optional parameter, used to configure an HTTP Connect proxy
// server for all outbound communications.
func SetProxy(proxy func(*http.Request) (*url.URL, error)) func(*apiOptions) {
return func(opts *apiOptions) {
opts.proxy = proxy
}
}

// SetTransport enables additional control over the HTTP transport used to connect to the API.
func SetTransport(transport func(*http.Transport)) func(*apiOptions) {
return func(opts *apiOptions) {
opts.transport = transport
}
}

type CalaosApi struct {
host string
userAgent string
apiClient *http.Client
}

// SetCustomHTTPClient allows one to set a completely custom http client that
// will be used to make network calls to the duo api
func (capi *CalaosApi) SetCustomHTTPClient(c *http.Client) {
capi.apiClient = c
}

// Build and return a CalaosApi struct
func NewCalaosApi(host string, options ...func(*apiOptions)) *CalaosApi {
opts := apiOptions{
proxy: http.ProxyFromEnvironment,
}
for _, o := range options {
o(&opts)
}

tr := &http.Transport{
Proxy: opts.proxy,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: opts.insecure,
},
}
if opts.transport != nil {
opts.transport(tr)
}

return &CalaosApi{
host: host,
userAgent: "calaos-os_api/1.0",
apiClient: &http.Client{
Timeout: opts.timeout,
Transport: tr,
},
}
}

// Make a CalaosApi Rest API call
// Example: api.Call("POST", "/xxxxx/xxxxx", nil)
func (capi *CalaosApi) call(method string, uri string, params url.Values, body interface{}) (*http.Response, []byte, error) {

url := url.URL{
Scheme: "http",
Host: capi.host,
Path: uri,
RawQuery: params.Encode(),
}
headers := make(map[string]string)
headers["User-Agent"] = capi.userAgent

var requestBody io.ReadCloser = nil
if body != nil {
headers["Content-Type"] = "application/json"

b, err := json.Marshal(body)
if err != nil {
return nil, nil, err
}
requestBody = io.NopCloser(bytes.NewReader(b))
}

return capi.makeHttpCall(method, url, headers, requestBody)
}

// Make a CalaosApi Rest API call using token
// Example: api.CallWithToken("GET", "/api/xxxx", token, params)
func (capi *CalaosApi) callWithToken(method string, uri string, token string, params url.Values, body interface{}) (*http.Response, []byte, error) {

url := url.URL{
Scheme: "http",
Host: capi.host,
Path: uri,
RawQuery: params.Encode(),
}
headers := make(map[string]string)
headers["User-Agent"] = capi.userAgent
headers["Authorization"] = "Bearer " + token

var requestBody io.ReadCloser = nil
if body != nil {
headers["Content-Type"] = "application/json"

b, err := json.Marshal(body)
if err != nil {
return nil, nil, err
}
requestBody = io.NopCloser(bytes.NewReader(b))
}

return capi.makeHttpCall(method, url, headers, requestBody)
}

func (capi *CalaosApi) makeHttpCall(
method string,
url url.URL,
headers map[string]string,
body io.ReadCloser) (*http.Response, []byte, error) {

request, err := http.NewRequest(method, url.String(), nil)
if err != nil {
return nil, nil, err
}

//set headers
for k, v := range headers {
request.Header.Set(k, v)
}

if body != nil {
request.Body = body
}

resp, err := capi.apiClient.Do(request)
var bodyBytes []byte
if err != nil {
return resp, bodyBytes, err
}

bodyBytes, err = io.ReadAll(resp.Body)
defer resp.Body.Close()

return resp, bodyBytes, err
}

// UpdateCheck forces an update check
func (capi *CalaosApi) UpdateCheck(token string) (imgs *images.ImageMap, err error) {

_, body, err := capi.callWithToken("GET", "/api/update/check", token, nil, nil)
if err != nil {
return
}

imgs = &images.ImageMap{}
if err = json.Unmarshal(body, imgs); err != nil {
return nil, fmt.Errorf("UpdateCheck failed: %v", err)
}

return
}

// UpdateAvailable returns available updates
func (capi *CalaosApi) UpdateAvailable(token string) (imgs *images.ImageMap, err error) {

_, body, err := capi.callWithToken("GET", "/api/update/available", token, nil, nil)
if err != nil {
return
}

imgs = &images.ImageMap{}
if err = json.Unmarshal(body, imgs); err != nil {
return nil, fmt.Errorf("UpdateAvailable failed: %v", err)
}

return
}

// UpdateImages returns currently installed images
func (capi *CalaosApi) UpdateImages(token string) (imgs *images.ImageMap, err error) {

_, body, err := capi.callWithToken("GET", "/api/update/images", token, nil, nil)
if err != nil {
return
}

imgs = &images.ImageMap{}
if err = json.Unmarshal(body, imgs); err != nil {
return nil, fmt.Errorf("UpdateImages failed: %v", err)
}

return
}
Loading

0 comments on commit 068a0b1

Please sign in to comment.