Skip to content

Commit 8b5c765

Browse files
committed
Support streaming logs for remote builds
Switch to the Go SDK for remote builds with the up and publish commands. Both commands now stream build logs if the Function Builder API supports it. Signed-off-by: Han Verstraete (OpenFaaS Ltd) <[email protected]>
1 parent 30655b0 commit 8b5c765

File tree

12 files changed

+834
-175
lines changed

12 files changed

+834
-175
lines changed

builder/build.go

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
package builder
55

66
import (
7+
"bytes"
78
"context"
89
"crypto/md5"
910
"encoding/hex"
10-
"encoding/json"
1111
"fmt"
12-
"io"
1312
"log"
1413
"net/http"
14+
"net/url"
1515
"os"
1616
"path"
1717
"path/filepath"
@@ -22,6 +22,7 @@ import (
2222
"github.com/openfaas/faas-cli/schema"
2323
"github.com/openfaas/faas-cli/stack"
2424
vcs "github.com/openfaas/faas-cli/versioncontrol"
25+
"github.com/openfaas/go-sdk/builder"
2526
)
2627

2728
// AdditionalPackageBuildArg holds the special build-arg keyname for use with build-opts.
@@ -84,32 +85,38 @@ func BuildImage(image string, handler string, functionName string, language stri
8485
return fmt.Errorf("failed to create tar file for %s, error: %w", functionName, err)
8586
}
8687

87-
res, err := callBuilder(tarPath, remoteBuilder, functionName, payloadSecretPath)
88+
// Get the HMAC secret used for payload authentication with the builder API.
89+
payloadSecret, err := os.ReadFile(payloadSecretPath)
8890
if err != nil {
89-
return err
91+
return fmt.Errorf("failed to read payload secret: %w", err)
9092
}
91-
defer res.Body.Close()
93+
payloadSecret = bytes.TrimSpace(payloadSecret)
9294

93-
data, _ := io.ReadAll(res.Body)
95+
// Initialize a new builder client.
96+
builderURL, _ := url.Parse(remoteBuilder)
97+
b := builder.NewFunctionBuilder(builderURL, http.DefaultClient, builder.WithHmacAuth(string(payloadSecret)))
9498

95-
result := builderResult{}
96-
if err := json.Unmarshal(data, &result); err != nil {
97-
return err
99+
stream, err := b.BuildWithStream(tarPath)
100+
if err != nil {
101+
return fmt.Errorf("failed to invoke builder: %w", err)
98102
}
103+
defer stream.Close()
99104

100-
if !quietBuild {
101-
for _, logMsg := range result.Log {
102-
fmt.Printf("%s\n", logMsg)
105+
for result := range stream.Results() {
106+
if !quietBuild {
107+
for _, logMsg := range result.Log {
108+
fmt.Printf("%s\n", logMsg)
109+
}
103110
}
104-
}
105111

106-
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
107-
fmt.Println(res.StatusCode)
108-
return fmt.Errorf("%s failure while building or pushing image %s: %s", functionName, imageName, result.Status)
112+
switch result.Status {
113+
case builder.BuildSuccess:
114+
log.Printf("%s success building and pushing image: %s", functionName, result.Image)
115+
case builder.BuildFailed:
116+
return fmt.Errorf("%s failure while building or pushing image %s: %s", functionName, imageName, result.Error)
117+
}
109118
}
110119

111-
log.Printf("%s success building and pushing image: %s", functionName, result.Image)
112-
113120
} else {
114121

115122
buildOptPackages, err := getBuildOptionPackages(buildOptions, language, langTemplate.BuildOptions)

builder/publish.go

Lines changed: 24 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ import (
77
"archive/tar"
88
"bytes"
99
"context"
10-
"crypto/sha256"
11-
"encoding/hex"
1210
"encoding/json"
1311
"fmt"
1412
"io"
1513
"log"
1614
"net/http"
15+
"net/url"
1716
"os"
1817
"path"
1918
"path/filepath"
@@ -22,8 +21,7 @@ import (
2221
v2execute "github.com/alexellis/go-execute/v2"
2322
"github.com/openfaas/faas-cli/schema"
2423
"github.com/openfaas/faas-cli/stack"
25-
26-
hmac "github.com/alexellis/hmac/v2"
24+
"github.com/openfaas/go-sdk/builder"
2725
)
2826

2927
type buildConfig struct {
@@ -33,12 +31,6 @@ type buildConfig struct {
3331
Platforms []string `json:"platforms,omitempty"`
3432
}
3533

36-
type builderResult struct {
37-
Log []string `json:"log"`
38-
Image string `json:"image"`
39-
Status string `json:"status"`
40-
}
41-
4234
const BuilderConfigFilename = "com.openfaas.docker.config"
4335

4436
// PublishImage will publish images as multi-arch
@@ -100,32 +92,38 @@ func PublishImage(image string, handler string, functionName string, language st
10092
return fmt.Errorf("failed to create tar file for %s, error: %w", functionName, err)
10193
}
10294

103-
res, err := callBuilder(tarPath, remoteBuilder, functionName, payloadSecretPath)
95+
// Get the HMAC secret used for payload authentication with the builder API.
96+
payloadSecret, err := os.ReadFile(payloadSecretPath)
10497
if err != nil {
105-
return err
98+
return fmt.Errorf("failed to read payload secret: %w", err)
10699
}
107-
defer res.Body.Close()
100+
payloadSecret = bytes.TrimSpace(payloadSecret)
108101

109-
data, _ := io.ReadAll(res.Body)
102+
// Initialize a new builder client.
103+
builderURL, _ := url.Parse(remoteBuilder)
104+
b := builder.NewFunctionBuilder(builderURL, http.DefaultClient, builder.WithHmacAuth(string(payloadSecret)))
110105

111-
result := builderResult{}
112-
if err := json.Unmarshal(data, &result); err != nil {
113-
return fmt.Errorf("error: %s, unable to unmarshal: %q", err, string(data))
106+
stream, err := b.BuildWithStream(tarPath)
107+
if err != nil {
108+
return fmt.Errorf("failed to invoke builder:: %w", err)
114109
}
110+
defer stream.Close()
115111

116-
if !quietBuild {
117-
for _, logMsg := range result.Log {
118-
fmt.Printf("%s\n", logMsg)
112+
for result := range stream.Results() {
113+
if !quietBuild {
114+
for _, logMsg := range result.Log {
115+
fmt.Printf("%s\n", logMsg)
116+
}
119117
}
120-
}
121118

122-
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusAccepted {
123-
fmt.Println(res.StatusCode)
124-
return fmt.Errorf("%s failure while building or pushing image %s: %s", functionName, imageName, result.Status)
119+
switch result.Status {
120+
case builder.BuildSuccess:
121+
log.Printf("%s success building and pushing image: %s", functionName, result.Image)
122+
case builder.BuildFailed:
123+
return fmt.Errorf("%s failure while building or pushing image %s: %s", functionName, imageName, result.Error)
124+
}
125125
}
126126

127-
log.Printf("%s success building and pushing image: %s", functionName, result.Image)
128-
129127
} else {
130128
buildOptPackages, buildPackageErr := getBuildOptionPackages(buildOptions, language, langTemplate.BuildOptions)
131129

@@ -260,41 +258,3 @@ func makeTar(buildConfig buildConfig, base, tarPath string) error {
260258

261259
return err
262260
}
263-
264-
func callBuilder(tarPath, builderAddress, functionName, payloadSecretPath string) (*http.Response, error) {
265-
266-
payloadSecret, err := os.ReadFile(payloadSecretPath)
267-
if err != nil {
268-
return nil, err
269-
}
270-
271-
tarFile, err := os.Open(tarPath)
272-
if err != nil {
273-
return nil, err
274-
}
275-
defer tarFile.Close()
276-
277-
tarFileBytes, err := io.ReadAll(tarFile)
278-
if err != nil {
279-
return nil, err
280-
}
281-
282-
digest := hmac.Sign(tarFileBytes, bytes.TrimSpace(payloadSecret), sha256.New)
283-
fmt.Println(hex.EncodeToString(digest))
284-
285-
r, err := http.NewRequest(http.MethodPost, builderAddress, bytes.NewReader(tarFileBytes))
286-
if err != nil {
287-
return nil, err
288-
}
289-
290-
r.Header.Set("X-Build-Signature", "sha256="+hex.EncodeToString(digest))
291-
r.Header.Set("Content-Type", "application/octet-stream")
292-
293-
log.Printf("%s invoking the API for build at %s", functionName, builderAddress)
294-
res, err := http.DefaultClient.Do(r)
295-
if err != nil {
296-
return nil, err
297-
}
298-
299-
return res, nil
300-
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ require (
1919
github.com/mitchellh/go-wordwrap v1.0.1
2020
github.com/moby/term v0.5.2
2121
github.com/morikuni/aec v1.0.0
22-
github.com/openfaas/faas-provider v0.25.5
22+
github.com/openfaas/faas-provider v0.25.7
2323
github.com/openfaas/faas/gateway v0.0.0-20241209094132-4e20249bc070
24-
github.com/openfaas/go-sdk v0.2.16
24+
github.com/openfaas/go-sdk v0.2.18
2525
github.com/pkg/errors v0.9.1
2626
github.com/ryanuber/go-glob v1.0.0
2727
github.com/spf13/cobra v1.8.1

go.sum

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,12 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
7676
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
7777
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
7878
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
79-
github.com/openfaas/faas-provider v0.25.4 h1:Cly/M8/Q+OOn8qFxxeaZGyC5B2x4f+RSU28hej+1WcM=
80-
github.com/openfaas/faas-provider v0.25.4/go.mod h1:t6RSPCvNfiqYEzf/CtdIj+0OItdyK6IzrOca1EOLNSg=
81-
github.com/openfaas/faas-provider v0.25.5 h1:qW2izX1otKfbOhArgf1GK9JjTqwBRL4BWioiJJVYH58=
82-
github.com/openfaas/faas-provider v0.25.5/go.mod h1:rMXbj+AYVpn82UoHIOgWHiDeV118t0bSxyoC9d00jpc=
79+
github.com/openfaas/faas-provider v0.25.7 h1:ZgJOk4AYElxDa8YOHkb5PvemYtG0eHpzBpYL6lLDAB8=
80+
github.com/openfaas/faas-provider v0.25.7/go.mod h1:rMXbj+AYVpn82UoHIOgWHiDeV118t0bSxyoC9d00jpc=
8381
github.com/openfaas/faas/gateway v0.0.0-20241209094132-4e20249bc070 h1:aeRDLXgwSOcMwUmZzXZsKf5GLoplZDF122SJVR62WgQ=
8482
github.com/openfaas/faas/gateway v0.0.0-20241209094132-4e20249bc070/go.mod h1:j5eUH36/clgztwBYFoXZ/s1UFQ9Alzt8rb50gh7L5Ns=
85-
github.com/openfaas/go-sdk v0.2.14 h1:N3bq0yparYZR6pR1AhZiPGvV8GAmQ1UfjmCOGaZMs68=
86-
github.com/openfaas/go-sdk v0.2.14/go.mod h1:DrKUCQ4F8L2cJOmWHNoX8zB8LQIZc/4hRgAtT4t0s4k=
87-
github.com/openfaas/go-sdk v0.2.16 h1:Z+sH+C6h3DtWWEosR8pEWyWpYxIo2hD63BcjZvLCB9c=
88-
github.com/openfaas/go-sdk v0.2.16/go.mod h1:INay8mhhat7stnJxt5KudR504T2wcc5ARXLKC6wkGcM=
83+
github.com/openfaas/go-sdk v0.2.18 h1:lSsI+GpUVkO6Z+bK75LtNfqSCrOA9n4OQFPMqRGgSeI=
84+
github.com/openfaas/go-sdk v0.2.18/go.mod h1:INay8mhhat7stnJxt5KudR504T2wcc5ARXLKC6wkGcM=
8985
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
9086
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
9187
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

vendor/github.com/openfaas/go-sdk/README.md

Lines changed: 52 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)