@@ -4,10 +4,8 @@ import (
4
4
"bytes"
5
5
"context"
6
6
"fmt"
7
- "net/url "
7
+ "io "
8
8
"os"
9
- "path/filepath"
10
- "strings"
11
9
12
10
"github.com/cenkalti/backoff/v4"
13
11
"github.com/docker/go-units"
@@ -26,15 +24,15 @@ func (s *EdgeRuntimeAPI) UpsertFunctions(ctx context.Context, functionConfig con
26
24
if resp , err := s .client .V1ListAllFunctionsWithResponse (ctx , s .project ); err != nil {
27
25
return errors .Errorf ("failed to list functions: %w" , err )
28
26
} else if resp .JSON200 == nil {
29
- return errors .Errorf ("unexpected status %d: %s" , resp .StatusCode (), string (resp .Body ))
27
+ return errors .Errorf ("unexpected list functions status %d: %s" , resp .StatusCode (), string (resp .Body ))
30
28
} else {
31
29
result = * resp .JSON200
32
30
}
33
31
exists := make (map [string ]struct {}, len (result ))
34
32
for _ , f := range result {
35
33
exists [f .Slug ] = struct {}{}
36
34
}
37
- toUpdate := map [ string ]api.BulkUpdateFunctionBody {}
35
+ var toUpdate [ ]api.BulkUpdateFunctionBody
38
36
OUTER:
39
37
for slug , function := range functionConfig {
40
38
if ! function .Enabled {
@@ -47,75 +45,29 @@ OUTER:
47
45
}
48
46
}
49
47
var body bytes.Buffer
50
- if err := s .eszip .Bundle (ctx , slug , function .Entrypoint , function .ImportMap , function .StaticFiles , & body ); err != nil {
48
+ meta , err := s .eszip .Bundle (ctx , slug , function .Entrypoint , function .ImportMap , function .StaticFiles , & body )
49
+ if err != nil {
51
50
return err
52
51
}
52
+ meta .VerifyJwt = & function .VerifyJWT
53
53
// Update if function already exists
54
- upsert := func () error {
54
+ upsert := func () (api. BulkUpdateFunctionBody , error ) {
55
55
if _ , ok := exists [slug ]; ok {
56
- resp , err := s .client .V1UpdateAFunctionWithBodyWithResponse (ctx , s .project , slug , & api.V1UpdateAFunctionParams {
57
- VerifyJwt : & function .VerifyJWT ,
58
- ImportMapPath : toFileURL (function .ImportMap ),
59
- EntrypointPath : toFileURL (function .Entrypoint ),
60
- }, eszipContentType , bytes .NewReader (body .Bytes ()))
61
- if err != nil {
62
- return errors .Errorf ("failed to update function: %w" , err )
63
- } else if resp .JSON200 == nil {
64
- return errors .Errorf ("unexpected status %d: %s" , resp .StatusCode (), string (resp .Body ))
65
- }
66
- toUpdate [slug ] = api.BulkUpdateFunctionBody {
67
- Id : resp .JSON200 .Id ,
68
- Name : resp .JSON200 .Name ,
69
- Slug : resp .JSON200 .Slug ,
70
- Version : resp .JSON200 .Version ,
71
- EntrypointPath : resp .JSON200 .EntrypointPath ,
72
- ImportMap : resp .JSON200 .ImportMap ,
73
- ImportMapPath : resp .JSON200 .ImportMapPath ,
74
- VerifyJwt : resp .JSON200 .VerifyJwt ,
75
- Status : api .BulkUpdateFunctionBodyStatus (resp .JSON200 .Status ),
76
- CreatedAt : & resp .JSON200 .CreatedAt ,
77
- }
78
- } else {
79
- resp , err := s .client .V1CreateAFunctionWithBodyWithResponse (ctx , s .project , & api.V1CreateAFunctionParams {
80
- Slug : & slug ,
81
- Name : & slug ,
82
- VerifyJwt : & function .VerifyJWT ,
83
- ImportMapPath : toFileURL (function .ImportMap ),
84
- EntrypointPath : toFileURL (function .Entrypoint ),
85
- }, eszipContentType , bytes .NewReader (body .Bytes ()))
86
- if err != nil {
87
- return errors .Errorf ("failed to create function: %w" , err )
88
- } else if resp .JSON201 == nil {
89
- return errors .Errorf ("unexpected status %d: %s" , resp .StatusCode (), string (resp .Body ))
90
- }
91
- toUpdate [slug ] = api.BulkUpdateFunctionBody {
92
- Id : resp .JSON201 .Id ,
93
- Name : resp .JSON201 .Name ,
94
- Slug : resp .JSON201 .Slug ,
95
- Version : resp .JSON201 .Version ,
96
- EntrypointPath : resp .JSON201 .EntrypointPath ,
97
- ImportMap : resp .JSON201 .ImportMap ,
98
- ImportMapPath : resp .JSON201 .ImportMapPath ,
99
- VerifyJwt : resp .JSON201 .VerifyJwt ,
100
- Status : api .BulkUpdateFunctionBodyStatus (resp .JSON201 .Status ),
101
- CreatedAt : & resp .JSON201 .CreatedAt ,
102
- }
56
+ return s .updateFunction (ctx , slug , meta , bytes .NewReader (body .Bytes ()))
103
57
}
104
- return nil
58
+ return s . createFunction ( ctx , slug , meta , bytes . NewReader ( body . Bytes ()))
105
59
}
106
60
functionSize := units .HumanSize (float64 (body .Len ()))
107
61
fmt .Fprintf (os .Stderr , "Deploying Function: %s (script size: %s)\n " , slug , functionSize )
108
62
policy := backoff .WithContext (backoff .WithMaxRetries (backoff .NewExponentialBackOff (), maxRetries ), ctx )
109
- if err := backoff .Retry (upsert , policy ); err != nil {
63
+ result , err := backoff .RetryWithData (upsert , policy )
64
+ if err != nil {
110
65
return err
111
66
}
67
+ toUpdate = append (toUpdate , result )
112
68
}
113
69
if len (toUpdate ) > 1 {
114
- var body []api.BulkUpdateFunctionBody
115
- for _ , b := range toUpdate {
116
- body = append (body , b )
117
- }
118
- if resp , err := s .client .V1BulkUpdateFunctionsWithResponse (ctx , s .project , body ); err != nil {
70
+ if resp , err := s .client .V1BulkUpdateFunctionsWithResponse (ctx , s .project , toUpdate ); err != nil {
119
71
return errors .Errorf ("failed to bulk update: %w" , err )
120
72
} else if resp .JSON200 == nil {
121
73
return errors .Errorf ("unexpected bulk update status %d: %s" , resp .StatusCode (), string (resp .Body ))
@@ -124,19 +76,54 @@ OUTER:
124
76
return nil
125
77
}
126
78
127
- func toFileURL (hostPath string ) * string {
128
- absHostPath , err := filepath .Abs (hostPath )
79
+ func (s * EdgeRuntimeAPI ) updateFunction (ctx context.Context , slug string , meta api.FunctionDeployMetadata , body io.Reader ) (api.BulkUpdateFunctionBody , error ) {
80
+ resp , err := s .client .V1UpdateAFunctionWithBodyWithResponse (ctx , s .project , slug , & api.V1UpdateAFunctionParams {
81
+ VerifyJwt : meta .VerifyJwt ,
82
+ ImportMapPath : meta .ImportMapPath ,
83
+ EntrypointPath : & meta .EntrypointPath ,
84
+ }, eszipContentType , body )
129
85
if err != nil {
130
- return nil
86
+ return api.BulkUpdateFunctionBody {}, errors .Errorf ("failed to update function: %w" , err )
87
+ } else if resp .JSON200 == nil {
88
+ return api.BulkUpdateFunctionBody {}, errors .Errorf ("unexpected update function status %d: %s" , resp .StatusCode (), string (resp .Body ))
131
89
}
132
- // Convert to unix path because edge runtime only supports linux
133
- parsed := url.URL {Scheme : "file" , Path : toUnixPath (absHostPath )}
134
- result := parsed .String ()
135
- return & result
90
+ return api.BulkUpdateFunctionBody {
91
+ Id : resp .JSON200 .Id ,
92
+ Name : resp .JSON200 .Name ,
93
+ Slug : resp .JSON200 .Slug ,
94
+ Version : resp .JSON200 .Version ,
95
+ EntrypointPath : resp .JSON200 .EntrypointPath ,
96
+ ImportMap : resp .JSON200 .ImportMap ,
97
+ ImportMapPath : resp .JSON200 .ImportMapPath ,
98
+ VerifyJwt : resp .JSON200 .VerifyJwt ,
99
+ Status : api .BulkUpdateFunctionBodyStatus (resp .JSON200 .Status ),
100
+ CreatedAt : & resp .JSON200 .CreatedAt ,
101
+ }, nil
136
102
}
137
103
138
- func toUnixPath (absHostPath string ) string {
139
- prefix := filepath .VolumeName (absHostPath )
140
- unixPath := filepath .ToSlash (absHostPath )
141
- return strings .TrimPrefix (unixPath , prefix )
104
+ func (s * EdgeRuntimeAPI ) createFunction (ctx context.Context , slug string , meta api.FunctionDeployMetadata , body io.Reader ) (api.BulkUpdateFunctionBody , error ) {
105
+ resp , err := s .client .V1CreateAFunctionWithBodyWithResponse (ctx , s .project , & api.V1CreateAFunctionParams {
106
+ Slug : & slug ,
107
+ Name : & slug ,
108
+ VerifyJwt : meta .VerifyJwt ,
109
+ ImportMapPath : meta .ImportMapPath ,
110
+ EntrypointPath : & meta .EntrypointPath ,
111
+ }, eszipContentType , body )
112
+ if err != nil {
113
+ return api.BulkUpdateFunctionBody {}, errors .Errorf ("failed to create function: %w" , err )
114
+ } else if resp .JSON201 == nil {
115
+ return api.BulkUpdateFunctionBody {}, errors .Errorf ("unexpected create function status %d: %s" , resp .StatusCode (), string (resp .Body ))
116
+ }
117
+ return api.BulkUpdateFunctionBody {
118
+ Id : resp .JSON201 .Id ,
119
+ Name : resp .JSON201 .Name ,
120
+ Slug : resp .JSON201 .Slug ,
121
+ Version : resp .JSON201 .Version ,
122
+ EntrypointPath : resp .JSON201 .EntrypointPath ,
123
+ ImportMap : resp .JSON201 .ImportMap ,
124
+ ImportMapPath : resp .JSON201 .ImportMapPath ,
125
+ VerifyJwt : resp .JSON201 .VerifyJwt ,
126
+ Status : api .BulkUpdateFunctionBodyStatus (resp .JSON201 .Status ),
127
+ CreatedAt : & resp .JSON201 .CreatedAt ,
128
+ }, nil
142
129
}
0 commit comments