Jenkins(2020年及以后版本,2.260以上)安装后,插件下载时失败,网上找了各种解决方法,修改jenkins插件的下载源地址:
找到菜单Manage Jenkins → Manage Plugins → Advanced → Update Site,
把URL改为 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
或把默认地址 https://updates.jenkins.io/update-center.json 的https改为http再重启。
我把这些方法都试了以后,下载插件还是报错,心拨凉拨凉的。学技术的都最怕遇到环境问题,一个小环境问题可能要倒腾好几天。
嘿嘿,在我刚要选择投降放弃时,柳暗花明又一村,摸索到了以下Jenkins安装插件失败的另一种解决方法。
(Update Site的默认URL不需要动)
1.报错图:
报错的首行提示:sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
报错原因:访问https的插件地址因为安全证书问题而报错。
2.解决方案:
1.先编译如下文件InstallCert.java
命令:javac InstallCert.java;
2.再运行InstallCert类,命令:java InstallCert <hostname>;出现提示后按1,回车。会生成jssecacerts 文件。
PS:此处hostname 为 mirrors.tuna.tsinghua.edu.cn,国内jenkins下载插件的地址会重定向到清华大学提供的镜像文件库。
3.然后将生成的 jssecacerts 文件,拷贝到jdk中,目录位置:%JAVA_HOME%jrelibsecurity
(例如 D:Program FilesJavajdk1.8.0_71jrelibsecurity)
4.最后重新启动jenkins,证书才能生效。
文件:InstallCert.java
1 /*
2 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * - Neither the name of Sun Microsystems nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 import java.io.BufferedReader;
33 import java.io.File;
34 import java.io.FileInputStream;
35 import java.io.FileOutputStream;
36 import java.io.InputStream;
37 import java.io.InputStreamReader;
38 import java.io.OutputStream;
39 import java.security.KeyStore;
40 import java.security.MessageDigest;
41 import java.security.cert.CertificateException;
42 import java.security.cert.X509Certificate;
43
44 import javax.net.ssl.SSLContext;
45 import javax.net.ssl.SSLException;
46 import javax.net.ssl.SSLSocket;
47 import javax.net.ssl.SSLSocketFactory;
48 import javax.net.ssl.TrustManager;
49 import javax.net.ssl.TrustManagerFactory;
50 import javax.net.ssl.X509TrustManager;
51
52 public class InstallCert {
53
54 public static void main(String[] args) throws Exception {
55 String host;
56 int port;
57 char[] passphrase;
58 if ((args.length == 1) || (args.length == 2)) {
59 String[] c = args[0].split(":");
60 host = c[0];
61 port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
62 String p = (args.length == 1) ? "changeit" : args[1];
63 passphrase = p.toCharArray();
64 } else {
65 System.out
66 .println("Usage: java InstallCert <host>[:port] [passphrase]");
67 return;
68 }
69
70 File file = new File("jssecacerts");
71 if (file.isFile() == false) {
72 char SEP = File.separatorChar;
73 File dir = new File(System.getProperty("java.home") + SEP + "lib"
74 + SEP + "security");
75 file = new File(dir, "jssecacerts");
76 if (file.isFile() == false) {
77 file = new File(dir, "cacerts");
78 }
79 }
80 System.out.println("Loading KeyStore " + file + "...");
81 InputStream in = new FileInputStream(file);
82 KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
83 ks.load(in, passphrase);
84 in.close();
85
86 SSLContext context = SSLContext.getInstance("TLS");
87 TrustManagerFactory tmf = TrustManagerFactory
88 .getInstance(TrustManagerFactory.getDefaultAlgorithm());
89 tmf.init(ks);
90 X509TrustManager defaultTrustManager = (X509TrustManager) tmf
91 .getTrustManagers()[0];
92 SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
93 context.init(null, new TrustManager[] { tm }, null);
94 SSLSocketFactory factory = context.getSocketFactory();
95
96 System.out
97 .println("Opening connection to " + host + ":" + port + "...");
98 SSLSocket socket = (SSLSocket) factory.createSocket(host, port);
99 socket.setSoTimeout(10000);
100 try {
101 System.out.println("Starting SSL handshake...");
102 socket.startHandshake();
103 socket.close();
104 System.out.println();
105 System.out.println("No errors, certificate is already trusted");
106 } catch (SSLException e) {
107 System.out.println();
108 e.printStackTrace(System.out);
109 }
110
111 X509Certificate[] chain = tm.chain;
112 if (chain == null) {
113 System.out.println("Could not obtain server certificate chain");
114 return;
115 }
116
117 BufferedReader reader = new BufferedReader(new InputStreamReader(
118 System.in));
119
120 System.out.println();
121 System.out.println("Server sent " + chain.length + " certificate(s):");
122 System.out.println();
123 MessageDigest sha1 = MessageDigest.getInstance("SHA1");
124 MessageDigest md5 = MessageDigest.getInstance("MD5");
125 for (int i = 0; i < chain.length; i++) {
126 X509Certificate cert = chain[i];
127 System.out.println(" " + (i + 1) + " Subject "
128 + cert.getSubjectDN());
129 System.out.println(" Issuer " + cert.getIssuerDN());
130 sha1.update(cert.getEncoded());
131 System.out.println(" sha1 " + toHexString(sha1.digest()));
132 md5.update(cert.getEncoded());
133 System.out.println(" md5 " + toHexString(md5.digest()));
134 System.out.println();
135 }
136
137 System.out
138 .println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
139 String line = reader.readLine().trim();
140 int k;
141 try {
142 k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
143 } catch (NumberFormatException e) {
144 System.out.println("KeyStore not changed");
145 return;
146 }
147
148 X509Certificate cert = chain[k];
149 String alias = host + "-" + (k + 1);
150 ks.setCertificateEntry(alias, cert);
151
152 OutputStream out = new FileOutputStream("jssecacerts");
153 ks.store(out, passphrase);
154 out.close();
155
156 System.out.println();
157 System.out.println(cert);
158 System.out.println();
159 System.out
160 .println("Added certificate to keystore 'jssecacerts' using alias '"
161 + alias + "'");
162 }
163
164 private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
165
166 private static String toHexString(byte[] bytes) {
167 StringBuilder sb = new StringBuilder(bytes.length * 3);
168 for (int b : bytes) {
169 b &= 0xff;
170 sb.append(HEXDIGITS[b >> 4]);
171 sb.append(HEXDIGITS[b & 15]);
172 sb.append(' ');
173 }
174 return sb.toString();
175 }
176
177 private static class SavingTrustManager implements X509TrustManager {
178
179 private final X509TrustManager tm;
180 private X509Certificate[] chain;
181
182 SavingTrustManager(X509TrustManager tm) {
183 this.tm = tm;
184 }
185
186 public X509Certificate[] getAcceptedIssuers() {
187 throw new UnsupportedOperationException();
188 }
189
190 public void checkClientTrusted(X509Certificate[] chain, String authType)
191 throws CertificateException {
192 throw new UnsupportedOperationException();
193 }
194
195 public void checkServerTrusted(X509Certificate[] chain, String authType)
196 throws CertificateException {
197 this.chain = chain;
198 tm.checkServerTrusted(chain, authType);
199 }
200 }
201
202 }
PS:1.尝遍了各种解决方法后,总有一款适合你(嘻嘻)。
3.终极解决方案:
宝宝不怕麻烦的话,就是比较费时间而已,可以手动一个个下载jenkins插件放到 ~.jenkinsplugins 目录下,重启jenkins即可实现换道成功。
笔者也整理了一份常用的jenkins插件集:Allure、HTML Publisher、Ant In Workspace、Subversion、git、Email Extension。
有需要的童鞋可以加技术交流QQ群获取,记得备注:博客园
有任何软件测试技术问题,呼叫群主管理员帮你解决