Jenkins CI 파이프 라인 스크립트는 groovy.lang.GroovyObject 메소드를 사용할 수 없습니다.


104

Java 프로젝트를 컴파일하기 위해 Jenkins 2를 사용하고 있으며 pom.xml에서 버전을 읽고 싶습니다.이 예제를 따르고 있습니다.

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

예제는 다음을 제안합니다.

문제가있는 기능이 동그라미로 표시된 전체 Jenkins 파이프 라인

파일 시스템에 액세스하는 데 보안 문제가있는 것 같지만 그 문제가 무엇인지 (또는 이유) 파악할 수 없습니다.

예제와 약간 다른 작업을 수행하고 있습니다.

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

'버전'메서드를 실행할 때 발생하는 오류 :

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)

이 버전을 사용하고 있습니다 : Plugin Pipeline 2.1 Jenkins 2.2


에 대해 비슷한 오류가 Scripts not permitted to use method있었지만 scm 'checkout'대신 썼기 때문에 발생했습니다 checkou scm. 누군가가 이것에 빠지는 경우를 대비하여 잘못된 구문을 확인하십시오. :). 이렇게 마틴 Kieft 날 : 나쁜 명령에 대해보다 명확한 오류 메시지가 표시 할 수 말했듯이
GabLeRoux

답변:


261

빠른 수정

비슷한 문제가 있었고 다음을 수행하여 해결했습니다.

  1. jenkins> jenkins 관리> In-process 스크립트 승인으로 이동합니다.
  2. 승인해야하는 보류중인 명령이있었습니다.

Jenkins 2.61의 프로세스 승인 링크 대안 1 : 샌드 박스 비활성화

기사 에서 자세히 설명하는 것처럼 groovy 스크립트는 기본적으로 샌드 박스 모드에서 실행됩니다. 이는 관리자의 승인없이 그루비 메서드의 하위 집합을 실행할 수 있음을 의미합니다. 샌드 박스 모드가 아닌 스크립트를 실행할 수도 있습니다. 즉, 관리자가 전체 스크립트를 한 번에 승인해야 함을 의미합니다. 이로 인해 사용자가 당시에 각 라인을 승인 할 수 없습니다.

스크립트 바로 아래의 프로젝트 구성에서이 확인란을 선택 취소하면 샌드 박스없이 스크립트를 실행할 수 있습니다. 여기에 이미지 설명 입력

대안 2 : 스크립트 보안 비활성화

기사에서 설명하는 것처럼 스크립트 보안을 완전히 비활성화 할 수도 있습니다. 먼저 허용 스크립트 보안 플러그인을 설치하고 그 후 jenkins.xml 파일을 변경 한 후 다음 인수를 추가하십시오.

-Dpermissive-script-security.enabled = true

따라서 jenkins.xml은 다음과 같습니다.

<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>

이것을 구현하는 경우 무엇을하고 있는지 확인하십시오!


1
전체 스크립트를 승인하는 것이 더 나은 경우 팀 구조에 따라 다릅니다. 전체 액세스 권한을 가진 일부 개발자에게는 매우 좋습니다. 그러나 여러 팀으로 구성된 설정에서는 관리자가 모든 파이프 라인 스크립트의 모든 변경 사항을 승인해야합니다.
로저 레만

2
대안 3 (실제로 첫 번째 제안이어야 함)은 문제가있는 허용되지 않은 코드변경하는 것 입니다. 이 경우, 간단한 사용 @NonCPS에 대한 Matcher사용은 충분하다. 이 경우 전체 파이프 라인, 특히 전체 Jenkins 설치에 대한 보안을 비활성화 할 필요가 없습니다. 차단 된 각 통화를 개별적으로 평가하고 정말로 승인해야하는지 결정합니다.
mkobit

1
@mkobit는 나를 위해 작동하지 않습니다. @NonCPS도움이되지 않습니다.
warvariuc

@warvariuc 흠, 인터페이스를 구현하지 않기 Matcher때문에 자신 을 반환하는 것일 수 있습니다 . 새로운 질문을 할 가치가 있습니다. 원래 질문에서 참조 된 문서가 유지되고 시작하기에 잘못되지 않았 으면합니다. MatcherSerializable
mkobit

2
내가 장식 @mkobit NonCPS 하는 사용하는 기능 currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId(). NonCPS는 내가 읽은 내용에서 보안 문제에 전혀 도움이되지 않습니다.
warvariuc


6

userInput의 사용자 입력 매개 변수 수를 3에서 1로 줄 였을 때이 문제가 발생했습니다. 이로 인해 userInput의 변수 출력 유형이 배열에서 기본 형식으로 변경되었습니다.

예:

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

에:

myvar = userInput

이것은 내가 경험 한 증상에 대한 수정입니다. 오류 메시지는 org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method groovy.lang.GroovyObject invokeMethod java.lang.String java.lang.Object입니다. 메소드는 2 개의 매개 변수를 예상했고 3 개를 수신했습니다.
Tyler W

4

SCM에 저장된 Groovy 스크립트의 샌드 박싱을 피하려면 스크립트를 Groovy 명령 으로 실행하는 것이 좋습니다 ( Groovy Script file 대신 ).

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)

이 경우 groovy 스크립트는 작업 공간에서 Jenkins Master로 전송되어 system Groovy Script. Use Groovy Sandbox선택 되어 있지 않으면 샌드 박싱이 억제됩니다 .


5
이것은 투박하고 위험하며 돌아와서 당신을 물릴 수밖에 없습니다.
Simon Forsberg

4
글쎄요, 보안은 특히 사용자의 민감한 데이터를 보호 할 때 중요하지만 개발 과정에서 복잡성과 같은 대가를 동반하기도합니다. 보안 도구가 절반 만 구현되면 더욱 악화됩니다. Jenkins 스크립트 샌드 박싱은 절반으로 구현 된 보안 도구의 좋은 예이며 결과적으로 기능을 완전히 비활성화해야 할 수도 있습니다. 그렇지 않으면 사용할 수 없음을 의미하기 때문입니다.
Stepan Vavra

3
제 경우에는 이전 Jenkins에서 업그레이드 한 후 Groovy 스크립트가 작동을 멈 췄고 작동하도록 만드는 유일한 방법은 스크립트를 300 회 (예상치) 실행하고 Jenkins UI에서 클릭 할 때마다 허용하는 것입니다. 모든 메서드는 200 줄 스크립트에서 호출됩니다. 더욱이 UI는 어떻게 든 생성 할 수있는 경우 허용 된 모든 메서드 호출의 전체 목록을 붙여 넣을 수 없습니다. 또한 UI에 일부 메서드 호출이 표시되지 않고 잠시 후 계속할 수 없습니다.
Stepan Vavra
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.