Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions pipelines/libs/global/vars/RWLock.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,18 @@ def call(Map info, String mode)
}
}

def call(Map info, String lockname, String stagename) {
def lockname_info = "lockfd_${stagename}_${lockname}".replace('-', '_')
node('built-in') {
do_unlock_one(info, lockname_info)
info.remove(lockname_info)
}
}

def call(Map info, String lockname, String mode, String stagename) {
call(info, lockname, mode,stagename, null)
}

// info - the global info[:] array of the job - we store the lock FDs in here
// lockname - name of the lock to get (a file in $JENKINS_HOME/locks/)
// mode - READ or WRITE
Expand Down Expand Up @@ -110,6 +122,7 @@ def call(Map info, String lockname, String mode, String stagename, Closure thing
}

// This MUST run on the Jenkins host, that's where the flocks are
def busy = false
node('built-in') {
sh "mkdir -p ${lockdir}"
lockmode |= 4 // LOCK_NB (no blocking - so the job doesn't seem to "die" according to jenkins
Expand All @@ -128,6 +141,11 @@ def call(Map info, String lockname, String mode, String stagename, Closure thing
if (jnaflock.CLibrary.INSTANCE.flock(lockfd, lockmode) == -1) {
def e = Native.getLastError()
if (e == 11) { // 11 = EAGAIN
if (thingtorun == null) {
jnaflock.CLibrary.INSTANCE.close(lockfd)
busy = true
return
}
wait_time = 60
println("Waiting for lock ${lockname}")
} else {
Expand All @@ -145,6 +163,13 @@ def call(Map info, String lockname, String mode, String stagename, Closure thing
info[lockname_info]['mode'] = mode
println("RWLock: ${lockname} in stage ${stagename} locked for ${mode}")
log_lock('LOCKED', mode, lockname, stagename)
if (thingtorun == null) {
busy = false
}
}

if (thingtorun == null) {
return busy
}

// Run a thing inside the lock, but catch any exceptions in case it fails
Expand Down
39 changes: 39 additions & 0 deletions pipelines/libs/global/vars/Semaphore.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

def call(Map info, int permits, String lockname, String mode, String stagename, Closure thingtorun) {
def acquired = false

while (!acquired) {
for (int slot = 0; slot < permits; slot++) {
String slotLock = "${lockname}_${slot}"

println("Trying ${slotLock}")

//Polymorph for trying to lock the specific slotLock
// one time and return the result to act upon it
def busy = RWLock(info, slotLock, mode, stagename)

if (!busy) {
acquired = true
def e = null
try {
thingtorun()
} catch (exp) {
e = exp
} finally {
//Polymorph for unlocking one lock
RWLock(info, slotLock, stagename)
}
if (e != null) {
throw(e)
}
break
}
println("${slotLock} is busy, trying next one")
}
if (!acquired) {
println("all locks are busy, sleeping ")
sleep(60)
}
}
return 0
}
8 changes: 8 additions & 0 deletions pipelines/libs/vapor/vars/getProviderProperties.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def call()
providers['libvirt'] = ['maxjobs_smoke': 4, 'maxjobs_all': 4, 'testlevel': 'smoke', 'vers': ['rhel8', 'rhel9', 'rhel10', 'centos10'],
'has_watchdog': true, 'has_storage': true, 'has_network': true, 'weekly': true, 'allprio': 1,
'api_rate_limit': false,
'api_creates': 1,
'defaultiscsi': '10',
'defaultuseiscsi': 'no',
'defaultblocksize': '200',
Expand All @@ -41,6 +42,7 @@ def call()
providers['osp'] = ['maxjobs_smoke': 4, 'maxjobs_all': 8, 'testlevel': 'all', 'vers': ['rhel8', 'rhel9'],
'has_watchdog': true, 'has_storage': true, 'has_network': true, 'weekly': true, 'allprio': 1,
'api_rate_limit': true,
'api_creates': 1,
'defaultiscsi': '200',
'defaultuseiscsi': 'yes',
'defaultblocksize': '10',
Expand All @@ -57,6 +59,7 @@ def call()
providers['azure'] = ['maxjobs_smoke': 4, 'maxjobs_all': 4, 'testlevel': 'smoke', 'vers': ['rhel8', 'rhel9', 'rhel10'],
'has_watchdog': false, 'has_storage': true, 'has_network': true, 'weekly': true, 'allprio': 1,
'api_rate_limit': true,
'api_creates': 1,
'defaultiscsi': '',
'defaultuseiscsi': 'no',
'defaultblocksize': '1024',
Expand All @@ -77,6 +80,7 @@ def call()
providers['aws'] = ['maxjobs_smoke': 4, 'maxjobs_all': 4, 'testlevel': 'smoke', 'vers': ['rhel8', 'rhel9', 'rhel10'],
'has_watchdog': false, 'has_storage': true, 'has_network': true, 'weekly': true, 'allprio': 1,
'api_rate_limit': true,
'api_creates': 1,
'defaultiscsi': '',
'defaultuseiscsi': 'no',
'defaultblocksize': '300',
Expand All @@ -97,6 +101,7 @@ def call()
providers['gcp'] = ['maxjobs_smoke': 4, 'maxjobs_all': 4, 'testlevel': 'smoke', 'vers': ['rhel8', 'rhel9', 'rhel10'],
'has_watchdog': false, 'has_storage': true, 'has_network': true, 'weekly': true, 'allprio': 1,
'api_rate_limit': true,
'api_creates': 1,
'defaultiscsi': '200',
'defaultuseiscsi': 'yes',
'defaultblocksize': '',
Expand All @@ -117,6 +122,7 @@ def call()
providers['aliyun'] = ['maxjobs_smoke': 4, 'maxjobs_all': 4, 'testlevel': 'smoke', 'vers': ['rhel8', 'rhel9', 'rhel10'],
'has_watchdog': false, 'has_storage': true, 'has_network': true, 'weekly': true, 'allprio': 1,
'api_rate_limit': true,
'api_creates': 1,
'defaultiscsi': '200',
'defaultuseiscsi': 'no',
'defaultblocksize': '512',
Expand All @@ -137,6 +143,7 @@ def call()
providers['ocpv'] = ['maxjobs_smoke': 4, 'maxjobs_all': 0, 'testlevel': 'all', 'vers': ['rhel8', 'rhel9', 'rhel10', 'centos10'],
'has_watchdog': true, 'has_storage': true, 'has_network': true, 'weekly': true, 'allprio': 0,
'api_rate_limit': false,
'api_creates': 1,
'defaultiscsi': '10',
'defaultuseiscsi': 'no',
'defaultblocksize': '200',
Expand All @@ -161,6 +168,7 @@ def call()
providers['ibmvpc'] = ['maxjobs_smoke': 4, 'maxjobs_all': 4, 'testlevel': 'smoke', 'vers': ['rhel8', 'rhel9'],
'has_watchdog': false, 'has_storage': false, 'has_network': false, 'weekly': true, 'allprio': 1,
'api_rate_limit': true,
'api_creates': 1,
'defaultiscsi': '200',
'defaultuseiscsi': 'yes',
'defaultblocksize': '10',
Expand Down
2 changes: 1 addition & 1 deletion pipelines/libs/vapor/vars/vapor_wrapper.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def cloud_create(Map p, Map info, Integer timeout_minutes)
${p['echorun']} vapor ${p['vaporopts']} create ${p['clusteropts']} ${p['createbaseopts']} ${p['createopts']} ${p['extraopts']} ${p['provideropts']}
"""

RWLock(info, "${p['provider']}_api_create", 'WRITE', 'create_stage', {
Semaphore(info, p['api_creates'], "${p['provider']}_api_create", 'WRITE', 'create_stage', {
timeout(time: timeout_minutes, unit: 'MINUTES') {
if (p['api_rate_limit'] == true) {
res = sh(returnStatus: true, script: create_script)
Expand Down