How to read system environment variables from repository-stored Java Specs
プラットフォームについて: Server および Data Center のみ。この記事は、Server および Data Center プラットフォームのアトラシアン製品にのみ適用されます。
Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Fisheye および Crucible は除く
本記事で説明している手順は、現時点でのものとなります。そのため、一部のお客様で特定の状況下で動作したという報告がありますが、正式にサポートされているわけではなく、お客様の特定のシナリオで動作することを保証するものではありません。
本番環境での実施の前に一通り非本番環境で検証し、成功しなかった場合にはサポートされている代替案にフォール バックしてください。
要約
Depending on your environment and scenario, you might need/want to read environment variables from your System. By default, it's not possible to do that, because, since version 6.3, Bamboo enables a Security Manager for Java Specs processing by default. It prevents the Java code from accessing the network, executing other applications, or reading/writing files. This strategy increases security since it could be very dangerous to get Java code from outside (remote repository) and execute it inside Bamboo.
環境
Using Repository-stored Bamboo Java Specs.
診断
When trying to read environment variables (example below), the Java Specs processing will fail with the following error:
public static final String rootDomain = System.getenv("MY_VARIABLE");
[ERROR] -----------------------------------------------------: access denied ("java.lang.RuntimePermission" "getenv.MY_VARIABLE")
...
Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getenv.MY_VARIABLE")
at java.security.AccessControlContext.checkPermission (AccessControlContext.java:472)
at java.security.AccessController.checkPermission (AccessController.java:886)
at java.lang.SecurityManager.checkPermission (SecurityManager.java:549)
at com.atlassian.bamboo.specs.maven.sandbox.AbstractThreadPermissionVerifier.checkPermission (AbstractThreadPermissionVerifier.java:18)
at com.atlassian.bamboo.specs.maven.sandbox.BambooSpecsSecurityManager.checkPermission (BambooSpecsSecurityManager.java:37)
at java.lang.System.getenv (System.java:894)
at PlanSpec.<clinit> (PlanSpec.java:23)
原因
As previously mentioned, this is expected because Bamboo enables a Security Manager by default which prevents accessing and executing files.
ソリューション
Options 1-3 below only work if you are not processing Specs in Docker. If you are, please refer to the Docker section below. Additionally, please make sure that the variable you're trying to read has been picked up by Bamboo. You can check that by going to Cog icon >> Overview >> System information >> Environment Variables section. Environment variables need to be available for the user that runs Bamboo, and Bamboo needs to be restarted in order to pick up newly added variables.
オプション 1
The best approach would be to manually modify the Java Policies used by the Security Manager to allow Bamboo to read the environment variables. This allows for more granular access control and poses fewer risks than Option 2 below.
In order to do that:
- Locate the .policy file under ${JAVA_HOME}/jre/lib/security/. It's usually default.policy or java.policy. Please note that this needs to be done under the Java Home directory of the JDK your Bamboo instance uses.
Add the required permissions within the last grant { section:
Policy filepermission java.lang.RuntimePermission "getenv.MY_VARIABLE";
- Save the file and run the Specs Scan again.
To know which permissions to add, please look at the error messages you get when you run the Specs Scan. You can grant access to specific variables only, or to all environment variables at once by using a wildcard: "getenv.*
" (less recommended).
Option 2 (less recommended)
You can fully disable the Security Manager for Specs by adding the following property to the <bamboo-install>/bin/setenv.sh
file and restarting Bamboo.
JVM_SUPPORT_RECOMMENDED_ARGS:="-Dbamboo.repository.stored.specs.security.manager.enabled=false"
Please see Configuring your system properties for detailed steps.
Disabling the Specs Security Manager brings some security risks since this way you will allow execution of any code in Specs.
オプション 3
If your scenario doesn't require the value of a variable to be available during the specs scanning process, but rather only during build time (for example, you don't have Specs conditional code that depends on a variable), the best approach would be to use Bamboo Global Variables.
You can reference Bamboo's Global Variables in your Java code directly. Let's say you have defined a Global Variable in Bamboo called "MY_VARIABLE".
[...]
.tasks(new ScriptTask()
.inlineBody("echo ${bamboo_MY_VARIABLE}"))))
[...]
The variable's value will be used when running the build plan:
Substituting variable: ${bamboo.MY_VARIABLE} with GLOBALVALUE
Docker
If your Bamboo is set to process Specs using Docker (cog icon >> Overview >> Security Settings >> Process Bamboo Specs in Docker), the approach will be different. You'll need to maintain your own Docker image to be used by the Docker Specs Runner, with the Java Policies already configured, since Bamboo creates a new container based on the default image every time it runs the Specs analysis. It wouldn't be possible to configure java.policy through Bamboo and use it in the Docker Specs's containers because the Docker Specs Runner runs isolated from Bamboo.
Customizing the image
You can follow the steps below to create your own customized image of the Bamboo Specs Runner:
Pull Atlassian's default image from the Docker Hub repository, replacing
<BAMBOO_VERSION>
accordingly:docker pull atlassian/bamboo-specs-runner:<BAMBOO_VERSION>
Run a dummy container which we'll use as the base for our new image:
docker run atlassian/bamboo-specs-runner:<BAMBOO_VERSION>
The container's Maven output will be an error, but that's expected since we're not actually processing any code at this moment.
Get the ID of the container we've just created:
docker ps -a CONTAINER ID IMAGE COMMAND CREATED b76b7f9198f5 atlassian/bamboo-specs-runner:7.2.6 "/usr/local/bin/mvn-…" 3 minutes ago
Copy the Java Policy file from the container to your local machine:
docker cp <CONTAINER_ID>:/usr/local/openjdk-8/jre/lib/security/java.policy ~/Desktop
Edit the Java Policy file according to your needs. Please see the Option 1 section above to understand what permissions to grant.
Copy the updated Java Policy file back into the container:
docker cp ~/Desktop/java.policy <CONTAINER_ID>:/usr/local/openjdk-8/jre/lib/security/
Commit the container into a Docker Image:
docker commit <CONTAINER_ID> <YOUR_REPO>/<YOUR_IMAGE>:<TAG>
Push the image to your Docker repository:
docker push <YOUR_REPO>/<YOUR_IMAGE>:<TAG>
Once you have your customized image, it's time to configure your Bamboo to use it. Please see Processing Specs in Docker with a customized image for details on how to do that.