Newbie: packer provision install gradle

Hi Guys,
Newbie here, I was able to follow provisioner which has been helpful to us on daily updates of our builder slaves. However I got challenges to include on the installation of gradle, I basically follow these for adding the instruction on our provisioner, however always gets issue on placing the gradle.sh in /etc/profile.d/ and sourcing it.

I have tried this:

echo ""

echo "INSTALL GRADLE"

sudo wget https://services.gradle.org/distributions/gradle-7.1-bin.zip -P /tmp

sleep 60

sudo unzip -d /opt/gradle /tmp/gradle-*.zip

sudo touch /etc/profile.d/gradle.sh

sudo echo "export GRADLE_HOME=/opt/gradle/gradle-6.3" >> /etc/profile.d/gradle.sh

sudo echo "export PATH=${GRADLE_HOME}/bin:${PATH}" >> /etc/profile.d/gradle.sh

sudo chmod +x /etc/profile.d/gradle.sh

source /etc/profile.d/gradle.sh

echo "CHECK GRADLE VERSION"

gradle --version

echo ""

Hello @fruitvendor-guy !

It sounds to me like your script is not being interpreted properly. In this case, perhaps you could change the shebang.

See troubleshooting

There is a Troubleshooting section in the shell provisioner documentation, which may help you to identify where exactly your provisioner isn’t working

What provisioner are you using? Since you present a script you’re using already,I presume you could have something like a shell provisioner:

"builders": [...],
"provisioners": [
  {
    "type": "shell",
    "script": "gradle.sh"
  }
]

where gradle.sh is a local file with the contents you provide in the original post.

Hi brucellino1, thanks for looking on my inquiry. I’m still getting the permission issue,

is there a way to ensure the provisioner will use “root” role?

For testing purposes, I made the provisioner simple by only trying to create a file in profile directory + change the permission with these wrapper script:

#!/bin/bash

set -x

sudo su -

touch /etc/profile.d/gradle.sh

echo "export GRADLE_HOME=/opt/gradle/gradle-6.3" >> /etc/profile.d/gradle.sh

echo "export PATH=${GRADLE_HOME}/bin:${PATH}" >> /etc/profile.d/gradle.sh

chmod +x /etc/profile.d/gradle.sh

however output still gives me permission denied error:

==> amazon-ebs.ec2: Waiting for instance (i-011asdjkwqej0321) to become ready...
==> amazon-ebs.ec2: Using SSH communicator to connect: 172.168.1.23
==> amazon-ebs.ec2: Waiting for SSH to become available...
==> amazon-ebs.ec2: Connected to SSH!
==> amazon-ebs.ec2: Provisioning with shell script: gradle.sh
==> amazon-ebs.ec2: + sudo su -
==> amazon-ebs.ec2: + touch /etc/profile.d/gradle.sh
==> amazon-ebs.ec2: touch: cannot touch ‘/etc/profile.d/gradle.sh’: Permission denied
==> amazon-ebs.ec2: + echo 'export GRADLE_HOME=/opt/gradle/gradle-6.3'
==> amazon-ebs.ec2: /tmp/script_6726.sh: line 8: /etc/profile.d/gradle.sh: Permission denied
==> amazon-ebs.ec2: + echo 'export PATH=/bin:/usr/local/bin:/usr/bin'
==> amazon-ebs.ec2: /tmp/script_6726.sh: line 10: /etc/profile.d/gradle.sh: Permission denied
==> amazon-ebs.ec2: + chmod +x /etc/profile.d/gradle.sh
==> amazon-ebs.ec2: chmod: cannot access ‘/etc/profile.d/gradle.sh’: No such file or directory
==> amazon-ebs.ec2: Provisioning step had errors: Running the cleanup provisioner, if present...
==> amazon-ebs.ec2: Terminating the source AWS instance...
==> amazon-ebs.ec2: Cleaning up any extra volumes...
==> amazon-ebs.ec2: No volumes to clean up, skipping
==> amazon-ebs.ec2: Deleting temporary keypair...
Build 'amazon-ebs.ec2' errored after 1 minute 14 seconds: Script exited with non-zero exit status: 1.Allowed exit codes are: [0]

Taking another look at the script:

Here the permission denied is as a result of the redirection being done by echo, not the shell itself. You would need to run the echo through a privileged shell, use tee, or sed, etc.

e.g:
echo "export GRADLE_HOME=/opt/gradle/gradle-6.3\nexport PATH=\${GRADLE_HOME}/bin:\${PATH}" | sudo tee -a /etc/profile.d/gradle.sh

Since it seems like most of the actions in your provisioner need escalated privileges, I would remove the sudo’s from the script and run the whole thing as a user with the correct privileges.

You are using the ssh communicator - you can change the connection to use a different user by setting ssh_username in the builder.

Thanks again brucellino1 I’ll surely try this out and get back here again for the result.
I was continuously trying to fix this also and made it working on a different way before I read this message of yours.

But I’m sure there is a better way to shorten this like your provided solution.

I have separated the environment export to another file named as “gradle.sh”. and added it on the provisioner block.
This is because when I tried to add the export path to install.sh it results to a malformed assignment on /etc/profile.d/gradle.sh file like these:

GRADLE_HOME=/opt/gradle/gradle-7.1
PATH=/bin:/sbin:/bin:/usr/sbin:/usr/bin

Instead of this:

GRADLE_HOME=/opt/gradle/gradle-7.1
PATH=${GRADLE_HOME}/bin:${PATH}

Also I have to separate the gradle installation (with sudo) to gradle-install.sh due to provisioner block needs to have execute_command

I have added the files here:

gradle.sh

export GRADLE_HOME=/opt/gradle/gradle-7.1
export PATH=${GRADLE_HOME}/bin:${PATH}

install.sh

#!/bin/bash
set -x
echo ""
echo "INSTALL THE JAVA"
sleep 10
sudo amazon-linux-extras enable java-openjdk11
sudo yum clean metadata
sudo yum -y install java-11-openjdk
echo "CHECK THE  JAVA VERSION"
sudo java --version
sleep 10
echo ""
echo "INSTALL THE GRADLE"
sudo wget https://services.gradle.org/distributions/gradle-7.1-bin.zip -P /tmp
sudo unzip -d /opt/gradle /tmp/gradle-*.zip

gradle-install.sh

#!/bin/bash
set -x
sudo su -
whoami
pwd
cp -pr /var/tmp/gradle.sh /etc/profile.d/gradle.sh
chmod +x /etc/profile.d/gradle.sh
sudo su -
whoami
source /etc/profile.d/gradle.sh
gradle --version

build.pkr.hcl

packer {
  required_plugins {
    amazon = {
      version = ">= 0.0.2"
      source  = "github.com/hashicorp/amazon"
    }
  }
}

source "amazon-ebs" "ec2" {
*build code here ...*
}
build {
  sources = [
    "source.amazon-ebs.ec2"
  ]
  provisioner "shell" {
    script = "install.sh"
  }
  provisioner "file" {
    source = "gradle.sh"
    destination = "/var/tmp/gradle.sh"
  }
  provisioner "shell" {
    scripts = [ "gradle-install.sh" ]
    execute_command = "sudo bash -c '{{ .Path }}'"
  }

Actual result:

==> amazon-ebs.ec2: Uploading gradle.sh => /var/tmp/gradle.sh
    amazon-ebs.ec2: gradle.sh 81 B / 81 B [===============================================================================] 100.00% 0s
==> amazon-ebs.ec2: Provisioning with shell script: gradle-install.sh
==> amazon-ebs.ec2: + sudo su -
==> amazon-ebs.ec2: + whoami
    amazon-ebs.ec2: root
    amazon-ebs.ec2: /home/ec2-user
==> amazon-ebs.ec2: + pwd
==> amazon-ebs.ec2: + cp -pr /var/tmp/gradle.sh /etc/profile.d/gradle.sh
==> amazon-ebs.ec2: + chmod +x /etc/profile.d/gradle.sh
==> amazon-ebs.ec2: + sudo su -
    amazon-ebs.ec2: Last login: Sun Jul 11 04:14:34 UTC 2021
==> amazon-ebs.ec2: + whoami
    amazon-ebs.ec2: root
==> amazon-ebs.ec2: + source /etc/profile.d/gradle.sh
==> amazon-ebs.ec2: ++ export GRADLE_HOME=/opt/gradle/gradle-7.1
==> amazon-ebs.ec2: ++ GRADLE_HOME=/opt/gradle/gradle-7.1
==> amazon-ebs.ec2: ++ export PATH=/opt/gradle/gradle-7.1/bin:/sbin:/bin:/usr/sbin:/usr/bin
==> amazon-ebs.ec2: ++ PATH=/opt/gradle/gradle-7.1/bin:/sbin:/bin:/usr/sbin:/usr/bin
==> amazon-ebs.ec2: + gradle --version
    amazon-ebs.ec2:
    amazon-ebs.ec2: Welcome to Gradle 7.1!
    amazon-ebs.ec2:
    amazon-ebs.ec2: Here are the highlights of this release:
    amazon-ebs.ec2:  - Faster incremental Java compilation
    amazon-ebs.ec2:  - Easier source set configuration in the Kotlin DSL
    amazon-ebs.ec2:
    amazon-ebs.ec2: For more details see https://docs.gradle.org/7.1/release-notes.html
    amazon-ebs.ec2:
    amazon-ebs.ec2:
    amazon-ebs.ec2: ------------------------------------------------------------
    amazon-ebs.ec2: Gradle 7.1
    amazon-ebs.ec2: ------------------------------------------------------------
    amazon-ebs.ec2:
    amazon-ebs.ec2: Build time:   2021-06-14 14:47:26 UTC
    amazon-ebs.ec2: Revision:     989ccc9952b140ee6ab88870e8a12f1b2998369e
    amazon-ebs.ec2:
    amazon-ebs.ec2: Kotlin:       1.4.31
    amazon-ebs.ec2: Groovy:       3.0.7
    amazon-ebs.ec2: Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
    amazon-ebs.ec2: JVM:          11.0.9 (Red Hat, Inc. 11.0.9+11-LTS)
    amazon-ebs.ec2: OS:           Linux 4.14.232-177.418.amzn2.x86_64 amd64
    amazon-ebs.ec2:
==> amazon-ebs.ec2: Stopping the source instance...
    amazon-ebs.ec2: Stopping instance
==> amazon-ebs.ec2: Waiting for the instance to stop...
==> amazon-ebs.ec2: Creating AMI POGI_BOY-20210711041309 from instance i-07asdjh344340123
    amazon-ebs.ec2: AMI: ami-07asdjh344340123
==> amazon-ebs.ec2: Waiting for AMI to become ready...
==> amazon-ebs.ec2: Modifying attributes on AMI (ami-20210711041309)...
    amazon-ebs.ec2: Modifying: users
==> amazon-ebs.ec2: Modifying attributes on snapshot (snap-20210711041309)...
==> amazon-ebs.ec2: Adding tags to AMI (ami-07asdjh344340123)...
==> amazon-ebs.ec2: Tagging snapshot: snap-07asdjh344340123
==> amazon-ebs.ec2: Creating AMI tags
    amazon-ebs.ec2: Adding tag: "ENV": "POC"
    amazon-ebs.ec2: Adding tag: "TYPE": "POGI"
    amazon-ebs.ec2: Adding tag: "TRIAL": "YES"
    amazon-ebs.ec2: Adding tag: "SCENT": "OHABAM"
==> amazon-ebs.ec2: Creating snapshot tags
==> amazon-ebs.ec2: Terminating the source AWS instance...
==> amazon-ebs.ec2: Cleaning up any extra volumes...
==> amazon-ebs.ec2: No volumes to clean up, skipping
==> amazon-ebs.ec2: Deleting temporary keypair...
Build 'amazon-ebs.ec2' finished after 4 minutes 14 seconds.