Дженкинс/Groovy: защо функциите са забранени от скриптове, разрешени от импортирани библиотеки?

Следният тръбопровод на Дженкинс успява да създаде директория:

@Library('my-shared-libs') _

pipeline {
  agent any
  stages {
    stage( "1" ) {
      steps {
        script {
          utils.MkDir("/home/user/workspace/prj/foo")
        }
      }
    }
  }
}
// vars/utils.groovy
import java.io.File

def MkDir(the_dir) {
  def f = new File(the_dir)
  if ( ! f.mkdirs() ) { echo "Failed creating ${the_dir}" }
  else { echo "Succeeded creating ${the_dir}" }
}

Но следният тръбопровод:

pipeline {
  agent any
  stages {
    stage( "1" ) {
      steps {
        script {
          def the_dir = "/home/user/workspace/prj/bar"
          def f = new File(the_dir)
          if ( ! f.mkdirs() ) { echo "Failed creating ${the_dir}" }
          else { echo "Succeeded creating ${the_dir}" }
        }
      }
    }
  }
}

... се проваля с тази грешка:

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use new java.io.File java.lang.String

Защо идентичен код за създаване на директория е успешен, ако е извикан от споделена библиотека от главния Jenkinsfile, но е неуспешен, ако е извикан директно от същия Jenkinsfile?

По-широкият въпрос повдига това: каква е основната разлика между Jenkinsfile и споделените библиотеки, които той използва? Има някакво разграничение или разграничение между скриптовете за декларативен синтаксис на Jenkinsfile и Groovy и споделените библиотеки, което не ми идва много на ум. Ще съм благодарен, ако някой ми помогне да разбера.


Следвайки предложението на @injecteer, опитах следната модификация на втория Jenkinsfile:

def the_dir = "/home/user/workspace/prj/bar"
def u = new URL( "file://${the_dir}" ).toURI()
def f = new File(u)
if ( ! f.mkdirs() ) { echo "Failed creating ${the_dir}" }
else { echo "Succeeded creating ${the_dir}" }

... което доведе до тази грешка:

Scripts not permitted to use method java.net.URL toURI. Administrators can decide whether to approve or reject this signature.

За мен не е опция да направя (или съм направил) това административно одобрение, така че това предложение не може да бъде опция за мен, за съжаление.


person StoneThrow    schedule 22.07.2021    source източник
comment
какво ще стане, ако извикате конструктора: new File(URI uri)?   -  person injecteer    schedule 23.07.2021
comment
@injecteer - съжалявам, мисля, че не разбирам как да приложа предложението ти. Ако оригиналният ми код е def f = new File("/path/to/my/dir"), какво трябва да направя, за да използвам new File(URI uri)?   -  person StoneThrow    schedule 23.07.2021
comment
Не съм сигурен дали ще проработи, но вашето изключение каза, че new File( String ) не е разрешено. Класът File има друг конструктор с URI като аргумент. Нещо като new File( new URL( 'file:///home/user/workspace/prj/bar' ).toURI() )   -  person injecteer    schedule 23.07.2021
comment
@injecteer - извинение за бавния отговор. Опитах вашето предложение, но получих грешка Scripts not permitted to use method java.net.URL toURI. Нямаме опция за административно одобрение за тази функция, така че трябва да изключа това решение :(. Ще оставя този въпрос отворен, защото смятам, че има стойност за общността, но приоритетът му за моите лични нужди е намалени, защото заобиколното решение, т.е. използването на utils.MkDir() от споделената библиотека, е приемливо. Все пак би било ценно да разберем защо тази странна разлика между възможността за конвейер и споделена библиотека да изпълняват една и съща функция.   -  person StoneThrow    schedule 30.07.2021
comment
добре, струваше си да опитам все пак. Не съм експерт по Дженкинс и не мога да ви помогна повече, за съжаление.   -  person injecteer    schedule 30.07.2021
comment
Разглеждали ли сте stackoverflow.com/questions/42654875/ ?   -  person Shane Bishop    schedule 02.08.2021
comment
@ShaneBishop - благодаря ти, не бях виждал това, а информацията е полезна. Въпросът ми обаче е малко по-различен от този. Въпросът ми е донякъде академичен в смисъл, че просто искам да разбера в името на разбирането, въпреки че има работещо решение. т.е. защо дадена функция е разрешена, ако е извикана от споделена библиотека (която е импортирана от Jenkinsfile), но не е разрешена, ако е извикана директно от Jenkinsfile. Изглежда като странно ограничение; Не мога да разбера намерението зад този (вероятно) умишлен избор на дизайн от създателите на Jenkins/Groovy.   -  person StoneThrow    schedule 03.08.2021
comment
@StoneThrow Тъй като въпросът ви е формулиран сега, всичко свързано със създаването на директория ще отвлече потенциалните отговарящи далеч от това, което наистина искате да знаете. Бих предложил да редактирате въпроса си, за да бъде общо защо функциите са забранени в тръбопроводи/задачи, но не и в споделени библиотеки. Мисля, че тази промяна ще увеличи шансовете ви да получите добър отговор.   -  person Shane Bishop    schedule 03.08.2021