I am pretty new to Jenkins and I am having difficulty understanding the Jenkins Controller/Agent structure.
In my setup I am trying to perform distributed build of a Unity game project on several agents. Basically I will invoke a command “path-to-unity/Unity --executeMethod build” which will tell the “Unity” that acts like a “compiler” to compile a bunch of source code. However I don’t understand whether I need to install Unity and pull the exact same copy of the source code on every single Jenkins Agent machine in order to do the distributed build, and/or whether I need to manually handle the build work-load distribution in my shell script.
Based on some of the readings I have read, it looks like Jenkins will do the “distribution of work” automatically to each agent, magically. However I am not sure whether my understanding is correct. The Unity program itself consists of several gigabytes of data and the source code also consists of gigabytes of data and at least for me it seems kind of impossible to “automatically distribute on-the-fly” by Jenkins.
If I indeed need to install Unity on every single agent machine, pull the exact same copy of source code on every machine and do the work-load distribution by myself that would imply a lot of work to be done.
What I don’t understand is, how can it be possible to run the several GIGABYTE Unity program on another machine, without it needed to be installed/transferred?
If it is the “transferred” way, wouldn’t it be really slow since the file is several GIGABYTE big.
So I don’t fully know what you are asking as I don’t know how distributed builds work with unity. I would guess like other systems, it’ll communicate with its other instances and provide what is needed.
On a gigabit network though it should be pretty fast.
Jenkins itself isn’t super optimized to transfer files, so stash()/unstash()/archiveArtifacts() etc are not top speed, but usually good enough for most cases. If you are using it a lot, it might be better to use a centralized storage like samba or nfs.
I think I might have misunderstood the “controller/agent” structure completely.
(1) My current understanding is based on the “master/slave” structure of MySQL, where the slave is basically a “replica” of the “master”. The master does everything itself and slaves do exactly the same things as master, the purpose of slave is only to distribute the work-load of the master.
(2) However, I have a feeling from our discussion that, the correct setup should be “Unity is installed at the agent environment and the controller environment will have nothing but Jenkins installed” and the controller literally only tells which agent to do what without doing anything itself.
May I kindly ask which of my above understanding is correct?
It is one of the many reasons the terms were changed away from master and slave.
Controller - where you use the UI, and do all the configuration and stuff - The Jenkins URL
agent - Where jobs run
job - Job can have one or more agents (actually can have 0, but that’s something else) to do tasks.
I’m not the best at following all the terms, but there is a glossary
Thank you for your clarification. When I first learnt about Jenkins the terms master and slave were used and I think I was filled by that prejudice along with comparison to MySQL then and misunderstood everything I read since then. I think I am now clear what to do.
The Controller acts as the UI for System Administration and Configuration point, Job Configuration and Logs repository, as well as the Orchestrator and Scheduler.
In a preferred configuration, all job are executed (via executors, running) on Agents. Agents are typically separate host “machines” - VMs, containers, etc… Running jobs on the controller is strongly discouraged as a security risk, though it’s possible to co-locate an Agent using a separate Userid on the same host as the controller (providing appropriate OS level security is in place).
The environment to perform your job is on the Agent. As the Agents are typically launched (on UNIX) as a non-interactive shell, you don’t get the same environment as a direct login. The software components to execute the steps of your job must be available on the Agent. Some plugin steps have options to point to a pre-installed location of or auto-install the binaries (eg: maven-plugin, Java JDK, nodeJS; these tend to be configurable under the ${JENKINS_URL}/configureTools} directory. They also tend to prepend the PATH and set up the environment for the tool.
Otherwise, you’d need to use something like the Environment Injector plugin to assist pre-configuration. You may also be able to construct a similar setup using the Custom Tools plugin.
It would seem your preferred option is to pre-install the binaries on the desired Agents, then specifically label those Nodes with a label (eg: Unity), and restrict your jobs to run on those nodes. You might even be able to make the binaries available from a single shared volume as long as each build gets its own workspace (that’s Jenkins default anyway). The Controller does not need the Unity binaries.
Others may suggest creating a custom Jenkins Docker Agent with the complete build environment configuration, though not sure what that would entail for Unity or if it would be persistent.
There does seem to be an open PR - Workflow/pipeline support #10, but like any plugin with no releases in 6+ years, appears to be unsupported, so no one to cut a new release incorporating such capability.