Skip to content

Commit 9194634

Browse files
authored
feat(kube-api-test): use binaries from GitHub releases (6281)
improve: use new GitHub based binary repo for KubeAPITest Signed-off-by: Attila Mészáros <[email protected]> --- wip Signed-off-by: Attila Mészáros <[email protected]> --- cleanup Signed-off-by: Attila Mészáros <[email protected]> --- add missing license Signed-off-by: Attila Mészáros <[email protected]> --- naming Signed-off-by: Attila Mészáros <[email protected]> --- changelog update Signed-off-by: Attila Mészáros <[email protected]> --- test update Signed-off-by: Attila Mészáros <[email protected]> --- sonar fixes Signed-off-by: Attila Mészáros <[email protected]>
1 parent 24f1b8e commit 9194634

File tree

9 files changed

+143
-72
lines changed

9 files changed

+143
-72
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Fix #5264: Remove deprecated `Config.errorMessages` field
99
* Fix #6008: removing the optional dependency on bouncy castle
1010
* Fix #6230: introduced Quantity.multiply(int) to allow for Quantity multiplication by an integer
11+
* Fix #6281: use GitHub binary repo for Kube API Tests
1112

1213
#### Dependency Upgrade
1314
* Fix #6052: Removed dependency on no longer maintained com.github.mifmif:generex

junit/kube-api-test/core/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,5 +106,9 @@
106106
<groupId>io.javaoperatorsdk</groupId>
107107
<artifactId>kubernetes-webhooks-framework-core</artifactId>
108108
</dependency>
109+
<dependency>
110+
<groupId>com.fasterxml.jackson.dataformat</groupId>
111+
<artifactId>jackson-dataformat-yaml</artifactId>
112+
</dependency>
109113
</dependencies>
110114
</project>

junit/kube-api-test/core/src/main/java/io/fabric8/kubeapitest/binary/BinaryDownloader.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ public class BinaryDownloader {
3939

4040
private static final Logger log = LoggerFactory.getLogger(BinaryDownloader.class);
4141

42-
private static final String OBJECT_TAR_PREFIX = "kubebuilder-tools-";
43-
4442
private final String kubeAPITestDir;
4543
private final BinaryRepo binaryRepo;
4644
private final OSInfo osInfoProvider;
@@ -161,15 +159,8 @@ public String findLatestOfWildcard(String wildcardVersion) {
161159

162160
private Stream<String> listAllRelevantVersions() {
163161
var objects = binaryRepo.listObjectNames();
164-
return objects.filter(o -> o.contains(osInfoProvider.getOSName())
165-
&& o.contains(osInfoProvider.getOSArch()))
166-
.map(o -> {
167-
String stripped = o.replace(OBJECT_TAR_PREFIX, "");
168-
String version = stripped.substring(0, stripped.indexOf("-"));
169-
if (version.startsWith("v")) {
170-
version = version.substring(1);
171-
}
172-
return version;
173-
});
162+
return objects.filter(o -> o.getOs().equals(osInfoProvider.getOSName())
163+
&& o.getArch().equals(osInfoProvider.getOSArch()))
164+
.map(o -> o.getVersion());
174165
}
175166
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (C) 2015 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.fabric8.kubeapitest.binary.repo;
17+
18+
public class ArchiveDescriptor {
19+
20+
private final String version;
21+
private final String arch;
22+
private final String os;
23+
24+
public ArchiveDescriptor(String version, String arch, String os) {
25+
this.version = version;
26+
this.arch = arch;
27+
this.os = os;
28+
}
29+
30+
public String getVersion() {
31+
return version;
32+
}
33+
34+
public String getArch() {
35+
return arch;
36+
}
37+
38+
public String getOs() {
39+
return os;
40+
}
41+
}
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,24 @@
1515
*/
1616
package io.fabric8.kubeapitest.binary.repo;
1717

18-
public class ObjectListItem {
18+
public class ArchiveReference {
1919

20-
private String name;
20+
private String selfLink;
21+
private String hash;
2122

22-
public String getName() {
23-
return name;
23+
public String getSelfLink() {
24+
return selfLink;
2425
}
2526

26-
public ObjectListItem setName(String name) {
27-
this.name = name;
28-
return this;
27+
public void setSelfLink(String selfLink) {
28+
this.selfLink = selfLink;
29+
}
30+
31+
public String getHash() {
32+
return hash;
33+
}
34+
35+
public void setHash(String hash) {
36+
this.hash = hash;
2937
}
3038
}
Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,17 @@
1515
*/
1616
package io.fabric8.kubeapitest.binary.repo;
1717

18-
import java.util.List;
18+
import java.util.Map;
1919

20-
public class ObjectList {
20+
public class BinaryIndex {
2121

22-
private List<ObjectListItem> items;
22+
private Map<String, Map<String, ArchiveReference>> releases;
2323

24-
public List<ObjectListItem> getItems() {
25-
return items;
24+
public Map<String, Map<String, ArchiveReference>> getReleases() {
25+
return releases;
2626
}
2727

28-
public ObjectList setItems(List<ObjectListItem> items) {
29-
this.items = items;
30-
return this;
28+
public void setReleases(Map<String, Map<String, ArchiveReference>> releases) {
29+
this.releases = releases;
3130
}
3231
}

junit/kube-api-test/core/src/main/java/io/fabric8/kubeapitest/binary/repo/BinaryRepo.java

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
*/
1616
package io.fabric8.kubeapitest.binary.repo;
1717

18-
import com.fasterxml.jackson.databind.DeserializationFeature;
1918
import com.fasterxml.jackson.databind.ObjectMapper;
19+
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
2020
import io.fabric8.kubeapitest.KubeAPITestException;
2121
import io.fabric8.kubeapitest.binary.OSInfo;
2222
import org.slf4j.Logger;
@@ -25,36 +25,58 @@
2525
import java.io.File;
2626
import java.io.IOException;
2727
import java.io.InputStream;
28-
import java.net.URI;
2928
import java.net.URL;
30-
import java.net.http.HttpClient;
31-
import java.net.http.HttpRequest;
32-
import java.net.http.HttpResponse;
3329
import java.nio.file.Files;
3430
import java.nio.file.StandardCopyOption;
3531
import java.util.List;
36-
import java.util.concurrent.locks.ReentrantLock;
3732
import java.util.stream.Collectors;
3833
import java.util.stream.Stream;
3934

4035
public class BinaryRepo {
4136

4237
private static final Logger log = LoggerFactory.getLogger(BinaryRepo.class);
4338

39+
private static final String BINARY_INDEX_URL = "https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/HEAD/envtest-releases.yaml";
40+
private static final ObjectMapper MAPPER = new ObjectMapper(new YAMLFactory());
41+
public static final String TAR_GZ_SUFFIX = ".tar.gz";
42+
43+
private static List<ArchiveDescriptor> objectNames;
44+
4445
private final OSInfo osInfo;
45-
private static List<String> objectNames;
46-
private static final ReentrantLock downloadLock = new ReentrantLock();
4746

4847
public BinaryRepo(OSInfo osInfo) {
4948
this.osInfo = osInfo;
5049
}
5150

51+
public synchronized Stream<ArchiveDescriptor> listObjectNames() {
52+
try {
53+
if (objectNames == null) {
54+
var index = MAPPER.readValue(new URL(BINARY_INDEX_URL), BinaryIndex.class);
55+
objectNames = index.getReleases().values().stream().flatMap(v -> v.values().stream()).map(
56+
a -> mapSelfLinkToArchiveDescriptor(a.getSelfLink()))
57+
.collect(Collectors.toList());
58+
}
59+
return objectNames.stream();
60+
} catch (IOException e) {
61+
throw new KubeAPITestException(e);
62+
}
63+
}
64+
65+
static ArchiveDescriptor mapSelfLinkToArchiveDescriptor(String selfLink) {
66+
var versionOsArch = selfLink.split("/")[8]
67+
.replace("envtest-v", "")
68+
.replace(TAR_GZ_SUFFIX, "")
69+
.split("-");
70+
71+
return new ArchiveDescriptor(versionOsArch[0], versionOsArch[2], versionOsArch[1]);
72+
}
73+
5274
public File downloadVersionToTempFile(String version) {
5375
try {
54-
String url = "https://storage.googleapis.com/kubebuilder-tools/kubebuilder-tools-" + version +
55-
"-" + osInfo.getOSName() + "-" + osInfo.getOSArch() + ".tar.gz";
76+
String url = "https://github.com/kubernetes-sigs/controller-tools/releases/download/envtest-v" + version +
77+
"/envtest-v" + version + "-" + osInfo.getOSName() + "-" + osInfo.getOSArch() + TAR_GZ_SUFFIX;
5678

57-
File tempFile = File.createTempFile("kubebuilder-tools-" + version, ".tar.gz");
79+
File tempFile = File.createTempFile("kubebuilder-tools-" + version, TAR_GZ_SUFFIX);
5880
log.debug("Downloading binary from url: {} to Temp file: {}", url, tempFile.getPath());
5981
copyURLToFile(url, tempFile);
6082
return tempFile;
@@ -68,35 +90,4 @@ private void copyURLToFile(String url, File tempFile) throws IOException {
6890
Files.copy(in, tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
6991
}
7092
}
71-
72-
public Stream<String> listObjectNames() {
73-
downloadLock.lock();
74-
try {
75-
if (objectNames == null) {
76-
log.debug("Listing objects from storage");
77-
var httpClient = HttpClient.newBuilder()
78-
.build();
79-
80-
HttpRequest request = HttpRequest.newBuilder()
81-
.GET()
82-
.uri(URI.create("https://storage.googleapis.com/storage/v1/b/kubebuilder-tools/o"))
83-
.build();
84-
85-
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()).body();
86-
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
87-
ObjectList objectList = mapper.readValue(response, ObjectList.class);
88-
objectNames = objectList.getItems().stream().map(ObjectListItem::getName)
89-
.collect(Collectors.toList());
90-
}
91-
return objectNames.stream();
92-
} catch (IOException e) {
93-
throw new KubeAPITestException(e);
94-
} catch (InterruptedException e) {
95-
Thread.currentThread().interrupt();
96-
throw new KubeAPITestException(e);
97-
} finally {
98-
downloadLock.unlock();
99-
}
100-
}
101-
10293
}

junit/kube-api-test/core/src/test/java/io/fabric8/kubeapitest/binary/BinaryDownloaderTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package io.fabric8.kubeapitest.binary;
1717

18+
import io.fabric8.kubeapitest.binary.repo.ArchiveDescriptor;
1819
import io.fabric8.kubeapitest.binary.repo.BinaryRepo;
1920
import org.junit.jupiter.api.Test;
2021
import org.mockito.Mockito;
@@ -38,9 +39,9 @@ void findsLatestBinary() {
3839
when(mockOsInfo.getOSArch()).thenReturn("amd64");
3940

4041
when(mockBinaryRepo.listObjectNames()).thenReturn(List.of(
41-
"kubebuilder-tools-1.17.9-linux-amd64.tar.gz"
42-
,"kubebuilder-tools-1.26.1-darwin-amd64.tar.gz",
43-
"kubebuilder-tools-"+VERSION+"-linux-amd64.tar.gz")
42+
new ArchiveDescriptor("1.17.9","amd64","linux"),
43+
new ArchiveDescriptor("1.26.1","amd64","darwin"),
44+
new ArchiveDescriptor(VERSION,"amd64","linux"))
4445
.stream());
4546

4647
var latest = binaryDownloader.findLatestVersion();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (C) 2015 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.fabric8.kubeapitest.binary.repo;
17+
18+
import org.junit.jupiter.api.Test;
19+
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
22+
class BinaryRepoTest {
23+
24+
@Test
25+
void parsesSelfLinkToArchiveDescriptor() {
26+
var archiveDescriptor = BinaryRepo
27+
.mapSelfLinkToArchiveDescriptor(
28+
"https://github.com/kubernetes-sigs/controller-tools/releases/download/envtest-v1.28.0/envtest-v1.28.0-linux-arm64.tar.gz");
29+
30+
assertThat(archiveDescriptor.getOs()).isEqualTo("linux");
31+
assertThat(archiveDescriptor.getArch()).isEqualTo("arm64");
32+
assertThat(archiveDescriptor.getVersion()).isEqualTo("1.28.0");
33+
}
34+
35+
}

0 commit comments

Comments
 (0)