Parallels DevOps

CI CD Jenkins Plugin GitHub Release

The Parallels DevOps plugin allows Jenkins to start ephemeral macOS, Windows, and Linux build agents on demand through Parallels DevOps Service.

When Jenkins detects queued work for a matching label, the plugin provisions a VM, waits for it to become ready, connects it as an inbound Jenkins agent, runs the build, and removes the VM when the one-shot agent is finished.

Table of contents

Introduction

This plugin integrates Jenkins with Parallels DevOps Service so that agents are provisioned only when they are needed.

Supported workflows include:

  • cloning an existing VM from a Parallels DevOps host or orchestrator
  • creating a VM from a Parallels catalog image
  • connecting the new VM as an inbound Jenkins agent (VM connects to Jenkins)
  • removing the VM automatically after a one-shot build completes

The plugin is designed for elastic build fleets where different jobs may need different operating systems, architectures, or golden images.

Features

  • Dynamic provisioning of Jenkins agents from Parallels DevOps Service
  • Support for both HOST and ORCHESTRATOR connection modes
  • Per-template label routing so jobs can request the right image
  • Provisioning modes:
    • Clone an existing VM (Supported in HOST connection mode)
    • Create from catalog (Supported in both HOST and ORCHESTRATOR connection modes)
  • Inbound agent architecture (VMs connect TO Jenkins, works through NAT/firewalls)
  • Configurable VM readiness timeout and polling interval
  • Configurable agent bootstrap settings (Java path, JVM options, connection timeout)
  • Automatic cleanup of one-shot agents and their backing VMs
  • Configuration as Code coverage for clone and catalog setups

Getting started

Before configuring the plugin in Jenkins, make sure you have:

  1. A reachable Parallels DevOps Service endpoint (version 1.0.6 or later required).
  2. Jenkins credentials for the Parallels DevOps API.
  3. Jenkins URL configured (Manage Jenkins → System → Jenkins Location) so VMs can connect back to Jenkins.
  4. At least one VM source, either:
    • an existing base VM registered on a Parallels DevOps host (for HOST mode clone provisioning), or
    • a Parallels catalog entry (for HOST or ORCHESTRATOR mode catalog provisioning).

Jobs are routed by label, so each template should use a label that clearly maps to an operating system or workload, for example macos, windows11, or ubuntu-arm64.

Usage

Create a cloud

Navigate to Manage Jenkins -> Clouds -> New cloud and choose Parallels Devops Cloud.

Create a new Parallels DevOps cloud

After the cloud is created, configure these top-level fields:

  • Name: the Jenkins name for this cloud configuration
  • Service URL: base URL of the Parallels DevOps Service instance
  • API Credentials: secret text bearer token or username/password credentials
  • Connection Mode:
    • HOST connects directly to a single Parallels DevOps host instance
    • ORCHESTRATOR connects to an orchestrator managing a fleet of hosts
  • Max Concurrent Agents: maximum number of VMs that may be alive at the same time for this cloud
  • Use WebSocket: tick to connect using WebSockets

Use Test Connection before saving.

Cloud service configuration (Host mode) Cloud service configuration (Orchestrator mode)

Configure a template

Each template represents one type of agent Jenkins may provision.

At the template level, configure:

  • Template Label: the Jenkins label that jobs will request
  • VM User: OS user account for executing bootstrap commands on the VM
  • Agent Workspace Directory: remote workspace path on the agent VM
  • Provisioning Mode: choose how the VM is created (Clone existing VM or Create from catalog)
  • VM Ready Timeout (s): maximum time to wait for the VM to become usable
  • VM Ready Poll Interval (s): how often Jenkins checks VM readiness

Expand Advanced to configure:

  • Agent Connection Timeout (s): maximum time to wait for the inbound agent to connect
  • Java Path: path to Java executable on the VM (default: java)
  • JVM Options: extra JVM flags for the agent process (e.g., -Xmx512m)

Clone existing VM

Use this mode when you connect directly to a single host (HOST mode) and want Jenkins to clone a base VM registered on that host per build.

Note

Clone mode is supported only in HOST connection mode. In ORCHESTRATOR mode, Clone mode is disabled in the UI because orchestrator deployments rely on centralized catalog provisioning.

Required field:

  • Base VM Name or VM ID: The identifier (name or ID) of the base VM to clone, as recognized by the Parallels DevOps host.

Clone-based provisioning template

Create from catalog

Use this mode when your images come from a Parallels catalog. This mode is supported in both HOST and ORCHESTRATOR connection modes. Learn more

Common fields:

  • Catalog ID: identifier of the catalog item (e.g., JENKINS_UBUNTU_SSH)
  • Catalog Version: tag or version of the catalog item (default: latest)
  • Architecture: target architecture (arm64 or x86_64)

Mode-specific fields:

  • In HOST connection mode:
    • Catalog Service URL: base URL of the remote catalog service
    • Catalog Credentials: API credentials (secret text or username/password) required for accessing the remote catalog
    • Test Catalog Connection button to validate catalog connectivity before saving
  • In ORCHESTRATOR connection mode:
    • Catalog Manager ID: ID of a registered Catalog Manager in Orchestrator (optional). Leave empty if Orchestrator and Catalog are in the same service instance.

Catalog-based provisioning template (Host mode) Catalog-based provisioning template (Orchestrator mode)

Run jobs on provisioned agents

Once a template is saved, use its label in Jenkins jobs or pipelines.

For Declarative Pipeline:

pipeline {
        agent { label 't1' }

        stages {
                stage('Verify environment') {
                        steps {
                                sh 'uname -a'
                        }
                }
        }
}

For Scripted Pipeline:

node('ubuntu-arm64') {
        sh 'hostname'
        sh 'java -version'
}

For freestyle jobs, set Restrict where this project can be run to the template label.

After provisioning succeeds, the cloud appears in Jenkins and jobs run on dynamically created nodes.

Configured clouds in Jenkins

Configuration as Code

The plugin supports Jenkins Configuration as Code (CasC).

Host Mode with Clone Provisioning

jenkins:
    clouds:
        - parallelsDevops:
                name: "test-clone-cloud"
                serviceUrl: "http://my-host.example.com:8080"
                credentialsId: "host-credentials-id"
                connectionMode: "HOST"
                maxAgents: 5
                templates:
                    - templateLabel: "macos-clone"
                        vmUser: "parallels"
                        agentWorkspaceDir: "/tmp/jenkins-agent"
                        vmReadyTimeoutSeconds: 300
                        vmReadyPollIntervalSeconds: 10
                        provisioningConfig:
                            clone:
                                baseVmName: "base-macos-sonoma"

Host Mode with Catalog Provisioning

jenkins:
    clouds:
        - parallelsDevops:
                name: "host-catalog-cloud"
                serviceUrl: "http://my-host.example.com:8080"
                credentialsId: "host-credentials-id"
                connectionMode: "HOST"
                maxAgents: 3
                templates:
                    - templateLabel: "ubuntu-host-catalog"
                        vmUser: "ubuntu"
                        agentWorkspaceDir: "/tmp/jenkins-agent"
                        vmReadyTimeoutSeconds: 600
                        vmReadyPollIntervalSeconds: 15
                        provisioningConfig:
                            catalog:
                                catalogId: "JENKINS_UBUNTU_SSH"
                                catalogVersion: "0.1"
                                architecture: "arm64"
                                catalogUrl: "https://devops-catalog.example.com"
                                catalogCredentialsId: "catalog-credentials-id"

Orchestrator Mode with Catalog Provisioning

jenkins:
    clouds:
        - parallelsDevops:
                name: "test-catalog-cloud"
                serviceUrl: "https://devops-orchestrator.example.com"
                credentialsId: "orchestrator-credentials-id"
                connectionMode: "ORCHESTRATOR"
                maxAgents: 10
                templates:
                    - templateLabel: "ubuntu-orch-catalog"
                        vmUser: "parallels"
                        agentWorkspaceDir: "/tmp/jenkins-agent"
                        vmReadyTimeoutSeconds: 600
                        vmReadyPollIntervalSeconds: 15
                        provisioningConfig:
                            catalog:
                                catalogId: "JENKINS_UBUNTU_SSH"
                                catalogVersion: "latest"
                                architecture: "arm64"
                                catalogManagerId: "cat-mgr-1234" # Optional: leave empty if Orchestrator built-in catalog is used

Behavior and troubleshooting

VM is running, but the build is still queued

The build starts only after the VM has connected to Jenkins as an inbound agent. A VM may already exist in Parallels DevOps Service while Jenkins is still:

  • waiting for the VM to report a valid IP address
  • waiting for the guest to become ready
  • waiting for the inbound agent to download agent.jar and connect

If this happens, inspect the Jenkins node launch log for the provisioned prl-... node.

Jobs using different labels still wait behind each other

Max Concurrent Agents is enforced at the cloud level, not per template. If a cloud is limited to 1, only one VM can be active at a time even when jobs target different template labels.

Cleanup may happen later than the end of the build

Normal one-shot cleanup happens when the build completes. There is also a background reconciler that removes stale or failed offline nodes on a periodic schedule, so delayed cleanup can happen after a failed or incomplete launch.

Choosing timeout and poll settings

If images boot quickly but Jenkins feels slow to pick them up, reducing VM Ready Poll Interval (s) can make readiness detection more responsive. If images need extra boot time or cloud-init work, increase VM Ready Timeout (s) instead.

Development

The README is focused on installation and usage on the Jenkins plugin site.

For local development, testing, and packaging instructions, see CONTRIBUTING.md.

Additional project-specific setup notes are available in docs/setup-guide.md.

Change log

Releases and changelog entries are published through GitHub Releases.