pf4jStagePlugin
.This guide explains how to set up a local Spinnaker environment on your Mac or Windows environment so you can test the pf4jStagePlugin
, which has both Orca and Deck components. Spinnaker services running locally communicate with the other Spinnaker services running in a local VM. Although this guide is specific to the pf4jStagePlugin
, you can adapt its contents to test your own plugin.
Software for development:
Specific to this guide:
release-1.20.x
release-1.20.x
Spinnaker setup used in this guide:
{my-workstation-ip}:8083
{my-workstation-ip}:9000
Minnaker is an open source tool that installs the latest release of Spinnaker and Halyard on Lightweight Kubernetes (K3s) .
Launch a Multipass VM with 2 cores, 10GB of memory, 30GB of storage.
multipass launch -c 2 -m 10G -d 30G
Get the name of your VM.
multipass list
Access your VM.
multipass shell <vm-name>
Download and unpack Minnaker.
curl -LO https://github.com/armory/minnaker/releases/download/0.0.20/minnaker.tgz
tar -xzvf minnaker.tgz
Install Spinnaker.
The minnaker/scripts
directory contains multiple scripts. Use the no_auth_install
script to install Spinnaker in no-auth mode so you can access Spinnaker without credentials. Be sure to use the -o
option to install the open source version of Spinnaker rather than Armory Spinnaker.
./minnaker/scripts/no_auth_install.sh -o
If you accidentally forget the -o
option, run ./minnaker/scripts/switch_to_oss.sh
to install open source Spinnaker.
The script prints out the IP address of Minnaker after installation is complete.
Check pod status:
kubectl -n spinnaker get pods
Consult the Minnaker README for basic troubleshooting information if you run into issues.
Revert Spinnaker to 1.20.6.
Minnaker forwards hal
commands to the Halyard pod so you don’t need to access the pod itself.
hal config version edit --version 1.20.6
hal deploy apply
``
Configure Minnaker to listen on all ports.
./minnaker/scripts/utils/expose_local.sh
This creates a load balancer for each service. Console output is similar to:
NAME READY STATUS RESTARTS AGE
minio-0 1/1 Running 0 18h
mariadb-0 1/1 Running 0 18h
halyard-0 1/1 Running 0 18h
spin-redis-664df6f896-b5px8 1/1 Running 0 18h
svclb-spin-clouddriver-lcmrq 1/1 Running 0 10m
svclb-spin-redis-24qf6 1/1 Running 0 10m
svclb-spin-front50-8hchk 1/1 Running 0 10m
svclb-spin-orca-9t89s 1/1 Running 0 10m
svclb-spin-gate-gn6g5 1/1 Running 0 10m
svclb-spin-deck-26vpf 1/1 Running 0 10m
svclb-spin-echo-s6zdv 1/1 Running 0 10m
svclb-spin-rosco-qwfhv 1/1 Running 0 10m
spin-deck-55b88d5fb9-v2ngf 1/1 Running 0 10m
spin-front50-8fd4f9459-fwpzc 1/1 Running 0 10m
spin-rosco-6885b6df45-jqkl9 1/1 Running 0 10m
spin-gate-75df95744b-7zvp5 1/1 Running 0 10m
spin-orca-766f9bbf7b-cw9f7 1/1 Running 0 10m
spin-echo-9bbcd9df8-td4rt 1/1 Running 0 10m
spin-clouddriver-55bc94ddcc-4d7cd 1/1 Running 0 10m
``
Decide which Spinnaker services you want to run locally. This example uses Orca and Deck.
Configure Minnaker to expect the relevant services to be external:
./minnaker/scripts/utils/external_service_setup.sh orca deck
Output is similar to:
Generated deploymentConfigurations[0].deploymentEnvironment.customSizing:
spin-orca:
replicas: 0
spin-deck:
replicas: 0
Generated local /etc/spinnaker/.hal/default/profiles/spinnaker-local.yml:
--------------
services:
orca:
baseUrl: {my-vm-ip}:8083
deck:
baseUrl: {my-vm-ip}:9000
--------------
Place this file at '~/.spinnaker/spinnaker-local.yml' on your workstation
--------------
services:
clouddriver:
baseUrl: {my-workstation-ip}:7002
redis:
baseUrl: {my-workstation-ip}:6379
front50:
baseUrl: {my-workstation-ip}:8080
orca:
host: 0.0.0.0
gate:
baseUrl: {my-workstation-ip}:8084
deck:
host: 0.0.0.0
echo:
baseUrl: {my-workstation-ip}:8089
rosco:
baseUrl: {my-workstation-ip}:8087
--------------
This script creates a spinnaker-local.yml
on the VM that indicates the IPs where Orca and Deck are running. Furthermore, the script generates Spinnaker configuration content that you need to copy on your OSX workstation. This content tells your locally running services where the rest of the Spinnaker services are running.
Note: external_service_setup.sh
removes the previous configuration each time you run it.
Copy the services
section between the dotted lines in the terminal output from the executing the external_service_setup.sh
script. Create or edit the ~/.spinnaker/spinnaker-local.yml
file on your workstation and paste the previously copied services
snippet into it.
The spinnaker-local.yml
has this content:
services:
clouddriver:
baseUrl: {my-workstation-ip}:7002
redis:
baseUrl: {my-workstation-ip}:6379
front50:
baseUrl: {my-workstation-ip}:8080
orca:
host: 0.0.0.0
gate:
baseUrl: {my-workstation-ip}:8084
deck:
host: 0.0.0.0
echo:
baseUrl: {my-workstation-ip}:8089
rosco:
baseUrl: {my-workstation-ip}:8087
--------------
Clone the Orca and Deck release-1.20.x
branches that correspond to the Spinnaker 1.20.6 version you installed using Minnaker. Then clone pf4jStagePlugin
v1.1.14, which works with Spinnaker 1.20.6.
git clone --single-branch --branch v1.1.14 https://github.com/spinnaker-plugin-examples/pf4jStagePlugin.git
git clone --single-branch --branch release-1.20.x https://github.com/spinnaker/orca.git
git clone --single-branch --branch release-1.20.x https://github.com/spinnaker/deck.git
Open the Orca project in IntelliJ.
If you don’t have a project open, you see a Welcome to IntellJ IDEA window.
build.gradle
and click OpenIf you already have one or more projects open, do the following:
build.gradle
and click OpenGrab a beverage and snack while you wait for IntelliJ to finish indexing the project.
If you have multiple JDKs installed, configure the Orca project to use JDK 11.
Through the next few steps, if you see an Unable to find Main
log message or fields are grayed out, reimport the project:
View > Tool Windows > Gradle
In the Gradle window, right click “Orca” and then click Reimport Gradle Project
Create a Run Configuration.
You can skip the following steps if IntelliJ automatically creates a “Main” Run Configuration. Rename “Main” to “RunOrca”.
Click the Add Configuration or Edit Configurations button to open the Run/Debug Configurations window.
Click the +
button to create a new configuration.
Select Application.
Enter “RunOrca” in the Name field.
Main class Click the … button. Wait for the list to load and then select Main (com.netflix.spinnaker.orca)
. Alternately, click on Project and navigate to orca > orca-web > src > main > groovy > com.netflix.spinnaker > orca > Main
.
In the dropdown for Use classpath of module, select orca-web_main
Click Apply and then OK.
Run orca
using the RunOrca
configuration.
Success output is similar to:
INFO 18111 --- [main] com.netflix.spinnaker.orca.Main: [] Started Main in 11.123 seconds (JVM running for 11.933)
``
If Orca can’t find Redis, make sure your Minnaker VM is running and that all the Spinnaker services are ready.
You can stop running Orca after you have verified that you can successfully run it.
Navigate to the pf4jStagePlugin
directory and execute:
./gradlew releaseBundle
The build process creates files you need in later steps:
random-wait-orca/build/Armory.RandomWaitPlugin-orca.plugin-ref
random-wait-deck/build/dist/index.js
Create a top-level plugins
directory in your Orca project.
Copy the Armory.RandomWaitPlugin-orca.plugin-ref
file to the plugins
directory.
Create the orca-local.yml
file in ~/.spinnaker/
with the following contents:
spinnaker:
extensibility:
plugins:
Armory.RandomWaitPlugin:
enabled: true
version: 1.1.14
extensions:
armory.randomWaitStage:
enabled: true
config:
defaultMaxWaitTime: 20
``
This tells Spinnaker to enable and use the plugin.
In IntelliJ, link the pf4jStagePlugin
project to your Orca project.
pf4jStagePlugin
Gradle project.pf4jStagePlugin
directory , select the build.gradle
file, and click Open.In the Gradle window, right click orca and click Reimport Gradle Project.
You can now run or debug Orca and the plugin using IntelliJ.
Update the deck/plugin-manifest.json
with the plugin information.
[
{
"id": "Armory.RandomWaitPlugin",
"url": "./plugins/index.js",
"version": "1.1.14"
}
]
``
For development, the values in id
and version
can be any value.
Create a deck/plugins
directory and symlink
random-wait-deck/build/dist/index.js
to deck/plugins/index.js
. For example:
cd <path-to-deck>
ln -s <path-to-pf4jStagePlugin>/random-wait-deck/build/dist/index.js plugins/index.js
``
Create a new build configuration.
Click Edit Configurations…
In the Run/Debug Configurations window, click the + icon and then select Application.
Fill in fields 1-6 with the following:
Run orca
and the pf4jStagePlugin
using the Build and Test Plugin configuration. On successful launch, you see a “Completed initialization” log statement in the console:
020-05-12 16:03:44.274 INFO 6973 --- [0.0-8083-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : [] Initializing Spring DispatcherServlet 'dispatcherServlet'
INFO 6973 --- [0.0-8083-exec-1] o.s.web.servlet.DispatcherServlet : [] Initializing Servlet 'dispatcherServlet'
INFO 6973 --- [0.0-8083-exec-1] o.s.web.servlet.DispatcherServlet : [] Completed initialization in 16 ms
``
If you see error messages about Redis, make sure all the pods in your Spinnaker instance are READY
. You can check the IP address and port for each service in ~/.spinnaker/spinnaker-local.yml
.
Plugin loading messages appear near the top of the Orca log. You should see statements similar to:
INFO 90843 --- [main] org.pf4j.AbstractPluginManager: [] Plugin 'Armory.RandomWaitPlugin@unspecified' resolved
INFO 90843 --- [main] org.pf4j.AbstractPluginManager: [] Start plugin 'Armory.RandomWaitPlugin@unspecified'
INFO 90843 --- [main] i.a.p.s.wait.random.RandomWaitPlugin: [] RandomWaitPlugin.start()
``
The Deck project README has instructions for building and running Deck locally.
Build Deck by executing yarn
from the deck
directory.
Start Deck with the API_HOST argument, which is the Gate URL.
cd deck
yarn
API_HOST={my-workstation-ip}:8084 AUTH_ENABLED=false yarn start
``
http://localhost:9000
.You can use the Developer Tools in your browser to troubleshoot Deck plugin issues.
Look for plugin-manifest.json
and index.js
. It’s normal to see 3 plugin-manifest.json
HTTP requests. The first one is from Deck - you created this file in the
Configure Deck for the plugin
section above. The next two from Gate are not relevant for local development. If you don’t see the plugin-manifest.json
and index.js
HTTP requests, check the Console tab for errors. Also verify that the content in your plugin-manifest.json
file is correct.
If you want to debug the backend component of the plugin without a working Deck component, you can create a new stage in the UI and configure it using JSON.
Start the Build and Test Plugin configuration in Debug mode.
Start Deck.
Access the the Spinnaker UI at http://localhost:9000
.
Go to Applications > spin > PIPELINES.
Create a new pipeline.
Add a new stage.
Do not choose a stage from the Type select list. Instead, click Edit stage as JSON to open the Edit Stage JSON window.
Paste this content in the text box:
{
"maxWaitTime": 15,
"name": "Test RandomWait",
"type": "randomWait"
}
maxWaitTime
: number of seconds; you get the maxWaitTime
field name from the variable passed into the RandomWaitInput
primary constructorname
: name of the new stagetype
: use the value returned by the
<code>getName</code> function
in RandomWaitStage
Click Update Stage.
Click Save Changes.
Go back to the PIPELINES screen.
Start Manual Execution and watch the stage wait for the specified number of seconds.
You can ask for help with plugins in the
Spinnaker Slack
’s #plugins
channel.