Skip to content

Commit e0dd2b9

Browse files
corneliusweigbalopat
authored andcommitted
Improve syntax for artifact.sync config [1/3] (#1847)
* Improved pipeline config for artifact.sync Currently, the pipeline config is a map of local glob pattern to destination directory. This scheme has been extended with some magic sequences, making it difficult to understand. This commit converts the sync map into a list of sync rules. All sync rules are consulted to determine the destination paths. This prepares for further changes to the sync logic. Also see #1844 * Update sync spec config according to design proposal - Wrap sync-rules under key 'sync.manual' - Config changes: - from -> src - to -> dest - flatten option removed and warn during schema upgrade if an incompatible pattern is migrated to the new schema version * Add validation for sync rules * Migrate sync config to new schema version * Update filesync documentation Extract example into sample snippet in order to have it tested. * Run validation on doc examples * Review comments: add test case and clarify example in docs * Improve doc and error message wording Signed-off-by: Cornelius Weig <[email protected]>
1 parent 3e21e73 commit e0dd2b9

File tree

19 files changed

+592
-309
lines changed

19 files changed

+592
-309
lines changed

docs/content/en/docs/how-tos/filesync/_index.md

+29-31
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,38 @@ This page discusses how to set up file sync for files that don't require full re
1010
File sync is alpha and may change between releases.
1111
{{< /alert >}}
1212

13-
Skaffold supports copying changed files to a deployed containers so as to avoid the need to
14-
rebuild, redeploy, and restart the corresponding pod. The file copying is enabled
15-
by adding a `sync` section with _sync rules_ to the `artifact` in the `skaffold.yaml`.
16-
17-
The following example will cause any changes to JavaScript files under the _context_ directory
18-
to be copied to the deployed container into the container's `WORKDIR`.
19-
20-
```yaml
21-
apiVersion: skaffold/v1beta8
22-
kind: Config
23-
build:
24-
artifacts:
25-
- image: gcr.io/k8s-skaffold/node-example
26-
context: node
27-
sync:
28-
'.filebaserc': .
29-
'*.html': static
30-
'**/*.png': assets
31-
'***/*.md': content
32-
```
33-
A double-asterisk (`**/`) applies recursively to all subdirectories but flattens the result,
34-
stripping the subdirectory structure.
35-
A triple-asterisk (`***/`) applies recursively to all subdirectories but retains
36-
the subdirectory structure.
37-
38-
Under the hood, Skaffold monitors and creates a tar file with changed files that match
39-
the sync rules. This tar file is sent and extracted on the corresponding containers.
40-
41-
### Limitations
13+
Skaffold supports copying changed files to a deployed container so as to avoid the need to rebuild, redeploy, and restart the corresponding pod.
14+
The file copying is enabled by adding a `sync` section with _sync rules_ to the `artifact` in the `skaffold.yaml`.
15+
Under the hood, Skaffold creates a tar file with changed files that match the sync rules.
16+
This tar file is sent to and extracted on the corresponding containers.
17+
18+
### Manual sync mode
19+
20+
A manual sync rule must specify the `src` and `dest` field.
21+
The `src` field is a glob pattern to match files relative to the artifact _context_ directory, which may contain `**` to match nested files.
22+
The `dest` field is the absolute or relative destination path in the container.
23+
If the destination is a relative path, an absolute path will be inferred by prepending the path with the container's `WORKDIR`.
24+
By default, matched files are transplanted with their whole directory hierarchy below the artifact context directory onto the destination.
25+
The optional `strip` field can cut off some levels from the directory hierarchy.
26+
The following example showcases manual filesync:
27+
28+
{{% readfile file="samples/filesync/filesync.yaml" %}}
29+
30+
- The first rule synchronizes the file `.filebaserc` to the `/etc` folder in the container.
31+
- The second rule synchronizes all `html` files in the `static-html` folder into the `<WORKDIR>/static` folder in the container.
32+
Note that this pattern does not match files in sub-folders below `static-html` (e.g. `static-html/a.html` but not `static-html/sub/a.html`).
33+
- The third rule synchronizes all `png` files from any sub-folder into the `assets` folder on the container.
34+
For example, `img.png``assets/img.png` or `sub/img.png``assets/sub/img.png`.
35+
- The last rule synchronizes all `md` files below the `content/en` directory into the `content` folder on the container.
36+
The `strip` directive ensures that only the directory hierarchy below `content/en` is re-created at the destination.
37+
For example, `content/en/index.md``content/index.md` or `content/en/sub/index.md``content/sub/index.md`.
38+
39+
Currently, there is only manual filesync mode, but a mode with destination inference is already in the making.
40+
41+
## Limitations
4242

4343
File sync has some limitations:
4444

4545
- File sync can only update files that can be modified by the container's configured User ID.
4646
- File sync requires the `tar` command to be available in the container.
4747
- Only local source files can be synchronized: files created by the builder will not be copied.
48-
49-
{{% todo 1076 %}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
build:
2+
artifacts:
3+
- image: gcr.io/k8s-skaffold/node-example
4+
context: node
5+
sync:
6+
manual:
7+
# sync a single file into the `/etc` folder
8+
- src: '.filebaserc'
9+
dest: /etc
10+
11+
# sync files directly below `static-html` into `static/`
12+
- src: 'static-html/*.html'
13+
dest: static
14+
15+
# sync any `png` file into the assets folder
16+
- src: '**/*.png'
17+
dest: assets
18+
19+
# sync all `md` files from `content/en` into `content`
20+
- src: 'content/en/**/*.md'
21+
dest: content
22+
strip: 'content/en/'

docs/content/en/schemas/v1beta10.json

+79-70
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,9 @@
6565
]
6666
},
6767
"sync": {
68-
"additionalProperties": {
69-
"type": "string"
70-
},
71-
"type": "object",
72-
"description": "*alpha* local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
73-
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
74-
"default": "{}",
75-
"examples": [
76-
"{\"*.py\": \".\", \"css/**/*.css\": \"app/css\"}"
77-
]
68+
"$ref": "#/definitions/Sync",
69+
"description": "*alpha* local files synced to pods instead of triggering an image build when modified.",
70+
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified."
7871
}
7972
},
8073
"preferredOrder": [
@@ -106,16 +99,9 @@
10699
]
107100
},
108101
"sync": {
109-
"additionalProperties": {
110-
"type": "string"
111-
},
112-
"type": "object",
113-
"description": "*alpha* local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
114-
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
115-
"default": "{}",
116-
"examples": [
117-
"{\"*.py\": \".\", \"css/**/*.css\": \"app/css\"}"
118-
]
102+
"$ref": "#/definitions/Sync",
103+
"description": "*alpha* local files synced to pods instead of triggering an image build when modified.",
104+
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified."
119105
}
120106
},
121107
"preferredOrder": [
@@ -148,16 +134,9 @@
148134
]
149135
},
150136
"sync": {
151-
"additionalProperties": {
152-
"type": "string"
153-
},
154-
"type": "object",
155-
"description": "*alpha* local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
156-
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
157-
"default": "{}",
158-
"examples": [
159-
"{\"*.py\": \".\", \"css/**/*.css\": \"app/css\"}"
160-
]
137+
"$ref": "#/definitions/Sync",
138+
"description": "*alpha* local files synced to pods instead of triggering an image build when modified.",
139+
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified."
161140
}
162141
},
163142
"preferredOrder": [
@@ -190,16 +169,9 @@
190169
"x-intellij-html-description": "<em>alpha</em> builds images using the <a href=\"https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin\">Jib plugin for Maven</a>."
191170
},
192171
"sync": {
193-
"additionalProperties": {
194-
"type": "string"
195-
},
196-
"type": "object",
197-
"description": "*alpha* local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
198-
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
199-
"default": "{}",
200-
"examples": [
201-
"{\"*.py\": \".\", \"css/**/*.css\": \"app/css\"}"
202-
]
172+
"$ref": "#/definitions/Sync",
173+
"description": "*alpha* local files synced to pods instead of triggering an image build when modified.",
174+
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified."
203175
}
204176
},
205177
"preferredOrder": [
@@ -232,16 +204,9 @@
232204
"x-intellij-html-description": "<em>alpha</em> builds images using the <a href=\"https://github.com/GoogleContainerTools/jib/tree/master/jib-gradle-plugin\">Jib plugin for Gradle</a>."
233205
},
234206
"sync": {
235-
"additionalProperties": {
236-
"type": "string"
237-
},
238-
"type": "object",
239-
"description": "*alpha* local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
240-
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
241-
"default": "{}",
242-
"examples": [
243-
"{\"*.py\": \".\", \"css/**/*.css\": \"app/css\"}"
244-
]
207+
"$ref": "#/definitions/Sync",
208+
"description": "*alpha* local files synced to pods instead of triggering an image build when modified.",
209+
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified."
245210
}
246211
},
247212
"preferredOrder": [
@@ -274,16 +239,9 @@
274239
"x-intellij-html-description": "<em>alpha</em> builds images using <a href=\"https://github.com/GoogleContainerTools/kaniko\">kaniko</a>."
275240
},
276241
"sync": {
277-
"additionalProperties": {
278-
"type": "string"
279-
},
280-
"type": "object",
281-
"description": "*alpha* local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
282-
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
283-
"default": "{}",
284-
"examples": [
285-
"{\"*.py\": \".\", \"css/**/*.css\": \"app/css\"}"
286-
]
242+
"$ref": "#/definitions/Sync",
243+
"description": "*alpha* local files synced to pods instead of triggering an image build when modified.",
244+
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified."
287245
}
288246
},
289247
"preferredOrder": [
@@ -316,16 +274,9 @@
316274
]
317275
},
318276
"sync": {
319-
"additionalProperties": {
320-
"type": "string"
321-
},
322-
"type": "object",
323-
"description": "*alpha* local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
324-
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified. This is a mapping of local files to sync to remote folders.",
325-
"default": "{}",
326-
"examples": [
327-
"{\"*.py\": \".\", \"css/**/*.css\": \"app/css\"}"
328-
]
277+
"$ref": "#/definitions/Sync",
278+
"description": "*alpha* local files synced to pods instead of triggering an image build when modified.",
279+
"x-intellij-html-description": "<em>alpha</em> local files synced to pods instead of triggering an image build when modified."
329280
}
330281
},
331282
"preferredOrder": [
@@ -1670,6 +1621,64 @@
16701621
"description": "holds the fields parsed from the Skaffold configuration file (skaffold.yaml).",
16711622
"x-intellij-html-description": "holds the fields parsed from the Skaffold configuration file (skaffold.yaml)."
16721623
},
1624+
"Sync": {
1625+
"properties": {
1626+
"manual": {
1627+
"items": {
1628+
"$ref": "#/definitions/SyncRule"
1629+
},
1630+
"type": "array",
1631+
"description": "manual sync rules indicating the source and destination.",
1632+
"x-intellij-html-description": "manual sync rules indicating the source and destination."
1633+
}
1634+
},
1635+
"preferredOrder": [
1636+
"manual"
1637+
],
1638+
"additionalProperties": false,
1639+
"description": "*alpha* specifies what files to sync into the container. This is a list of sync rules indicating the intent to sync for source files.",
1640+
"x-intellij-html-description": "<em>alpha</em> specifies what files to sync into the container. This is a list of sync rules indicating the intent to sync for source files."
1641+
},
1642+
"SyncRule": {
1643+
"required": [
1644+
"src",
1645+
"dest"
1646+
],
1647+
"properties": {
1648+
"dest": {
1649+
"type": "string",
1650+
"description": "destination path in the container where the files should be synced to.",
1651+
"x-intellij-html-description": "destination path in the container where the files should be synced to.",
1652+
"examples": [
1653+
"\"app/\""
1654+
]
1655+
},
1656+
"src": {
1657+
"type": "string",
1658+
"description": "a glob pattern to match local paths against.",
1659+
"x-intellij-html-description": "a glob pattern to match local paths against.",
1660+
"examples": [
1661+
"\"css/**/*.css\""
1662+
]
1663+
},
1664+
"strip": {
1665+
"type": "string",
1666+
"description": "specifies the path prefix to remove from the source path when transplanting the files into the destination folder.",
1667+
"x-intellij-html-description": "specifies the path prefix to remove from the source path when transplanting the files into the destination folder.",
1668+
"examples": [
1669+
"\"css/\""
1670+
]
1671+
}
1672+
},
1673+
"preferredOrder": [
1674+
"src",
1675+
"dest",
1676+
"strip"
1677+
],
1678+
"additionalProperties": false,
1679+
"description": "specifies which local files to sync to remote folders.",
1680+
"x-intellij-html-description": "specifies which local files to sync to remote folders."
1681+
},
16731682
"TagPolicy": {
16741683
"properties": {
16751684
"dateTime": {

examples/hot-reload/skaffold.yaml

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
apiVersion: skaffold/v1beta9
1+
apiVersion: skaffold/v1beta10
22
kind: Config
33
build:
44
artifacts:
55
- image: gcr.io/k8s-skaffold/node-example
66
context: node
77
sync:
8-
'**/*.js': .
8+
manual:
9+
- src: 'src/**/*.js'
10+
dest: .
11+
strip: src/
912
- image: gcr.io/k8s-skaffold/python-reload
1013
context: python
1114
sync:
12-
'**/*.py': .
15+
manual:
16+
- src: 'src/**/*.py'
17+
dest: .
18+
strip: src/
1319
deploy:
1420
kubectl:
1521
manifests:

examples/nodejs/skaffold.yaml

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
apiVersion: skaffold/v1beta9
1+
apiVersion: skaffold/v1beta10
22
kind: Config
33
build:
44
artifacts:
55
- image: gcr.io/k8s-skaffold/node-example
66
context: backend
77
sync:
8-
# Sync all the javascript files that are in the src folder
9-
# with the container src folder
10-
'src/***/*.js': src/
8+
manual:
9+
# Sync all the javascript files that are in the src folder
10+
# with the container src folder
11+
- src: 'src/**/*.js'
12+
dest: .
1113
deploy:
1214
kubectl:
1315
manifests:

integration/examples/hot-reload/skaffold.yaml

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@ build:
55
- image: gcr.io/k8s-skaffold/node-example
66
context: node
77
sync:
8-
'**/*.js': .
8+
manual:
9+
- src: 'src/**/*.js'
10+
dest: .
11+
strip: src/
912
- image: gcr.io/k8s-skaffold/python-reload
1013
context: python
1114
sync:
12-
'**/*.py': .
15+
manual:
16+
- src: 'src/**/*.py'
17+
dest: .
18+
strip: src/
1319
deploy:
1420
kubectl:
1521
manifests:

integration/examples/nodejs/skaffold.yaml

+4-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ build:
88
buildArgs:
99
SCRIPT: "{{.SCRIPT}}"
1010
sync:
11-
# Sync all the javascript files that are in the src folder
11+
manual:
12+
# Sync all the javascript files that are in the src folder
1213
# with the container src folder
13-
'src/***/*.js': src/
14+
- src: 'src/**/*.js'
15+
dest: .
1416
deploy:
1517
kubectl:
1618
manifests:

integration/testdata/file-sync/skaffold.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ build:
77
- image: gcr.io/k8s-skaffold/test-file-sync
88
context: .
99
sync:
10-
'**/foo*' : /test
10+
manual:
11+
- src: '**/foo*'
12+
dest: /test
1113
deploy:
1214
kubectl:
1315
manifests:

pkg/skaffold/runner/dev_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,8 @@ func TestDevSync(t *testing.T) {
346346
err := runner.Dev(context.Background(), ioutil.Discard, []*latest.Artifact{
347347
{
348348
ImageName: "img1",
349-
Sync: map[string]string{
350-
"file1": "file1",
349+
Sync: &latest.Sync{
350+
Manual: []*latest.SyncRule{{Src: "file1", Dest: "file1"}},
351351
},
352352
},
353353
{

0 commit comments

Comments
 (0)