Get hidden user input in erlang app running thru rebar3 shell - erlang

I need to start an SSH connection in my app which requires a username and password. The username is constant so can be hardcoded, but I want the password to be hidden (similar to read -s pass in bash).
I tried doing this with io:read, io:fread, io:read_line, io:get_chars, and even os:cmd("read -s pass") but it seems they always break from the code and only interact in shell:
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling app
Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
Eshell V12.2.1 (abort with ^G)
.
.
. app init code......
.
Enter SSH pass: abc.
(node#comp)1>
(node#comp)1> normal shell, app waiting to continue
(node#comp)1>
Am I missing something? Is there another way to get user input to the app? should I just use the .ssh hashed passwords? If so, How?

To suppress the echo you can use the hidden io:get_password function.
Password = io:get_password().
[Edit]
Based on your feedback this doesn't solve the whole problem.

Related

upgrade of erlang applications based on relup by rebar3

I am studying the upgrade of erlang applications based on this article.
But there is some problem when I execute rebar3 relup:
Option --relname is missing
hello#centos7-dev:~/relapp1 ((1.0.12))$ rebar3 relup
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling relapp
Solving Release relapp-1.0.12Resolved relapp-1.0.12release: relapp-1.0.12
erts: 13.0.4
goals:
relapp
parse_trans
sasl
applications:
{kernel,"8.4.2"}
{stdlib,"4.0.1"}
{syntax_tools,"3.0"}
{parse_trans,"3.0.0"}
{relapp,"1.0.12"}
{sasl,"4.2"}
......
....relapp1/_build/default/rel/relapp/lib/sasl-4.2/ebin/sasl.apprelease start script createdRelease successfully assembled:
_build/default/rel/relapp===> Option --relname is missing
The environments are as follows:
erlang
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]
Eshell V13.0.4 (abort with ^G)
rebar3
rebar 3.20.0 on Erlang/OTP 25 Erts 13.0.4
After many times of retry and experiment, I found it in this article.
Hot code reloading with Erlang and Rebar3
The answer is such as:
rebar3 relup -n nine9s -v "0.2.0" -u "0.1.0"
However, there are some issues which need attention.
The rebar.config file
You should replace the default options {mode, dev} with {dev_mode, false}
the *.appup.src
You cannot include the point_of_no_return option in this file, otherwise there will be some problem such as:
No release upgrade script entry for xxxx-0.2.0 to xxxx-0.1.0 in file

Rebar3 + Cowboy Kernel PID Terminated

I installed rebar3 and created a new release with
cd ~/apps
rebar3 new release tunnel
Then
I copied my src files from ~/tunnel/src/* to ~/apps/tunnel/src/
I ran into a compile error with rebar3 run and found Erlang "Kernel pid terminated" error as a possible solution. I renamed everything about tunnel_app to tunnel. So my src contains tunnel.erl , tunnel.app.src and tunnel_sup.erl. I renamed the module definition as appropriate.
Here's the rebar3 run error:
~/apps/tunnel:.rebar3 run
===> Verifying dependencies...
===> Compiling tunnel
===> Starting relx build process ...
===> Resolving OTP Applications from directories:
/Users/quantum/apps/tunnel/_build/default/lib
/Users/quantum/apps/tunnel/apps
/usr/local/Cellar/erlang/19.2/lib/erlang/lib
/Users/quantum/apps/tunnel/_build/default/rel
===> Resolved tunnel-0.1.0
===> Dev mode enabled, release will be symlinked
===> release successfully created!
readlink: illegal option -- f
usage: readlink [-n] [file ...]
Exec: /usr/local/Cellar/erlang/19.2/lib/erlang/erts-8.2/bin/erlexec -boot /Users/quantum/apps/tunnel/_build/default/rel/tunnel/releases/0.1.0/tunnel -mode embedded -boot_var ERTS_LIB_DIR /usr/local/Cellar/erlang/19.2/lib/erlang/lib -config /Users/quantum/apps/tunnel/_build/default/rel/tunnel/releases/0.1.0/sys.config -args_file /Users/quantum/apps/tunnel/_build/default/rel/tunnel/releases/0.1.0/vm.args -pa -- console
Root: /Users/quantum/apps/tunnel/_build/default/rel/tunnel
/Users/quantum/apps/tunnel/_build/default/rel/tunnel
Erlang/OTP 19 [erts-8.2] [source] [64-bit] [smp:8:8] [async-threads:30] [hipe] [kernel-poll:true] [dtrace]
=INFO REPORT==== 16-Feb-2017::15:02:21 ===
application: tunnel
exited: {bad_return,
{{tunnel,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy_router,compile,
[[{'_',
[{"/info",lobby_handler,[]},
{"/join/:name",join_handler,[]},
{"/play/:table_pid/:name/:auth/:team/:action/:x/:y",
play_handler,[]}]}]],
[]},
{tunnel,start,2,
[{file,
"/Users/quantum/apps/tunnel/_build/default/lib/tunnel/src/tunnel.erl"},
{line,8}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,273}]}]}}}}
type: permanent
{"Kernel pid terminated",application_controller,"{application_start_failure,tunnel,{bad_return,{{tunnel,start,[normal,[]]},{'EXIT',{undef,[{cowboy_router,compile,[[{'_',[{\"/info\",lobby_handler,[]},{\"/join/:name\",join_handler,[]},{\"/play/:table_pid/:name/:auth/:team/:action/:x/:y\",play_handler,[]}]}]],[]},{tunnel,start,2,[{file,\"/Users/quantum/apps/tunnel/_build/default/lib/tunnel/src/tunnel.erl\"},{line,8}]},{application_master,start_it_old,4,[{file,\"application_master.erl\"},{line,273}]}]}}}}}"}
Kernel pid terminated (application_controller) ({application_start_failure,tunnel,{bad_return,{{tunnel,start,[normal,[]]},{'EXIT',{undef,[{cowboy_router,compile,[[{'_',[{"/info",lobby_handler,[]},{"/j
Crash dump is being written
Why is this crashing?
If this is your first experience with rebar3, I suggest starting with an OTP application, not an OTP release:
rebar3 new app tunnel
and then do not blindly copy over the source files because you risk overwriting the files that have been created for you below src. Have a look at the contents of that directory beforehand.
I also suggest to take the time to read the rebar3 https://www.rebar3.org/docs/basic-usage page.
You will also have to read about what an OTP application is. I know, quite a lot to understand and sometimes confusing. A free source is http://learnyousomeerlang.com/building-applications-with-otp. It is also worthwhile to buy a book about Erlang. There are a few, I suggest https://www.manning.com/books/erlang-and-otp-in-action.
There is also an online course, free, that starts in a few days (20th Feb 2017) https://www.mooc-list.com/course/functional-programming-erlang-futurelearn

Copying files from one server to other via erlang code

I want to copy files from one server(Say A) to other(Say B).Scenerio is->User sends me a file(video,zip or photo) in binary.I write this to /var/www/myfolder of A.Now in next step i want this to be copied at B.I used os:cmd(scp ----) command.But it gives error like->
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
I think it is asking for password of B.How can i configure password in scp command or is there any other method to do this in erlang?
You can use Erlang File I/O if you have both servers connected using erlang distribution protocol. (You can do it over TCP or UDP or any other networking as well but it is more complicated).
Let's demonstrate it using two "servers" running on the same machine (it works same over a network, but you have to connect them properly). First we make directory for each server and content of file foo to transfer:
$ mkdir a b
$ echo Hello World > a/foo
Let's start two servers each in a different directory:
$ cd a
a$ erl -sname a
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
(a#hynek-notebook)1>
and the second server in a different console:
$ cd b
b$ erl -sname b
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
(b#hynek-notebook)1>
Now we check there is nothing on the b server yet:
(b#hynek-notebook)1> ls().
ok
(b#hynek-notebook)2>
Now we can connect nodes, check if they are connected and read the file foo.
(a#hynek-notebook)1> net_kernel:connect('b#hynek-notebook').
true
(a#hynek-notebook)2> net_adm:ping('b#hynek-notebook').
pong
(a#hynek-notebook)3> ls().
foo
ok
(a#hynek-notebook)4> {ok, Bin} = file:read_file("foo").
{ok,<<"Hello World\n">>}
(a#hynek-notebook)5>
And write file to server b using rpc:call/4:
(a#hynek-notebook)5> rpc:call('b#hynek-notebook', file, write_file, ["bar", Bin]).
ok
(a#hynek-notebook)6>
Check the result on the server b:
(b#hynek-notebook)2> ls().
bar
ok
(b#hynek-notebook)3> {ok, Bin} = file:read_file("bar").
{ok,<<"Hello World\n">>}
(b#hynek-notebook)4>
For bigger files, you should not transfer a whole file in the one big binary. Unfortunately, you need at least some code support from sending or receiving side. You can transfer file handler from one node to another but the process which calls file:open/2 has to keep running. It is reason you can't just use {ok, FH} = rpc:call(Node, file, open, [FN, [write]]). It's a bummer. One way is to make a very simple server which opens a file and keeps running.
(b#hynek-notebook)4> Self = self().
<0.40.0>
(b#hynek-notebook)5> F = fun() -> Self ! file:open("baz", [write]), receive close -> ok end end.
#Fun<erl_eval.20.54118792>
(b#hynek-notebook)6> FS = spawn_link('a#hynek-notebook', F).
<7329.48.0>
(b#hynek-notebook)7> {ok, FH} = receive X -> X end.
{ok,<7329.49.0>}
(b#hynek-notebook)8> file:write(FH, Bin).
ok
(b#hynek-notebook)9> FS ! close.
close
(b#hynek-notebook)10>
And we expect file baz with proper content on the server a:
(a#hynek-notebook)6> ls().
baz foo
ok
(a#hynek-notebook)7> {ok, _} = file:read_file("baz").
{ok,<<"Hello World\n">>}
(a#hynek-notebook)8>
The other option is to write a server which will receive blocks and write them instead of sending a file handler. And there are many other options how to do it using direct TCP connection using HTTP or your own protocol and using file:send_file/2,5 and many other ways.

Tsung error: can't start newbeam on host

I have been trying to get tsung to connect to a box I have running kubuntu 12.04
Here is the client portion of my config
<clients>
<client host="klaptop" weight="1" maxusers="500"/>
</clients>
I run tsung with the following command
tsung -f /var/tsung/xml/config.xml -l /var/tsung/logs/ start
I get the following error in my tsung_controller log file
=INFO REPORT==== 20-Jun-2012::15:06:01 ===
ts_config_server:(0:<0.72.0>) Can't start newbeam on host klaptop (reason: timeout) ! Aborting!
I have read the manual's trouble shooting and tried to make sure that all of my bases are covered
(same erlang version, ssh connection works without password, hostnames are set up right, etc)
I have confirmed connectivity with the example they gave, here are my results.
[/var/tsung]$ erl -rsh ssh -sname foo -setcookie mycookie
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9.1 (abort with ^G)
(foo#macbook)1> slave:start(klaptop,bar,"-setcookie mycookie").
{ok,bar#klaptop}
The user manual seems to make the assumption that once the connection works in erlang, tsung will also work, this is not the case for me though, I am still getting the same timeout issue.
I am not sure how to further debug this, any help or suggestions would be appreciated.
UPDATE:
As requested in the comments I tried using the IP. With the following config
<client host="klaptop" weight="1" maxusers="500">
<ip value="10.160.1.89"></ip>
</client>
I got the same error though.
I had similar problem, it's possible that ssh key checking might get in the way.
Try this:
Use tsung 1.4.3 or newer
Create a script file (say, some_dir/ssh_no_check):
#!/bin/sh
/usr/bin/ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $#
Make it executable.
Add:
-r some_dir/ssh_no_check
to your tsung command params.
This will disable ssh key checking for tsung.
Can't start newbeam on host XXXX (reason: timeout)
In my case (Debian 6.0, tsung 1.4.2) the reason of this error was that client also must has ssh key to connect to master. There is no explicit mention about it in documentation.
Ensure ssh key verification is disabled
~/.ssh/config
Host *
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
Make sure all ports are accessible across controller and worker nodes.
If it is in the cloud make sure firewall or security groups allow all ports.
3.Erlang, Tsung must have same version.
4.Ensure all machines are reachable to each other
5.Run erlang test
erl -rsh ssh -name subbu -setcookie tsung
Erlang R16B03-1 (erts-5.10.4) [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V5.10.4 (abort with ^G)
(daya#ip-10-0-100-224.ec2.internal)1> slave:start("worker1.com",bar,"-setcookie tsung").
Warning: Permanently added 'worker1,10.0.100.225' (ECDSA) to the list of known hosts.
{ok,bar#worker1}
Run this test from controller to all worker nodes.
You should be able run tests without any issues.
Good Luck!
Subbu

How does one start an Erlang OTP application and allow the passing of command-line arguments to the application's root supervisor?

Quick 1 liner: How does one start an OTP application and pass command-line args to it?
I wanted be able to start an OTP application in a generic "UNIX" way, being able to pass command-line arguments parsed by getopts. So, I have an erlang escript which uses the getopt library to handle parsing of command-line arguments.
shino's answer got me on the right path:
I have my escript do the getopts parsing
The escript then loads the application description into memory with application:load/1
I then use application:set_env/3 to store the CLI args
Now, launch the application with application:start/2
Once the application launches, the arguments can be accessed via application:get_env/2
You can also override application environment settings on the command line:
erl -myapp foo bar ...
This will set application.get_env(myapp, foo) to "bar", overriding any app.config setting.
You can use init:get_plain_arguments/0 function in order to access command line (extra) arguments.
Example:
$ erl -sname example -extra extra args here
Erlang R15B (erts-5.9) [source] [64-bit] [smp:2:2] [async-threads:0] [kernel-poll:false]
Eshell V5.9 (abort with ^G)
(example#localhost)1> init:get_plain_arguments().
["extra","args","here"]
init:get_plain_argumets/0 returns arguments after -extra option as a list of strings. Option sname is just for explanation, which does not appear in init:get_plain_argumets/0.
For more detail, see document on init module http://www.erlang.org/doc/man/init.html .

Resources