environments = new HashMap<>();
String serverUrl;
if (serverConfig.getHttpPort() != 0)
serverUrl = "http://localhost:" + serverConfig.getHttpPort();
else
- serverUrl = "https://localhost:" + serverConfig.getSslConfig().getPort();
+ serverUrl = "https://localhost:" + serverConfig.getHttpsPort();
environments.put("ONEDEV_CURL", configManager.getSystemSetting().getCurlConfig().getExecutable());
environments.put("ONEDEV_URL", serverUrl);
diff --git a/server-core/src/main/java/io/onedev/server/maintenance/DefaultDataManager.java b/server-core/src/main/java/io/onedev/server/maintenance/DefaultDataManager.java
index 63aa57e8fb..1ea91d0881 100644
--- a/server-core/src/main/java/io/onedev/server/maintenance/DefaultDataManager.java
+++ b/server-core/src/main/java/io/onedev/server/maintenance/DefaultDataManager.java
@@ -38,7 +38,7 @@ import io.onedev.server.event.system.SystemStarting;
import io.onedev.server.model.Setting;
import io.onedev.server.model.Setting.Key;
import io.onedev.server.model.User;
-import io.onedev.server.model.support.DiscoveredJobExecutor;
+import io.onedev.server.model.support.AutoDiscoveredJobExecutor;
import io.onedev.server.model.support.setting.BackupSetting;
import io.onedev.server.model.support.setting.GlobalIssueSetting;
import io.onedev.server.model.support.setting.MailSetting;
@@ -154,7 +154,7 @@ public class DefaultDataManager implements DataManager, Serializable {
}
setting = settingManager.getSetting(Key.JOB_EXECUTORS);
if (setting == null) {
- settingManager.saveJobExecutors(Lists.newArrayList(new DiscoveredJobExecutor()));
+ settingManager.saveJobExecutors(Lists.newArrayList(new AutoDiscoveredJobExecutor()));
}
setting = settingManager.getSetting(Key.MAIL);
diff --git a/server-core/src/main/java/io/onedev/server/maintenance/Upgrade.java b/server-core/src/main/java/io/onedev/server/maintenance/Upgrade.java
index f926e22f90..152f3a721d 100644
--- a/server-core/src/main/java/io/onedev/server/maintenance/Upgrade.java
+++ b/server-core/src/main/java/io/onedev/server/maintenance/Upgrade.java
@@ -110,7 +110,14 @@ public class Upgrade extends DefaultPersistManager {
System.exit(1);
}
- if (upgradeDir.list().length != 0) {
+ boolean isEmpty = true;
+ for (File file: upgradeDir.listFiles()) {
+ if (!file.getName().equals("lost+found")) {
+ isEmpty = false;
+ break;
+ }
+ }
+ if (!isEmpty) {
if (!new File(upgradeDir, "boot/bootstrap.keys").exists()) {
logger.error("Invalid OneDev installation directory: {}, make sure you are specifying the top level "
+ "installation directory (it contains sub directories such as \"bin\", \"boot\", \"conf\", etc)",
diff --git a/server-core/src/main/java/io/onedev/server/model/support/DiscoveredJobExecutor.java b/server-core/src/main/java/io/onedev/server/model/support/AutoDiscoveredJobExecutor.java
similarity index 96%
rename from server-core/src/main/java/io/onedev/server/model/support/DiscoveredJobExecutor.java
rename to server-core/src/main/java/io/onedev/server/model/support/AutoDiscoveredJobExecutor.java
index b6214646b0..3aa36c3792 100644
--- a/server-core/src/main/java/io/onedev/server/model/support/DiscoveredJobExecutor.java
+++ b/server-core/src/main/java/io/onedev/server/model/support/AutoDiscoveredJobExecutor.java
@@ -13,7 +13,7 @@ import io.onedev.server.web.editable.EditableUtils;
import io.onedev.server.web.editable.annotation.Editable;
@Editable(order=10000, description="Discover appropriate job executor automatically to run CI jobs")
-public class DiscoveredJobExecutor extends JobExecutor {
+public class AutoDiscoveredJobExecutor extends JobExecutor {
private static final long serialVersionUID = 1L;
diff --git a/server-core/src/main/java/io/onedev/server/util/serverconfig/ServerConfig.java b/server-core/src/main/java/io/onedev/server/util/ServerConfig.java
similarity index 58%
rename from server-core/src/main/java/io/onedev/server/util/serverconfig/ServerConfig.java
rename to server-core/src/main/java/io/onedev/server/util/ServerConfig.java
index 1bf17784b8..8026bf5a42 100644
--- a/server-core/src/main/java/io/onedev/server/util/serverconfig/ServerConfig.java
+++ b/server-core/src/main/java/io/onedev/server/util/ServerConfig.java
@@ -1,4 +1,8 @@
-package io.onedev.server.util.serverconfig;
+package io.onedev.server.util;
+
+import java.io.File;
+
+import javax.annotation.Nullable;
public interface ServerConfig {
@@ -12,15 +16,15 @@ public interface ServerConfig {
*/
int getHttpPort();
- /**
- * Get ssl config of the server.
- *
- * @return
- * ssl config of the server, or null if ssl setting is not defined.
- * In case ssl setting is not defined, {@link #getHttpPort()} must not
- * return 0
- */
- SslConfig getSslConfig();
+ int getHttpsPort();
+
+ @Nullable
+ File getKeystoreFile();
+
+ String getKeystorePassword();
+
+ @Nullable
+ File getTrustCertsDir();
/**
* Get web session timeout in seconds.
diff --git a/server-core/src/main/java/io/onedev/server/util/serverconfig/SslConfig.java b/server-core/src/main/java/io/onedev/server/util/serverconfig/SslConfig.java
deleted file mode 100644
index e73270c45b..0000000000
--- a/server-core/src/main/java/io/onedev/server/util/serverconfig/SslConfig.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.onedev.server.util.serverconfig;
-
-public interface SslConfig {
- int getPort();
-
- String getKeystore();
-
- String getKeystorePassword();
-}
diff --git a/server-core/src/main/java/io/onedev/server/web/websocket/WebSocketPolicyProvider.java b/server-core/src/main/java/io/onedev/server/web/websocket/WebSocketPolicyProvider.java
index 190d4f8e6e..78627eb8b0 100644
--- a/server-core/src/main/java/io/onedev/server/web/websocket/WebSocketPolicyProvider.java
+++ b/server-core/src/main/java/io/onedev/server/web/websocket/WebSocketPolicyProvider.java
@@ -6,7 +6,7 @@ import javax.inject.Singleton;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
-import io.onedev.server.util.serverconfig.ServerConfig;
+import io.onedev.server.util.ServerConfig;
@Singleton
public class WebSocketPolicyProvider implements Provider {
diff --git a/server-plugin/server-plugin-kubernetes/pom.xml b/server-plugin/server-plugin-kubernetes/pom.xml
index 2019c8ce4b..4d2fbb08e5 100644
--- a/server-plugin/server-plugin-kubernetes/pom.xml
+++ b/server-plugin/server-plugin-kubernetes/pom.xml
@@ -1,4 +1,5 @@
-
4.0.0
server-plugin-kubernetes
@@ -7,6 +8,13 @@
server-plugin
3.0.1
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.62
+
+
io.onedev.server.plugin.kubernetes.KubernetesModule
diff --git a/server-plugin/server-plugin-kubernetes/src/main/java/io/onedev/server/plugin/kubernetes/KubernetesExecutor.java b/server-plugin/server-plugin-kubernetes/src/main/java/io/onedev/server/plugin/kubernetes/KubernetesExecutor.java
index 49bd371f7d..207f730fbc 100644
--- a/server-plugin/server-plugin-kubernetes/src/main/java/io/onedev/server/plugin/kubernetes/KubernetesExecutor.java
+++ b/server-plugin/server-plugin-kubernetes/src/main/java/io/onedev/server/plugin/kubernetes/KubernetesExecutor.java
@@ -1,10 +1,21 @@
package io.onedev.server.plugin.kubernetes;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.Serializable;
+import java.io.StringWriter;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
@@ -16,6 +27,8 @@ import javax.annotation.Nullable;
import org.apache.commons.codec.Charsets;
import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.util.io.pem.PemObject;
+import org.bouncycastle.util.io.pem.PemWriter;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,6 +58,7 @@ import io.onedev.server.model.support.JobExecutor;
import io.onedev.server.model.support.RegistryLogin;
import io.onedev.server.plugin.kubernetes.KubernetesExecutor.TestData;
import io.onedev.server.util.JobLogger;
+import io.onedev.server.util.ServerConfig;
import io.onedev.server.util.inputspec.SecretInput;
import io.onedev.server.web.editable.annotation.Editable;
import io.onedev.server.web.editable.annotation.NameOfEmptyValue;
@@ -410,6 +424,72 @@ public class KubernetesExecutor extends JobExecutor implements Testable configMapData = new LinkedHashMap<>();
+ ServerConfig serverConfig = OneDev.getInstance(ServerConfig.class);
+ File keystoreFile = serverConfig.getKeystoreFile();
+ if (keystoreFile != null) {
+ try (InputStream is = new FileInputStream(keystoreFile)) {
+ KeyStore keystore = KeyStore.getInstance("pkcs12");
+ keystore.load(is, serverConfig.getKeystorePassword().toCharArray());
+ Enumeration aliases = keystore.aliases();
+ while (aliases.hasMoreElements()) {
+ String alias = aliases.nextElement();
+ String siteCertContent = getCertContent(keystore.getCertificate(alias));
+ String safeAlias = alias.replaceAll("[^a-zA-Z0-9\\.\\_]", "-");
+ configMapData.put("keystore-site-cert-" + safeAlias + ".pem", siteCertContent);
+
+ Certificate chain[] = keystore.getCertificateChain(alias);
+ if (chain != null) {
+ for (int i=0; i configMapDef = Maps.newLinkedHashMap(
+ "apiVersion", "v1",
+ "kind", "ConfigMap",
+ "metadata", Maps.newLinkedHashMap(
+ "generateName", "configmap-",
+ "namespace", "onedev"),
+ "data", configMapData);
+ return createResource(configMapDef, new HashSet<>(), logger);
+ } else {
+ return null;
+ }
+ }
+
private void execute(String dockerImage, String jobToken, JobLogger logger, @Nullable JobContext jobContext) {
logger.log("Executing job with Kubernetes executor...");
@@ -417,10 +497,12 @@ public class KubernetesExecutor extends JobExecutor implements Testable jobSecrets = Maps.newLinkedHashMap(KubernetesHelper.ENV_JOB_TOKEN, jobToken);
jobSecretName = createSecret(jobSecrets, null, logger);
imagePullSecretName = createImagePullSecret(logger);
+ trustCertsConfigMapName = createTrustCertsConfigMap(logger);
String osName = getOSName(logger);
@@ -433,28 +515,36 @@ public class KubernetesExecutor extends JobExecutor implements Testable ciPathMount = Maps.newLinkedHashMap(
+ Map ciHomeMount = Maps.newLinkedHashMap(
"name", "ci-home",
"mountPath", containerCIHome);
Map cacheHomeMount = Maps.newLinkedHashMap(
"name", "cache-home",
"mountPath", containerCacheHome);
+ Map trustCertsMount = Maps.newLinkedHashMap(
+ "name", "trust-certs-home",
+ "mountPath", trustCertsHome);
- List