The task is to:
- SSH to a Linux server.
- Stop a service.
-
Using tar create a tar.gz file.
from a directory (30GB size Max). - Upload that file to an FTP server.
- Start the stopped service.
- Whole above process is going to be done on Each Sunday
I have covered pretty much all steps and failures in the code, assuming that there is going to be a service running and also directory is present as well on which it’s going to do tar operation.
I am using https://github.com/rubencaro/sshex for SSH to the server and then do all the commands.
Questions:
- How can I make the pipe to wait until the tar process completed and then run the next command? as on 30GB file, It almost takes more than 10 minutes to tar that size of the directory. Task 3 and Task 4 are the most time consuming, And I want to make pipe wait until these commands are done then proceed to next.
- Is this the best way to do
tar
on a big directory (32GB max). - Is it the best way to do FTP? in linux?
- Is it the best solution to do that? I mean Elixir is great but is doing all these steps through an Elixir Task is good?
- Can you suggest me some notes and changes to the code, I have written to make it better?
UPDATE:
While doing tar
I get this error from ssh connection
{:error, "Timeout. Did not receive data for 5000ms."}
All Module:
defmodule EvercamMedia.BackUpSeaweedfsFiler do
require Logger
@zip_date Calendar.Strftime.strftime(Calendar.DateTime.now_utc, "%Y%m%d") |> elem(1)
@ftp_domain Application.get_env(:evercam_media, :ftp_domain)
@ftp_username Application.get_env(:evercam_media, :ftp_username)
@ftp_password Application.get_env(:evercam_media, :ftp_password)
@filer_server Application.get_env(:evercam_media, :filer_server)
@filer_username Application.get_env(:evercam_media, :filer_username)
@filer_password Application.get_env(:evercam_media, :filer_password)
@stop_seaweedfs_command "systemctl stop seaweedfs.service"
@start_seaweedfs_command "systemctl start seaweedfs.service"
@zip_filer_directory "tar -czf #{@zip_date}.tar.gz /storage/filer"
@copy_to_ftp "curl -T #{@zip_date}.tar.gz #{@ftp_domain} --user #{@ftp_username}:#{@ftp_password}"
def start do
connect_to_server(@filer_server, @filer_username, @filer_password)
|> connected?
|> grant_for_backup()
end
defp grant_for_backup({:exit, true}), do: :noop
defp grant_for_backup(connected) do
connected
|> run_command_on_server(@stop_seaweedfs_command)
|> response_is(connected)
|> run_command_on_server(@zip_filer_directory)
|> response_is(connected)
|> run_command_on_server(@copy_to_ftp)
|> response_is(connected)
|> run_command_on_server(@start_seaweedfs_command)
|> completed?
end
defp connected?({:ok, connected}), do: connected
defp connected?({:halt, true, message}) do
Logger.info("Process stopped due to: " <> message)
send_email_for_backup("Process stopped due to: " <> message)
{:exit, true}
end
defp completed?({:halt, reason}) do
Logger.info("Process stopped due to: " <> reason)
send_email_for_backup("Process stopped due to: " <> reason)
end
defp completed?(_conn) do
Logger.info "Process has been completed."
send_email_for_backup("Process has been completed.")
end
defp run_command_on_server({:halt, reason}, _command) do
Logger.info("Process stopped due to: " <> reason)
send_email_for_backup("Command Couldn't run due to: " <> reason)
:noop
end
defp run_command_on_server(connected, command) do
connected
|> SSHEx.run(command)
end
defp response_is({:ok, _res, _}, connected), do: connected
defp response_is({:error, reason}, _connected), do: {:halt, reason}
defp connect_to_server(ip, username, password, tries \\ 1)
defp connect_to_server(_ip, _username, _password, 3), do: {:halt, true, "Not possible to make connection with server."}
defp connect_to_server(ip, username, password, tries) do
SSHEx.connect(ip: ip, user: username, password: password)
|> case do
{:error, :nxdomain} -> {:halt, true, "IP does'nt seem correct."}
{:error, :timeout} -> connect_to_server(ip, username, password, tries + 1)
{:error, reason} -> {:halt, true, reason}
{:ok, connected} -> {:ok, connected}
end
end
defp send_email_for_backup(message) do
EvercamMedia.UserMailer.seaweedfs_filer_backup(message)
end
end
Thanks in Advance.