2014 Dariusz Łuksza
Preconditions
● Basic concept of Dependeny Injection (or have open mind to grasp it during presentation)
● POSIX compatibe operating system (Linux or Mac... or Windows with cygwin, sshd is required)
● Being familiar with JavaScript● Maven
2014 Dariusz Łuksza
How Gerrit and Jenkins Gerrit Trigger plugin works?
Trigger buldPush
Retrigger build
Post comments
Send email
developer
2014 Dariusz Łuksza
What we will build?1
2
3
Plus maven configuration to build and deploy plugin in running Gerrit instance.
2014 Dariusz Łuksza
What it requires?
● REST endpoint – to schedule a build and receive confirmation
● UI Action – part of Gerrit Web UI that will show button on change screen and popups
● Capabilities – so that only members of given groups can retrigger builds
● Two HTTP calls from Gerrit to CI server – this is implementation detail, how we actually retrigger build
Initialize project
2014 Dariusz Łuksza
2014 Dariusz Łuksza
Add archetype catalog
Window → Preferences → Maven → Archetypes
First of all you need to add remote archetype catalog to Eclipse... don't know why repo1.maven.org is not on the default list.
2014 Dariusz Łuksza
Create project from archetype
Ctrl + n → Maven → Maven Project → Next x2
Fill out those addional archetype properties
2014 Dariusz Łuksza
Default project structure
You can also provide documentation for plugin ;)
Automated plugin deployment
2014 Dariusz Łuksza
2014 Dariusz Łuksza
How to intall plugin in gerrit?● Copy jar file to $gerrit_home/plugins directory
– Works fine in local development environment but could be not compatible with integration tests
or● Use Gerrit ssh command to install it remotley
– Plugin jar file must be on server file system
– Use scp command to copy plugin jar file, then gerrit ssh command to install it
– Requires additional setting in $gerrit_site/etc/gerrit.config:[plugins]
allowRemoteAdmin = true
2014 Dariusz Łuksza
How to deploy plugin from command line?
$ scp [email protected] /path/to/plugin/file.jar /tmp/
$ ssh -p 4918 [email protected] gerrit plugin install /tmp/jar.file
First operation require SSHD running on the server and system account.
Second, require account in Gerrit (this is different then one used in first step) and membership in Gerrit Administrators group*.
* or Administrate Server capability
2014 Dariusz Łuksza
Deploy from Maven? Yes, we can!
Those lines goes on and on... On last slide you will find link to repository that contains this pom.xml file
2014 Dariusz Łuksza
And missing Maven profile setting
systemUser name is used in scp command
deployUser should be member of Gerrit Administrators group*.Plus have SSH public key in Gerrit of local system user.
* or have Administrate Server capability
2014 Dariusz Łuksza
And we are good to go!Now you can simply type `mvn verify` to deploy newest plugin version in running Gerrit
Our two commands being executed
Configure your plugin
2014 Dariusz Łuksza
2014 Dariusz Łuksza
Configure plugin in gerrit.config
● Add:[plugin "RetriggerMe"]
jenkinsUrl = http://localhost:9090/
selfName = localhost 8080to $gerrit_site/etc/gerrit.config and restart Gerrit
● From now on, our plugin must be installed under `RetriggerMe` name. Otherwise it will not see this configuration.
2014 Dariusz Łuksza
Let's start from plugin configuration!
pluginName will contain name under which our plugin was installed in Gerrit, annotation here is very important. That value is dynamically bound in plugin context during installation process.
Extract `jenkinsUrl` and `selfName` from $gerrit_site/etc/gerrit.config file
Don't forget about @Inject
Communicate with outside world via REST
endpoints
2014 Dariusz Łuksza
2014 Dariusz Łuksza
Let's communicate with outside world! - REST end points
Will be automatically serialized to JSON before sending to client.
Inject our configuration provider
Implement proper interface
2014 Dariusz Łuksza
Let's communicate with outside world! - REST end points
Inform Gerrit that we want to have our REST enpoint to be registered in `change` context, with name `retrigger`. This is another part of Gerrit's Guice magic ;)
2014 Dariusz Łuksza
Let's communicate with outside world! - REST end points
Install our child Guice module in main plugin module.
2014 Dariusz Łuksza
Let's communicate with outside world! - REST end points
Let's test it:
$ mvn verify
$ curl -X POST –digest \ http://admin:tJESZhrTpZGm@localhost:8080/a/changes/2/RetriggerMe~retrigger
)]}'
{
"jenkins_url": "http://localhost:9090/"
}
Generated HTTP password for admin user
Name under which plugin was installed
REST endpoint name
Response
Context name
Response always starts with magic “)]}'” prefix. This is preventing from JavaScript injection, this is a security feature of Gerrit.
Extend Web UI
2014 Dariusz Łuksza
2014 Dariusz Łuksza
Add button on Web UI
Add UiAction interface
2014 Dariusz Łuksza
Add button on Web UI
Handle button `onclick` action
Gerrit's JavaScript magic ;)
Context name
Our REST endpoint name
2014 Dariusz Łuksza
Communicate back to server
Callback function
Call associated REST endpoint
Note object fields naming convention (underscores)
2014 Dariusz Łuksza
Handle data from client and trigger build
Input datastructure, remember about name convention, camelCase in Java, underscores_in_java_script
Gerrit will automatically deserialize JSON to Java object
Extend Gerrit permission system
2014 Dariusz Łuksza
2014 Dariusz Łuksza
Protect retrigger button with plugin own capability
Extend CapabilityDefinition class
2014 Dariusz Łuksza
Protect retrigger button with plugin own capability
Grant our plugin capability to users group
Configuring capabilities requires changes in All-Projects access rights.
2014 Dariusz Łuksza
Protect retrigger button with plugin own capability
Bind it in plugin main module
2014 Dariusz Łuksza
Protect retrigger button with plugin own capability
Anotate our UiAction with @RequiresCapability
And that is it! Only members of groups with `retrigger` capability will see `Retrigger Me!` button in Web UI.
Debugging?
2014 Dariusz Łuksza
2014 Dariusz Łuksza
How to debug?
● Modify $gerrit_site/etc/gerrit.config:
[container] javaOptions = -Xdebug -Xrunjdwp:transport=dt_socket,address=8998,server=y,suspend=n
● Use 'Remote debug' from Eclipse :)
2014 Dariusz Łuksza
Dariusz Łuksza, [email protected]
@dluksza
Thank you!
Questions?Links:● Gerrit documentation:
https://gerrit-documentation.storage.googleapis.com/Documentation/2.9/index.htmlPlugins development part:https://gerrit-documentation.storage.googleapis.com/Documentation/2.9/dev-plugins.htmlJavaScript API part:https://gerrit-documentation.storage.googleapis.com/Documentation/2.9/js-api.html
● RetriggerMe source:https://github.com/dluksza/gerrit-retriggerme
● Presentation:http://www.slideshare.net/dluksza/gerrit-plugins
● Create Gerrit Web UI plugins using AngularJS:https://github.com/dluksza/angular-gerrit