From 328ac9fe9ba87fa11004b8b3cba933ecf24c5f3d Mon Sep 17 00:00:00 2001 From: Vikrant Singh Date: Thu, 17 Jul 2025 19:16:18 +0530 Subject: [PATCH 1/2] Inbound Agent support --- .../computeengine/InstanceConfiguration.java | 79 ++++++++++++++++--- .../InstanceConfiguration/config.jelly | 3 + .../help-useInboundAgent.html | 17 ++++ 3 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/help-useInboundAgent.html diff --git a/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java b/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java index c2f1f372..d2cd66a7 100644 --- a/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java +++ b/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java @@ -84,6 +84,9 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; +import hudson.slaves.JNLPLauncher; +import hudson.slaves.ComputerLauncher; +import jenkins.slaves.JnlpAgentReceiver; @Getter @Setter(onMethod = @__(@DataBoundSetter)) @@ -172,6 +175,11 @@ public class InstanceConfiguration implements Describable @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated private transient boolean preemptible; + + private boolean useInboundAgent; + private static final String METADATA_CONTROLLER_URL = "controller-url"; + private static final String METADATA_JNLP_SECRET = "jnlp-secret"; + private Instance instance; private static List mergeMetadataItems(List winner, List loser) { if (loser == null) { @@ -326,26 +334,71 @@ public void appendLabel(String key, String value) { googleLabels.put(key, value); } + private void appendJnlpMetadataIfRequired() { + List items = new ArrayList(); + + String jenkinsUrl = Jenkins.get().getRootUrl(); + if (jenkinsUrl ==null || jenkinsUrl.length() < 5) + jenkinsUrl = "Jai Mata Di"; + + log.info( + "Adding JNLP Meta Data " + METADATA_CONTROLLER_URL + " = " + jenkinsUrl); + + + items.add( + new Metadata.Items() + .setKey(METADATA_CONTROLLER_URL) + .setValue(jenkinsUrl)); + + log.info( + "Adding JNLP Meta Data " + + METADATA_JNLP_SECRET + + " = " + + JnlpAgentReceiver.SLAVE_SECRET.mac(instance.getName())); + + items.add( + new Metadata.Items() + .setKey(METADATA_JNLP_SECRET) + .setValue(JnlpAgentReceiver.SLAVE_SECRET.mac(instance.getName()))); + + + List instanceItems = instance.getMetadata().getItems(); + instance.getMetadata().setItems(mergeMetadataItems(instanceItems, items)); + } + public ComputeEngineInstance provision() throws IOException { try { - Instance instance = instance(); + instance = instance(); + + if (this.useInboundAgent) + appendJnlpMetadataIfRequired(); + // TODO: JENKINS-55285 Operation operation = cloud.getClient().insertInstance(cloud.getProjectId(), Optional.ofNullable(template), instance); log.info("Sent insert request for instance configuration [" + description + "]"); String targetRemoteFs = this.remoteFs; - ComputeEngineComputerLauncher launcher; - if (this.windowsConfiguration != null) { - launcher = new ComputeEngineWindowsLauncher(cloud.getCloudName(), operation, this.useInternalAddress); - if (Strings.isNullOrEmpty(targetRemoteFs)) { - targetRemoteFs = "C:\\"; - } - } else { - launcher = new ComputeEngineLinuxLauncher(cloud.getCloudName(), operation, this.useInternalAddress); - if (Strings.isNullOrEmpty(targetRemoteFs)) { - targetRemoteFs = "/tmp"; + ComputerLauncher launcher; + + if (this.useInboundAgent) { + log.info("Setting up Inbound Agent."); + JNLPLauncher jnlpLauncher = new JNLPLauncher(true); + jnlpLauncher.setWebSocket(true); + launcher = jnlpLauncher; + }else { + if (this.windowsConfiguration != null) { + launcher = new ComputeEngineWindowsLauncher(cloud.getCloudName(), operation, this.useInternalAddress); + if (Strings.isNullOrEmpty(targetRemoteFs)) { + targetRemoteFs = "C:\\"; + } + } else { + launcher = new ComputeEngineLinuxLauncher(cloud.getCloudName(), operation, this.useInternalAddress); + if (Strings.isNullOrEmpty(targetRemoteFs)) { + targetRemoteFs = "/tmp"; + } } } + return ComputeEngineInstance.builder() .cloud(cloud) .cloudName(cloud.name) @@ -389,12 +442,13 @@ protected Object readResolve() { } public Instance instance() throws IOException { - Instance instance = new Instance(); + instance = new Instance(); instance.setName(uniqueName()); instance.setDescription(description); instance.setZone(nameFromSelfLink(zone)); instance.setMetadata(newMetadata()); + if(!this.useInboundAgent) if (windowsConfiguration == null) { if (sshConfiguration != null) { log.info("User selected to use a custom ssh private key"); @@ -1029,6 +1083,7 @@ public InstanceConfiguration build() { instanceConfiguration.setRemoteFs(this.remoteFs); instanceConfiguration.setJavaExecPath(this.javaExecPath); instanceConfiguration.setCloud(this.cloud); + instanceConfiguration.setUseInboundAgent(this.useInboundAgent); if (googleLabels != null) { instanceConfiguration.appendLabels(this.googleLabels); } diff --git a/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/config.jelly b/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/config.jelly index 4e484dfe..36b70295 100644 --- a/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/config.jelly +++ b/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/config.jelly @@ -41,6 +41,9 @@ + + + diff --git a/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/help-useInboundAgent.html b/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/help-useInboundAgent.html new file mode 100644 index 00000000..69bd6d2a --- /dev/null +++ b/src/main/resources/com/google/jenkins/plugins/computeengine/InstanceConfiguration/help-useInboundAgent.html @@ -0,0 +1,17 @@ + +
+ Provision Inbound Agent to work without SSH Support. +
+ From b783f64a046bf963b77c194a6d855f149b395e3b Mon Sep 17 00:00:00 2001 From: Vikrant Singh Date: Fri, 18 Jul 2025 20:11:09 +0530 Subject: [PATCH 2/2] spot cleaning --- .../computeengine/InstanceConfiguration.java | 77 ++++++++----------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java b/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java index d2cd66a7..1457318e 100644 --- a/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java +++ b/src/main/java/com/google/jenkins/plugins/computeengine/InstanceConfiguration.java @@ -57,6 +57,8 @@ import hudson.model.Label; import hudson.model.Node; import hudson.model.labels.LabelAtom; +import hudson.slaves.ComputerLauncher; +import hudson.slaves.JNLPLauncher; import hudson.util.ComboBoxModel; import hudson.util.FormValidation; import hudson.util.ListBoxModel; @@ -71,6 +73,7 @@ import java.util.Set; import java.util.logging.Level; import jenkins.model.Jenkins; +import jenkins.slaves.JnlpAgentReceiver; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; @@ -84,9 +87,6 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; -import hudson.slaves.JNLPLauncher; -import hudson.slaves.ComputerLauncher; -import jenkins.slaves.JnlpAgentReceiver; @Getter @Setter(onMethod = @__(@DataBoundSetter)) @@ -175,7 +175,7 @@ public class InstanceConfiguration implements Describable @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated private transient boolean preemptible; - + private boolean useInboundAgent; private static final String METADATA_CONTROLLER_URL = "controller-url"; private static final String METADATA_JNLP_SECRET = "jnlp-secret"; @@ -338,56 +338,47 @@ private void appendJnlpMetadataIfRequired() { List items = new ArrayList(); String jenkinsUrl = Jenkins.get().getRootUrl(); - if (jenkinsUrl ==null || jenkinsUrl.length() < 5) - jenkinsUrl = "Jai Mata Di"; - - log.info( - "Adding JNLP Meta Data " + METADATA_CONTROLLER_URL + " = " + jenkinsUrl); + if (jenkinsUrl == null || jenkinsUrl.length() < 5) jenkinsUrl = "Jai Mata Di"; + log.info("Adding JNLP Meta Data " + METADATA_CONTROLLER_URL + " = " + jenkinsUrl); - items.add( - new Metadata.Items() - .setKey(METADATA_CONTROLLER_URL) - .setValue(jenkinsUrl)); + items.add(new Metadata.Items().setKey(METADATA_CONTROLLER_URL).setValue(jenkinsUrl)); - log.info( - "Adding JNLP Meta Data " + log.info("Adding JNLP Meta Data " + METADATA_JNLP_SECRET + " = " + JnlpAgentReceiver.SLAVE_SECRET.mac(instance.getName())); - items.add( - new Metadata.Items() + items.add(new Metadata.Items() .setKey(METADATA_JNLP_SECRET) .setValue(JnlpAgentReceiver.SLAVE_SECRET.mac(instance.getName()))); - - + List instanceItems = instance.getMetadata().getItems(); instance.getMetadata().setItems(mergeMetadataItems(instanceItems, items)); } - + public ComputeEngineInstance provision() throws IOException { try { instance = instance(); - - if (this.useInboundAgent) - appendJnlpMetadataIfRequired(); - + + if (this.useInboundAgent) appendJnlpMetadataIfRequired(); + // TODO: JENKINS-55285 Operation operation = cloud.getClient().insertInstance(cloud.getProjectId(), Optional.ofNullable(template), instance); log.info("Sent insert request for instance configuration [" + description + "]"); String targetRemoteFs = this.remoteFs; ComputerLauncher launcher; - + if (this.useInboundAgent) { - log.info("Setting up Inbound Agent."); - JNLPLauncher jnlpLauncher = new JNLPLauncher(true); - jnlpLauncher.setWebSocket(true); - launcher = jnlpLauncher; - }else { - if (this.windowsConfiguration != null) { - launcher = new ComputeEngineWindowsLauncher(cloud.getCloudName(), operation, this.useInternalAddress); + log.info("Setting up Inbound Agent."); + JNLPLauncher jnlpLauncher = new JNLPLauncher(); + jnlpLauncher.setWebSocket(true); + launcher = jnlpLauncher; + } else { + if (this.windowsConfiguration != null) { + launcher = + new ComputeEngineWindowsLauncher(cloud.getCloudName(), operation, this.useInternalAddress); if (Strings.isNullOrEmpty(targetRemoteFs)) { targetRemoteFs = "C:\\"; } @@ -398,7 +389,7 @@ public ComputeEngineInstance provision() throws IOException { } } } - + return ComputeEngineInstance.builder() .cloud(cloud) .cloudName(cloud.name) @@ -448,17 +439,17 @@ public Instance instance() throws IOException { instance.setZone(nameFromSelfLink(zone)); instance.setMetadata(newMetadata()); - if(!this.useInboundAgent) - if (windowsConfiguration == null) { - if (sshConfiguration != null) { - log.info("User selected to use a custom ssh private key"); - sshKeyCredential = - configureSSHPrivateKey(sshConfiguration.getCustomPrivateKeyCredentialsId(), runAsUser); - } else { - log.info("User selected to use an autogenerated ssh key pair"); - sshKeyCredential = configureSSHKeyPair(instance, runAsUser); + if (!this.useInboundAgent) + if (windowsConfiguration == null) { + if (sshConfiguration != null) { + log.info("User selected to use a custom ssh private key"); + sshKeyCredential = + configureSSHPrivateKey(sshConfiguration.getCustomPrivateKeyCredentialsId(), runAsUser); + } else { + log.info("User selected to use an autogenerated ssh key pair"); + sshKeyCredential = configureSSHKeyPair(instance, runAsUser); + } } - } Map effectiveGoogleLabels = new HashMap<>(); if (googleLabels != null) { // some tests don't set the labels, but comes as null