Skip to content

Commit 8336a9e

Browse files
authored
Merge pull request #232 from saucelabs/alexh-handle-legacy-sc-cli
Handle legacy SC CLI options
2 parents 757f769 + d465084 commit 8336a9e

File tree

18 files changed

+357
-58
lines changed

18 files changed

+357
-58
lines changed

CHANGELOG.md

+19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
1+
# Jenkins 2.0 - 2025-01-15
2+
3+
This is a new major version of the Sauce Ondemand Plugin to support Sauce
4+
Connect 5.
5+
6+
There is a new option field added to the 'Freestyle' projects called "Sauce
7+
Connect v5 Options", and a new argument to 'Pipeline' projects is added called
8+
`optionsSC5`. This is meant to be used for all new versions, and the previous
9+
field has been renamed "Sauce Connect v4 Legacy Options".
10+
11+
If you have anything in the legacy options, it will run the Sauce Connect
12+
client in `sc legacy` mode, and it will continue to work as before. **Note:**
13+
This legacy field/argument will be removed in a future release, so please
14+
convert your command line options to the new options format. See the [SC 5 Migration](https://docs.saucelabs.com/secure-connections/sauce-connect-5/migrating/#cli-changes-in-sauce-connect-5)
15+
docs for more details.
16+
17+
If the legacy options are empty, the SC client will be started in `sc run`
18+
mode, any no additional changes are needed.
19+
120
# Jenkins 1.206 - 2022-11-07
221

322
* Bump saucerest from 1.1.8 to 1.1.9

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<!-- Baseline Jenkins version you use to build the plugin. Users must have this version or newer to run. -->
1515
<jenkins.baseline>2.452</jenkins.baseline>
1616
<jenkins.version>${jenkins.baseline}.4</jenkins.version>
17-
<ci-sauce.version>2.1</ci-sauce.version>
17+
<ci-sauce.version>2.3</ci-sauce.version>
1818
<saucerest.version>2.5.3</saucerest.version>
1919
</properties>
2020

src/main/java/com/saucelabs/jenkins/pipeline/SauceConnectStep.java

+45-15
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.saucelabs.ci.sauceconnect.AbstractSauceTunnelManager;
77
import com.saucelabs.ci.sauceconnect.SauceConnectManager;
88
import com.saucelabs.jenkins.HudsonSauceManagerFactory;
9+
import com.saucelabs.saucerest.DataCenter;
910
import edu.umd.cs.findbugs.annotations.NonNull;
1011
import hudson.Extension;
1112
import hudson.ProxyConfiguration;
@@ -48,25 +49,28 @@ public class SauceConnectStep extends Step {
4849
private Boolean useLatestSauceConnect = false;
4950
private Boolean useGeneratedTunnelIdentifier = false;
5051
private String options;
52+
private String optionsSC5;
5153
private String sauceConnectPath;
5254

5355
@DataBoundConstructor
5456
public SauceConnectStep() {
5557
}
5658

57-
public SauceConnectStep(String options, Boolean verboseLogging, Boolean useLatestSauceConnect, Boolean useGeneratedTunnelIdentifier, String sauceConnectPath) {
59+
public SauceConnectStep(String options, String optionsSC5, Boolean verboseLogging, Boolean useLatestSauceConnect, Boolean useGeneratedTunnelIdentifier, String sauceConnectPath) {
5860
this.verboseLogging = verboseLogging;
5961
this.useLatestSauceConnect = useLatestSauceConnect;
6062
this.useGeneratedTunnelIdentifier = useGeneratedTunnelIdentifier;
6163
this.sauceConnectPath = Util.fixEmptyAndTrim(sauceConnectPath);
6264
this.options = StringUtils.trimToEmpty(options);
65+
this.optionsSC5 = StringUtils.trimToEmpty(optionsSC5);
6366
}
6467

6568
@Override
6669
public StepExecution start(StepContext context) throws Exception {
6770
return new SauceConnectStepExecution(context,
6871
PluginImpl.get().getSauceConnectOptions(),
6972
options,
73+
optionsSC5,
7074
useGeneratedTunnelIdentifier,
7175
verboseLogging,
7276
sauceConnectPath,
@@ -82,7 +86,16 @@ public String getOptions() {
8286

8387
@DataBoundSetter
8488
public void setOptions(String options) {
85-
this.options = options;
89+
this.options = options.strip();
90+
}
91+
92+
public String getOptionsSC5() {
93+
return optionsSC5;
94+
}
95+
96+
@DataBoundSetter
97+
public void setOptionsSC5(String optionsSC5) {
98+
this.optionsSC5 = optionsSC5.strip();
8699
}
87100

88101
public String getSauceConnectPath() {
@@ -154,16 +167,18 @@ private static final class SauceStartConnectHandler extends MasterToSlaveCallabl
154167
private final Boolean verboseLogging;
155168
private final String sauceConnectPath;
156169
private final Boolean useLatestSauceConnect;
170+
private final Boolean legacyCLI;
157171
private final ProxyConfiguration proxy;
158172

159-
SauceStartConnectHandler(SauceCredentials sauceCredentials, int port, String options, TaskListener listener, Boolean verboseLogging, String sauceConnectPath, Boolean useLatestSauceConnect, ProxyConfiguration proxy) {
173+
SauceStartConnectHandler(SauceCredentials sauceCredentials, int port, String options, TaskListener listener, Boolean verboseLogging, String sauceConnectPath, Boolean useLatestSauceConnect, Boolean legacyCLI, ProxyConfiguration proxy) {
160174
this.sauceCredentials = sauceCredentials;
161175
this.port = port;
162-
this.options = options;
176+
this.options = options.strip();
163177
this.listener = listener;
164178
this.verboseLogging = verboseLogging;
165179
this.sauceConnectPath = sauceConnectPath;
166180
this.useLatestSauceConnect = useLatestSauceConnect;
181+
this.legacyCLI = legacyCLI;
167182
this.proxy = proxy;
168183
}
169184

@@ -175,13 +190,14 @@ public Void call() throws AbstractSauceTunnelManager.SauceConnectException {
175190
sauceTunnelManager.openConnection(
176191
sauceCredentials.getUsername(),
177192
sauceCredentials.getApiKey().getPlainText(),
178-
sauceCredentials.getRestEndpointName(),
193+
DataCenter.fromString(sauceCredentials.getRestEndpointName()),
179194
port,
180195
null, /*sauceConnectJar,*/
181196
options,
182197
listener.getLogger(),
183198
verboseLogging,
184-
sauceConnectPath
199+
sauceConnectPath,
200+
legacyCLI
185201
);
186202
return null;
187203
}
@@ -217,6 +233,7 @@ public Void call() throws AbstractSauceTunnelManager.SauceConnectException {
217233
public static class SauceConnectStepExecution extends StepExecution {
218234
private final String globalOptions;
219235
private final String options;
236+
private final String optionsSC5;
220237
private final boolean useGeneratedTunnelIdentifier;
221238
private final boolean verboseLogging;
222239
private final String sauceConnectPath;
@@ -231,6 +248,7 @@ public SauceConnectStepExecution(
231248
@NonNull StepContext context,
232249
String globalOptions,
233250
String options,
251+
String optionsSC5,
234252
boolean useGeneratedTunnelIdentifier,
235253
boolean verboseLogging,
236254
String sauceConnectPath,
@@ -240,6 +258,7 @@ public SauceConnectStepExecution(
240258
super(context);
241259
this.globalOptions = globalOptions;
242260
this.options = options;
261+
this.optionsSC5 = optionsSC5;
243262
this.useGeneratedTunnelIdentifier = useGeneratedTunnelIdentifier;
244263
this.verboseLogging = verboseLogging;
245264
this.sauceConnectPath = sauceConnectPath;
@@ -249,6 +268,14 @@ public SauceConnectStepExecution(
249268

250269
@Override
251270
public boolean start() throws Exception {
271+
boolean legacyCLI = false;
272+
if (options != null && optionsSC5 != null && !options.isEmpty() && !optionsSC5.isEmpty()) {
273+
throw new Exception("Legacy and SC5 CLI options cannot both be specified");
274+
}
275+
276+
if (options != null && !options.isEmpty()) {
277+
legacyCLI = true;
278+
}
252279

253280
Run<?, ?> run = getContext().get(Run.class);
254281
Job<?,?> job = run.getParent();
@@ -266,10 +293,14 @@ public boolean start() throws Exception {
266293

267294
ArrayList<String> optionsArray = new ArrayList<String>();
268295
optionsArray.add(globalOptions);
269-
optionsArray.add(options);
296+
if (legacyCLI) {
297+
optionsArray.add(options);
298+
} else {
299+
optionsArray.add(optionsSC5);
300+
}
270301
optionsArray.removeAll(Collections.singleton("")); // remove the empty strings
271302

272-
String options = StringUtils.join(optionsArray, " ");
303+
String combinedOptions = StringUtils.join(optionsArray, " ");
273304

274305
HashMap<String,String> overrides = new HashMap<String,String>();
275306
overrides.put(SauceOnDemandBuildWrapper.SELENIUM_PORT, String.valueOf(port));
@@ -278,26 +309,25 @@ public boolean start() throws Exception {
278309
if (useGeneratedTunnelIdentifier) {
279310
final String tunnelName = SauceEnvironmentUtil.generateTunnelName(job.getName(), run.number);
280311
overrides.put(SauceOnDemandBuildWrapper.TUNNEL_NAME, tunnelName);
281-
options = options + " --tunnel-name " + tunnelName;
312+
combinedOptions = combinedOptions + " --tunnel-name " + tunnelName;
282313
}
283314

284315
SauceCredentials sauceCredentials = getContext().get(SauceCredentials.class);
285-
final String restEndpoint = sauceCredentials.getRestEndpoint();
286-
287-
overrides.put(SauceOnDemandBuildWrapper.SAUCE_REST_ENDPOINT, restEndpoint);
288-
options = options + " -x " + restEndpoint + "rest/v1";
316+
final String region = sauceCredentials.getRegion();
317+
combinedOptions = combinedOptions + " --region " + region;
289318

290319
TaskListener listener = getContext().get(TaskListener.class);
291320
listener.getLogger().println("Starting sauce connect");
292321

293322
SauceStartConnectHandler handler = new SauceStartConnectHandler(
294323
sauceCredentials,
295324
port,
296-
options,
325+
combinedOptions,
297326
listener,
298327
verboseLogging,
299328
sauceConnectPath,
300329
useLatestSauceConnect,
330+
legacyCLI,
301331
proxy
302332
);
303333
computer.getChannel().call(handler);
@@ -352,4 +382,4 @@ private static final class Callback extends BodyExecutionCallback.TailCall {
352382

353383
}
354384
}
355-
}
385+
}

src/main/java/hudson/plugins/sauce_ondemand/PluginImpl.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ public class PluginImpl extends Plugin implements Describable<PluginImpl> {
6969

7070
private String sauceConnectDirectory;
7171

72-
private String sauceConnectOptions;
72+
private String sauceConnectOptions; // SC4 Legacy CLI Options
73+
74+
private String sauceConnectCLIOptions; // SC5 options
7375

7476
private String sauceConnectMaxRetries;
7577

@@ -150,6 +152,7 @@ public void configure(StaplerRequest req, JSONObject formData)
150152
throws IOException, ServletException, Descriptor.FormException {
151153
sauceConnectDirectory = formData.getString("sauceConnectDirectory");
152154
sauceConnectOptions = formData.getString("sauceConnectOptions");
155+
sauceConnectCLIOptions = formData.getString("sauceConnectCLIOptions");
153156
environmentVariablePrefix = formData.getString("environmentVariablePrefix");
154157
setDisableUsageStats(formData.getBoolean("disableUsageStats"));
155158
sauceConnectMaxRetries = formData.getString("sauceConnectMaxRetries");
@@ -220,6 +223,14 @@ public void setSauceConnectOptions(String sauceConnectOptions) {
220223
this.sauceConnectOptions = sauceConnectOptions;
221224
}
222225

226+
public String getSauceConnectCLIOptions() {
227+
return sauceConnectCLIOptions;
228+
}
229+
230+
public void setSauceConnectCLIOptions(String sauceConnectCLIOptions) {
231+
this.sauceConnectCLIOptions = sauceConnectCLIOptions;
232+
}
233+
223234
public void setDisableUsageStats(boolean disableUsageStats) {
224235
this.disableUsageStats = disableUsageStats;
225236
}
@@ -243,4 +254,4 @@ public ListBoxModel doFillCredentialIdItems(final @AncestorInPath ItemGroup<?> c
243254
return new StandardUsernameListBoxModel().withAll(SauceCredentials.all(context));
244255
}
245256
}
246-
}
257+
}

0 commit comments

Comments
 (0)