forked from glenux/mfm
refactor: use a better class hierarchy for filesystems
This commit is contained in:
parent
8f2c2442a3
commit
994f9e1885
8 changed files with 123 additions and 115 deletions
|
@ -97,7 +97,7 @@ module GX
|
||||||
end
|
end
|
||||||
|
|
||||||
def mount()
|
def mount()
|
||||||
names_display = {} of String => NamedTuple(filesystem: Filesystem, ansi_name: String)
|
names_display = {} of String => NamedTuple(filesystem: Filesystem::AbstractFilesystem, ansi_name: String)
|
||||||
@config.filesystems.each do |filesystem|
|
@config.filesystems.each do |filesystem|
|
||||||
fs_str = filesystem.type.ljust(12,' ')
|
fs_str = filesystem.type.ljust(12,' ')
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,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(Filesystem)
|
getter filesystems : Array(Filesystem::AbstractFilesystem)
|
||||||
getter home_dir : String
|
getter home_dir : String
|
||||||
getter global_mount_point : String?
|
getter global_mount_point : String?
|
||||||
property verbose : Bool
|
property verbose : Bool
|
||||||
|
@ -39,7 +39,7 @@ module GX
|
||||||
|
|
||||||
@verbose = false
|
@verbose = false
|
||||||
@mode = Mode::Mount
|
@mode = Mode::Mount
|
||||||
@filesystems = [] of Filesystem
|
@filesystems = [] of Filesystem::AbstractFilesystem
|
||||||
@path = nil
|
@path = nil
|
||||||
@global_mount_point = nil
|
@global_mount_point = nil
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ module GX
|
||||||
path = detect_config_file()
|
path = detect_config_file()
|
||||||
end
|
end
|
||||||
@path = path
|
@path = path
|
||||||
@filesystems = [] of Filesystem
|
@filesystems = [] of Filesystem::AbstractFilesystem
|
||||||
|
|
||||||
if !File.exists? path
|
if !File.exists? path
|
||||||
Log.error { "File #{path} does not exist!".colorize(:red) }
|
Log.error { "File #{path} does not exist!".colorize(:red) }
|
||||||
|
@ -111,7 +111,7 @@ module GX
|
||||||
type = filesystem_data["type"].as_s
|
type = filesystem_data["type"].as_s
|
||||||
name = filesystem_data["name"].as_s
|
name = filesystem_data["name"].as_s
|
||||||
# encrypted_path = filesystem_data["encrypted_path"].as_s
|
# encrypted_path = filesystem_data["encrypted_path"].as_s
|
||||||
@filesystems << Filesystem.from_yaml(filesystem_data.to_yaml)
|
@filesystems << Filesystem::AbstractFilesystem.from_yaml(filesystem_data.to_yaml)
|
||||||
# @filesystems << Filesystem.new(name, encrypted_path, "#{name}.Open")
|
# @filesystems << Filesystem.new(name, encrypted_path, "#{name}.Open")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,4 +6,4 @@
|
||||||
require "./filesystems/gocryptfs"
|
require "./filesystems/gocryptfs"
|
||||||
require "./filesystems/sshfs"
|
require "./filesystems/sshfs"
|
||||||
require "./filesystems/httpdirfs"
|
require "./filesystems/httpdirfs"
|
||||||
require "./filesystems/filesystem"
|
require "./filesystems/abstract_filesystem"
|
||||||
|
|
50
src/filesystems/abstract_filesystem.cr
Normal file
50
src/filesystems/abstract_filesystem.cr
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
#
|
||||||
|
# SPDX-FileCopyrightText: 2023 Glenn Y. Rolland <glenux@glenux.net>
|
||||||
|
# Copyright © 2023 Glenn Y. Rolland <glenux@glenux.net>
|
||||||
|
|
||||||
|
require "yaml"
|
||||||
|
|
||||||
|
module GX
|
||||||
|
module Filesystem
|
||||||
|
abstract class AbstractFilesystem
|
||||||
|
include YAML::Serializable
|
||||||
|
|
||||||
|
use_yaml_discriminator "type", {
|
||||||
|
gocryptfs: GoCryptFS,
|
||||||
|
sshfs: SshFS,
|
||||||
|
httpdirfs: HttpDirFS
|
||||||
|
}
|
||||||
|
|
||||||
|
property type : String
|
||||||
|
end
|
||||||
|
|
||||||
|
module FilesystemBase
|
||||||
|
def unmount
|
||||||
|
system("fusermount -u #{mount_dir.shellescape}")
|
||||||
|
fusermount_status = $?
|
||||||
|
|
||||||
|
if fusermount_status.success?
|
||||||
|
puts "Filesystem #{name} is now closed.".colorize(:green)
|
||||||
|
else
|
||||||
|
puts "Error: Unable to unmount filesystem #{name} (exit code: #{fusermount_status.exit_code}).".colorize(:red)
|
||||||
|
end
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
require "./gocryptfs"
|
||||||
|
require "./sshfs"
|
|
@ -1,48 +0,0 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
#
|
|
||||||
# SPDX-FileCopyrightText: 2023 Glenn Y. Rolland <glenux@glenux.net>
|
|
||||||
# Copyright © 2023 Glenn Y. Rolland <glenux@glenux.net>
|
|
||||||
|
|
||||||
require "yaml"
|
|
||||||
|
|
||||||
module GX
|
|
||||||
abstract class Filesystem
|
|
||||||
include YAML::Serializable
|
|
||||||
|
|
||||||
use_yaml_discriminator "type", {
|
|
||||||
gocryptfs: GoCryptFS,
|
|
||||||
sshfs: SshFS,
|
|
||||||
httpdirfs: HttpDirFS
|
|
||||||
}
|
|
||||||
|
|
||||||
property type : String
|
|
||||||
end
|
|
||||||
|
|
||||||
module GenericFilesystem
|
|
||||||
def unmount
|
|
||||||
system("fusermount -u #{mount_dir.shellescape}")
|
|
||||||
fusermount_status = $?
|
|
||||||
|
|
||||||
if fusermount_status.success?
|
|
||||||
puts "Filesystem #{name} is now closed.".colorize(:green)
|
|
||||||
else
|
|
||||||
puts "Error: Unable to unmount filesystem #{name} (exit code: #{fusermount_status.exit_code}).".colorize(:red)
|
|
||||||
end
|
|
||||||
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"
|
|
|
@ -4,42 +4,44 @@
|
||||||
# Copyright © 2023 Glenn Y. Rolland <glenux@glenux.net>
|
# Copyright © 2023 Glenn Y. Rolland <glenux@glenux.net>
|
||||||
|
|
||||||
require "shellwords"
|
require "shellwords"
|
||||||
require "./filesystem"
|
require "./abstract_filesystem"
|
||||||
|
|
||||||
module GX
|
module GX
|
||||||
class GoCryptFS < Filesystem
|
module Filesystem
|
||||||
getter name : String = ""
|
class GoCryptFS < AbstractFilesystem
|
||||||
getter encrypted_path : String = ""
|
getter name : String = ""
|
||||||
|
getter encrypted_path : String = ""
|
||||||
|
|
||||||
@[YAML::Field(key: "mount_dir", ignore: true)]
|
@[YAML::Field(key: "mount_dir", ignore: true)]
|
||||||
getter mount_dir : String = ""
|
getter mount_dir : String = ""
|
||||||
|
|
||||||
include GenericFilesystem
|
include FilesystemBase
|
||||||
|
|
||||||
def after_initialize()
|
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/#{@name}.Open")
|
@mount_dir = File.join(home_dir, "mnt/#{@name}.Open")
|
||||||
end
|
end
|
||||||
|
|
||||||
def mounted? : Bool
|
def mounted? : Bool
|
||||||
`mount`.includes?("#{encrypted_path} on #{mount_dir}")
|
`mount`.includes?("#{encrypted_path} on #{mount_dir}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def mount
|
def mount
|
||||||
super do
|
super do
|
||||||
input = STDIN
|
input = STDIN
|
||||||
output = STDOUT
|
output = STDOUT
|
||||||
error = STDERR
|
error = STDERR
|
||||||
process = Process.new(
|
process = Process.new(
|
||||||
"gocryptfs",
|
"gocryptfs",
|
||||||
["-idle", "15m", encrypted_path, mount_dir],
|
["-idle", "15m", encrypted_path, mount_dir],
|
||||||
input: input,
|
input: input,
|
||||||
output: output,
|
output: output,
|
||||||
error: error
|
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
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,17 +4,18 @@
|
||||||
# Copyright © 2023 Glenn Y. Rolland <glenux@glenux.net>
|
# Copyright © 2023 Glenn Y. Rolland <glenux@glenux.net>
|
||||||
|
|
||||||
require "shellwords"
|
require "shellwords"
|
||||||
require "./filesystem"
|
require "./abstract_filesystem"
|
||||||
|
|
||||||
module GX
|
module GX
|
||||||
class HttpDirFS < Filesystem
|
module Filesystem
|
||||||
|
class HttpDirFS < AbstractFilesystem
|
||||||
getter name : String = ""
|
getter name : String = ""
|
||||||
getter url : String = ""
|
getter url : String = ""
|
||||||
|
|
||||||
@[YAML::Field(key: "mount_dir", ignore: true)]
|
@[YAML::Field(key: "mount_dir", ignore: true)]
|
||||||
getter mount_dir : String = ""
|
getter mount_dir : String = ""
|
||||||
|
|
||||||
include GenericFilesystem
|
include FilesystemBase
|
||||||
|
|
||||||
def after_initialize()
|
def after_initialize()
|
||||||
home_dir = ENV["HOME"] || raise "Home directory not found"
|
home_dir = ENV["HOME"] || raise "Home directory not found"
|
||||||
|
@ -44,5 +45,6 @@ module GX
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,38 +4,39 @@
|
||||||
# Copyright © 2023 Glenn Y. Rolland <glenux@glenux.net>
|
# Copyright © 2023 Glenn Y. Rolland <glenux@glenux.net>
|
||||||
|
|
||||||
require "shellwords"
|
require "shellwords"
|
||||||
require "./filesystem"
|
require "./abstract_filesystem"
|
||||||
|
|
||||||
module GX
|
module GX
|
||||||
class SshFS < Filesystem
|
module Filesystem
|
||||||
getter name : String = ""
|
class SshFS < AbstractFilesystem
|
||||||
getter remote_path : String = ""
|
getter name : String = ""
|
||||||
getter remote_user : String = ""
|
getter remote_path : String = ""
|
||||||
getter remote_host : String = ""
|
getter remote_user : String = ""
|
||||||
getter remote_port : String = "22"
|
getter remote_host : String = ""
|
||||||
|
getter remote_port : String = "22"
|
||||||
|
|
||||||
@[YAML::Field(key: "mount_dir", ignore: true)]
|
@[YAML::Field(key: "mount_dir", ignore: true)]
|
||||||
getter mount_dir : String = ""
|
getter mount_dir : String = ""
|
||||||
|
|
||||||
include GenericFilesystem
|
include FilesystemBase
|
||||||
|
|
||||||
def after_initialize()
|
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/#{@name}")
|
@mount_dir = File.join(home_dir, "mnt/#{@name}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def mounted? : Bool
|
def mounted? : Bool
|
||||||
`mount`.includes?("#{remote_user}@#{remote_host}:#{remote_path} on #{mount_dir}")
|
`mount`.includes?("#{remote_user}@#{remote_host}:#{remote_path} on #{mount_dir}")
|
||||||
end
|
end
|
||||||
|
|
||||||
def mount
|
def mount
|
||||||
super do
|
super do
|
||||||
input = STDIN
|
input = STDIN
|
||||||
output = STDOUT
|
output = STDOUT
|
||||||
error = STDERR
|
error = STDERR
|
||||||
process = Process.new(
|
process = Process.new(
|
||||||
"sshfs",
|
"sshfs",
|
||||||
[
|
[
|
||||||
"-p", remote_port,
|
"-p", remote_port,
|
||||||
"#{remote_user}@#{remote_host}:#{remote_path}",
|
"#{remote_user}@#{remote_host}:#{remote_path}",
|
||||||
mount_dir
|
mount_dir
|
||||||
|
@ -43,10 +44,11 @@ module GX
|
||||||
input: input,
|
input: input,
|
||||||
output: output,
|
output: output,
|
||||||
error: error
|
error: error
|
||||||
)
|
)
|
||||||
unless process.wait.success?
|
unless process.wait.success?
|
||||||
puts "Error mounting the filesystem".colorize(:red)
|
puts "Error mounting the filesystem".colorize(:red)
|
||||||
return
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue