Ansible: Changing permission of a directory issue - java

I'm running the following Ansible task to change permission of a directory and its content.
- name: Change ownership of everything below /opt/as2/app-server
file: path=/opt/as2/app-server state=directory recurse=yes owner=adrt group=adrt
When running it I get the following issue:
TASK [appserver : Change ownership of everything below /opt/as2/app-server] ****
fatal: [192.168.1.182]: FAILED! => {"changed": false, "failed": true, "module_stderr": "", "module_stdout": "Traceback (most recent call last):\r\n File \"/tmp/ansible_UrBo6x/ansible_module_file.py\", line 451, in \r\n main()\r\n File \"/tmp/ansible_UrBo6x/ansible_module_file.py\", line 335, in main\r\n changed |= recursive_set_attributes(module, to_bytes(file_args['path'], errors='surrogate_or_strict'), follow, file_args)\r\n File \"/tmp/ansible_UrBo6x/ansible_module_file.py\", line 146, in recursive_set_attributes\r\n changed |= module.set_fs_attributes_if_different(tmp_file_args, changed)\r\n File \"/tmp/ansible_UrBo6x/ansible_modlib.zip/ansible/module_utils/basic.py\", line 1163, in set_fs_attributes_if_different\r\n File \"/tmp/ansible_UrBo6x/ansible_modlib.zip/ansible/module_utils/basic.py\", line 929, in set_owner_if_different\r\n File \"/tmp/ansible_UrBo6x/ansible_modlib.zip/ansible/module_utils/basic.py\", line 842, in user_and_group\r\nOSError: [Errno 2] No such file or directory: '/opt/as2/app-server-1.0.0/apps/station/WEB-INF/classes/org/adroitlogic/isuite/metrics/As2MetricsService/usr/bin/python$tt__collectStats_closure14.class'\r\n", "msg": "MODULE FAILURE"}
Basically it says there is no such file or directory as,
/opt/as2/app-server-1.0.0/apps/station/WEB-INF/classes/org/adroitlogic/isuite/metrics/As2MetricsService/usr/bin/python$tt__collectStats_closure14.class
The content of the directory, /opt/as2/app-server/apps/station/WEB-INF/classes/org/adroitlogic/isuite/metrics/ is,
As2MetricsService$_$tt__CountStatisticsLists_closure3.class
As2MetricsService$_$tt__collectStats_closure10.class
As2MetricsService$_$tt__collectStats_closure11.class
As2MetricsService$_$tt__collectStats_closure12.class
As2MetricsService$_$tt__collectStats_closure13.class
As2MetricsService$_$tt__collectStats_closure14.class
As2MetricsService$_$tt__collectStats_closure15.class
As2MetricsService$_$tt__collectStats_closure4.class
As2MetricsService$_$tt__collectStats_closure5.class
As2MetricsService$_$tt__collectStats_closure6.class
As2MetricsService$_$tt__collectStats_closure7.class
As2MetricsService$_$tt__collectStats_closure8.class
As2MetricsService$_$tt__collectStats_closure9.class
As2MetricsService$_CountStatisticsLists_closure1.class
As2MetricsService$_collectStats_closure2.class
As2MetricsService.class
There are no subdirectories.
Also when I run the command chown -R adrt:adrt . inside the directory /opt/as2/app-server it executes without any issue.
Help me to understand what is happening here.

Help me to understand what is happening here.
You have just found a bug in Ansible which causes modules to fail when the names of files it processes contain $_ sequence.
The name is passed without escaping the $ character (or rather with an explicit conversion request os.path.expandvars(filename)) and the sequence $_ is processed as an built-in variable resolving to the path of the current process (/usr/bin/python in this case, as Ansible uses Python to run its modules).
In result the file name:
As2MetricsService$_$tt__collectStats_closure14.class
is interpreted as:
As2MetricsService/usr/bin/python$tt__collectStats_closure14.class
and the system throws an error that the file does not exist (which is true).
Until it is fixed, I guess you have to call chown with the command module

Related

tabula-py unable to read pdf file

My code:
import tabula
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
file_path = dir_path + '\ALPINE_' + str(20191107) + '.pdf'
print(file_path)
df = tabula.read_pdf('ALPINE_20191107.pdf',multiple_tables=True, pages="all")
result:
runfile('C:/Users/Admin/Documents/lucas/testTabula.py.py', wdir='C:/Users/Admin/Documents/lucas')
Traceback (most recent call last):
File "<ipython-input-29-a6b390aef3cf>", line 1, in <module>
runfile('C:/Users/Admin/Documents/lucas/sem título0.py', wdir='C:/Users/Admin/Documents/lucas')
File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile
execfile(filename, namespace)
File "C:\ProgramData\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/Admin/Documents/lucas/sem título0.py", line 12, in <module>
df = tabula.read_pdf('ALPINE_20191107.pdf',multiple_tables=True, pages="all")
File "C:\ProgramData\Anaconda3\lib\site-packages\tabula\io.py", line 332, in read_pdf
return _extract_from(raw_json, pandas_options)
File "C:\ProgramData\Anaconda3\lib\site-packages\tabula\io.py", line 664, in _extract_from
df[c] = pd.to_numeric(df[c], errors="ignore")
File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\tools\numeric.py", line 138, in to_numeric
raise TypeError("arg must be a list, tuple, 1-d array, or Series")
TypeError: arg must be a list, tuple, 1-d array, or Series
It's function doesn't seem to work. I could directly type the path to make even simpler, but it didn't work either. It could be a problem with the pdf file, but I already saw it working in another environment with the same script and the same file.
I already have java set on both possible PATHs ('C:\Program Files\Java\jre1.8.0_231\bin') as by documentation but it really doesn't matter, the error occurs with or without then set on PATH. I've tried adding jdk as well but didn't solve either.
I notice the error mentioning pandas so maybe it's conflicting with my version (the latest), but i'm not sure.
python is 3.7.4 and java is the latest to this date
I have had the same issue. I was using the version installed using pip, i.e. tabula-py 2.0.0. I uninstalled the version, and installed from Anaconda using conda install -c conda-forge tabula-py, and current version is tabula-py 1.4.1, which resolved this issue.

`touch` a file that uses ACL on Linux causes "Operation not permitted"

In Java code I want to "touch" a file. I want to update the timestamps to the current time. The file uses ACL. And this seems to be the problem.
The file:
$ ll file.xml
-rw-rwxrw-+ 1 root root 8611 Oct 4 17:28 file.xml
$ getfacl file.xml
# file: file.xml
# owner: root
# group: root
user::rw-
user:tomcat8:rwx
group::r-x
mask::rwx
other::rw-
And my Java app runs from Tomcat 8 with user tomcat8. A sudo -u tomcat8 touch file.xml works. It also works if I completely remove ACL and set tomcat8 as owner. But this is not possible in the production environment.
So at first I tried Apache common-io:
FileUtils.touch(path);
This causes an IOException. I debugged it a bit more and found out that the library calls FileSystem.setLastModifiedTime which calls the Linux function utimes.
I debugged the Linux touch command and saw it calls another more modern function: utimensat(0, NULL, NULL, 0). It also calls dup2and duplicates the file descriptor.
So I built my own touch method in Java:
long time = System.currentTimeMillis();
FileTime fileTimeNow = FileTime.fromMillis(time);
BasicFileAttributeView fileAttributeView = Files.getFileAttributeView(derivative.toPath(), BasicFileAttributeView.class);
fileAttributeView.setTimes(fileTimeNow, fileTimeNow, fileTimeNow);
This throws an Exception too (Operation not permitted).
Internally it calls utimensat(69, NULL, [{1538666780, 483000000}, {1538666780, 483000000}], 0).
I can not set null on .setTimes(...). This call gets ignored. And there is no Java-way to duplicate a file descriptor (dup2). So I can not test further steps to make it more like Linux' touch.
How to make this working when a file uses ACL? I don't want to run external programs (touch).
If the file is not written concurrently, you can open it, read its first byte, and write it back again at offset zero. This will update the modification time of the file without requiring ownership permissions.
(By the way, the ACL looks really curious, particularly the other:: rw- part.)
Here's man utimensat:
Permissions requirements
To set both file timestamps to the current time (i.e., times is NULL, or both tv_nsec fields specify UTIME_NOW), either:
the caller must have write access to the file;
the caller's effective user ID must match the owner of the file; or
the caller must have appropriate privileges.
To make any change other than setting both timestamps to the current time (i.e., times is not NULL, and neither tv_nsec field is UTIME_NOW and neither tv_nsec field is UTIME_OMIT), either condition 2 or 3 above must
apply.
You have #1, but not #2 or #3. If you ask touch to explicitly set the time to the current timestamp, it fails as well:
$ getfacl test | sed -e "s/$USER/myuser/"
# file: test
# owner: root
# group: root
user::rw-
user:myuser:rwx
group::r--
mask::rwx
other::r--
$ touch -d "#$(date +%s)" test
touch: setting times of ‘test’: Operation not permitted
I don't have any good suggestions for what to do instead though. You could either make a no-op change to the file, or call touch as an external command:
String path="some path";
// See https://stackoverflow.com/a/52651585 for why we're not doing this via Java
int result = Runtime.getRuntime().exec(new String[] { "touch", "--", path }).waitFor();
if(result != 0) throw new IOException("Can't update timestamp");

How to provide the -Dlogback.configurationFile=./logback.xml option in nodejs spawn method

I have angular2-node.js application. I am executing a jar file through the node server.
Jar execution is happening fine but it's using the logback.xml present in the jar file.
Node js code:
app.get('/report/:parameter1/:parameter2', function(req, res) {
var fileName = path.join(__dirname, '..', 'javaFile', 'xyz.jar');
spawn('/usr/bin/java', ['-jar ', fileName, parameter1 , parameter2, '&'],{
stdio : ['ignore', out, err],
detached : true }).unref();
data = '{response: Success}';
res.status(200).json(data);
res.end();
});
I want to refer the different logback.xml file for jar execution while running the jar from UI. So, i tried the below code:
spawn('/usr/bin/java', ['-jar -Dlogback.configurationFile=./logback.xml', fileName, cacheName , cacheType, '&'],{
stdio : ['ignore', out, err],
detached : true }).unref();
But, it also didn't work and throw the below error:
Unrecognized option: -jar -Dlogback.configurationFile=./logback.xml
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
I am new to node js. I searched the web but couldn't get an answer.
Is there any way to provide the logback.xml file dynamically in node.js code something like we do in shell script like below:
nohup java -jar -Dlogback.configurationFile=./logback.xml xyz.jar
Can anyone provide any solution for this.
The args arguments is <string[]>, so you should split the multiple args into multiple elements of the array, like you've done for the other arguments. You can check the signature of the method here.
Try,
spawn('/usr/bin/java', ['-jar', '-Dlogback.configurationFile=./logback.xml'], ....

Internal Action was not loaded Error: java.lang.ClassNotFoundException

I am trying to run an implementation a jason code that is using some Internal Actions. The interpreter is showing that it was not possible to find the "java" code of the internal action, as showed:
Server running on http://191.36.8.42:3272
[aslparser] [peleus.asl:29] warning: The internal action class for 'org.soton.peleus.act.plan(Goals)' was not loaded! Error:
java.lang.ClassNotFoundException: org.soton.peleus.act.plan
[aslparser] [peleus.asl:42] warning: The internal action class for 'org.soton.peleus.act.isTrue(H)' was not loaded! Error:
java.lang.ClassNotFoundException: org.soton.peleus.act.isTrue
[peleus] Could not finish intention: intention 1: +des([on(b3,table),on(b2,b3),on(b1,b2)])[source(self)] <- ... org.soton.peleus.act.plan(Goals); !checkGoals(Goals); .print("Goals ",Goals," were satisfied") /
{Goals=[on(b3,table),on(b2,b3),on(b1,b2)]}Trigger: +des([on(b3,table),on(b2,b3),on(b1,b2)])[noenv,code(org.soton.peleus.act.plan([on(b3,table),on(b2,b3),on(b1,b2)])),code_line(29),code_src("peleus.asl"),error(action_failed),error_msg("no environment configured!"),source(self)]
[peleus] Adding belief clear(table)
This mas2j file is as following:
MAS peleus {
infrastructure: Centralised
agents:
peleus;
}
Part of agent code (written by Felipe Meneguzzi) is showed bellow:
//The next line is line 28
+des(Goals) : true
<- org.soton.peleus.act.plan(Goals);
!checkGoals(Goals);
.print("Goals ",Goals," were satisfied").
+!checkGoals([]) : true <- true.
//The next line is line 40
+!checkGoals([H|T]) : true
<- .print("Checking ", H);
org.soton.peleus.act.isTrue(H);
!checkGoals(T).
I guess it is about the folder structure, how to set up Jason to search for java files in specific locations?
The folders structure is like this:
Peleus\src\org\soton\peleus for java files
Peleus\examples for mas2j and asl tested project
It all depends on how you are executing the application.
If you are using java, the CLASSPATH should be defined to include the missing classes.
if you are using jason script (that uses Ant), the .mas2j file should include the class path as well.
More on that in the FAQ. Notice that CLASSPATH is where .class files are found, not .java source code files. The error regards a missing class, not a missing source code.

odd .bat file behavior

I have a bat file with the following contents:
set logfile= D:\log.txt
java com.stuff.MyClass %1 %2 %3 >> %logfile%
when I run the bat file though, I get the following:
C:\>set logfile= D:\log.txt
C:\>java com.stuff.MyClass <val of %1> <val of %2> <val of %3> 1>>D:\log.txt
The parameter is incorrect.
I'm almost positive the "The parameter is incorrect." is due to the extraneous 1 in there. I also think this might have something with the encoding of the .bat file, but I can't quite figure out what is causing it. Anyone ever run into this before or know what might be causing it and how to fix it?
Edit
And the lesson, as always, is check if its plugged in first before you go asking for help. The bat file, in version control, uses D:\log.txt because it is intended to be run from the server which contains a D drive. When testing my changes and running locally, on my computer which doesn't have a D drive, I failed to make the change to use C:\log.txt which is what caused the error. Sorry for wasting you time, thanks for the help, try to resist the urge to downvote me too much.
I doubt that that's the problem - I expect the command processor to deal with that part for you.
Here's evidence of it working for me:
Test.java:
public class Test
{
public static void main(String args[]) throws Exception
{
System.out.println(args.length);
for (String arg : args)
{
System.out.println(arg);
}
}
}
test.bat:
set logfile= c:\users\jon\test\test.log
java Test %1 %2 %3 >> %logfile%
On the command line:
c:\Users\Jon\Test> [User input] test.bat first second third
c:\Users\Jon\Test>set logfile= c:\users\jon\test\test.log
c:\Users\Jon\Test>java Test first second third 1>>c:\users\jon\test\test.log
c:\Users\Jon\Test> [User input] type test.log
3
first
second
third
the 1 is not extraneous: it is inserted by cmd.exe meaning stdout (instead of ">>", you can also write "1>>". contrast this to redirecting stderr: "2>>"). so the problem must be with your parameters.
This may seem like a stupid question, but is there an existing D: drive in the context that the bat file runs in?
Once I had a case where a bat file was used as the command line of a task within the Task Manager, but the Run As user was set to a local user on the box, giving no access to network drives.
Interpolated for your case, if the D: drive were a network drive, running the bat file as, say, the local administrator account on that machine instead of a domain user account would likely fail to have access to D:.

Categories