Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move jib sync testdata to integration/examples #4367

Merged
merged 4 commits into from
Jun 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions integration/examples/jib-sync/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
### Example: Jib Sync

[Jib](https://github.com/GoogleContainerTools/jib) is one of the supported builders in Skaffold. Jib
has special sync support using the `auto` configuration.

## Running the example

Run the maven or gradle version of the example with port forwarding on.

#### Gradle
```
$ skaffold dev -f skaffold-gradle.yaml --port-forward
```

#### Maven
```
$ skaffold dev -f skaffold-maven.yaml --port-forward
```

You can now see sync in action:
1. See the original response from the `HelloController` in the spring application
```
$ curl localhost:8080
text-to-replace
```
1. Edit the hello controller `src/main/java/hello/HelloController.java`
```diff
+ return "some-new-text\n";
- return "text-to-replace\n";
```
1. Give skaffold a few seconds to synchronize the file to the container, and give Spring
Boot Developer Tools a chance to reload your application.
1. See the updated response from the `HelloController`
```
$ curl localhost:8080
some-new-text
```
1. You've now seen auto sync in action!

## How it works

This example contains both maven and gradle build configs and separate skaffold.yamls.

- **gradle**: `skaffold-gradle.yaml`
- **maven**: `skaffold-maven.yaml`

use the `-f` flag to specify the correct buildfile when running (or rename your preferred option to `skaffold.yaml`)
```
$ skaffold -f skaffold-gradle.yaml ...
```

We configure it in `skaffold.yaml`, by enabling sync on the jib artifact.

```yaml
build:
artifacts:
- image: skaffold-example
context: .
jib: {}
sync:
auto: {}
```

This example is designed around the functionality available in [Spring Boot Developer Tools](https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools) for developing against running applications.

Some additional steps in your java build are required for this to work:
- Sync requires `tar` on the running container to copy files over. The default base image that Jib uses `gcr.io/distroless/java` does not include `tar` or any utilities. During development you must use a base image that includes `tar`, in this example we use the `debug` flavor of distroless: `gcr.io/distroless/java:debug`

`maven`
loosebazooka marked this conversation as resolved.
Show resolved Hide resolved
```xml
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>${jib.maven-plugin-version}</version>
<configuration>
...
<from>
<image>gcr.io/distroless/java:debug</image>
</from>
</configuration>
</plugin>
```

`gradle`
```groovy
jib {
...
from {
image = "gcr.io/distroless/java:debug"
}
}
```

- You must include the `spring-boot-devtools` dependency at the `compile/implementation` scope, which is contrary to the configuration outlined in the [official docs](https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools). Because jib is unaware of any special spring only configuration in your builds, we recommend using profiles to turn on or off devtools support in your jib container builds.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Jib currently includes spring-boot-devtools even if <optional>true. (And we decided to take care of this using an extension.) Should we still advise to set <scope>compile?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we leave optional dependencies out. no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it's not explicitly resolved to be a runtime dependency.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh about the scope, <compile> is default isn't it?

Copy link
Member

@chanseokoh chanseokoh Jun 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, right, compile is already the default. Then, the Spring Boot doc only adds <optional>true, so I think this comment to add it as compile doesn't apply.

And I think we include spring-boot-devtools regardless of <optional>true. (Would be good to double-check.)

Copy link
Member Author

@loosebazooka loosebazooka Jun 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah you're right. I can say <!-- optional not necessary -->


`maven`
```xml
<profiles>
<profile>
<id>sync<id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<!-- <optional>true</optional> not required -->
</dependency>
</dependencies>
</profile>
</profiles>
```

`gradle`
```groovy
dependencies {
...
if (project.hasProperty('sync')) {
implementation "org.springframework.boot:spring-boot-devtools"
// do not use developmentOnly
}
}
```

To activate these profiles, we add `-Psync` to the maven/gradle build command. This can be done directly in the artifact configuration

`skaffold.yaml`
```
build:
artifacts:
- image: skaffold-example
context: .
jib:
args:
- -Psync
sync:
auto: {}
```

You can also take advantage of [skaffold profiles](https://skaffold.dev/docs/environment/profiles/) to control when to activate sync on your project.

`skaffold.yaml`
```
build:
artifacts:
- image: test-file-sync
jib: {}

profiles:
- name: sync
patches:
# assuming jib is the first artifact (index 0) in your build.artifacts list
- op: add
# we want to activate sync on our skaffold artifact
path: /build/artifacts/0/sync
value:
- auto: {}
- op: add
# we activate the sync profile in our java builds
path: /build/artifacts/0/jib/args
value:
- -Psync
```

skaffold profiles can be activated using the the `-p` flag when running

```
$ skaffold -p sync ...
```
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-devtools"
implementation "org.springframework.boot:spring-boot-starter-web"
implementation "org.springframework.boot:spring-boot-starter-actuator"
if (project.hasProperty('sync')) {
implementation "org.springframework.boot:spring-boot-devtools"
}

testCompile("org.springframework.boot:spring-boot-starter-test")
testImplementation "org.springframework.boot:spring-boot-starter-test"
}

jib {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ spec:
containers:
- name: test-file-sync
image: test-file-sync
ports:
- containerPort: 8080
File renamed without changes.
65 changes: 65 additions & 0 deletions integration/examples/jib-sync/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.skaffold</groupId>
<artifactId>hello-spring-boot</artifactId>
<version>0.1.0</version>
<description>Spring Boot with Skaffold and Jib</description>

<properties>
<java.version>1.8</java.version>
<jib.maven-plugin-version>2.4.0</jib.maven-plugin-version>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

<build>
<finalName>hello</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>${jib.maven-plugin-version}</version>
<configuration>
<from>
<image>gcr.io/distroless/java:debug</image>
</from>
<container>
<jvmFlags>
<jvmFlag>-Djava.security.egd=file:/dev/./urandom</jvmFlag>
</jvmFlags>
</container>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>sync</id>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<!-- <optional>true</optional> not required -->
</dependency>
</dependencies>
</profile>
</profiles>
</project>
16 changes: 16 additions & 0 deletions integration/examples/jib-sync/skaffold-gradle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: skaffold/v2beta5
kind: Config
build:
artifacts:
- image: test-file-sync
jib:
type: gradle
args:
- -Psync
sync:
auto: {}

portForward:
- resourceType: pod
resourceName: test-file-sync
port: 8080
loosebazooka marked this conversation as resolved.
Show resolved Hide resolved
17 changes: 17 additions & 0 deletions integration/examples/jib-sync/skaffold-maven.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: skaffold/v2beta5
kind: Config
build:
artifacts:
- image: test-file-sync
jib:
type: maven
args:
- --no-transfer-progress
- -Psync
sync:
auto: {}

portForward:
- resourceType: pod
resourceName: test-file-sync
port: 8080
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ public class HelloController {

@RequestMapping("/")
public String index() throws Exception {
return "text-to-replace";
return "text-to-replace\n";
}
}
11 changes: 6 additions & 5 deletions integration/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,32 +82,33 @@ func TestDevSync(t *testing.T) {
func TestDevAutoSync(t *testing.T) {
MarkIntegrationTest(t, CanRunWithoutGcp)

dir := "testdata/jib-sync/"
dir := "examples/jib-sync/"

tests := []struct {
description string
configFile string
profiles []string
uniqueStr string
}{
{
description: "jib maven auto sync",
profiles: []string{"maven"},
configFile: "skaffold-maven.yaml",
uniqueStr: "maven-maven",
},
{
description: "jib gradle auto sync",
profiles: []string{"gradle"},
configFile: "skaffold-gradle.yaml",
uniqueStr: "gradle-gradle",
},
}
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
// Run skaffold build first to fail quickly on a build failure
skaffold.Build().WithProfiles(test.profiles).InDir(dir).RunOrFail(t)
skaffold.Build().WithConfig(test.configFile).InDir(dir).RunOrFail(t)

ns, client := SetupNamespace(t)

output := skaffold.Dev("--trigger", "notify").WithProfiles(test.profiles).InDir(dir).InNs(ns.Name).RunBackground(t)
output := skaffold.Dev("--trigger", "notify").WithConfig(test.configFile).InDir(dir).InNs(ns.Name).RunBackground(t)

client.WaitForPodsReady("test-file-sync")

Expand Down
56 changes: 0 additions & 56 deletions integration/testdata/jib-sync/pom.xml

This file was deleted.