feat: add support for sshfs
This commit is contained in:
parent
002db7026b
commit
67cd9ae964
6 changed files with 117 additions and 30 deletions
|
@ -67,7 +67,7 @@ module GX
|
||||||
def run()
|
def run()
|
||||||
@config.load_from_file
|
@config.load_from_file
|
||||||
|
|
||||||
names_display = {} of String => NamedTuple(filesystem: GoCryptFS, ansi_name: String)
|
names_display = {} of String => NamedTuple(filesystem: Filesystem, ansi_name: String)
|
||||||
@config.filesystems.each do |filesystem|
|
@config.filesystems.each do |filesystem|
|
||||||
result_name = filesystem.mounted? ? "#{filesystem.name} [open]" : filesystem.name
|
result_name = filesystem.mounted? ? "#{filesystem.name} [open]" : filesystem.name
|
||||||
ansi_name = filesystem.mounted? ? "#{filesystem.name} [#{ "open".colorize(:green) }]" : filesystem.name
|
ansi_name = filesystem.mounted? ? "#{filesystem.name} [#{ "open".colorize(:green) }]" : filesystem.name
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
require "./filesystems/gocryptfs"
|
require "./filesystems"
|
||||||
|
|
||||||
module GX
|
module GX
|
||||||
class Config
|
class Config
|
||||||
|
@ -13,7 +13,7 @@ module GX
|
||||||
record AddArgs, name : String, path : String
|
record AddArgs, name : String, path : String
|
||||||
record DelArgs, name : String
|
record DelArgs, name : String
|
||||||
|
|
||||||
getter filesystems : Array(GoCryptFS)
|
getter filesystems : Array(Filesystem)
|
||||||
getter home_dir : String
|
getter home_dir : String
|
||||||
property mode : Mode
|
property mode : Mode
|
||||||
property path : String
|
property path : String
|
||||||
|
@ -28,30 +28,31 @@ module GX
|
||||||
@home_dir = ENV["HOME"]
|
@home_dir = ENV["HOME"]
|
||||||
|
|
||||||
@mode = Mode::Run
|
@mode = Mode::Run
|
||||||
@filesystems = [] of GoCryptFS
|
@filesystems = [] of Filesystem
|
||||||
@path = File.join(@home_dir, ".config", DEFAULT_CONFIG_PATH)
|
@path = File.join(@home_dir, ".config", DEFAULT_CONFIG_PATH)
|
||||||
@args = NoArgs
|
@args = NoArgs
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_from_file
|
def load_from_file
|
||||||
@filesystems = [] of GoCryptFS
|
@filesystems = [] of Filesystem
|
||||||
|
|
||||||
if !File.exists? @path
|
if !File.exists? @path
|
||||||
STDERR.puts "Error: file #{@path} does not exist!".colorize(:red)
|
STDERR.puts "Error: file #{@path} does not exist!".colorize(:red)
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
load_vaults(@path)
|
load_filesystems(@path)
|
||||||
end
|
end
|
||||||
|
|
||||||
private def load_vaults(config_path : String)
|
private def load_filesystems(config_path : String)
|
||||||
yaml_data = YAML.parse(File.read(config_path))
|
yaml_data = YAML.parse(File.read(config_path))
|
||||||
vaults_data = yaml_data["filesystems"].as_a
|
vaults_data = yaml_data["filesystems"].as_a
|
||||||
|
|
||||||
vaults_data.each do |vault_data|
|
vaults_data.each do |filesystem_data|
|
||||||
type = vault_data["type"].as_s
|
type = filesystem_data["type"].as_s
|
||||||
name = vault_data["name"].as_s
|
name = filesystem_data["name"].as_s
|
||||||
encrypted_path = vault_data["encrypted_path"].as_s
|
# encrypted_path = filesystem_data["encrypted_path"].as_s
|
||||||
@filesystems << GoCryptFS.new(name, encrypted_path, "#{name}.Open")
|
@filesystems << Filesystem.from_yaml(filesystem_data.to_yaml)
|
||||||
|
# @filesystems << Filesystem.new(name, encrypted_path, "#{name}.Open")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
3
src/filesystems.cr
Normal file
3
src/filesystems.cr
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
require "./filesystems/gocryptfs"
|
||||||
|
require "./filesystems/filesystem"
|
38
src/filesystems/filesystem.cr
Normal file
38
src/filesystems/filesystem.cr
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
|
||||||
|
require "yaml"
|
||||||
|
|
||||||
|
module GX
|
||||||
|
abstract class Filesystem
|
||||||
|
include YAML::Serializable
|
||||||
|
|
||||||
|
use_yaml_discriminator "type", {
|
||||||
|
gocryptfs: GoCryptFS,
|
||||||
|
sshfs: SshFS
|
||||||
|
}
|
||||||
|
|
||||||
|
property type : String
|
||||||
|
end
|
||||||
|
|
||||||
|
module GenericFilesystem
|
||||||
|
def unmount
|
||||||
|
system("fusermount -u #{mount_dir.shellescape}")
|
||||||
|
puts "Filesystem #{name} is now closed.".colorize(:green)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mount(&block)
|
||||||
|
Dir.mkdir_p(mount_dir) unless Dir.exists?(mount_dir)
|
||||||
|
if mounted?
|
||||||
|
puts "Already mounted. Skipping.".colorize(:yellow)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
puts "Filesystem #{name} is now available on #{mount_dir}".colorize(:green)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require "./gocryptfs"
|
||||||
|
require "./sshfs"
|
|
@ -1,14 +1,19 @@
|
||||||
require "shellwords"
|
require "shellwords"
|
||||||
|
require "./filesystem"
|
||||||
|
|
||||||
module GX
|
module GX
|
||||||
class GoCryptFS
|
class GoCryptFS < Filesystem
|
||||||
getter name : String
|
getter name : String = ""
|
||||||
getter encrypted_path : String
|
getter encrypted_path : String = ""
|
||||||
getter mount_dir : String
|
|
||||||
|
|
||||||
def initialize(@name, @encrypted_path, mount_name : String)
|
@[YAML::Field(key: "mount_dir", ignore: true)]
|
||||||
|
getter mount_dir : String = ""
|
||||||
|
|
||||||
|
include GenericFilesystem
|
||||||
|
|
||||||
|
def after_initialize()
|
||||||
home_dir = ENV["HOME"] || raise "Home directory not found"
|
home_dir = ENV["HOME"] || raise "Home directory not found"
|
||||||
@mount_dir = File.join(home_dir, "mnt/#{mount_name}")
|
@mount_dir = File.join(home_dir, "mnt/#{@name}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def mounted? : Bool
|
def mounted? : Bool
|
||||||
|
@ -16,26 +21,22 @@ module GX
|
||||||
end
|
end
|
||||||
|
|
||||||
def mount
|
def mount
|
||||||
Dir.mkdir_p(mount_dir) unless Dir.exists?(mount_dir)
|
super do
|
||||||
|
|
||||||
if mounted?
|
|
||||||
puts "Already mounted. Skipping.".colorize(:yellow)
|
|
||||||
else
|
|
||||||
input = STDIN
|
input = STDIN
|
||||||
output = STDOUT
|
output = STDOUT
|
||||||
error = STDERR
|
error = STDERR
|
||||||
process = Process.new("gocryptfs", ["-idle", "15m", encrypted_path, mount_dir], input: input, output: output, error: error)
|
process = Process.new(
|
||||||
|
"gocryptfs",
|
||||||
|
["-idle", "15m", encrypted_path, mount_dir],
|
||||||
|
input: input,
|
||||||
|
output: output,
|
||||||
|
error: error
|
||||||
|
)
|
||||||
unless process.wait.success?
|
unless process.wait.success?
|
||||||
puts "Error mounting the vault".colorize(:red)
|
puts "Error mounting the vault".colorize(:red)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
puts "GoCryptFS #{name} is now available on #{mount_dir}".colorize(:green)
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def unmount
|
|
||||||
system("fusermount -u #{mount_dir.shellescape}")
|
|
||||||
puts "GoCryptFS #{name} is now closed.".colorize(:green)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
44
src/filesystems/sshfs.cr
Normal file
44
src/filesystems/sshfs.cr
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
require "shellwords"
|
||||||
|
require "./filesystem"
|
||||||
|
|
||||||
|
module GX
|
||||||
|
class SshFS < Filesystem
|
||||||
|
getter name : String = ""
|
||||||
|
getter remote_path : String = ""
|
||||||
|
getter remote_user : String = ""
|
||||||
|
getter remote_host : String = ""
|
||||||
|
|
||||||
|
@[YAML::Field(key: "mount_dir", ignore: true)]
|
||||||
|
getter mount_dir : String = ""
|
||||||
|
|
||||||
|
include GenericFilesystem
|
||||||
|
|
||||||
|
def after_initialize()
|
||||||
|
home_dir = ENV["HOME"] || raise "Home directory not found"
|
||||||
|
@mount_dir = File.join(home_dir, "mnt/#{@name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def mounted? : Bool
|
||||||
|
`mount`.includes?("#{remote_user}@#{remote_host}:#{remote_path} on #{mount_dir}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def mount
|
||||||
|
super do
|
||||||
|
input = STDIN
|
||||||
|
output = STDOUT
|
||||||
|
error = STDERR
|
||||||
|
process = Process.new(
|
||||||
|
"sshfs",
|
||||||
|
["#{remote_user}@#{remote_host}:#{remote_path}", mount_dir],
|
||||||
|
input: input,
|
||||||
|
output: output,
|
||||||
|
error: error
|
||||||
|
)
|
||||||
|
unless process.wait.success?
|
||||||
|
puts "Error mounting the filesystem".colorize(:red)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue