SlideShare une entreprise Scribd logo
1  sur  47
Jenkins User Conference   San Francisco, Sept 30 2012   #jenkinsconf


       Take Control. Write a Plugin.
       Part II

                     Baruch Sadogursky
                           JFrog
                       www.jfrog.com
About me
Developer Advocate @JFrog
Job definition:
     Write code
     Talk about it




github.com/jbaruch
@jbaruch
JFrog & Jenkins

With Jenkins from day 1
Jenkins Artifactory Plugin
Hosted JUC Israel
repo.jenkins-ci.org
JavaOne DEMOzone
Agenda

Vote and guessing
Working with remote agents
Working in multiple operation systems
Creating UI using Groovy
Writing custom Jelly(?) tags
Maintaining backwards compatibility
Agenda

Vote and guessing
Working with remote agents
Working in multiple operation systems
Creating UI using Groovy
Writing custom Jelly(?) tags
Maintaining backwards compatibility
First, let’s vote

Who saw “Take Control. Write a Plugin” session
on YouTube?
Let me guess…
              one or two hands…
“Hello, my name is Noam Tenne”

PREVIOUSLY IN “TAKE CONTROL.
WRITE A PLUGIN”…
Overview – Why plugins

What you can do with plugins
What you can’t do with plugins
Plugins statistics
What can I extend?
UI
SCM
Build Processes
Slave management
Tooling
... Many, many, more

You can even create new extension points!
Environment

IDE
  All majors have good support
  We love IntelliJ IDEA
Build tool
  Can be Maven or Gradle
The “Motivation” Plugin

Target: Rewarding failing builds with insulting
mockery
Global configuration: Motivation phrase
Project configuration: Is motivator enabled
Outcome: Message appears in log after failure
Nowdays…

BACK TO OUR AGENDA
Agenda

Vote and guessing
Working with remote agents
Working in multiple operation systems
Creating UI using Groovy
Writing custom Jelly(?) tags
Maintaining backwards compatibility
Working with remote agents

Jenkins has remote agents!
Working with remote agents

Send closures to remote agents
hudson.remoting.Callable




              Java Serialization
Closure

    Poor guy’s Java closure
    Usually anonymous inner class (not always)

1   private static class GetSystemProperties implements Callable<Properties,RuntimeException> {
2       public Properties call() {
3           return System.getProperties();
4       }
5       private static final long serialVersionUID = 1L;
6   }
Cast your bread on the waters



1   this.systemProperties = channel.call(new GetSystemProperties());




    Channel?
Channel

Represents a communication channel to the
remote peer

Obtain from:
Distribution Abstractions – FilePath

Where is the file?
Distribution Abstractions – FilePath

hudson.FilePath
  Much like java.util.File


Consider pushing logic to the file
  Use FilePath.act(FileCallable)
Distribution Abstractions – Launcher

Launch stuff remotely!
Distribution Abstractions – Launcher

hudson.Launcher
  Much like java.lang.ProcessBuilder


Pick your environment variables wisely!
Agenda

Vote and guessing
Working with remote agents
Working in multiple operation systems
Creating UI using Groovy
Writing custom Jelly(?) tags
Maintaining backwards compatibility
Working in multiple OSs
WORA. You know. But.

/ vs 
.sh vs .bat
Quotes around commands
Permissions
      (wait for it…)
Running script…

Executing
     file…
             remotely…
                 platform independent…
Can You Spot The Error?


1 String workspaceDir = build.getWorkspace().getRemote();
2 String scriptName = launcher.isUnix() ? "proc.sh" : "proc.bat";
3 Launcher.ProcStarter procStarter =
launcher.launch().stdout(System.out);
4 procStarter.cmds(new File(workspaceDir, scriptName)).join();




                             Executed
                             locally!
Going Remote with File

Use FilePath – it will take care of all the details!
Execute FilePath.act(FileCallable)

If you need the File API, invoke() method
      has it, converted to remote file properly
Permissions Dance

 1   public boolean isDirectoryReadOnly(final FilePath filePath) throws IOException,
 2           InterruptedException {
 3       return filePath.getChannel().call(new Callable<Boolean, IOException>() {
 4           public Boolean call() throws IOException {
 5               Path path = FileSystems.getDefault().getPath(filePath.getRemote());
 6               Set<String> systems = FileSystems.getDefault().supportedFileAttributeViews();
 7               if (systems.contains("dos")) {
 8                   DosFileAttributeView dosView =
 9                           Files.getFileAttributeView(path, DosFileAttributeView.class);
10                   DosFileAttributes dosAttributes = dosView.readAttributes();
11                   return dosAttributes.isReadOnly();
12               }
13               if (systems.contains("posix")) {
14                   PosixFileAttributeView posixView =
15                           Files.getFileAttributeView(path, PosixFileAttributeView.class);
16                   PosixFileAttributes posixAttributes = posixView.readAttributes();
17                   Set<PosixFilePermission> permissions = posixAttributes.permissions();
18                   return !permissions.contains(PosixFilePermission.OTHERS_WRITE)
19               }
20               throw new IOException("Unknown filesystem");
21           }
22       });
23   }
Agenda

Vote and guessing
Working with remote agents
Working in multiple operation systems
Creating UI using Groovy
Writing custom Jelly(?) tags
Maintaining backwards compatibility
Creating UI using Groovy

First, let’s look at the docs:
Creating UI using Groovy

Analogous to Jelly
Can use Jelly tags and libraries

     Kohsuke:
                   When                    What
     Lots of program logic        Groovy
     Lots of HTML layout markup   Jelly
Creating UI using Groovy

Analogous to Jelly
Can use Jelly tags and libraries

     me:
               When                 What
     Always!               Groovy
Creating UI using Groovy

    Jelly:
1 <j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
2     <f:section title="Motivation Plugin">
3         <f:entry title=" Motivating Message" field="motivatingMessage"
4                  description="The motivational message to display when a build fails">
5             <f:textbox/>
6         </f:entry>
7     </f:section>
8 </j:jelly>


    Groovy:
1 f=namespace('lib/form')
2
3 f.section(title:'Motivation Plugin') {
4     f.entry(title:'Motivating Message', field:'motivatingMessage',
5     description:'The motivational message to display when a build fails'){
6         f.textbox()
7     }
8 }
Creating UI using Groovy

   Real code
   Debuggable, etc.
         (stay tuned…)
1 f=namespace('lib/form')
2
3 f.section(title:'Motivation Plugin') {
4     f.entry(title:'Motivating Message', field:'motivatingMessage',
5     description:'The motivational message to display when a build fails'){
6         f.textbox()
7     }
8 }
Agenda

Vote and guessing
Working with remote agents
Working in multiple operation systems
Creating UI using Groovy
Writing custom Jelly(?) tags
Maintaining backwards compatibility
Writing custom Jelly(?) tags

Documentation:
Writing custom Jelly(?) tags
Writing custom Jelly Groovy tags

Simple as 1,2…
     that’s it.
1. Implement

 1 class MotivationTagLib extends
 2         AbstractGroovyViewModule {
 3     def tools = builder.namespace('hudson/tools')
 4
 5     MotivationTagLib(JellyBuilder b) {
 6         super(b)
 7     }
 8
 9     def evilLaugh() {
10         tools.label('mu-ha-ha!')
11     }
12 }
2. Use!


 1   import org._10ne.jenkins.MotivationTagLib
 2
 3   f = namespace('lib/form')
 4   m = new MotivationTagLib(builder);
 5
 6   f.entry(title: '') {
 7       m.evilLaugh()
 8       f.checkbox(…)
11   }
Agenda

Vote and guessing
Working with remote agents
Working in multiple operation systems
Creating UI using Groovy
Writing custom Jelly(?) tags
Maintaining backwards compatibility
Maintaining backwards compatibility

Back to Motivation plugin…
Refactoring!

Rename defaultMotivatingMessage
             to
         motivatingMessage

What happens to existing configuration on
users machines?
XStream Aliasing To The Rescue
1   @Initializer(before = PLUGINS_STARTED)
2   public static void addAliases() {
3      Items.XSTREAM2.aliasField("defaultMotivatingMessage",
4              DescriptorImpl.class, "motivatingMessage");
5      }


    Register field (or class) alias
    In Initializer that runs before plugins started

    More complex cases might reqiure XStream
    converter
Thank you!




See you at our DEMOzone!
Thank You To Our Sponsors

Contenu connexe

Tendances

Tendances (20)

Extending NetBeans IDE
Extending NetBeans IDEExtending NetBeans IDE
Extending NetBeans IDE
 
Powershell training material
Powershell training materialPowershell training material
Powershell training material
 
Netbeans IDE & Platform
Netbeans IDE & PlatformNetbeans IDE & Platform
Netbeans IDE & Platform
 
How we realized SOA by Python at PyCon JP 2015
How we realized SOA by Python at PyCon JP 2015How we realized SOA by Python at PyCon JP 2015
How we realized SOA by Python at PyCon JP 2015
 
DevOps meetup 16oct docker and jenkins
DevOps meetup 16oct docker and jenkinsDevOps meetup 16oct docker and jenkins
DevOps meetup 16oct docker and jenkins
 
Maven 3.0 at Øredev
Maven 3.0 at ØredevMaven 3.0 at Øredev
Maven 3.0 at Øredev
 
Intro to JavaScript Tooling in Visual Studio Code
Intro to JavaScript Tooling in Visual Studio CodeIntro to JavaScript Tooling in Visual Studio Code
Intro to JavaScript Tooling in Visual Studio Code
 
PHP Frameworks, or how I learnt to stop worrying and love the code
PHP Frameworks, or how I learnt to stop worrying and love the codePHP Frameworks, or how I learnt to stop worrying and love the code
PHP Frameworks, or how I learnt to stop worrying and love the code
 
Intro to Angular.js & Zend2 for Front-End Web Applications
Intro to Angular.js & Zend2  for Front-End Web ApplicationsIntro to Angular.js & Zend2  for Front-End Web Applications
Intro to Angular.js & Zend2 for Front-End Web Applications
 
Introduction to Apache Ant
Introduction to Apache AntIntroduction to Apache Ant
Introduction to Apache Ant
 
Rest apis with DRF
Rest apis with DRFRest apis with DRF
Rest apis with DRF
 
Introduction to NodeJS
Introduction to NodeJSIntroduction to NodeJS
Introduction to NodeJS
 
XDebug For php debugging
XDebug For php debuggingXDebug For php debugging
XDebug For php debugging
 
CollabSphere 2018 - Java in Domino After XPages
CollabSphere 2018 - Java in Domino After XPagesCollabSphere 2018 - Java in Domino After XPages
CollabSphere 2018 - Java in Domino After XPages
 
Django - Python MVC Framework
Django - Python MVC FrameworkDjango - Python MVC Framework
Django - Python MVC Framework
 
DevOps MeetUp NL - Docker (Oct 2014)
DevOps MeetUp NL - Docker (Oct 2014)DevOps MeetUp NL - Docker (Oct 2014)
DevOps MeetUp NL - Docker (Oct 2014)
 
淺談 Geb 網站自動化測試(JCConf 2014)
淺談 Geb 網站自動化測試(JCConf 2014)淺談 Geb 網站自動化測試(JCConf 2014)
淺談 Geb 網站自動化測試(JCConf 2014)
 
Dr. Strangelove, or how I learned to love plugin development
Dr. Strangelove, or how I learned to love plugin developmentDr. Strangelove, or how I learned to love plugin development
Dr. Strangelove, or how I learned to love plugin development
 
Apache ANT vs Apache Maven
Apache ANT vs Apache MavenApache ANT vs Apache Maven
Apache ANT vs Apache Maven
 
Intelligent Projects with Maven - DevFest Istanbul
Intelligent Projects with Maven - DevFest IstanbulIntelligent Projects with Maven - DevFest Istanbul
Intelligent Projects with Maven - DevFest Istanbul
 

En vedette

Jenkins plugin memo
Jenkins plugin memoJenkins plugin memo
Jenkins plugin memo
Kiyotaka Oku
 
Jenkins and Groovy
Jenkins and GroovyJenkins and Groovy
Jenkins and Groovy
Kiyotaka Oku
 
SF Gradle Meetup - Netflix OSS
SF Gradle Meetup - Netflix OSSSF Gradle Meetup - Netflix OSS
SF Gradle Meetup - Netflix OSS
Justin Ryan
 

En vedette (19)

BaseScriptについて
BaseScriptについてBaseScriptについて
BaseScriptについて
 
javafx-mini4wd
javafx-mini4wdjavafx-mini4wd
javafx-mini4wd
 
Jenkins plugin memo
Jenkins plugin memoJenkins plugin memo
Jenkins plugin memo
 
Netflix Nebula - Gradle Summit 2014
Netflix Nebula - Gradle Summit 2014Netflix Nebula - Gradle Summit 2014
Netflix Nebula - Gradle Summit 2014
 
Configuration As Code: The Job DSL Plugin
Configuration As Code: The Job DSL PluginConfiguration As Code: The Job DSL Plugin
Configuration As Code: The Job DSL Plugin
 
Using Groovy with Jenkins
Using Groovy with JenkinsUsing Groovy with Jenkins
Using Groovy with Jenkins
 
Jenkins and Groovy
Jenkins and GroovyJenkins and Groovy
Jenkins and Groovy
 
The Jenkins Plugin for OpenStack
The Jenkins Plugin for OpenStackThe Jenkins Plugin for OpenStack
The Jenkins Plugin for OpenStack
 
Jenkins Plugin Development With Gradle And Groovy
Jenkins Plugin Development With Gradle And GroovyJenkins Plugin Development With Gradle And Groovy
Jenkins Plugin Development With Gradle And Groovy
 
Zero To Cloud (OSCon 2014)
Zero To Cloud (OSCon 2014)Zero To Cloud (OSCon 2014)
Zero To Cloud (OSCon 2014)
 
Writing your Third Plugin
Writing your Third PluginWriting your Third Plugin
Writing your Third Plugin
 
Writing a Jenkins / Hudson plugin
Writing a Jenkins / Hudson pluginWriting a Jenkins / Hudson plugin
Writing a Jenkins / Hudson plugin
 
Ruby Plugins for Jenkins
Ruby Plugins for JenkinsRuby Plugins for Jenkins
Ruby Plugins for Jenkins
 
Jenkins Workflow - An Introduction
Jenkins Workflow - An IntroductionJenkins Workflow - An Introduction
Jenkins Workflow - An Introduction
 
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-Code
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-CodeSD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-Code
SD DevOps Meet-up - Jenkins 2.0 and Pipeline-as-Code
 
SF Gradle Meetup - Netflix OSS
SF Gradle Meetup - Netflix OSSSF Gradle Meetup - Netflix OSS
SF Gradle Meetup - Netflix OSS
 
Job DSL Plugin for Jenkins
Job DSL Plugin for JenkinsJob DSL Plugin for Jenkins
Job DSL Plugin for Jenkins
 
Configuration As Code - Adoption of the Job DSL Plugin at Netflix
Configuration As Code - Adoption of the Job DSL Plugin at NetflixConfiguration As Code - Adoption of the Job DSL Plugin at Netflix
Configuration As Code - Adoption of the Job DSL Plugin at Netflix
 
Jenkins 再入門
Jenkins 再入門Jenkins 再入門
Jenkins 再入門
 

Similaire à Take control. write a plugin. part II

Jquery Plugin
Jquery PluginJquery Plugin
Jquery Plugin
Ravi Mone
 
Android developer's toolbox
Android developer's toolboxAndroid developer's toolbox
Android developer's toolbox
Alex Verdyan
 

Similaire à Take control. write a plugin. part II (20)

An Introduction to Gradle for Java Developers
An Introduction to Gradle for Java DevelopersAn Introduction to Gradle for Java Developers
An Introduction to Gradle for Java Developers
 
Introduction to Software Development
Introduction to Software DevelopmentIntroduction to Software Development
Introduction to Software Development
 
A brief overview of java frameworks
A brief overview of java frameworksA brief overview of java frameworks
A brief overview of java frameworks
 
CollabSphere 2021 - DEV114 - The Nuts and Bolts of CI/CD With a Large XPages ...
CollabSphere 2021 - DEV114 - The Nuts and Bolts of CI/CD With a Large XPages ...CollabSphere 2021 - DEV114 - The Nuts and Bolts of CI/CD With a Large XPages ...
CollabSphere 2021 - DEV114 - The Nuts and Bolts of CI/CD With a Large XPages ...
 
IEDOTNETUG Silverlight Class Week 6
IEDOTNETUG Silverlight Class Week 6IEDOTNETUG Silverlight Class Week 6
IEDOTNETUG Silverlight Class Week 6
 
Jquery Plugin
Jquery PluginJquery Plugin
Jquery Plugin
 
Zepto and the rise of the JavaScript Micro-Frameworks
Zepto and the rise of the JavaScript Micro-FrameworksZepto and the rise of the JavaScript Micro-Frameworks
Zepto and the rise of the JavaScript Micro-Frameworks
 
Bringing classical OOP into JavaScript
Bringing classical OOP into JavaScriptBringing classical OOP into JavaScript
Bringing classical OOP into JavaScript
 
Play framework
Play frameworkPlay framework
Play framework
 
Apache Felix Web Console
Apache Felix Web ConsoleApache Felix Web Console
Apache Felix Web Console
 
Java Deserialization Vulnerabilities - The Forgotten Bug Class (DeepSec Edition)
Java Deserialization Vulnerabilities - The Forgotten Bug Class (DeepSec Edition)Java Deserialization Vulnerabilities - The Forgotten Bug Class (DeepSec Edition)
Java Deserialization Vulnerabilities - The Forgotten Bug Class (DeepSec Edition)
 
Introduction to PowerShell
Introduction to PowerShellIntroduction to PowerShell
Introduction to PowerShell
 
What is the Joomla Framework and why do we need it?
What is the Joomla Framework and why do we need it?What is the Joomla Framework and why do we need it?
What is the Joomla Framework and why do we need it?
 
Js Saturday 2013 your jQuery could perform better
Js Saturday 2013 your jQuery could perform betterJs Saturday 2013 your jQuery could perform better
Js Saturday 2013 your jQuery could perform better
 
Introduction to clojure
Introduction to clojureIntroduction to clojure
Introduction to clojure
 
Android developer's toolbox
Android developer's toolboxAndroid developer's toolbox
Android developer's toolbox
 
Griffon: Re-imaging Desktop Java Technology
Griffon: Re-imaging Desktop Java TechnologyGriffon: Re-imaging Desktop Java Technology
Griffon: Re-imaging Desktop Java Technology
 
Plug yourself in and your app will never be the same (1 hr edition)
Plug yourself in and your app will never be the same (1 hr edition)Plug yourself in and your app will never be the same (1 hr edition)
Plug yourself in and your app will never be the same (1 hr edition)
 
Selenium interview questions and answers
Selenium interview questions and answersSelenium interview questions and answers
Selenium interview questions and answers
 
Cape Cod Web Technology Meetup - 3
Cape Cod Web Technology Meetup - 3Cape Cod Web Technology Meetup - 3
Cape Cod Web Technology Meetup - 3
 

Plus de Baruch Sadogursky

Plus de Baruch Sadogursky (20)

DevOps Patterns & Antipatterns for Continuous Software Updates @ NADOG April ...
DevOps Patterns & Antipatterns for Continuous Software Updates @ NADOG April ...DevOps Patterns & Antipatterns for Continuous Software Updates @ NADOG April ...
DevOps Patterns & Antipatterns for Continuous Software Updates @ NADOG April ...
 
DevOps Patterns & Antipatterns for Continuous Software Updates @ DevOps.com A...
DevOps Patterns & Antipatterns for Continuous Software Updates @ DevOps.com A...DevOps Patterns & Antipatterns for Continuous Software Updates @ DevOps.com A...
DevOps Patterns & Antipatterns for Continuous Software Updates @ DevOps.com A...
 
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at Oracle Code NY...
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at Oracle Code NY...DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at Oracle Code NY...
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at Oracle Code NY...
 
Data driven devops as presented at QCon London 2018
Data driven devops as presented at QCon London 2018Data driven devops as presented at QCon London 2018
Data driven devops as presented at QCon London 2018
 
A Research Study Into DevOps Bottlenecks as presented at Oracle Code LA 2018
A Research Study Into DevOps Bottlenecks as presented at Oracle Code LA 2018A Research Study Into DevOps Bottlenecks as presented at Oracle Code LA 2018
A Research Study Into DevOps Bottlenecks as presented at Oracle Code LA 2018
 
Java Puzzlers NG S03 a DevNexus 2018
Java Puzzlers NG S03 a DevNexus 2018Java Puzzlers NG S03 a DevNexus 2018
Java Puzzlers NG S03 a DevNexus 2018
 
Where the Helm are your binaries? as presented at Canada Kubernetes Meetups
Where the Helm are your binaries? as presented at Canada Kubernetes MeetupsWhere the Helm are your binaries? as presented at Canada Kubernetes Meetups
Where the Helm are your binaries? as presented at Canada Kubernetes Meetups
 
Data driven devops as presented at Codemash 2018
Data driven devops as presented at Codemash 2018Data driven devops as presented at Codemash 2018
Data driven devops as presented at Codemash 2018
 
A Research Study into DevOps Bottlenecks as presented at Codemash 2018
A Research Study into DevOps Bottlenecks as presented at Codemash 2018A Research Study into DevOps Bottlenecks as presented at Codemash 2018
A Research Study into DevOps Bottlenecks as presented at Codemash 2018
 
Best Practices for Managing Docker Versions as presented at JavaOne 2017
Best Practices for Managing Docker Versions as presented at JavaOne 2017Best Practices for Managing Docker Versions as presented at JavaOne 2017
Best Practices for Managing Docker Versions as presented at JavaOne 2017
 
Troubleshooting & Debugging Production Microservices in Kubernetes as present...
Troubleshooting & Debugging Production Microservices in Kubernetes as present...Troubleshooting & Debugging Production Microservices in Kubernetes as present...
Troubleshooting & Debugging Production Microservices in Kubernetes as present...
 
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at Devoxx 2017
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at Devoxx 2017DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at Devoxx 2017
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at Devoxx 2017
 
Amazon Alexa Skills vs Google Home Actions, the Big Java VUI Faceoff as prese...
Amazon Alexa Skills vs Google Home Actions, the Big Java VUI Faceoff as prese...Amazon Alexa Skills vs Google Home Actions, the Big Java VUI Faceoff as prese...
Amazon Alexa Skills vs Google Home Actions, the Big Java VUI Faceoff as prese...
 
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at DevOps Days Be...
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at DevOps Days Be...DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at DevOps Days Be...
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at DevOps Days Be...
 
Java Puzzlers NG S02: Down the Rabbit Hole as it was presented at The Pittsbu...
Java Puzzlers NG S02: Down the Rabbit Hole as it was presented at The Pittsbu...Java Puzzlers NG S02: Down the Rabbit Hole as it was presented at The Pittsbu...
Java Puzzlers NG S02: Down the Rabbit Hole as it was presented at The Pittsbu...
 
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at The Pittsburgh...
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at The Pittsburgh...DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at The Pittsburgh...
DevOps @Scale (Greek Tragedy in 3 Acts) as it was presented at The Pittsburgh...
 
Let’s Wing It: A Study in DevRel Strategy
 Let’s Wing It: A Study in DevRel Strategy Let’s Wing It: A Study in DevRel Strategy
Let’s Wing It: A Study in DevRel Strategy
 
Log Driven First Class Customer Support at Scale
Log Driven First Class Customer Support at ScaleLog Driven First Class Customer Support at Scale
Log Driven First Class Customer Support at Scale
 
[Webinar] The Frog And The Butler: CI Pipelines For Modern DevOps
[Webinar] The Frog And The Butler: CI Pipelines For Modern DevOps[Webinar] The Frog And The Butler: CI Pipelines For Modern DevOps
[Webinar] The Frog And The Butler: CI Pipelines For Modern DevOps
 
Patterns and antipatterns in Docker image lifecycle as was presented at DC Do...
Patterns and antipatterns in Docker image lifecycle as was presented at DC Do...Patterns and antipatterns in Docker image lifecycle as was presented at DC Do...
Patterns and antipatterns in Docker image lifecycle as was presented at DC Do...
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Dernier (20)

Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 

Take control. write a plugin. part II

  • 1. Jenkins User Conference San Francisco, Sept 30 2012 #jenkinsconf Take Control. Write a Plugin. Part II Baruch Sadogursky JFrog www.jfrog.com
  • 2. About me Developer Advocate @JFrog Job definition: Write code Talk about it github.com/jbaruch @jbaruch
  • 3. JFrog & Jenkins With Jenkins from day 1 Jenkins Artifactory Plugin Hosted JUC Israel repo.jenkins-ci.org JavaOne DEMOzone
  • 4. Agenda Vote and guessing Working with remote agents Working in multiple operation systems Creating UI using Groovy Writing custom Jelly(?) tags Maintaining backwards compatibility
  • 5. Agenda Vote and guessing Working with remote agents Working in multiple operation systems Creating UI using Groovy Writing custom Jelly(?) tags Maintaining backwards compatibility
  • 6. First, let’s vote Who saw “Take Control. Write a Plugin” session on YouTube? Let me guess… one or two hands…
  • 7. “Hello, my name is Noam Tenne” PREVIOUSLY IN “TAKE CONTROL. WRITE A PLUGIN”…
  • 8. Overview – Why plugins What you can do with plugins What you can’t do with plugins Plugins statistics
  • 9. What can I extend? UI SCM Build Processes Slave management Tooling ... Many, many, more You can even create new extension points!
  • 10. Environment IDE All majors have good support We love IntelliJ IDEA Build tool Can be Maven or Gradle
  • 11. The “Motivation” Plugin Target: Rewarding failing builds with insulting mockery Global configuration: Motivation phrase Project configuration: Is motivator enabled Outcome: Message appears in log after failure
  • 13. Agenda Vote and guessing Working with remote agents Working in multiple operation systems Creating UI using Groovy Writing custom Jelly(?) tags Maintaining backwards compatibility
  • 14. Working with remote agents Jenkins has remote agents!
  • 15. Working with remote agents Send closures to remote agents hudson.remoting.Callable Java Serialization
  • 16. Closure Poor guy’s Java closure Usually anonymous inner class (not always) 1 private static class GetSystemProperties implements Callable<Properties,RuntimeException> { 2 public Properties call() { 3 return System.getProperties(); 4 } 5 private static final long serialVersionUID = 1L; 6 }
  • 17. Cast your bread on the waters 1 this.systemProperties = channel.call(new GetSystemProperties()); Channel?
  • 18. Channel Represents a communication channel to the remote peer Obtain from:
  • 19. Distribution Abstractions – FilePath Where is the file?
  • 20. Distribution Abstractions – FilePath hudson.FilePath Much like java.util.File Consider pushing logic to the file Use FilePath.act(FileCallable)
  • 21. Distribution Abstractions – Launcher Launch stuff remotely!
  • 22. Distribution Abstractions – Launcher hudson.Launcher Much like java.lang.ProcessBuilder Pick your environment variables wisely!
  • 23. Agenda Vote and guessing Working with remote agents Working in multiple operation systems Creating UI using Groovy Writing custom Jelly(?) tags Maintaining backwards compatibility
  • 24. Working in multiple OSs WORA. You know. But. / vs .sh vs .bat Quotes around commands Permissions (wait for it…)
  • 25. Running script… Executing file… remotely… platform independent…
  • 26. Can You Spot The Error? 1 String workspaceDir = build.getWorkspace().getRemote(); 2 String scriptName = launcher.isUnix() ? "proc.sh" : "proc.bat"; 3 Launcher.ProcStarter procStarter = launcher.launch().stdout(System.out); 4 procStarter.cmds(new File(workspaceDir, scriptName)).join(); Executed locally!
  • 27. Going Remote with File Use FilePath – it will take care of all the details! Execute FilePath.act(FileCallable) If you need the File API, invoke() method has it, converted to remote file properly
  • 28. Permissions Dance 1 public boolean isDirectoryReadOnly(final FilePath filePath) throws IOException, 2 InterruptedException { 3 return filePath.getChannel().call(new Callable<Boolean, IOException>() { 4 public Boolean call() throws IOException { 5 Path path = FileSystems.getDefault().getPath(filePath.getRemote()); 6 Set<String> systems = FileSystems.getDefault().supportedFileAttributeViews(); 7 if (systems.contains("dos")) { 8 DosFileAttributeView dosView = 9 Files.getFileAttributeView(path, DosFileAttributeView.class); 10 DosFileAttributes dosAttributes = dosView.readAttributes(); 11 return dosAttributes.isReadOnly(); 12 } 13 if (systems.contains("posix")) { 14 PosixFileAttributeView posixView = 15 Files.getFileAttributeView(path, PosixFileAttributeView.class); 16 PosixFileAttributes posixAttributes = posixView.readAttributes(); 17 Set<PosixFilePermission> permissions = posixAttributes.permissions(); 18 return !permissions.contains(PosixFilePermission.OTHERS_WRITE) 19 } 20 throw new IOException("Unknown filesystem"); 21 } 22 }); 23 }
  • 29. Agenda Vote and guessing Working with remote agents Working in multiple operation systems Creating UI using Groovy Writing custom Jelly(?) tags Maintaining backwards compatibility
  • 30. Creating UI using Groovy First, let’s look at the docs:
  • 31. Creating UI using Groovy Analogous to Jelly Can use Jelly tags and libraries Kohsuke: When What Lots of program logic Groovy Lots of HTML layout markup Jelly
  • 32. Creating UI using Groovy Analogous to Jelly Can use Jelly tags and libraries me: When What Always! Groovy
  • 33. Creating UI using Groovy Jelly: 1 <j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form"> 2 <f:section title="Motivation Plugin"> 3 <f:entry title=" Motivating Message" field="motivatingMessage" 4 description="The motivational message to display when a build fails"> 5 <f:textbox/> 6 </f:entry> 7 </f:section> 8 </j:jelly> Groovy: 1 f=namespace('lib/form') 2 3 f.section(title:'Motivation Plugin') { 4 f.entry(title:'Motivating Message', field:'motivatingMessage', 5 description:'The motivational message to display when a build fails'){ 6 f.textbox() 7 } 8 }
  • 34. Creating UI using Groovy Real code Debuggable, etc. (stay tuned…) 1 f=namespace('lib/form') 2 3 f.section(title:'Motivation Plugin') { 4 f.entry(title:'Motivating Message', field:'motivatingMessage', 5 description:'The motivational message to display when a build fails'){ 6 f.textbox() 7 } 8 }
  • 35. Agenda Vote and guessing Working with remote agents Working in multiple operation systems Creating UI using Groovy Writing custom Jelly(?) tags Maintaining backwards compatibility
  • 36. Writing custom Jelly(?) tags Documentation:
  • 37.
  • 39. Writing custom Jelly Groovy tags Simple as 1,2… that’s it.
  • 40. 1. Implement 1 class MotivationTagLib extends 2 AbstractGroovyViewModule { 3 def tools = builder.namespace('hudson/tools') 4 5 MotivationTagLib(JellyBuilder b) { 6 super(b) 7 } 8 9 def evilLaugh() { 10 tools.label('mu-ha-ha!') 11 } 12 }
  • 41. 2. Use! 1 import org._10ne.jenkins.MotivationTagLib 2 3 f = namespace('lib/form') 4 m = new MotivationTagLib(builder); 5 6 f.entry(title: '') { 7 m.evilLaugh() 8 f.checkbox(…) 11 }
  • 42. Agenda Vote and guessing Working with remote agents Working in multiple operation systems Creating UI using Groovy Writing custom Jelly(?) tags Maintaining backwards compatibility
  • 43. Maintaining backwards compatibility Back to Motivation plugin…
  • 44. Refactoring! Rename defaultMotivatingMessage to motivatingMessage What happens to existing configuration on users machines?
  • 45. XStream Aliasing To The Rescue 1 @Initializer(before = PLUGINS_STARTED) 2 public static void addAliases() { 3 Items.XSTREAM2.aliasField("defaultMotivatingMessage", 4 DescriptorImpl.class, "motivatingMessage"); 5 } Register field (or class) alias In Initializer that runs before plugins started More complex cases might reqiure XStream converter
  • 46. Thank you! See you at our DEMOzone!
  • 47. Thank You To Our Sponsors

Notes de l'éditeur

  1. Let it runOverall structureGlobal.jellyConfig.jellyCode:Extends NotifierDatabound constructorPerform Descriptor:ExtensionSerializationXML
  2. MD5 digest
  3. Represents file path, but may be local or remoteisRemote()moveAllChilderenTo()Etc.Push – MD5
  4. MD5 digest
  5. Starts a process, but may be local or remoteCall to launch() returns builderjoin() on builder actually starts the processDon’t include machine specific ones, like PATH, TIMEZONE, etc.
  6. Show defaultMotivating method refactoring