Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-44515

Implement lock_any option for pipelines

    XMLWordPrintable

    Details

    • Similar Issues:

      Description

      My CI server has multiple executors and multiple android devices attached to it. Each executor can perform either android or linux build. If android build is being performed, a test must be also performed on the device. To ensure unique access to specific android device, I use lockable resources plugin to "lock" the device.

      However, in order to check if device1 is in use and then use device2, I am currently relying on custom locking logic (manually keeping lock files). It would be ideal if lockable resources plugin would have an option to enter the lock block if any of the listed resources can be acquired (and provide which resource was required).

      For example:

      lock_any( [ 'device1', 'device2', 'device3' ] ) { acquired_device ->
          // run tests on ${acquired_device}
      }

        Attachments

          Activity

          Hide
          dageissl Daniel Geißler added a comment - - edited

          What you are looking for is the label property. You'll have to configure the resources with a label (e.g. device) and use

          lock(label:'device', quantity: 1){
              def acquired_device = org.jenkins.plugins.lockableresources.LockableResourcesManager.class.get()
                                      .getResourcesFromBuild(currentBuild.getRawBuild())[0].name
              // run tests on ${acquired_device}
          }
          

          to get the name of the locked resource you ll have to approve several apis, but currently this is the only way until JENKINS-40997 is solved.

          Show
          dageissl Daniel Geißler added a comment - - edited What you are looking for is the label property. You'll have to configure the resources with a label (e.g. device ) and use lock(label: 'device' , quantity: 1){ def acquired_device = org.jenkins.plugins.lockableresources.LockableResourcesManager. class. get() .getResourcesFromBuild(currentBuild.getRawBuild())[0].name // run tests on ${acquired_device} } to get the name of the locked resource you ll have to approve several apis, but currently this is the only way until JENKINS-40997 is solved.
          Hide
          dodoent Nenad Miksa added a comment -

          Thank you! I'll try that.

          Show
          dodoent Nenad Miksa added a comment - Thank you! I'll try that.
          Hide
          git Thomas Gimpel added a comment -

          Unfortunately the proposed work-around works only if your build acquires only one lock or if the label is unambiguous. If you have multiple locks in parallel, then getResourcesFromBuild() will give you a list all locks already acquired. Most likely the lock of interest is the last one in the list, but that can't be guarantied. For instance in our pipeline we start multiple test runs in parallel each allocating a DUT resource. Since all test runs start almost at the same time the overall list of resources locked by the build changes very quickly, so that a certain thread is not able to determine its own allocated resource by just looking at the end if the list. You are in luck if all resource labels used in the build are unique, i.e. no two parallel threads use the same label for locking the resource. Then you can iterate through the list of resources and find that one having the appropriate label:

          def getLockedResourceName(requestedLabel)
          {
              def resources = org.jenkins.plugins.lockableresources.LockableResourcesManager.class.get().getResourcesFromBuild(currentBuild.getRawBuild());
              for (res in resources) {
                  def labels = res.getLabels().tokenize(" ");
                  for (label in labels) {
                      if (label == requestedLabel) {
                          return res.getName();
                      }
                  }
              }
              error "Could not determine locked resource";
          }
          

          But of course, it would be much better to have an API call, which directly gives you the names of resources just locked:

          // Some comments here
          lock (label: 'device', quantity: 1 ) {
              def resources = getLockedResourceNames(); // this function should be provided by the lockable resources plugin
             ...
          }
          
          Show
          git Thomas Gimpel added a comment - Unfortunately the proposed work-around works only if your build acquires only one lock or if the label is unambiguous. If you have multiple locks in parallel, then getResourcesFromBuild() will give you a list all locks already acquired. Most likely the lock of interest is the last one in the list, but that can't be guarantied. For instance in our pipeline we start multiple test runs in parallel each allocating a DUT resource. Since all test runs start almost at the same time the overall list of resources locked by the build changes very quickly, so that a certain thread is not able to determine its own allocated resource by just looking at the end if the list. You are in luck if all resource labels used in the build are unique, i.e. no two parallel threads use the same label for locking the resource. Then you can iterate through the list of resources and find that one having the appropriate label: def getLockedResourceName(requestedLabel) { def resources = org.jenkins.plugins.lockableresources.LockableResourcesManager. class. get().getResourcesFromBuild(currentBuild.getRawBuild()); for (res in resources) { def labels = res.getLabels().tokenize( " " ); for (label in labels) { if (label == requestedLabel) { return res.getName(); } } } error "Could not determine locked resource" ; } But of course, it would be much better to have an API call, which directly gives you the names of resources just locked: // Some comments here lock (label: 'device' , quantity: 1 ) { def resources = getLockedResourceNames(); // this function should be provided by the lockable resources plugin ... }

            People

            • Assignee:
              Unassigned
              Reporter:
              dodoent Nenad Miksa
            • Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated: