Git Product home page Git Product logo

digitalocean-plugin's Introduction

Jenkins Digital Ocean Plugin

Allow Jenkins to start agents on DigitalOcean droplets on demand and destroy them as they get unused.

Our friends at Digital Ocean have provided an awesome promo code if you are new to Digital Ocean. After signing up for DigitalOcean, use DOJENKINS100 to get $100 credit to use over your first 60 days. Offer only valid for new accounts.

Known Issues

As of 2021-03-05 - If your using Freestyle Jobs and using something older than 2.277.2 (LTS) or 2.285 (Weekly) you will likely have your build crash the first time it connects to a given droplet. Its been fixed in newer version.

Configure plugin via Groovy script

Either automatically upon Jenkins post-initialization or through Jenkins script console, example:

import com.dubture.jenkins.digitalocean.DigitalOceanCloud
import com.dubture.jenkins.digitalocean.SlaveTemplate
import jenkins.model.Jenkins

// parameters
def agentTemplateParameters = [
  idleTerminationInMinutes: '10',
  imageId:                  'ubuntu-17-10-x64',
  initScript:               '',
  installMonitoring:        false,
  instanceCap:              '2',
  labellessJobsAllowed:     false,
  labelString:              'digitalocean.toronto.ubuntu.17.10',
  name:                     'digitalocean.toronto.ubuntu.17.10',
  numExecutors:             '1',
  regionId:                 'tor1',
  sizeId:                   '512mb',
  sshPort:                  22,
  tags:                     '',
  userData:                 '',
  username:                 'root',
  workspacePath:            '/home/jenkins'
]

def cloudParameters = [
  authToken:            '01234567890123456789012345678901234567890123456789',
  connectionRetryWait:  '30',
  instanceCap:          '2',
  name:                 'mycompany',
  sshKeyId:             '01234567',
  timeoutMinutes:       '10',
  usePrivateNetworking: false,
  privateKey:     '''-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgGuoiHtwl8T2cKfclsWLOcv8S6p74iOAQX1kwCLvLy7ioDFlNzsI
U235N1StnZYZIwGla+3Uo3jMSUuWkMH85+d3KoRFPS+6RJCiAvMI0hr8FByes22v
DAVDnhkZ2SFOeh1SPxWDygPo2fW5sgqL2eYLO1CplDdqYhHLAL1FDV5tAgMBAAEC
gYBWRZoJgXK9zdb9TZIs/6LzSlzAY8IWPOM+PwyRcibXZZiFvNyDm+pviHTEkNRl
wgMBgLR6xBmz5dEel6utKKQVEPtD1m6N+z6hwUw+Nis35DCvmBX+hQSK+atGgjYH
ZKz0oqWUSuzHG+CxxcrePDTYJ4fdSyLPsQqaWoCZseDDwQJBANLey9r+juBEQe2N
MJoZTU1q/AoS5kY7OWQ1aF495I9fz87u9vx8BJh8djvmABwidUWREnd4vwwEIS3M
JtFGn+kCQQCCsvBvOXgVAlcR54/6ro6R42/0F3bZw0ZFVXvgRRjCZW6m4FyHq4AL
+gfAV0HERkMdlO1zBpBwkSURekDc9NvlAkAA3zj6k9jlZoLbR50u1fHy4wFdzUw0
eCQ5nNrsoNbkHOJQGb7dtmmSc9lNUBsqAp53hi0MX2xy0UWN2e1DKkaZAkBi9stH
7OQYRGVZkVVcI8Cghu7GjN3ZlhsndMsPzkIpMFTQ1yI5OIsEhpZH9co+rFU1mQcT
Ce1kzwKacU+b/2xhAkEAovqzUMFB9YEbc8C9AzTej5F2ttyuKBDJJ+kvQeJP+PnW
4ovFI4Ee5UmTWI6k/Md9BM+MvEMWs3nPoF4MULHqNg==
-----END RSA PRIVATE KEY-----'''
]

// https://github.com/jenkinsci/digitalocean-plugin/blob/digitalocean-plugin-0.17/src/main/java/com/dubture/jenkins/digitalocean/SlaveTemplate.java
SlaveTemplate agentTemplate = new SlaveTemplate(
  agentTemplateParameters.name,
  agentTemplateParameters.imageId,
  agentTemplateParameters.sizeId,
  agentTemplateParameters.regionId,
  agentTemplateParameters.username,
  agentTemplateParameters.workspacePath,
  agentTemplateParameters.sshPort,
  agentTemplateParameters.idleTerminationInMinutes,
  agentTemplateParameters.numExecutors,
  agentTemplateParameters.labelString,
  agentTemplateParameters.labellessJobsAllowed,
  agentTemplateParameters.instanceCap,
  agentTemplateParameters.installMonitoring,
  agentTemplateParameters.tags,
  agentTemplateParameters.userData,
  agentTemplateParameters.initScript
)

// https://github.com/jenkinsci/digitalocean-plugin/blob/digitalocean-plugin-0.17/src/main/java/com/dubture/jenkins/digitalocean/DigitalOceanCloud.java
DigitalOceanCloud digitalOceanCloud = new DigitalOceanCloud(
  cloudParameters.name,
  cloudParameters.authToken,
  cloudParameters.privateKey,
  cloudParameters.sshKeyId,
  cloudParameters.instanceCap,
  cloudParameters.usePrivateNetworking,
  cloudParameters.timeoutMinutes,
  cloudParameters.connectionRetryWait,
  [agentTemplate]
)

// get Jenkins instance
Jenkins jenkins = Jenkins.getInstance()

// add cloud configuration to Jenkins
jenkins.clouds.add(digitalOceanCloud)

// save current Jenkins state to disk
jenkins.save()

Configure plugin via Jenkins Configuration As Code

jenkins:
  clouds:
    - digitalOcean:
        authToken: "01234567890123456789012345678901234567890123456789"
        connectionRetryWait: 10
        instanceCap: 5
        name: "mycompany"
        privateKey: |
          ----BEGIN RSA PRIVATE KEY-----
          MIICWwIBAAKBgGuoiHtwl8T2cKfclsWLOcv8S6p74iOAQX1kwCLvLy7ioDFlNzsI
          U235N1StnZYZIwGla+3Uo3jMSUuWkMH85+d3KoRFPS+6RJCiAvMI0hr8FByes22v
          DAVDnhkZ2SFOeh1SPxWDygPo2fW5sgqL2eYLO1CplDdqYhHLAL1FDV5tAgMBAAEC
          gYBWRZoJgXK9zdb9TZIs/6LzSlzAY8IWPOM+PwyRcibXZZiFvNyDm+pviHTEkNRl
          wgMBgLR6xBmz5dEel6utKKQVEPtD1m6N+z6hwUw+Nis35DCvmBX+hQSK+atGgjYH
          ZKz0oqWUSuzHG+CxxcrePDTYJ4fdSyLPsQqaWoCZseDDwQJBANLey9r+juBEQe2N
          MJoZTU1q/AoS5kY7OWQ1aF495I9fz87u9vx8BJh8djvmABwidUWREnd4vwwEIS3M
          JtFGn+kCQQCCsvBvOXgVAlcR54/6ro6R42/0F3bZw0ZFVXvgRRjCZW6m4FyHq4AL
          +gfAV0HERkMdlO1zBpBwkSURekDc9NvlAkAA3zj6k9jlZoLbR50u1fHy4wFdzUw0
          eCQ5nNrsoNbkHOJQGb7dtmmSc9lNUBsqAp53hi0MX2xy0UWN2e1DKkaZAkBi9stH
          7OQYRGVZkVVcI8Cghu7GjN3ZlhsndMsPzkIpMFTQ1yI5OIsEhpZH9co+rFU1mQcT
          Ce1kzwKacU+b/2xhAkEAovqzUMFB9YEbc8C9AzTej5F2ttyuKBDJJ+kvQeJP+PnW
          4ovFI4Ee5UmTWI6k/Md9BM+MvEMWs3nPoF4MULHqNg==
          -----END RSA PRIVATE KEY-----
        sshKeyId: 1234567
        templates:
          - idleTerminationInMinutes: 10
            imageId: "docker-20-04"
            installMonitoring: false
            instanceCap: 2
            labellessJobsAllowed: false
            name: "docker-20-04"
            numExecutors: 1
            regionId: "tor1"
            setupPrivateNetworking: false
            sizeId: "s-1vcpu-1gb"
            sshPort: 22
            username: "root"
            workspacePath: "/jenkins/"
        timeoutMinutes: 5
        usePrivateNetworking: false

digitalocean-plugin's People

Contributors

abguy avatar anpieber avatar bertg avatar christophgr avatar ctataryn avatar daniel-beck-bot avatar darxriggs avatar halkeye avatar hsitter avatar joshuajamesong avatar maximilianriemensberger avatar notmyfault avatar nurupo avatar nwholloway avatar olamy avatar pulse00 avatar theminecoder avatar thomedw avatar timja avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

digitalocean-plugin's Issues

DigitalOceanComputerLauncher: [ED25519] PEM problem: it is of unknown type

Jenkins and plugins versions report

Environment Jenkins: 2.361.2 OS: Linux - 5.15.0-48-generic --- ace-editor:1.1 analysis-model-api:10.17.0 ant:481.v7b_09e538fcca antisamy-markup-formatter:2.7 apache-httpcomponents-client-4-api:4.5.13-138.v4e7d9a_7b_a_e61 bootstrap5-api:5.2.1-3 bouncycastle-api:2.26 branch-api:2.1046.v0ca_37783ecc5 build-timeout:1.24 caffeine-api:2.9.3-65.v6a_47d0f4d1fe checks-api:1.7.5 cloud-stats:0.27 cloudbees-folder:6.758.vfd75d09eea_a_1 command-launcher:90.v669d7ccb_7c31 commons-lang3-api:3.12.0-36.vd97de6465d5b_ commons-text-api:1.9-19.v8df45c678366 conditional-buildstep:1.4.2 config-file-provider:3.11.1 configuration-as-code:1512.vb_79d418d5fc8 credentials:1189.vf61b_a_5e2f62e credentials-binding:523.vd859a_4b_122e6 dashboard-view:2.447.vda_124dd35f11 data-tables-api:1.12.1-4 digitalocean-plugin:1.3.1 display-url-api:2.3.6 durable-task:501.ve5d4fc08b0be echarts-api:5.4.0-1 email-ext:2.91 embeddable-build-status:255.va_d2370ee8fde extended-read-permission:3.2 font-awesome-api:6.2.0-3 forensics-api:1.16.0 git:4.12.1 git-client:3.12.1 git-parameter:0.9.18 github:1.35.0 github-api:1.303-400.v35c2d8258028 github-branch-source:1695.v88de84e9f6b_9 gradle:1.40 htmlpublisher:1.31 instance-identity:116.vf8f487400980 ionicons-api:28.va_f3a_84439e5f jackson2-api:2.13.3-285.vc03c0256d517 jakarta-activation-api:2.0.1-2 jakarta-mail-api:2.0.1-2 javax-activation-api:1.2.0-5 javax-mail-api:1.6.2-8 jaxb:2.3.6-2 jdk-tool:55.v1b_32b_6ca_f9ca jjwt-api:0.11.5-77.v646c772fddb_0 jquery3-api:3.6.1-2 jsch:0.1.55.61.va_e9ee26616e7 junit:1150.v5c2848328b_60 ldap:2.12 mailer:438.v02c7f0a_12fa_4 matrix-auth:3.1.5 matrix-project:785.v06b_7f47b_c631 mina-sshd-api-common:2.9.1-44.v476733c11f82 mina-sshd-api-core:2.9.1-44.v476733c11f82 momentjs:1.1.1 nodejs:1.5.1 okhttp-api:4.9.3-108.v0feda04578cf pam-auth:1.10 parameterized-trigger:2.45 pipeline-build-step:2.18 pipeline-github-lib:38.v445716ea_edda_ pipeline-graph-analysis:195.v5812d95a_a_2f9 pipeline-groovy-lib:612.v84da_9c54906d pipeline-input-step:451.vf1a_a_4f405289 pipeline-milestone-step:101.vd572fef9d926 pipeline-model-api:2.2114.v2654ca_721309 pipeline-model-definition:2.2114.v2654ca_721309 pipeline-model-extensions:2.2114.v2654ca_721309 pipeline-rest-api:2.25 pipeline-stage-step:296.v5f6908f017a_5 pipeline-stage-tags-metadata:2.2114.v2654ca_721309 pipeline-stage-view:2.25 plain-credentials:139.ved2b_9cf7587b plugin-util-api:2.18.0 popper2-api:2.11.6-2 prism-api:1.29.0-1 rebuild:1.34 resource-disposer:0.20 run-condition:1.5 scm-api:621.vda_a_b_055e58f7 script-security:1183.v774b_0b_0a_a_451 snakeyaml-api:1.32-86.ve3f030a_75631 ssh-agent:295.v9ca_a_1c7cc3a_a_ ssh-credentials:305.v8f4381501156 ssh-slaves:2.846.v1b_70190624f5 sshd:3.249.v2dc2ea_416e33 structs:324.va_f5d6774f3a_d timestamper:1.20 token-macro:308.v4f2b_ed62b_b_16 trilead-api:2.72.v2a_3236754f73 variant:59.vf075fe829ccb warnings-ng:9.20.1 workflow-aggregator:590.v6a_d052e5a_a_b_5 workflow-api:1192.v2d0deb_19d212 workflow-basic-steps:994.vd57e3ca_46d24 workflow-cps:2802.v5ea_628154b_c2 workflow-durable-task-step:1199.v02b_9244f8064 workflow-job:1239.v71b_b_a_124a_725 workflow-multibranch:716.vc692a_e52371b_ workflow-scm-step:400.v6b_89a_1317c9a_ workflow-step-api:639.v6eca_cd8c04a_a_ workflow-support:838.va_3a_087b_4055b ws-cleanup:0.43

What Operating System are you using (both controller, and any agents involved in the problem)?

Ubuntu 22.04 x64

Reproduction steps

  • Fresh Jenkins install on a master node in Docker
  • Created SSH key with ssh-keygen -t ed25519
  • Configured SSH and API keys in Jenkins
  • Added public key to Digital Ocean
  • Install DigitalOcean-plugin
  • Configure Clouds in Jenkins for the DigitalOcean plugin using info in the "Anything else?" section below
  • Run a build manually in Jenkins

Expected Results

Jenkins spins up a usable agent using an ED25519 SSH Key generated with ssh-keygen -t ed25519.

Actual Results

Jenkins gets stuck in an endless loop of creating and destroying the droplet, as it is unable to connect.
The following exception message occurs:

Oct 10, 2022 4:20:43 PM WARNING com.dubture.jenkins.digitalocean.DigitalOceanComputerLauncher launch

Publickey authentication failed.
java.io.IOException: PEM problem: it is of unknown type. Supported algorithms are :[ssh-ed25519, ecdsa-sha2-nistp521, ecdsa-sha2-nistp384, ecdsa-sha2-nistp256, rsa-sha2-256, rsa-sha2-512, ssh-rsa, ssh-dss]
	at com.trilead.ssh2.crypto.PEMDecoder.decodeKeyPair(PEMDecoder.java:482)
	at com.trilead.ssh2.auth.AuthenticationManager.authenticatePublicKey(AuthenticationManager.java:290)
Caused: java.io.IOException: Publickey authentication failed.
	at com.trilead.ssh2.auth.AuthenticationManager.authenticatePublicKey(AuthenticationManager.java:349)
	at com.trilead.ssh2.Connection.authenticateWithPublicKey(Connection.java:472)
	at com.dubture.jenkins.digitalocean.DigitalOceanComputerLauncher.launch(DigitalOceanComputerLauncher.java:170)
	at hudson.slaves.SlaveComputer.lambda$_connect$0(SlaveComputer.java:298)
	at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:48)
	at jenkins.security.ImpersonatingExecutorService$2.call(ImpersonatingExecutorService.java:82)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)

Anything else?

I am able to connect to the newly created droplet by SSH'ing from the Jenkins master node to the agent, using the SSH key I have saved in Jenkins.

I currently have the following configuration for the cloud agent:
Instance cap: 2
Timeout in minutes: 10
Connection retry wait in seconds: 30
Image: Ubuntu 22.04 x64
Run as user: root
Jenkins workspace directory path: /jenkins/
SSH port: 22
Labels [none]
Setup Private Networking: Yes
Allow jobs with no label restriction: Yes
Number of executors: 2
Idle termination time: -1
Instance cap: 2
Install monitoring: Yes

User data:

#cloud-config
apt_upgrade: true
package_upgrade: true
packages:
  - openjdk-11-jre-headless
  - docker.io
runcmd:
  - [ mkdir, /jenkins ]
  - [ chmod, 777, /jenkins ]

Init script:

#!/bin/bash

echo "starting init script"
while ! cloud-init status|grep -qF 'done'
do
  echo "waiting for cloud-init to be done"
  sleep 10
done

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.