Ansible - how to run Java jar with parameters? - linux

I have a problem with ansible playbook. I am trying to run a Java jar as a command. Whenever I run this directly on the virtual machine - it works all the time:
java -jar Installer20161018.jar -readImage Linux_x86-64_20161111.zip -installDir /opt/installPath/vf5511/instDir
important information: the installation HAS to be run from user vf5511, and his home folder is /opt/installPath/vf5511
But when trying to write a playbook and run it - it gets all wrong.
This is the playbook:
---
- hosts: webmwc10
become: yes
become_user: wm5511
become_method: sudo
tasks:
- name: installing server
shell: java -jar Installer20161018.jar -readImage Linux_x86-64_20161111.zip -installDir /opt/installPath/vf5511/instDir
When I run the playbook, I get an error:
"rc": 127,
"start": "2017-06-02 09:21:31.931049",
"stderr": "/bin/sh: java: command not found",
"stderr_lines": [
"/bin/sh: java: command not found"
],
"stdout": "",
"stdout_lines": []
Java not found? I don't understand this. Java is installed and working properly!
Can anyone help me with this?

Run below commands on your target server to rule out Java issues
which java
java -version
Upon successful results add quotes to your shell command like below and run the playbook again.
shell: "java -jar Installer20161018.jar -readImage Linux_x86-64_20161111.zip -installDir /opt/installPath/vf5511/instDir"

You should add your java address before "java". This problem may be occurs when using ssh too. For example:
shell: /your_java_address_in_target_server/java -jar Installer20161018.jar -readImage Linux_x86-64_20161111.zip -installDir /opt/installPath/vf5511/instDir

#1. make sure you "become_user" who has access to java
#2. In the .bash_profile, make sure you are setting the Java home path.
#3. Before calling the java command, run .bash_profile to make sure the JDK path is set.
Eg: - name: unjar abc.jar
shell: source ~/.bash_profile; jar xvf abc.jar

Related

Upload bash script to Ubuntu machine deploymed by MAAS

Info + objective:
I'm using MAAS to deploy workstations with Ubuntu.
MAAS just deploys the machine with stock Ubuntu, and I then run a bash script I wrote to set up everything needed.
So far, I've ran that bash script manually on the newly deployed machines. Now, I'm trying to have MAAS run that script automatically.
 
 
What I did + error:
In the MAAS machine, I create the following file curtin file called /var/snap/maas/current/preseeds/curtin_userdata_ubuntu which contains the following:
write_files:
bash_script:
path: /root/script.sh
content: |
#!/bin/bash
echo blabla
... very long bash script
permissions: '0755'
late_commands:
run_script: ["/bin/bash /root/script.sh"]
However, in the log, I see the following:
known-caiman cloud-init[1372]: Command: ['/bin/bash /root/script.sh']
known-caiman cloud-init[1372]: Exit code: -
known-caiman cloud-init[1372]: Reason: [Errno 2] No such file or directory: '/bin/bash /root/script.sh': '/bin/bash /root/script.sh'
 
 
Question
I'm not sure putting such a large bash script in the curtin file is a good idea. Is there a way to store the bash script on the MAAS machine, and have curtin upload it to the server, and then execute it? If not, Is it possible to fix the error I'm having?
Thanks ahead!
This worked executing the command:
["curtin", "in-target", "--", "/bin/bash", "/root/script.sh"]
Though this method still means I have to write to a file and then execute it. I'm still hoping there's a way to upload a file and then execute it.
I do not add my script to curtin file.
I run below command and deploy servers.
maas admin machine deploy $system_id user_data=$(base64 -w0 /root/script.sh)
I would try
runcmd:
- [/bin/scp, user#host:/somewhere/script.sh, /root/]
late_commands:
run_script: ['/bin/bash', '/root/script.sh']
This obviously imply that you inject the proper credentials on the machine being deployed.

How can I start a java application with parameters using a pm2 config file?

I'm trying to start graphhopper using pm2... graphhopper is a java application and the way I initiate it on the terminal is by going to its folder and entering the following command:
java -jar matching-web/target/graphhopper-map-matching-web-1.0-SNAPSHOT.jar server config.yml
This application works fine running from the command line, but I haven't succeeded on running it as a service with pm2. The config file I'm using is this one (pm2 start config.json):
{
"apps":[
{
"name":"graphhopper",
"cwd":".",
"script":"/usr/bin/java",
"args":[
"-jar",
"/home/myyser/graphhopper/map-matching/matching-web/target/graphhopper-map-matching-web-1.0-SNAPSHOT.jar",
"server",
"config.yml"
],
"log_date_format":"YYYY-MM-DD HH:mm Z",
"exec_interpreter":"",
"exec_mode":"fork"
}
]
}
I'm 100% sure that what I'm getting wrong here is the way I'm writing the "server", "config.yml" parameters... Looking into pm2 logs graphhopper I can see that those parameters are not being recognized at all... I've tried to tweak the way it's done as well but I didn't manage to figure out the right solution. I know how to start a java application using pm2 with no parameters. But how can I do it with a java application that has parameters as in the case of graphhopper?
As stated in the comments, this issue can be solved by creating a bash script and running it with pm2 instead of running directly the java application... The bash script used was the file graphhopper.sh as the following:
#!/bin/bash
java -jar matching-web/target/graphhopper-map-matching-web-1.0-SNAPSHOT.jar server config.yml
And to start it as a service with pm2:
pm2 start graphhopper.sh --name=graphhopper
You can also run a fat jar directly in pm2 - use two dashes to separate the command args:
pm2 start java -- -jar matching-web/target/graphhopper-map-matching-web-1.0-SNAPSHOT.jar server config.yml
Mine java app worked fine - just use 1 arg - no array.
apps:
- name : 'admin'
script: '/opt/homebrew/opt/openjdk#11/bin/java'
args: '-jar ./wweevvAdmin/target/wweevvAdmin-1.0-SNAPSHOT.jar'
instances: '1'
autorestart: true

Selenium testing with Jenkins

I have been trying to start selenium tests with browsers, not headless. I have my code in SVN and this should be build by Jenkins. Jenkins is on Linux.
Has anyone ever tried that or do you know what steps I should take? I am going through tutorials available on the internet but none of them work for me.
My current error is:
java.io.IOException: Cannot run program "cmd" (in directory
"/var/lib/jenkins/jobs/Tests/workspace"): error=2, No such file or
directory at java.lang.ProcessBuilder.start(ProcessBuilder.java:1047)
at hudson.Proc$LocalProc.(Proc.java:240) at
hudson.Proc$LocalProc.(Proc.java:212) at
hudson.Launcher$LocalLauncher.launch(Launcher.java:815) at
hudson.Launcher$ProcStarter.start(Launcher.java:381) at
hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:95)
at
hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:64)
at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
at
hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:779)
at hudson.model.Build$BuildExecution.build(Build.java:205) at
hudson.model.Build$BuildExecution.doRun(Build.java:162) at
hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534)
at hudson.model.Run.execute(Run.java:1720) at
hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43) at
hudson.model.ResourceController.execute(ResourceController.java:98)
at hudson.model.Executor.run(Executor.java:410) Caused by:
java.io.IOException: error=2, No such file or directory at
java.lang.UNIXProcess.forkAndExec(Native Method) at
java.lang.UNIXProcess.(UNIXProcess.java:187) at
java.lang.ProcessImpl.start(ProcessImpl.java:130) at
java.lang.ProcessBuilder.start(ProcessBuilder.java:1028) ... 15 more
Build step 'Execute Windows batch command' marked build as failure
Finished: FAILURE
When built without error, the workspace was only updated:
Building in workspace /var/lib/jenkins/jobs/Tests/workspace
Updating http://XX.XX.XXX.XX/resp/extend/Tests/EO at revision '2016-07-04T14:34:05.110 +0200'
At revision 5536
No changes for http://XX.XX.XXX.XX/resp/extend/Tests/EO since the previous build
Finished: SUCCESS
If you need any further details, let me know ...
UPDATE:
[workspace] $ /bin/sh -xe /tmp/hudson8771943326851387647.sh
+ ./script.sh
/tmp/hudson8771943326851387647.sh: line 2: ./script.sh: Permission denied
Build step 'Execute shell' marked build as failure
Finished: FAILURE
I have changed the windows command to shell command. The shell command is:
./script.sh
I think that the script inside the file i wrong, but does the error I have now mean that the script is wrong or does it reflect to something else? I do not know hwy we have "permission denied" - I have all the right in jenkins.
And this is my script.sh file content:
#!/bin/bash
function run_test {
echo "=== run Selenium tests in Jenkins ==="
ssh root#$1 "/src/test/java/mainTest/MainOrderTest start"
}
fi
I have no knowledge on shell command and I have not found any command that would run this program.
You are trying to run windows batch scripts on Linux hence the error.
Two options :
1. Either convert your build scripts to shell and use "execute shell" to call your shell scripts in jenkins
2. Add a windows slave which will build your windows batch script

How to run supervisor with Ansible?

I've got a server on which Supervisord is managing my processes. I normally start supervisord with the following command:
sudo /var/www/imd/venv/bin/supervisord -c /var/www/imd/deploy/supervisord.conf
I'm now trying to set things up with Ansible, but I'm unsure of how I should start Ansible. I can of course do it using something like:
- name: run supervisord
command: "/var/www/imd/venv/bin/supervisord -c /var/www/imd/deploy/supervisord.conf"
This works, but only the first time that you run it. Second time you run the same script supervisord is of course already running, which causes the following error:
TASK [run supervisord]
******************************************************* fatal: [ansible-test1]: FAILED! => {"changed": true, "cmd":
["/var/www/imd/venv/bin/supervisord", "-c",
"/var/www/imd/deploy/supervisord.conf"], "delta": "0:00:00.111700",
"end": "2016-06-03 11:57:38.605804", "failed": true, "rc": 2, "start":
"2016-06-03 11:57:38.494104", "stderr": "Error: Another program is
already listening on a port that one of our HTTP servers is configured
to use. Shut this program down first before starting
supervisord.\nFor help, use /var/www/imd/venv/bin/supervisord -h",
"stdout": "", "stdout_lines": [], "warnings": []}
Does anybody know how I can correctly run supervisord with Ansible? All tips are welcome!
[EDIT]
Because the solution in the answer by mbarthelemy doesn't work for socket files I now managed to get it working with the following:
- name: run supervisord
shell: if [ ! -S /var/run/supervisor.sock ]; then sudo /var/www/imd/venv/bin/supervisord -c /var/www/imd/deploy/supervisord.conf; fi
This of course is not very "ansibleish". If anybody has a real Ansible-based solution that would still be really welcome.
You can use supervisor module
- supervisorctl:
name: my_app
state: restarted
config: /var/opt/my_project/supervisord.conf
or
- name: Restart my_app
supervisorctl:
name: my_app
state: restarted
config: /var/opt/my_project/supervisord.conf
full documentation on https://docs.ansible.com/ansible/2.7/modules/supervisorctl_module.html#examples
Your situation is specific since you don't seem to use a regular Supervisor installed as a normal system package ; in that case you would start/stop/restart it like any other regular system service, using Ansible's service module.
By default, upon starting Supervisor creates a socket to listen for administrations commands from supervisorctl. When it stops it it supposed to remove it.
Try to find where this socket is created in your specific setup (default would be /var/run/supervisor.sock).
Then, let the Ansible command module know that if the Suopervisord process is already running, the socket exists, using the creates option (documentation). This way it won't try to run the command if it's already running:
- name: run supervisord
command: "./venv/bin/supervisord -c ./deploy/supervisord.conf"
args:
chdir=/var/www/imd
creates=/var/run/supervisor.sock
Edit : while this would be the right answer if /var/run/supervisor.sock were a file, it won't work because it's a socket, and Ansible's create parameter won't work.
The most Ansible-ish solution I can think of is using an external Ansible module like one of these, to check if you process already exists (test_process) or is already listening (test_tcp)

Capistrano check fails on DigitalOcean VPS

I'm trying to deploy a Node.js app to a VPS running on DigitalOcean and so far I'm getting well..very far. My understanding of *nix is very limited so please bear with me :)
I can ssh as root into my VPS (Ubuntu 13.04 x32) with my SSH keys without any problems. When I run "$cap deploy:setup" on my local machine I get this result:
* 2013-09-11 12:39:08 executing `deploy:setup'
* executing "mkdir -p /var/www/yable /var/www/yable/releases /var/www/yable/shared /var/www/yable/shared/system /var/www/yable/shared/log /var/www/yable/shared/pids"
servers: ["162.243.1.207"]
[162.243.1.207] executing command
** [out :: 162.243.1.207] env: sh: No such file or directory
command finished in 118ms
failed: "env PATH=/var/www/yable NODE_ENV=production sh -c 'mkdir -p /var/www/yable /var/www/yable/releases /var/www/yable/shared /var/www/yable/shared/system /var/www/yable/shared/log /var/www/yable/shared/pids'" on 162.243.1.207
When I run "$cap deploy:check" I get the following output:
* 2013-09-11 12:40:36 executing `deploy:check'
* executing "test -d /var/www/yable/releases"
servers: ["162.243.1.207"]
[162.243.1.207] executing command
command finished in 67ms
* executing "test -w /var/www/yable"
servers: ["162.243.1.207"]
[162.243.1.207] executing command
command finished in 76ms
* executing "test -w /var/www/yable/releases"
servers: ["162.243.1.207"]
[162.243.1.207] executing command
command finished in 69ms
* executing "which git"
servers: ["162.243.1.207"]
[162.243.1.207] executing command
command finished in 75ms
The following dependencies failed. Please check them and try again:
--> `/var/www/yable/releases' does not exist. Please run `cap deploy:setup'. (162.243.1.207)
--> You do not have permissions to write to `/var/www/yable'. (162.243.1.207)
--> You do not have permissions to write to `/var/www/yable/releases'. (162.243.1.207)
--> `git' could not be found in the path (162.243.1.207)
Here's my config/deploy.rb file:
set :application, "Yable.com"
set :scm, :git
set :repository, "git#github.com:Yable/yable-node-js.git"
set :user, "root"
set :ssh_options, { :forward_agent => true }
default_run_options[:pty] = true
set :use_sudo, false
set :branch, "master"
role :app, "162.243.1.207"
set :deploy_to, "/var/www/yable"
set :default_environment, {
'PATH' => "/var/www/yable",
'NODE_ENV' => 'production'
}
I'm dumbfounded as the directory mentioned (/var/www/yable/releases) does exist and that git has been installed. Any ideas?
Thanks,
Francis
I installed ruby 2.0.0 and Bundler and it seems to have solved my deployment issues.

Resources