Skip to content
This repository was archived by the owner on Sep 12, 2024. It is now read-only.

Commit 48398bd

Browse files
hstefanStefan Puhlmann
authored andcommitted
Adding global flag --strict-start to wildcard-based commands.
This forces job names to be matched from the string start. By default, some commands will match on any jobs that contain the input name as a substring, this option forces the match to only happen if the string starts with the input name. Affects the subcommands: remove, inspect, rolling-update, undeploy, deploy and stop. The motivation behind this is production usages returning "JOB_AMBIGUOUS_REFERENCE" in cases where a job's name is a substring of another (eg: foo-bar and bar-foo-bar, as the first a substring of the second).
1 parent c9000bc commit 48398bd

File tree

7 files changed

+54
-6
lines changed

7 files changed

+54
-6
lines changed

helios-tools/src/main/java/com/spotify/helios/cli/command/JobInspectCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ private static String formatRolloutOptions(final RolloutOptions options) {
125125
}
126126

127127
public JobInspectCommand(final Subparser parser) {
128-
super(parser);
128+
super(parser, false);
129129
parser.help("print the configuration of a job");
130130
}
131131

helios-tools/src/main/java/com/spotify/helios/cli/command/JobRemoveCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class JobRemoveCommand extends WildcardJobCommand {
4040
private final Argument yesArg;
4141

4242
public JobRemoveCommand(Subparser parser) {
43-
super(parser);
43+
super(parser, false);
4444

4545
parser.help("remove a job");
4646

helios-tools/src/main/java/com/spotify/helios/cli/command/JobStartCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class JobStartCommand extends WildcardJobCommand {
4141
private final Argument tokenArg;
4242

4343
public JobStartCommand(Subparser parser) {
44-
super(parser);
44+
super(parser, false);
4545

4646
parser.help("start a stopped job");
4747

helios-tools/src/main/java/com/spotify/helios/cli/command/JobStopCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class JobStopCommand extends WildcardJobCommand {
4141
private final Argument tokenArg;
4242

4343
public JobStopCommand(Subparser parser) {
44-
super(parser);
44+
super(parser, false);
4545

4646
parser.help("stop a running job without undeploying it");
4747

helios-tools/src/main/java/com/spotify/helios/cli/command/JobUndeployCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class JobUndeployCommand extends WildcardJobCommand {
4646
private final Argument yesArg;
4747

4848
public JobUndeployCommand(final Subparser parser) {
49-
super(parser);
49+
super(parser, false);
5050

5151
parser.help("undeploy a job from hosts");
5252

helios-tools/src/main/java/com/spotify/helios/cli/command/WildcardJobCommand.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
abstract class WildcardJobCommand extends ControlCommand {
4242

4343
private final Argument jobArg;
44+
private final Argument strictStartArg;
4445

4546
public WildcardJobCommand(final Subparser parser) {
4647
this(parser, false);
@@ -51,16 +52,31 @@ public WildcardJobCommand(final Subparser parser, final boolean shortCircuit) {
5152

5253
jobArg = parser.addArgument("job")
5354
.help("Job id.");
55+
strictStartArg = parser.addArgument("--strict-start")
56+
.type(Boolean.class)
57+
.setDefault(false)
58+
.help("Forces job names to be matched from the string start. "
59+
+ "By default, some commands will match on any jobs that contain the input name as a"
60+
+ " substring, this option forces the match to only happen if the string starts with"
61+
+ " the input name. Affects the subcommands: remove, inspect, rolling-update,"
62+
+ " undeploy, deploy and stop.");
5463
}
5564

5665
@Override
5766
int run(final Namespace options, final HeliosClient client, final PrintStream out,
5867
final boolean json, final BufferedReader stdin)
5968
throws ExecutionException, InterruptedException, IOException {
60-
6169
final String jobIdString = options.getString(jobArg.getDest());
6270
final Map<JobId, Job> jobs = client.jobs(jobIdString).get();
6371

72+
if (options.getBoolean(strictStartArg.getDest())) {
73+
for (final Map.Entry<JobId, Job> entry : jobs.entrySet()) {
74+
if (!entry.getKey().toShortString().startsWith(jobIdString)) {
75+
jobs.remove(entry.getKey());
76+
}
77+
}
78+
}
79+
6480
if (jobs.size() == 0) {
6581
if (!json) {
6682
out.printf("Unknown job: %s%n", jobIdString);

helios-tools/src/test/java/com/spotify/helios/cli/command/RollingUpdateCommandTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static com.spotify.helios.common.descriptors.DeploymentGroup.RollingUpdateReason.MANUAL;
2525
import static org.hamcrest.CoreMatchers.containsString;
2626
import static org.hamcrest.CoreMatchers.equalTo;
27+
import static org.hamcrest.CoreMatchers.not;
2728
import static org.hamcrest.MatcherAssert.assertThat;
2829
import static org.junit.Assert.assertEquals;
2930
import static org.mockito.Matchers.any;
@@ -648,6 +649,37 @@ public void testTimeoutDuringRolloutOutput() throws Exception {
648649
assertThat(baos.toString(), containsString(expectedSubstring));
649650
}
650651

652+
@Test
653+
public void testStrictStartJobName() throws Exception {
654+
final JobId jobId1 = JobId.parse("foo-bar:cafe");
655+
Job job1 = Job.newBuilder()
656+
.setName(jobId1.getName())
657+
.setHash(jobId1.getHash())
658+
.setRolloutOptions(jobOptions)
659+
.build();
660+
final JobId jobId2 = JobId.parse("bar:beef");
661+
Job job2 = Job.newBuilder()
662+
.setName(jobId2.getName())
663+
.setHash(jobId2.getHash())
664+
.setRolloutOptions(jobOptions)
665+
.build();
666+
final Map<JobId, Job> jobs = ImmutableMap.of(
667+
jobId1, job1,
668+
jobId2, job2
669+
);
670+
when(client.jobs(anyString())).thenReturn(immediateFuture(jobs));
671+
672+
when(options.getBoolean("strict-start")).thenReturn(true);
673+
674+
when(options.getString("job")).thenReturn("bar");
675+
676+
final int ret = command.run(options, client, out, false, null);
677+
678+
assertEquals(ret, 0);
679+
680+
assertThat(out.toString(), not(containsString("Ambiguous job reference")));
681+
}
682+
651683
private static class TimeUtil implements RollingUpdateCommand.SleepFunction, Supplier<Long> {
652684

653685
private long curentTimeMillis = 0;

0 commit comments

Comments
 (0)