Skip to content

Commit bee9a5b

Browse files
bepearsorikgibson
authored andcommitted
Support resource copy into Fn Docker image via func.yaml (#591)
1 parent 37a3940 commit bee9a5b

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

common/common.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"os/exec"
1616
"os/signal"
1717
"path/filepath"
18+
"strconv"
1819
"strings"
1920
"time"
2021
"unicode"
@@ -388,6 +389,15 @@ func writeTmpDockerfile(helper langs.LangHelper, dir string, ff *FuncFile) (stri
388389
dfLines = append(dfLines, fmt.Sprintf("FROM %s", ri))
389390
dfLines = append(dfLines, "WORKDIR /function")
390391
dfLines = append(dfLines, helper.DockerfileCopyCmds()...)
392+
393+
resources := ff.CopyResources
394+
for _, resource := range resources {
395+
if Exists(resource.From) {
396+
dfLines = append(dfLines, fmt.Sprintf("COPY %s %s", strconv.Quote(resource.From), strconv.Quote(resource.To)))
397+
} else {
398+
return "", errors.New(fmt.Sprintf("Filepath %s does not exist", resource.From))
399+
}
400+
}
391401
}
392402
if ff.Entrypoint != "" {
393403
dfLines = append(dfLines, fmt.Sprintf("ENTRYPOINT [%s]", stringToSlice(ff.Entrypoint)))
@@ -442,6 +452,15 @@ func writeTmpDockerfileV20180708(helper langs.LangHelper, dir string, ff *FuncFi
442452
dfLines = append(dfLines, fmt.Sprintf("FROM %s", ri))
443453
dfLines = append(dfLines, "WORKDIR /function")
444454
dfLines = append(dfLines, helper.DockerfileCopyCmds()...)
455+
456+
resources := ff.CopyResources
457+
for _, resource := range resources {
458+
if Exists(resource.From) {
459+
dfLines = append(dfLines, fmt.Sprintf("COPY %s %s", strconv.Quote(resource.From), strconv.Quote(resource.To)))
460+
} else {
461+
return "", errors.New(fmt.Sprintf("Filepath %s does not exist", resource.From))
462+
}
463+
}
445464
}
446465
if ff.Entrypoint != "" {
447466
dfLines = append(dfLines, fmt.Sprintf("ENTRYPOINT [%s]", stringToSlice(ff.Entrypoint)))

common/funcfile.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ type Expects struct {
5252
Config []inputVar `yaml:"config" json:"config"`
5353
}
5454

55+
type copyResources struct {
56+
From string `yaml:"from,omitempty" json:"from,omitempty"`
57+
To string `yaml:"to,omitempty" json:"to,omitempty"`
58+
}
59+
5560
// FuncFile defines the internal structure of a func.yaml/json/yml
5661
type FuncFile struct {
5762
// just for posterity, this won't be set on old files, but we can check that
@@ -70,6 +75,9 @@ type FuncFile struct {
7075
RunImage string `yaml:"run_image,omitempty" json:"run_image,omitempty"` // Image to use for running
7176
ContentType string `yaml:"content_type,omitempty" json:"content_type,omitempty"`
7277

78+
//Allows resource copy
79+
CopyResources []copyResources `yaml:"copy_resources,omitempty" json:"copy_resources,omitempty"`
80+
7381
// Route params
7482
// TODO embed models.Route
7583
Type string `yaml:"type,omitempty" json:"type,omitempty"`
@@ -102,6 +110,8 @@ type FuncFileV20180708 struct {
102110
Timeout *int32 `yaml:"timeout,omitempty" json:"timeout,omitempty"`
103111
IDLE_timeout *int32 `yaml:"idle_timeout,omitempty" json:"idle_timeout,omitempty"`
104112

113+
CopyResources []copyResources `yaml:"copy_resources,omitempty" json:"copy_resources,omitempty"`
114+
105115
Config map[string]string `yaml:"config,omitempty" json:"config,omitempty"`
106116
Annotations map[string]interface{} `yaml:"annotations,omitempty" json:"annotations,omitempty"`
107117

test/cli_copy_resource_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package test
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
"github.com/fnproject/cli/testharness"
8+
)
9+
10+
func TestResourceCopy(t *testing.T) {
11+
12+
const testFuncSource = `package main
13+
import (
14+
"context"
15+
"io"
16+
"os"
17+
fdk "github.com/fnproject/fdk-go"
18+
)
19+
func main() {
20+
fdk.Handle(fdk.HandlerFunc(myHandler))
21+
}
22+
func myHandler(ctx context.Context, in io.Reader, out io.Writer) {
23+
testFile,err := os.Open("/testfile.txt")
24+
if err != nil {
25+
panic(err.Error())
26+
}
27+
defer testFile.Close()
28+
io.Copy(out,testFile)
29+
}
30+
`
31+
32+
const funcYaml =
33+
`schema_version: 20180708
34+
name: filefn
35+
version: 0.0.1
36+
runtime: go
37+
entrypoint: ./func
38+
copy_resources:
39+
- from: testfile.txt
40+
to: /
41+
`
42+
43+
const gomod = `module func`
44+
const testFile = `hello world!`
45+
46+
t.Parallel()
47+
h := testharness.Create(t)
48+
defer h.Cleanup()
49+
50+
appName := h.NewAppName()
51+
52+
h.WithFile("func.yaml", funcYaml, 0644)
53+
h.WithFile("func.go", testFuncSource, 0644)
54+
h.WithFile("testfile.txt", testFile, 0644)
55+
h.WithFile("go.mod", gomod, 0644)
56+
57+
h.Fn("deploy", "--app", appName, "--local", "--create-app").AssertSuccess()
58+
59+
res := h.Fn("invoke", appName, "filefn")
60+
61+
res.AssertSuccess()
62+
if strings.TrimSpace(res.Stdout) != testFile {
63+
t.Fatalf("Expected result to be '%s', got '%s'", testFile, res.Stdout)
64+
}
65+
}

0 commit comments

Comments
 (0)