How Do You Invoke a Function in Groovy?

Problem scenario
You want to call a function and have it return a value. How do you do this?

Solution
Overview
(If you need assistance installing Groovy, see this posting for CentOS. or see this posting for Debian/Ubuntu Linux.)

Groovy has something called "Closures." These act like functions in other programming languages. The syntax looks like his with the square brackets portion being a comma-delimited list of parameters:

{ [closureParameters -> ] statements }

In the above, the "statements" signifies zero or more Groovy expressions. Here is an example of a Groovy statement:

println "${str1} ${param}"

The above will print the value of "str1" and the value of "param". Normally "param" will be a parameter passed at the time the closure is invoked. Closures can be invoked with syntax like this: nameOfClosure.call("coolvalue")

The above would pass "coolvalue" as a parameter when nameOfClosure was invoked.

Procedures
Create a Groovy program called test.groovy with the following code:

def str1 = "Cool attempt: ";
def contint = { param -> println "${str1} ${param}" }
contint.call("This shows how a Closure is invoked!");

How Do You Deactivate a HipChat User with Only His/Her Email Address Using the REST API?

Problem scenario
You have email addresses of users that you want deactivated. You do not want to use the GUI for HipChat. How do you invoke REST APIs to deactivate a user?

Prerequisite
You need an API token for HipChat. If you have this, start with the Procedures below. Otherwise keep reading this "Prerequisite" section. You need several scopes for the API token authorize you to be able to deactivate a user. Once you have the alphanumeric string of an unexpired token that has sufficient privileges to delete users, you can craft a curl command.

To generate a token, log into the HipChat web UI. Go to the upper right hand corner and click on your icon, then click on "Account". See these directions and start on step #5:
https://community.frontapp.com/t/186p1p/how-to-enable-and-use-the-hipchat-integration

Procedures
Here is how to deactivate a user based on email address using the REST API:

curl -H "Authorization:Bearer abcd1234" -X DELETE http://hipchatservername.com/v2/user/jdoe@acme.com --insecure

# The command is "DELETE", but it does not delete the user.  It deactivates the user.

# If you want to learn more about how passing an API token works, you may want to read this link https://stackoverflow.com/questions/22229996/basic-http-and-bearer-token-authentication

How Do You Install Docker on Debian Linux in GCP?

Problem scneario
In Google Cloud Platform you have a Debian Linux server. You want to install Docker on it. What do you do?

Solution
1. Create a file called dockerinstall.sh in the /tmp/ directory with the following content:

apt-get -y update
apt-get install -y apt-transport-https ca-certificates wget software-properties-common

wget https://download.docker.com/linux/debian/gpg 
apt-key add gpg

echo "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee -a /etc/apt/sources.list.d/docker.list
apt-get -y update

apt-get -y install docker-ce

2. Run this script with sudo (e.g., sudo bash /tmp/dockerinstall.sh). It may take 10 minutes and appear to stall. This is normal.

How Do You Create a Dockerfile That Will Use Reserved Words Such as FROM, RUN, COPY, WORKDIR, ADD, and LABEL?

Problem scenario
You want to create your own Dockerfile. You also want to invoke reserved words such as FROM, RUN, COPY, WORKDIR, ADD, and LABEL. You want to then create a Docker image from it. You want to ultimately create a working Docker container from that image. How do you do all of this?

Solution

1. In a given directory, create a file called extra.txt. It can have nothing in it and be created with a "touch" command.

2. In this directory create a file calle hello.py with this as its content:

from flask import Flask
app = Flask(__name__)

@app.route('/hi')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

3. In this directory create a file called Dockerfile with the content below:

FROM ubuntu:latest

LABEL Remarks="www.continualintegration.com created this Dockerfile"

RUN apt-get update
RUN apt-get install -y python3 python-pip
RUN apt-get clean all

RUN pip install flask

ADD hello.py /tmp/hello.py
# This stanza expects a hello.py file to be in the same directory as the Dockerfile itself.

COPY extra.txt /tmp/extra.txt
# This stanza expects an extra.txt file to be in the same directory as the Dockerfile itself.

EXPOSE 5000

ENV HOME /home/   
# This stanza will set Docker container's home directory in container's env settings 

WORKDIR /tmp/  
# The default directory when you enter the container will be the directory set above

CMD ["python","/tmp/hello.py"]

4. Run this command (but replace "foobar" and "contint" as you see fit):

docker build -t foobar:contint .

5. Replace abcd1234 below with the alphanumeric value that was displayed (associated with the newly created image ID):

docker create -it abcd1234 bash

# Run the above command with the substituted abcd1234 / container ID.

6. The above command should produce a new container. The container ID should be displayed. Run this command, but substituted wxyz6789 with the container ID you just created:

docker start wxyz6789

7. Run this command, but substitute wxyz6789 with the container ID you just started:

docker exec -it wxyz6789 bash

How Do You Troubleshoot the Error “Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not find artifact com.sun:tools:jar:1.8.0”?

Problem scenario
You run a Maven command but you get this:

"Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not find artifact com.sun:tools:jar:1.8.0 at specified path /usr/lib/jvm/java-8-openjdk-amd64/jre/../lib/tools.jar:

You are running Ubuntu or Debian Linux. What should you do?

Solution
Run this: sudo apt install default-jdk

How Do You Change the Indentation of the GUI-Rendering of a File in Bitbucket?

Problem scenario
You are using a web browser and some items in a list are indenting where you do not want them indented. How do you make them line up with the other items in the list without indentation?

Solution
Bitbucket's rendering of a text file does an auto-indent for natural numbers (with no sub-numbering scheme). If you have this in a file, you'll get an unintended indentation for #3:

1.a
1.b

2.a.
2.b.
2.c.

3.
4.a.

The number three item has no sub-part. The sub-numbers could have been Roman numerals. Bitbucket recognizes the sub-numbers and never indents those numbers. In this situation if #3 has only one part, give it a sub-number (e.g., 3.a.). Then there will be no accidental indentation.

How Do You Troubleshoot the Maven Error “Malformed POM…Unrecognised tag: ‘dependency'”?

Problem scenario
You run a Maven (mvn) command. But you receive an error like this:

[INFO] Scanning for projects…
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[ERROR] Malformed POM /home/jdoe/b/gs-maven/initial/src/pom.xml: Unrecognised tag: 'dependency' (position: START_TAG seen …\n \n \n … @17:17) @ /home/jdoe/b/gs-maven/initial/src/pom.xml, line 17, column 17
@
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project org.springframework:gs-maven:0.1.0 (/home/jdoe/b/gs-maven/initial/src/pom.xml) has 1 error
[ERROR] Malformed POM /home/jdoe/b/gs-maven/initial/src/pom.xml: Unrecognised tag: 'dependency' (position: START_TAG seen …\n \n \n … @17:17) @ /home/jdoe/b/gs-maven/initial/src/pom.xml, line 17, column 17 -> [Help 2]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/ModelParseException

What do you do to fix it?

Solution

Inside your pom.xml file encapsulate the <dependency> and </dependency> within tags <dependencies> and </dependencies> respectively.  So instead of this:
<dependency>
  ...
</dependency>

have it look like this:

<dependencies>
  <dependency>
    ...
  <dependency>
</dependencies>

How Do You Get around The AccessDeniedException Error with SonarQube?

Problem scenario
You are trying to set up SonarQube for the first time. You run this command:

bash /opt/sonarqube/bin/linux-x86-64/sonar.sh console

You see this error:

"jvm 1 | java.nio.file.AccessDeniedException: /opt/sonarqube/temp/conf/es/elasticsearch.yml"

What do you do?

Solution
Make sure that the user who is running the command has the ability to execute files in the /opt/sonarqube/ directory (or wherever the destination is that you are installing Sonarqube). You may want to run a command such as this:

sudo chown -R jdoe:goodgroup /opt/sonarqube

Replace jdoe with the username that is trying to run the command. Replace goodgroup with the group associated with the user. If you do not know what group that is, log in as that user or use "su jdoe" (where jdoe is the username). Then run the command "groups".

Then run these two commands:
sudo bash /opt/sonarqube/bin/linux-x86-64/sonar.sh stop

bash /opt/sonarqube/bin/linux-x86-64/sonar.sh console

How Do You Troubleshoot the Google Kubernetes Engine error “Request had insufficient authentication scopes”?

Problem scenario
You run a command like this:
gcloud container clusters get-credentials standard-cluster-1 --region us-central1-a

But you receive one of the following messages:
"Fetching cluster endpoint and auth data.
ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Request had insufficient authentication scopes."

ERROR: (gcloud.projects.describe) User [123456789-compute@developer.gserviceaccount.com] does not have permission to access projects instance [123456789] (or it may not exist): Request had insufficient
authentication scopes.
'@type': type.googleapis.com/google.rpc.ErrorInfo
domain: googleapis.com
metadata:
method: google.cloudresourcemanager.v1.Projects.GetProject
service: cloudresourcemanager.googleapis.com
reason: ACCESS_TOKEN_SCOPE_INSUFFICIENT

What should you do?

Solution
Here is a basic solution that is ideal for a proof-of-concept. It is not ideal for an enterprise environment. Ideally the server you are using is either secure, or you plan on terminating it in an hour or two.

Procedures
1. Log into the GCP console
2. Go to Compute engine in the web UI.
3. Stop the VM.
4. Click on the hyperlinked name of the VM.
5. Click "Edit"
6. Check the option to "Allow full access to all Cloud APIs" if it was not checked. (If it was chosen, these directions will not help you. Please try to find something else.)
7. Click Save
8. Restart the VM.
9. Try again.

How Do You Verify the Jenkins Credentials Plugin Username and Password Are Correct and in the Right Syntax?

Problem Scenario
You are using Jenkins and its Credentials plugin. You are not sure if the syntax of the username and password are correct. You think that there may be a wrong username or password. You want to see how things look as they are used in a pipeline job. The console output shows the credentials as "****". What should you do?

Solution
Warning: this is not a recommended practice. The console output of a job will show the credentials in clear text.

#1 Configure a pipeline job to echo the credentials to a file (e.g., /tmp/sensitive). There is syntax in a Jenkins pipeline to invoke raw shell commands: sh 'echo $userpasscombo > /tmp/sensitive'

#2 Run the above pipeline.

#3 Change the pipeline in two ways. First remove the "withCredentials" syntax that allows you to get the username and password from the credentials plugin. Secondly configure a pipeline job to echo the /tmp/sensitive file.

#4 Run the above pipeline (from step #3). Look at the console output. You will see the credentials in plain text.