1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
use ate::prelude::*;
use ate_auth::opt::*;
#[allow(unused_imports)]
use tracing::{debug, error, info, instrument, span, trace, warn, Level};
use url::Url;

use ate::compact::CompactMode;

#[cfg(feature = "enable_tokera")]
use tokera::opt::{OptsContract, OptsLogin, OptsLogout, OptsService, OptsWallet};

use clap::Parser;

#[derive(Parser)]
#[clap(version = "1.6", author = "John S. <johnathan.sharratt@gmail.com>")]
pub struct Opts {
    /// Sets the level of log verbosity, can be used multiple times
    #[allow(dead_code)]
    #[clap(short, long, parse(from_occurrences))]
    pub verbose: i32,
    /// URL where the user is authenticated
    #[clap(short, long, default_value = "ws://tokera.sh/auth")]
    pub auth: Url,
    /// No authentication or passcode will be used to protect this file-system
    #[clap(short, long)]
    pub no_auth: bool,
    /// Token used to access your encrypted file-system (if you do not supply a token then you will
    /// be prompted for a username and password)
    #[clap(short, long)]
    pub token: Option<String>,
    /// Token file to read that holds a previously created token to be used to access your encrypted
    /// file-system (if you do not supply a token then you will be prompted for a username and password)
    #[cfg(not(feature = "enable_tokera"))]
    #[clap(long)]
    pub token_path: Option<String>,
    /// Token file to read that holds a previously created token to be used for this operation
    #[cfg(feature = "enable_tokera")]
    #[clap(long, default_value = "~/ate/token")]
    pub token_path: String,
    /// No NTP server will be used to synchronize the time thus the server time
    /// will be used instead
    #[clap(long)]
    pub no_ntp: bool,
    /// NTP server address that the file-system will synchronize with
    #[clap(long)]
    pub ntp_pool: Option<String>,
    /// NTP server port that the file-system will synchronize with
    #[clap(long)]
    pub ntp_port: Option<u16>,
    /// Logs debug info to the console
    #[clap(short, long)]
    pub debug: bool,
    /// Determines if ATE will use DNSSec or just plain DNS
    #[clap(long)]
    pub dns_sec: bool,
    /// Address that DNS queries will be sent to
    #[clap(long, default_value = "8.8.8.8")]
    pub dns_server: String,

    #[clap(subcommand)]
    pub subcmd: SubCommand,
}

#[derive(Parser)]
pub enum SubCommand {
    /// Users are personal accounts and services that have an authentication context.
    /// Every user comes with a personal wallet that can hold commodities.
    #[clap()]
    User(OptsUser),
    /// Groups are collections of users that share same remote file system
    #[cfg(not(feature = "enable_tokera"))]
    #[clap()]
    Group(OptsDomain),
    /// Domain groups are collections of users that share something together in association
    /// with an internet domain name. Every group has a built in wallet(s) that you can
    /// use instead of a personal wallet. In order to claim a domain group you will need
    /// DNS access to an owned internet domain that can be validated.
    #[cfg(feature = "enable_tokera")]
    #[clap()]
    Domain(OptsDomain),
    /// Databases are chains of data that make up a particular shard. These databases can be
    /// use for application data persistance, file systems and web sites.
    #[clap()]
    Db(OptsDatabase),
    /// Tokens are stored authentication and authorization secrets used by other processes.
    /// Using this command you may generate a custom token however the usual method for
    /// authentication is to use the login command instead.
    #[clap()]
    Token(OptsToken),
    /// Services offered by Tokera (and other 3rd parties) are accessible via this
    /// sub command menu, including viewing the available services and subscribing
    /// to them.
    #[cfg(feature = "enable_tokera")]
    #[clap()]
    Service(OptsService),
    /// Contracts represent all the subscriptions you have made to specific services
    /// you personally consume or a group consume that you act on your authority on
    /// behalf of. This sub-menu allows you to perform actions such as cancel said
    /// contracts.
    #[cfg(feature = "enable_tokera")]
    #[clap()]
    Contract(OptsContract),
    /// Wallets are directly attached to groups and users - they hold a balance,
    /// store transaction history and facilitate transfers, deposits and withdraws.
    #[cfg(feature = "enable_tokera")]
    #[clap()]
    Wallet(OptsWallet),
    /// Login to an account and store the token locally for reuse.
    #[cfg(feature = "enable_tokera")]
    #[clap()]
    Login(OptsLogin),
    /// Logout of the account by deleting the local token.
    #[cfg(feature = "enable_tokera")]
    #[clap()]
    Logout(OptsLogout),
    /// Mounts a local or a remote file system (e.g. ws://tokera.sh/db). When
    /// using a Tokera remote you can either use the default free hosting or subscribe
    /// to the service which will consume funds from the wallet.
    #[clap()]
    Mount(OptsMount),
}

/// Mounts a particular directory as an ATE file system
#[derive(Parser)]
pub struct OptsMount {
    /// Path to directory that the file system will be mounted at
    #[clap(index = 1)]
    pub mount_path: String,
    /// Name of the file-system to be mounted (e.g. myfs).
    /// If this URL is not specified then data will only be stored in a local chain-of-trust
    #[clap(index = 2)]
    pub remote_name: Option<String>,
    /// URL where the data is remotely stored on a distributed commit log.
    #[clap(short, long, default_value = "ws://tokera.sh/db")]
    pub remote: Url,
    /// (Optional) Location of the local persistent redo log (e.g. ~/ate/fs")
    /// If this parameter is not specified then chain-of-trust will cache in memory rather than disk
    #[clap(long)]
    pub log_path: Option<String>,
    /// Path to the backup and restore location of log files
    #[clap(short, long)]
    pub backup_path: Option<String>,
    /// Determines how the file-system will react while it is nominal and when it is
    /// recovering from a communication failure (valid options are 'async', 'readonly-async',
    /// 'readonly-sync' or 'sync')
    #[clap(long, default_value = "readonly-async")]
    pub recovery_mode: RecoveryMode,
    /// User supplied passcode that will be used to encrypt the contents of this file-system
    /// instead of using an authentication. Note that this can 'not' be used as combination
    /// with a strong authentication system and hence implicitely implies the 'no-auth' option
    /// as well.
    #[clap(short, long)]
    pub passcode: Option<String>,
    /// Local redo log file will be deleted when the file system is unmounted, remotely stored data on
    /// any distributed commit log will be persisted. Effectively this setting only uses the local disk
    /// as a cache of the redo-log while it's being used.
    #[clap(long)]
    pub temp: bool,
    /// UID of the user that this file system will be mounted as
    #[clap(short, long)]
    pub uid: Option<u32>,
    /// GID of the group that this file system will be mounted as
    #[clap(short, long)]
    pub gid: Option<u32>,
    /// Allow the root user to have access to this file system
    #[clap(long)]
    pub allow_root: bool,
    /// Allow other users on the machine to have access to this file system
    #[clap(long)]
    pub allow_other: bool,
    /// Mount the file system in readonly mode (`ro` mount option), default is disable.
    #[clap(long)]
    pub read_only: bool,
    /// Enable write back cache for buffered writes, default is disable.
    #[clap(short, long)]
    pub write_back: bool,
    /// By default this process will perform an extra umask(0o007) to prevent everything being public by default,
    /// you can prevent this behaviour by selecting another umask (32bit) or just passing 0
    #[clap(long, default_value = "7")]
    pub umask: u32,
    /// Allow fuse filesystem mount on a non-empty directory, default is not allowed.
    #[clap(long)]
    pub non_empty: bool,
    /// For files and directories that the authenticated user owns, translate the UID and GID to the local machine ids instead of the global ones.
    #[clap(short, long)]
    pub impersonate_uid: bool,
    /// Configure the log file for <raw>, <barebone>, <speed>, <compatibility>, <balanced> or <security>
    #[clap(long, default_value = "speed")]
    pub configured_for: ate::conf::ConfiguredFor,
    /// Format of the metadata in the log file as <bincode>, <json> or <mpack>
    #[clap(long, default_value = "bincode")]
    pub meta_format: ate::spec::SerializationFormat,
    /// Format of the data in the log file as <bincode>, <json> or <mpack>
    #[clap(long, default_value = "bincode")]
    pub data_format: ate::spec::SerializationFormat,
    /// Forces the compaction of the local redo-log before it streams in the latest values
    #[clap(long)]
    pub compact_now: bool,
    /// Mode that the compaction will run under (valid modes are 'never', 'modified', 'timer', 'factor', 'size', 'factor-or-timer', 'size-or-timer')
    #[clap(long, default_value = "factor-or-timer")]
    pub compact_mode: CompactMode,
    /// Time in seconds between compactions of the log file (default: 1 hour) - this argument is ignored if you select a compact_mode that has no timer
    #[clap(long, default_value = "3600")]
    pub compact_timer: u64,
    /// Factor growth in the log file which will trigger compaction - this argument is ignored if you select a compact_mode that has no growth trigger
    #[clap(long, default_value = "0.4")]
    pub compact_threshold_factor: f32,
    /// Size of growth in bytes in the log file which will trigger compaction (default: 100MB) - this argument is ignored if you select a compact_mode that has no growth trigger
    #[clap(long, default_value = "104857600")]
    pub compact_threshold_size: u64,
}