| Benjamin Copeland | 4e09671 | 2020-08-11 16:09:55 +0100 | [diff] [blame] | 1 | /* |
| 2 | Configure Yet Another Docker clouds provided by the Yet Another Docker |
| 3 | Plugin. This Jenkins Script Console script makes it easy to maintain large |
| 4 | amounts of configured clouds. |
| 5 | |
| 6 | Note: This script deletes all yet another docker cloud configurations from |
| 7 | Jenkins before configuring the clouds. It does not affect in-process |
| 8 | builds. However, if there are previously configured yet another docker |
| 9 | clouds then they will be removed. |
| 10 | |
| 11 | Yet Another Docker Plugin 0.1.0-rc31 |
| 12 | */ |
| 13 | |
| 14 | import com.github.kostyasha.yad.DockerCloud |
| 15 | import com.github.kostyasha.yad.DockerConnector |
| 16 | import com.github.kostyasha.yad.DockerContainerLifecycle |
| 17 | import com.github.kostyasha.yad.DockerSlaveTemplate |
| 18 | import com.github.kostyasha.yad.commons.DockerCreateContainer |
| 19 | import com.github.kostyasha.yad.commons.DockerImagePullStrategy |
| 20 | import com.github.kostyasha.yad.commons.DockerPullImage |
| 21 | import com.github.kostyasha.yad.commons.DockerRemoveContainer |
| 22 | import com.github.kostyasha.yad.commons.DockerSSHConnector |
| 23 | import com.github.kostyasha.yad.commons.DockerStopContainer |
| 24 | import com.github.kostyasha.yad.launcher.DockerComputerJNLPLauncher |
| 25 | import com.github.kostyasha.yad.launcher.DockerComputerLauncher |
| 26 | import com.github.kostyasha.yad.launcher.DockerComputerSSHLauncher |
| 27 | import com.github.kostyasha.yad.other.ConnectorType |
| 28 | import com.github.kostyasha.yad.strategy.DockerOnceRetentionStrategy |
| 29 | import hudson.plugins.sshslaves.verifiers.NonVerifyingKeyVerificationStrategy |
| 30 | import hudson.plugins.sshslaves.verifiers.SshHostKeyVerificationStrategy |
| 31 | |
| 32 | import hudson.model.Node |
| 33 | import hudson.slaves.EnvironmentVariablesNodeProperty |
| 34 | import hudson.slaves.NodeProperty |
| 35 | import hudson.slaves.RetentionStrategy |
| 36 | import hudson.tools.ToolLocationNodeProperty |
| 37 | import jenkins.model.Jenkins |
| 38 | import net.sf.json.JSONArray |
| 39 | import net.sf.json.JSONObject |
| 40 | |
| 41 | /* |
| 42 | Configure the Yet Another Docker Plugin via this clouds_yadocker variable. |
| 43 | |
| 44 | This variable can be removed and referenced for other configurations. All |
| 45 | values are optional with defaults set. |
| 46 | */ |
| 47 | |
| 48 | JSONArray clouds_yadocker = [ {% for host in hosts %} |
| 49 | [ |
| 50 | cloud_name: '{{host.cloud_name}}', |
| 51 | docker_url: '{{host.docker_url}}', |
| 52 | docker_api_version: '{{host.docker_api_version}}', |
| 53 | host_credentials_id: '{{host.host_credentials_id}}', |
| 54 | //valid values: netty, jersey |
| 55 | connection_type: '{{host.connection_type}}', |
| 56 | connect_timeout: '{{host.connect_timeout}}', |
| 57 | max_containers: '{{host.max_containers}}', |
| 58 | docker_templates: [ |
| 59 | // List item of templates {% for docker in host.docker_templates %} |
| 60 | [ |
| 61 | max_instances: '{{docker.max_instances}}', |
| 62 | //DOCKER CONTAINER LIFECYCLE |
| 63 | docker_image_name: '{{docker.docker_image_name}}', |
| 64 | //PULL IMAGE SETTINGS |
| 65 | //valid values: pull_latest, pull_always, pull_once, pull_never |
| 66 | pull_strategy: '{{docker.pull_strategy}}', |
| 67 | pull_registry_credentials_id: '{{docker.pull_registry_credentials_id}}', |
| 68 | //CREATE CONTAINER SETTINGS |
| 69 | docker_command: '{{docker.docker_command}}', |
| 70 | hostname: '{{docker.hostname}}', |
| 71 | dns: '{{docker.dns|default('8.8.8.8')}}', |
| 72 | //volumes can be a string or list of strings |
| 73 | volumes: '{{docker.volumes}}', |
| 74 | //volumes_from can be a string or list of strings |
| 75 | //volumes_from: '{{docker.volumes_from}}', |
| 76 | //environment can be a string or list of strings |
| 77 | environment: '{{docker.environment}}', |
| Benjamin Copeland | a650a7a | 2022-03-03 14:25:46 +0000 | [diff] [blame^] | 78 | port_bindings: '{{docker.port_bindings|default('0.0.0.0::22')}}', |
| Benjamin Copeland | 4e09671 | 2020-08-11 16:09:55 +0100 | [diff] [blame] | 79 | bind_all_declared_ports: '{{docker.bind_all_declared_ports}}', |
| 80 | //0 is unlimited |
| 81 | memory_limit_in_mb: '{{docker.memory_limit_in_mb}}', |
| 82 | //0 is unlimited |
| 83 | cpu_shares: '{{docker.cpu_shares}}', |
| 84 | run_container_privileged: '{{docker.run_container_privileged}}', |
| 85 | allocate_pseudo_tty: '{{docker.allocate_pseudo_tty}}', |
| 86 | mac_address: '{{docker.mac_address}}', |
| 87 | //extra_hosts can be a string or list of strings |
| 88 | extra_hosts: '{{docker.extra_hosts}}', |
| 89 | network_mode: '{{docker.network_mode}}', |
| 90 | //devices can be a string or list of strings |
| 91 | devices: '{{docker.devices}}', |
| 92 | cpuset_constraint_cpus: '{{docker.cpuset_constraint_cpus}}', |
| 93 | cpuset_constraint_mems: '{{docker.cpuset_constraint_mems}}', |
| 94 | //links can be a string or list of strings |
| 95 | links: '{{docker.links}}', |
| 96 | //STOP CONTAINER SETTINGS |
| 97 | stop_container_timeout: '{{docker.stop_container_timeout}}', |
| 98 | //STOP CONTAINER SETTINGS |
| 99 | remove_volumes: '{{docker.remove_volumes}}', |
| 100 | force_remove_containers: '{{docker.force_remove_containers}}', |
| 101 | //JENKINS SLAVE CONFIG |
| 102 | remote_fs_root: '{{docker.remote_fs_root|default('/home/buildslave')}}', |
| 103 | labels: '{{docker.labels}}', |
| 104 | //valid values: exclusive or normal |
| 105 | usage: '{{docker.usage}}', |
| 106 | availability_strategy: '{{docker.availability_strategy}}', |
| 107 | availability_idle_timeout: '{{docker.availability_idle_timeout}}', |
| 108 | executors: '{{docker.executors}}', |
| 109 | //LAUNCH METHOD |
| 110 | //valid values: launch_ssh or launch_jnlp |
| 111 | {%if docker.launch_method == 'launch_ssh' %} |
| 112 | launch_method: 'launch_ssh', |
| 113 | //settings specific to launch_ssh (you only need one or the other) |
| 114 | launch_ssh_credentials_id: '{{docker.ssh.launch_ssh_credentials_id}}', |
| 115 | launch_ssh_port: '{{docker.ssh.launch_ssh_port|default('22')}}', |
| 116 | launch_ssh_java_path: '{{docker.ssh.launch_ssh_java_path}}', |
| 117 | launch_ssh_jvm_options: '{{docker.ssh.launch_ssh_jvm_options}}', |
| 118 | launch_ssh_prefix_start_slave_command: '{{docker.ssh.launch_ssh_prefix_start_slave_command}}', |
| 119 | launch_ssh_suffix_start_slave_command: '{{docker.ssh.launch_ssh_suffix_start_slave_command}}', |
| 120 | launch_ssh_connection_timeout: '{{docker.ssh.launch_ssh_connection_timeout}}', |
| 121 | launch_ssh_max_num_retries: '{{docker.ssh.launch_ssh_max_num_retries}}', |
| 122 | launch_ssh_time_wait_between_retries: '{{docker.ssh.launch_ssh_time_wait_between_retries}}', |
| 123 | {%elif docker.launch_method == 'launch_jnlp' %} |
| 124 | launch_method: 'launch_jnlp', |
| 125 | //settings specific to launch_jnlp |
| 126 | launch_jnlp_linux_user: '{{docker.jnlp.launch_jnlp_linux_user}}', |
| 127 | launch_jnlp_lauch_timeout: '{{docker.jnlp.launch_jnlp_lauch_timeout}}', |
| 128 | launch_jnlp_slave_jar_options: '{{docker.jnlp.launch_jnlp_slave_jar_options}}', |
| 129 | launch_jnlp_slave_jvm_options: '{{docker.jnlp.launch_jnlp_slave_jvm_options}}', |
| 130 | launch_jnlp_different_jenkins_master_url: '{{docker.jnlp.launch_jnlp_different_jenkins_master_url}}', |
| 131 | launch_jnlp_ignore_certificate_check: '{{docker.jnlp.launch_jnlp_ignore_certificate_check}}', |
| 132 | {%endif%} |
| 133 | //NODE PROPERTIES |
| 134 | //environment_variables is a HashMap of key/value pairs |
| Benjamin Copeland | 5a08ae3 | 2020-08-28 13:47:42 +0100 | [diff] [blame] | 135 | environment_variables: [ {% for env in docker.environment_variables %} {% for name, value in env.items() %} |
| 136 | '{{name}}': '{{value}}', |
| 137 | {% endfor %}{% endfor %} ], |
| Benjamin Copeland | 4e09671 | 2020-08-11 16:09:55 +0100 | [diff] [blame] | 138 | //tool location key/value pairs from https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/tools/ToolLocationNodeProperty.java |
| 139 | //The key is type@name = home where type is typically the class name of the tool and name is the name given in the Global Tools configuration. |
| 140 | //For example let's say you have a global tool configuration named OracleJDK8 for JDK installations |
| 141 | //tool_locations would be something like ['hudson.model.JDK$DescriptorImpl@OracleJDK8': '/path/to/java_home'] |
| 142 | //If you're unsure of the tool@name then check config.xml where YADocker configurations are saved. |
| 143 | tool_locations: '{{docker.tool_locations}}', |
| 144 | remote_fs_root_mapping: '{{docker.remote_fs_root_mapping}}' |
| 145 | |
| 146 | ], |
| 147 | {% endfor %} |
| 148 | ], |
| 149 | ], |
| 150 | {% endfor %} |
| 151 | ] as JSONArray |
| 152 | |
| 153 | //detect an existing global tool |
| 154 | def detectGlobalToolExists(String location) { |
| 155 | def (toolType, toolName) = location.split('@') |
| 156 | boolean found_installation = Jenkins.instance.getExtensionList(toolType)[0].installations.findAll { it.name == toolName } as boolean |
| 157 | return found_installation |
| 158 | } |
| 159 | |
| 160 | //return a launcher |
| 161 | def selectLauncher(String launcherType, JSONObject obj) { |
| 162 | switch(launcherType) { |
| 163 | case 'launch_ssh': |
| 164 | def jenkinsCredentials = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials( |
| 165 | com.cloudbees.plugins.credentials.Credentials.class, |
| 166 | Jenkins.instance, |
| 167 | null, |
| 168 | null |
| 169 | ); |
| 170 | def launch_credentials = null |
| 171 | for (creds in jenkinsCredentials) { |
| 172 | if(creds.id == obj.optString('launch_ssh_credentials_id')){ |
| 173 | launch_credentials = creds; |
| 174 | } |
| 175 | } |
| 176 | DockerSSHConnector sshConnector = new DockerSSHConnector(obj.optInt('launch_ssh_port', 22), |
| 177 | launch_credentials, |
| 178 | obj.optString('launch_ssh_credentials_id'), |
| 179 | obj.optString('launch_ssh_jvm_options'), |
| 180 | obj.optString('launch_ssh_java_path'), |
| 181 | null, |
| 182 | obj.optString('launch_ssh_prefix_start_slave_command'), |
| 183 | obj.optString('launch_ssh_suffix_start_slave_command'), |
| 184 | obj.optInt('launch_ssh_connection_timeout'), |
| 185 | obj.optInt('launch_ssh_max_num_retries'), |
| 186 | obj.optInt('launch_ssh_time_wait_between_retries'), |
| 187 | new NonVerifyingKeyVerificationStrategy() |
| 188 | ) |
| 189 | return new DockerComputerSSHLauncher(sshConnector) |
| 190 | case 'launch_jnlp': |
| 191 | DockerComputerJNLPLauncher dockerComputerJNLPLauncher = new DockerComputerJNLPLauncher() |
| 192 | dockerComputerJNLPLauncher.setUser(obj.optString('launch_jnlp_linux_user','jenkins')) |
| 193 | dockerComputerJNLPLauncher.setLaunchTimeout(obj.optLong('launch_jnlp_lauch_timeout', 120L)) |
| 194 | dockerComputerJNLPLauncher.setSlaveOpts(obj.optString('launch_jnlp_slave_jar_options')) |
| 195 | dockerComputerJNLPLauncher.setJvmOpts(obj.optString('launch_jnlp_slave_jvm_options')) |
| 196 | dockerComputerJNLPLauncher.setJenkinsUrl(obj.optString('launch_jnlp_different_jenkins_master_url')) |
| 197 | dockerComputerJNLPLauncher.setNoCertificateCheck(obj.optBoolean('launch_jnlp_ignore_certificate_check', false)) |
| 198 | return dockerComputerJNLPLauncher |
| 199 | default: |
| 200 | return null |
| 201 | } |
| 202 | } |
| 203 | |
| 204 | //create a new instance of the DockerCloud class from a JSONObject |
| 205 | def newDockerCloud(JSONObject obj) { |
| 206 | DockerConnector connector = new DockerConnector(obj.optString('docker_url', 'tcp://localhost:2375')) |
| 207 | if(obj.optInt('connect_timeout')) { |
| 208 | connector.setConnectTimeout(obj.optInt('connect_timeout')) |
| 209 | } |
| 210 | connector.setApiVersion(obj.optString('docker_api_version')) |
| 211 | connector.setCredentialsId(obj.optString('host_credentials_id')) |
| 212 | //select connection_type |
| 213 | List<String> connection_types = ['NETTY', 'JERSEY'] |
| 214 | String connection_type_default = 'JERSEY' |
| 215 | String user_selected_connection_type = obj.optString('connection_type', connection_type_default).toUpperCase() |
| 216 | String connection_type = (user_selected_connection_type in connection_types)? user_selected_connection_type : connection_type_default |
| 217 | connector.setConnectorType(ConnectorType."${connection_type}") |
| 218 | |
| 219 | DockerCloud cloud = new DockerCloud(obj.optString('cloud_name'), |
| 220 | bindJSONToList(DockerSlaveTemplate.class, obj.opt('docker_templates')), |
| 221 | obj.optInt('max_containers', 1), |
| 222 | connector) |
| 223 | |
| 224 | return cloud |
| 225 | } |
| 226 | |
| 227 | def newDockerSlaveTemplate(JSONObject obj) { |
| 228 | //DockerPullImage |
| 229 | DockerPullImage pullImage = new DockerPullImage() |
| 230 | String pullStrategy = obj.optString('pull_strategy', 'PULL_LATEST').toUpperCase() |
| 231 | if(pullStrategy in ['PULL_LATEST', 'PULL_ALWAYS', 'PULL_ONCE', 'PULL_NEVER']) { |
| 232 | pullImage.setPullStrategy(DockerImagePullStrategy."${pullStrategy}") |
| 233 | } else { |
| 234 | pullImage.setPullStrategy(DockerImagePullStrategy.PULL_LATEST) |
| 235 | } |
| 236 | pullImage.setCredentialsId(obj.optString('pull_registry_credentials_id')) |
| 237 | |
| 238 | //DockerCreateContainer |
| 239 | DockerCreateContainer createContainer = new DockerCreateContainer() |
| 240 | createContainer.setBindPorts(obj.optString('port_bindings')) |
| 241 | createContainer.setBindAllPorts(obj.optBoolean('bind_all_declared_ports', false)) |
| 242 | createContainer.setDnsString(obj.optString('dns')) |
| 243 | createContainer.setHostname(obj.optString('hostname')) |
| 244 | if(obj.optLong('memory_limit_in_mb')) { |
| 245 | createContainer.setMemoryLimit(obj.optLong('memory_limit_in_mb')) |
| 246 | } |
| 247 | createContainer.setPrivileged(obj.optBoolean('run_container_privileged', true)) |
| 248 | createContainer.setTty(obj.optBoolean('allocate_pseudo_tty', false)) |
| 249 | if(obj.optJSONArray('volumes')) { |
| 250 | createContainer.setVolumes(obj.optJSONArray('volumes') as List<String>) |
| 251 | } else { |
| 252 | createContainer.setVolumesString(obj.optString('volumes')) |
| 253 | } |
| 254 | if(obj.optJSONArray('volumes_from')) { |
| 255 | createContainer.setVolumesFrom(obj.optJSONArray('volumes_from') as List<String>) |
| 256 | } else { |
| 257 | createContainer.setVolumesFromString(obj.optString('volumes_from')) |
| 258 | } |
| 259 | createContainer.setMacAddress(obj.optString('mac_address')) |
| 260 | if(obj.optInt('cpu_shares')) { |
| 261 | createContainer.setCpuShares(obj.optInt('cpu_shares')) |
| 262 | } |
| 263 | createContainer.setCommand(obj.optString('docker_command')) |
| 264 | if(obj.optJSONArray('environment')) { |
| 265 | createContainer.setEnvironment(obj.optJSONArray('environment') as List<String>) |
| 266 | } else { |
| 267 | createContainer.setEnvironmentString(obj.optString('environment')) |
| 268 | } |
| 269 | if(obj.optJSONArray('extra_hosts')) { |
| 270 | createContainer.setExtraHosts(obj.optJSONArray('extra_hosts') as List<String>) |
| 271 | } else { |
| 272 | createContainer.setExtraHostsString(obj.optString('extra_hosts')) |
| 273 | } |
| 274 | createContainer.setNetworkMode(obj.optString('network_mode')) |
| 275 | if(obj.optJSONArray('devices')) { |
| 276 | createContainer.setDevices(obj.optJSONArray('devices')) |
| 277 | } else { |
| 278 | createContainer.setDevicesString(obj.optString('devices')) |
| 279 | } |
| 280 | createContainer.setCpusetCpus(obj.optString('cpuset_constraint_cpus')) |
| 281 | createContainer.setCpusetMems(obj.optString('cpuset_constraint_mems')) |
| 282 | if(obj.optJSONArray('links')) { |
| 283 | createContainer.setLinks(obj.optJSONArray('links')) |
| 284 | } else { |
| 285 | createContainer.setLinksString(obj.optString('links')) |
| 286 | } |
| 287 | |
| 288 | //DockerStopContainer |
| 289 | DockerStopContainer stopContainer = new DockerStopContainer() |
| 290 | stopContainer.setTimeout(obj.optInt('stop_container_timeout', 10)) |
| 291 | |
| 292 | //DockerRemoveContainer |
| 293 | DockerRemoveContainer removeContainer = new DockerRemoveContainer() |
| 294 | removeContainer.setRemoveVolumes(obj.optBoolean('remove_volumes', false)) |
| 295 | removeContainer.setForce(obj.optBoolean('force_remove_containers', false)) |
| 296 | |
| 297 | //DockerContainerLifecycle |
| 298 | DockerContainerLifecycle dockerContainerLifecycle = new DockerContainerLifecycle() |
| 299 | dockerContainerLifecycle.setImage(obj.optString('docker_image_name')) |
| 300 | dockerContainerLifecycle.setPullImage(pullImage) |
| 301 | dockerContainerLifecycle.setCreateContainer(createContainer) |
| 302 | dockerContainerLifecycle.setStopContainer(stopContainer) |
| 303 | dockerContainerLifecycle.setRemoveContainer(removeContainer) |
| 304 | |
| 305 | //DockerOnceRetentionStrategy |
| 306 | //this availability_strategy is for "run_once". We can customize it later |
| 307 | RetentionStrategy retentionStrategy = new DockerOnceRetentionStrategy(obj.optInt('availability_idle_timeout', 10)) |
| 308 | |
| 309 | //DockerComputerLauncher |
| 310 | //select a launch method from the list of available launch methods |
| 311 | List<String> launch_methods = ['launch_ssh', 'launch_jnlp'] |
| 312 | String default_launch_method = 'launch_jnlp' |
| 313 | String user_selected_launch_method = obj.optString('launch_method', default_launch_method).toLowerCase() |
| 314 | String launch_method = (user_selected_launch_method in launch_methods)? user_selected_launch_method : default_launch_method |
| 315 | DockerComputerLauncher launcher = selectLauncher(launch_method, obj) |
| 316 | |
| 317 | //DockerSlaveTemplate |
| 318 | DockerSlaveTemplate dockerSlaveTemplate = new DockerSlaveTemplate() |
| 319 | dockerSlaveTemplate.setDockerContainerLifecycle(dockerContainerLifecycle) |
| 320 | dockerSlaveTemplate.setLabelString(obj.optString('labels', 'docker')) |
| 321 | String node_usage = (obj.optString('usage', 'EXCLUSIVE').toUpperCase().equals('NORMAL'))? 'NORMAL' : 'EXCLUSIVE' |
| 322 | dockerSlaveTemplate.setMode(Node.Mode."${node_usage}") |
| 323 | dockerSlaveTemplate.setNumExecutors(obj.optInt('executors', 1)) |
| 324 | dockerSlaveTemplate.setRetentionStrategy(retentionStrategy) |
| 325 | dockerSlaveTemplate.setLauncher(launcher) |
| 326 | dockerSlaveTemplate.setRemoteFs(obj.optString('remote_fs_root', '/srv/jenkins')) |
| 327 | dockerSlaveTemplate.setMaxCapacity(obj.optInt('max_instances', 1)) |
| 328 | //dockerSlaveTemplate.setRemoteFsMapping(obj.optString('remote_fs_root_mapping')) |
| 329 | //dockerSlaveTemplate.remoteFsMapping = obj.optString('remote_fs_root_mapping') |
| 330 | //define NODE PROPERTIES |
| 331 | List<NodeProperty> nodeProperties = [] as List<NodeProperty> |
| 332 | if(obj.optJSONObject('environment_variables')) { |
| 333 | HashMap<String,String> env = obj.optJSONObject('environment_variables') as HashMap<String,String> |
| 334 | List<EnvironmentVariablesNodeProperty.Entry> envEntries = [] as List<EnvironmentVariablesNodeProperty.Entry> |
| 335 | (env.keySet() as String[]).each { var -> |
| 336 | envEntries << (new EnvironmentVariablesNodeProperty.Entry(var, env[var])) |
| 337 | } |
| 338 | //add environment_variables to nodeProperties |
| 339 | nodeProperties << (new EnvironmentVariablesNodeProperty(envEntries)) |
| 340 | } |
| 341 | if(obj.optJSONObject('tool_locations')) { |
| 342 | HashMap<String,String> tool = obj.optJSONObject('tool_locations') as HashMap<String,String> |
| 343 | List<ToolLocationNodeProperty.ToolLocation> toolLocations = [] as List<ToolLocationNodeProperty.ToolLocation> |
| 344 | (tool.keySet() as String[]).each { location -> |
| 345 | //tool location is only valid if it contains a type i.e. @ symbol |
| 346 | if(location.contains('@') && detectGlobalToolExists(location)) { |
| 347 | toolLocations << (new ToolLocationNodeProperty.ToolLocation(location, tool[location])) |
| 348 | } else { |
| 349 | //alert the user they configured an invalid tool type or name in tool_locations |
| 350 | println "WARNING: Invalid tool: '${location}'. Format should be 'type@name' where both type and name already exist in global tool configurations." |
| 351 | } |
| 352 | } |
| 353 | nodeProperties << (new ToolLocationNodeProperty(toolLocations)) |
| 354 | } |
| 355 | //set NODE PROPERTIES |
| 356 | if(nodeProperties) { |
| 357 | dockerSlaveTemplate.setNodeProperties(nodeProperties) |
| 358 | } |
| 359 | return dockerSlaveTemplate |
| 360 | } |
| 361 | |
| 362 | def bindJSONToList(Class type, Object src) { |
| 363 | if(!(type == DockerCloud) && !(type == DockerSlaveTemplate)) { |
| 364 | throw new Exception("Must use DockerCloud or DockerSlaveTemplate class.") |
| 365 | } |
| 366 | //docker_array should be a DockerCloud or DockerSlaveTemplate |
| 367 | ArrayList<?> docker_array |
| 368 | if(type == DockerCloud){ |
| 369 | docker_array = new ArrayList<DockerCloud>() |
| 370 | } else { |
| 371 | docker_array = new ArrayList<DockerSlaveTemplate>() |
| 372 | } |
| 373 | //cast the configuration object to a Docker instance which Jenkins will use in configuration |
| 374 | if (src instanceof JSONObject) { |
| 375 | //uses string interpolation to call a method |
| 376 | //e.g instead of newDockerCloud(src) we use instead... |
| 377 | docker_array.add("new${type.getSimpleName()}"(src)) |
| 378 | } else if(src instanceof JSONArray) { |
| 379 | for (Object o : src) { |
| 380 | if (o instanceof JSONObject) { |
| 381 | docker_array.add("new${type.getSimpleName()}"(o)) |
| 382 | } |
| 383 | } |
| 384 | } |
| 385 | return docker_array |
| 386 | } |
| 387 | |
| 388 | if(!Jenkins.instance.isQuietingDown()) { |
| 389 | ArrayList<DockerCloud> clouds = new ArrayList<DockerCloud>() |
| 390 | clouds = bindJSONToList(DockerCloud.class, clouds_yadocker) |
| 391 | if(clouds.size() > 0) { |
| 392 | {%if dryrun == True %} |
| 393 | clouds*.name.each { cloudName -> |
| 394 | println "DRYRUN: Configured Yet Another Docker cloud ${cloudName}" |
| 395 | } |
| 396 | {%else%} |
| 397 | dockerConfigUpdated = true |
| 398 | Jenkins.instance.clouds.removeAll(DockerCloud) |
| 399 | Jenkins.instance.clouds.addAll(clouds) |
| 400 | clouds*.name.each { cloudName -> |
| 401 | println "Configured Yet Another Docker cloud ${cloudName}" |
| 402 | } |
| 403 | Jenkins.instance.save() |
| 404 | {%endif%} |
| 405 | } else { |
| 406 | println 'Nothing changed. No Yet Another docker clouds to configure.' |
| 407 | } |
| 408 | } else { |
| 409 | println 'Shutdown mode enabled. Configure Yet Another Docker clouds SKIPPED.' |
| 410 | } |
| 411 | |
| 412 | //return null so there's no result value in the script console |
| 413 | null |
| 414 | |
| 415 | /* |
| 416 | The MIT License (MIT) |
| 417 | |
| 418 | Copyright 2017 Sam Gleske - https://github.com/samrocketman/jenkins-bootstrap-jervis |
| 419 | |
| 420 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| 421 | of this software and associated documentation files (the "Software"), to |
| 422 | deal in the Software without restriction, including without limitation the |
| 423 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| 424 | sell copies of the Software, and to permit persons to whom the Software is |
| 425 | furnished to do so, subject to the following conditions: |
| 426 | |
| 427 | The above copyright notice and this permission notice shall be included in |
| 428 | all copies or substantial portions of the Software. |
| 429 | |
| 430 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 431 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 432 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 433 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 434 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 435 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 436 | IN THE SOFTWARE. |
| 437 | */ |