Skrip Pipeline CI Jenkins tidak diizinkan untuk menggunakan metode groovy.lang.GroovyObject

104

Saya Menggunakan Jenkins 2 untuk menyusun Proyek Java, saya ingin membaca versi dari pom.xml, saya mengikuti contoh ini:

https://github.com/jenkinsci/pipeline-plugin/blob/master/TUTORIAL.md

Contoh menyarankan:

Pipeline Jenkins penuh dengan fungsi bermasalah yang dilingkari

Tampaknya ada beberapa masalah keamanan dalam mengakses Sistem File tetapi saya tidak tahu apa yang memberikan (atau mengapa) masalah itu:

Saya hanya melakukan sedikit berbeda dari contoh:

def version() {
    String path = pwd();
    def matcher = readFile("${path}/pom.xml") =~ '<version>(.+)</version>'
    return matcher ? matcher[0][1] : null
}

Kesalahan yang saya dapatkan saat menjalankan metode 'versi':

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object (org.codehaus.groovy.runtime.GStringImpl call org.codehaus.groovy.runtime.GStringImpl)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists.StaticWhitelist.rejectMethod(StaticWhitelist.java:165)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:117)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:103)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:149)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:146)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:15)
    at WorkflowScript.run(WorkflowScript:71)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:55)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:100)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:106)
    at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:79)
    at sun.reflect.GeneratedMethodAccessor408.invoke(Unknown Source)

Saya menggunakan versi ini: Plugin Pipeline 2.1 Jenkins 2.2

Daniel Hernández
sumber
Saya mengalami kesalahan serupa Scripts not permitted to use method, tetapi itu terjadi karena saya menulis scm 'checkout'alih-alih checkou scm. Untuk berjaga-jaga jika seseorang jatuh dalam hal ini, perhatikan sintaks yang buruk :). Melakukan apa yang dikatakan Maarten Kieft memungkinkan saya melihat pesan kesalahan yang lebih jelas tentang perintah yang buruk :)
GabLeRoux

Jawaban:

261

Perbaikan cepat

Saya memiliki masalah serupa dan saya mengatasinya dengan melakukan hal berikut

  1. Navigasikan ke jenkins> Kelola jenkins> Persetujuan Skrip Dalam Proses
  2. Ada perintah yang menunggu keputusan, yang harus saya setujui.

Tautan persetujuan dalam proses di Jenkins 2.61 Alternatif 1: Nonaktifkan sandbox

Saat artikel ini menjelaskan secara mendalam, skrip keren dijalankan dalam mode kotak pasir secara default. Ini berarti bahwa subset dari metode menarik diizinkan untuk dijalankan tanpa persetujuan administrator. Ini juga memungkinkan untuk menjalankan skrip tidak dalam mode kotak pasir, yang menyiratkan bahwa seluruh skrip harus disetujui oleh administrator sekaligus. Ini mencegah pengguna menyetujui setiap baris pada saat itu.

Menjalankan skrip tanpa sandbox dapat dilakukan dengan menghapus centang pada kotak ini di konfigurasi proyek Anda tepat di bawah skrip Anda: masukkan deskripsi gambar di sini

Alternatif 2: Nonaktifkan keamanan skrip

Saat artikel ini menjelaskan, mungkin juga untuk menonaktifkan keamanan skrip sepenuhnya. Pertama instal plugin keamanan skrip permisif dan setelah itu ubah file jenkins.xml Anda tambahkan argumen ini:

-Dpermissive-script-security.enabled = true

Jadi Anda jenkins.xml akan terlihat seperti ini:

<executable>..bin\java</executable>
<arguments>-Dpermissive-script-security.enabled=true -Xrs -Xmx4096m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=80 --webroot="%BASE%\war"</arguments>

Pastikan Anda tahu apa yang Anda lakukan jika menerapkan ini!

Maarten Kieft
sumber
1
Lebih baik menyetujui keseluruhan skrip, tergantung pada struktur tim. Untuk beberapa developer dengan akses penuh itu cukup bagus. Namun penyiapan dengan banyak tim akan memaksa admin untuk menyetujui setiap perubahan di semua skrip pipeline.
Roger Lehmann
2
Alternatif 3 (harus menjadi saran pertama) adalah mengubah kode bermasalah yang tidak masuk daftar putih . Dalam hal ini, penggunaan sederhana @NonCPSuntuk Matcherpenggunaan sudah cukup. Dalam hal ini, tidak perlu menonaktifkan keamanan untuk seluruh pipeline, dan terutama seluruh penginstalan Jenkins. Evaluasi setiap panggilan yang diblokir satu per satu dan putuskan apakah Anda benar-benar perlu menyetujuinya.
mkobit
1
@mkobit tidak bekerja untuk saya. @NonCPStidak membantu.
warvariuc
@warvariuc hmm, bisa jadi jika Anda mengembalikan Matcherdirinya sendiri, karena Matchertidak mengimplementasikan Serializableantarmuka. Mungkin ada baiknya mengajukan pertanyaan baru. Saya berharap bahwa dokumentasi yang dirujuk dalam pertanyaan asli dipertahankan dan tidak salah untuk memulai.
mkobit
2
@mkobit Saya didekorasi dengan NonCPS fungsi yang menggunakan currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(). NonCPS sama sekali tidak membantu dengan masalah keamanan, dari apa yang saya baca.
warvariuc
12

Anda harus menonaktifkan sandbox untuk Groovy di konfigurasi pekerjaan Anda.

Saat ini, hal ini tidak dapat dilakukan untuk project multibranch yang skrip kerennya berasal dari scm. Untuk informasi selengkapnya, lihat https://issues.jenkins-ci.org/browse/JENKINS-28178

Andre
sumber
6

Saya mengalami ini ketika saya mengurangi jumlah parameter input pengguna di userInput dari 3 menjadi 1. Ini mengubah jenis output variabel userInput dari array menjadi primitif.

Contoh:

myvar1 = userInput['param1']
myvar2 = userInput['param2']

untuk:

myvar = userInput
Menandai
sumber
Inilah perbaikan untuk gejala yang saya alami. Pesan kesalahannya adalah org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object. Metode ini mengharapkan 2 parameter dan menerima 3.
Tyler W
4

Untuk mengatasi sandboxing dari skrip Groovy yang disimpan SCM, saya sarankan untuk menjalankan skrip sebagai Perintah Groovy (bukan file Skrip Groovy ):

import hudson.FilePath
final GROOVY_SCRIPT = "workspace/relative/path/to/the/checked/out/groovy/script.groovy"

evaluate(new FilePath(build.workspace, GROOVY_SCRIPT).read().text)

dalam kasus seperti itu, skrip keren ditransfer dari ruang kerja ke Jenkins Master tempat skrip tersebut dapat dieksekusi sebagai file system Groovy Script. Sandboxing disembunyikan selama Use Groovy Sandbox tidak dicentang .

Stepan Vavra
sumber
5
Ini tampak kikuk, berisiko dan pasti akan kembali dan menggigit Anda.
Simon Forsberg
4
Nah, keamanan itu penting terutama ketika melindungi data sensitif pengguna tetapi juga disertai dengan harga seperti komplikasi selama proses pengembangan. Ketika perkakas keamanan hanya diterapkan setengahnya, itu akan menjadi lebih buruk. Sandboxing skrip Jenkins adalah contoh bagus dari alat keamanan yang setengah diterapkan dan sebagai hasilnya Anda mungkin perlu menonaktifkan fitur sepenuhnya karena jika tidak, itu berarti tidak ada jalan untuk Anda.
Stepan Vavra
3
Dalam kasus saya, setelah peningkatan dari Jenkins yang lebih lama, skrip Groovy saya berhenti berfungsi dan satu-satunya cara untuk membuatnya berfungsi adalah menjalankan skrip 300 kali (hanya perkiraan) dan untuk setiap proses mengklik di Jenkins UI untuk mengizinkan semua metode memanggil dalam skrip 200 baris. Selain itu, UI tidak mengizinkan Anda untuk menempelkan daftar lengkap dari semua panggilan metode yang diizinkan jika Anda entah bagaimana dapat membuatnya. Selain itu, UI berhenti menampilkan beberapa panggilan metode dan setelah beberapa saat saya tidak dapat melanjutkan.
Stepan Vavra