Support for 'pool' resource type

This commit is contained in:
Kris De Volder
2017-01-29 10:01:06 -08:00
parent 3372adcf75
commit f615f171d1
16 changed files with 186 additions and 8 deletions

View File

@@ -19,6 +19,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
@@ -294,6 +295,13 @@ public class YTypeFactory {
Assert.isLegal(properties.length>1);
this.oneOfConstraints.add(properties);
}
public String[] getPropertyNames() {
return getProperties().stream()
.map(YTypedProperty::getName)
.collect(Collectors.toCollection(TreeSet::new))
.toArray(new String[0]);
}
}
/**

View File

@@ -99,6 +99,9 @@ public class PipelineYmlSchema implements YamlSchema {
.parseWith(ValueParsers.NE_STRING)
.addHints(MimeTypes.getKnownMimeTypes());
public final YType t_duration = f.yatomic("Duration")
.parseWith(ConcourseValueParsers.DURATION);
public final AbstractType task;
private final ResourceTypeRegistry resourceTypes = new ResourceTypeRegistry();
@@ -109,9 +112,6 @@ public class PipelineYmlSchema implements YamlSchema {
// define schema types
TOPLEVEL_TYPE = f.ybean("Pipeline");
YAtomicType t_duration = f.yatomic("Duration");
t_duration.parseWith(ConcourseValueParsers.DURATION);
YAtomicType t_version = f.yatomic("Version");
t_version.addHints("latest", "every");
@@ -208,7 +208,7 @@ public class PipelineYmlSchema implements YamlSchema {
YBeanType putStep = f.ybean("PutStep");
addProp(putStep, "put", t_resource_name);
addProp(putStep, "resource", t_job_name);
addProp(putStep, "resource", t_resource_name);
addProp(putStep, "params", f.contextAware("PutParams", (dc) ->
resourceTypes.getOutParamsType(getResourceType("put", models, dc))
));
@@ -291,8 +291,8 @@ public class PipelineYmlSchema implements YamlSchema {
AbstractType source = f.ybean("GitSource");
addProp(source, "uri", t_string).isRequired(true);
addProp(source, "branch", t_string).isRequired(true);
addProp(source, "private_key", t_string);
addProp(source, "username", t_string);
addProp(source, "private_key", t_ne_string);
addProp(source, "username", t_ne_string);
addProp(source, "password", t_string);
addProp(source, "paths", t_strings);
addProp(source, "ignore_paths", t_strings);
@@ -369,8 +369,6 @@ public class PipelineYmlSchema implements YamlSchema {
}
//s3
{
String[] validRegions = {
};
YType t_s3_region = f.yenum("S3Region",
//See: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUT.html
"us-west-1", "us-west-2",
@@ -414,6 +412,32 @@ public class PipelineYmlSchema implements YamlSchema {
resourceTypes.def("s3", source, get, put);
}
//pool
{
AbstractType source = f.ybean("PoolSource");
addProp(source, "uri", t_ne_string).isRequired(true);
addProp(source, "branch", t_ne_string).isRequired(true);
addProp(source, "pool", t_ne_string).isRequired(true);
addProp(source, "private_key", t_ne_string);
addProp(source, "username", t_ne_string);
addProp(source, "password", t_string);
addProp(source, "retry_delay", t_duration);
AbstractType get = f.ybean("PoolGetParams");
//get params deliberately left empty
AbstractType put = f.ybean("PoolPutParams");
addProp(put, "acquire", t_boolean);
addProp(put, "claim", t_ne_string);
addProp(put, "release", t_ne_string);
addProp(put, "add", t_ne_string);
addProp(put, "add_claimed", t_ne_string);
addProp(put, "remove", t_ne_string);
put.requireOneOf(put.getPropertyNames());
resourceTypes.def("pool", source, get, put);
}
}
private String getResourceType(String resourceNameProp, ConcourseModel models, DynamicSchemaContext dc) {

View File

@@ -0,0 +1,3 @@
If true, we will attempt to move a randomly chosen lock from the
pool's unclaimed directory to the claimed directory. Acquiring will retry
until a lock becomes available.

View File

@@ -0,0 +1,4 @@
If set, we will add a new lock to the pool in the unclaimed state. The
value is the path to a directory containing the files `name` and `metadata`
which should contain the name of your new lock and the contents you would like
in the lock, respectively.

View File

@@ -0,0 +1 @@
Exactly the same as the `add` param, but adds a lock to the pool in the *claimed* state.

View File

@@ -0,0 +1,3 @@
If set, the specified lock from the pool will be acquired, rather
than a random one (as in `acquire`). Like `acquire`, claiming will retry
until the specific lock becomes available

View File

@@ -0,0 +1,8 @@
If set, we will release the lock by moving it from claimed to
unclaimed. The value is the path of the lock to release (a directory
containing `name` and `metadata`), which typically is just the step that
provided the lock (either a `get` to pass one along or a `put` to acquire).
Note: the lock must be available in your job before you can release it. In
other words, a `get` step to fetch metadata about the lock is necessary
before a `put` step can release the lock.

View File

@@ -0,0 +1,4 @@
If set, we will remove the given lock from the pool. The value is
the same as `release`. This can be used for e.g. tearing down an environment,
or moving a lock between pools by using `add` with a different pool in a
second step.

View File

@@ -0,0 +1 @@
*Required.* The branch to track.

View File

@@ -0,0 +1 @@
*Optional.* Password for HTTP(S) auth when pulling/pushing.

View File

@@ -0,0 +1 @@
*Required.* The logical name of your pool of things to lock.

View File

@@ -0,0 +1,10 @@
*Optional.* Private key to use when pulling/pushing. Ensure it does not require a password.
Example:
private_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W
<Lots more text>
DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,3 @@
*Optional.* If specified, dictates how long to wait until retrying
to acquire a lock or release a lock. The default is 10 seconds.
Valid values: `60s`, `90m`, `1h`.

View File

@@ -0,0 +1 @@
*Required.* The location of the repository.

View File

@@ -0,0 +1,2 @@
*Optional.* Username for HTTP(S) auth when pulling/pushing.
This is needed when only HTTP/HTTPS protocol for git is available (which does not support private key auth) and auth is required.

View File

@@ -1499,6 +1499,110 @@ public class ConcourseEditorTest {
);
}
@Test public void poolResourceSourceReconcileAndHovers() throws Exception {
Editor editor;
editor = harness.newEditor(
"resources:\n" +
"- name: swimming-pool\n" +
" type: pool\n" +
" source:\n" +
" private_key: stuff"
);
editor.assertProblems(
"private_key: stuff|[branch, pool, uri] are required"
);
editor = harness.newEditor(
"resources:\n" +
"- name: the--locks\n" +
" type: pool\n" +
" source:\n" +
" uri: git@github.com:concourse/locks.git\n" +
" branch: master\n" +
" pool: aws\n" +
" private_key: |\n" +
" -----BEGIN RSA PRIVATE KEY-----\n" +
" MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W\n" +
" ...\n" +
" DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l\n" +
" -----END RSA PRIVATE KEY-----\n" +
" username: jonhsmith\n" +
" password: his-password\n" +
" retry_delay: retry-after\n"
);
System.out.println(editor.getRawText());
editor.assertProblems(
"retry-after|'Duration'"
);
editor.assertHoverContains("uri", "The location of the repository.");
editor.assertHoverContains("branch", "The branch to track");
editor.assertHoverContains("pool", 2, "The logical name of your pool of things to lock");
editor.assertHoverContains("private_key", "Private key to use when pulling/pushing");
editor.assertHoverContains("username", "Username for HTTP(S) auth");
editor.assertHoverContains("password", "Password for HTTP(S) auth ");
editor.assertHoverContains("retry_delay", "how long to wait until retrying");
}
@Test public void poolResourceGetParamsReconcileAndHovers() throws Exception {
Editor editor;
editor = harness.newEditor(
"resources:\n" +
"- name: my-locks\n" +
" type: pool\n" +
"jobs:\n" +
"- name: a-job\n" +
" plan:\n" +
" - get: my-locks\n" +
" params:\n" +
" no-params-expected: bad"
);
editor.assertProblems(
"no-params-expected|Unknown property"
);
}
@Test public void poolResourcePutParamsReconcileAndHovers() throws Exception {
Editor editor;
editor = harness.newEditor(
"resources:\n" +
"- name: my-locks\n" +
" type: pool\n" +
"jobs:\n" +
"- name: a-job\n" +
" plan:\n" +
" - put: my-locks\n" +
" params:\n" +
" acquire: should-acquire\n" +
" claim: a-specific-lock\n" +
" release: path/to/lock\n" +
" add: path/to/lock\n" +
" add_claimed: path/to/lock\n" +
" remove: path/to/lock"
);
editor.assertProblems(
"acquire|Only one of",
"should-acquire|'boolean'",
"claim|Only one of",
"release|Only one of",
"add|Only one of",
"add_claimed|Only one of",
"remove|Only one of"
);
editor.assertHoverContains("acquire", "attempt to move a randomly chosen lock");
editor.assertHoverContains("claim", "the specified lock from the pool will be acquired");
editor.assertHoverContains("release", "release the lock");
editor.assertHoverContains("add", "add a new lock to the pool in the unclaimed state");
editor.assertHoverContains("add_claimed", "in the *claimed* state");
editor.assertHoverContains("remove", "remove the given lock from the pool");
}
@Test
public void gotoResourceDefinition() throws Exception {
Editor editor = harness.newEditor(