linux: add [--features distro] build flag

This commit is contained in:
hinto-janaiyo 2022-12-17 21:42:30 -05:00
parent 233ccd62ac
commit 3db1adce75
No known key found for this signature in database
GPG key ID: B1C5A64B80691E45
10 changed files with 104 additions and 33 deletions

4
Cargo.lock generated
View file

@ -3823,9 +3823,9 @@ dependencies = [
[[package]] [[package]]
name = "sysinfo" name = "sysinfo"
version = "0.27.0" version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d08ba83d6dde63d053e42d7230f0dc7f8d8efeb8d30d3681580d158156461ba" checksum = "ccb297c0afb439440834b4bcf02c5c9da8ec2e808e70f36b0d8e815ff403bd24"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"core-foundation-sys", "core-foundation-sys",

View file

@ -12,6 +12,10 @@ strip = "symbols"
codegen-units = 1 codegen-units = 1
lto = true lto = true
[features]
default = []
distro = []
[dependencies] [dependencies]
anyhow = "1.0.65" anyhow = "1.0.65"
arti-client = { version = "0.7.0", features = ["static"] } arti-client = { version = "0.7.0", features = ["static"] }

View file

@ -28,6 +28,7 @@ Gupax is a (Windows|macOS|Linux) GUI for mining [**Monero**](https://github.com/
* [Build](#Build) * [Build](#Build)
- [General Info](#General-Info) - [General Info](#General-Info)
- [Linux](#Linux) - [Linux](#Linux)
- [Building for a distribution](#building-for-a-distribution)
- [macOS](#macOS) - [macOS](#macOS)
- [Windows](#Windows) - [Windows](#Windows)
* [License](#License) * [License](#License)
@ -126,7 +127,7 @@ P2Pool Simple allows you to ping & connect to a [Community Monero Node](#communi
To start P2Pool, first input the Monero address you'd like to receive payouts from. You must use a primary Monero address to mine on P2Pool (starts with a 4). It is highly recommended to create a new wallet since addresses are public on P2Pool! To start P2Pool, first input the Monero address you'd like to receive payouts from. You must use a primary Monero address to mine on P2Pool (starts with a 4). It is highly recommended to create a new wallet since addresses are public on P2Pool!
**Warning: [There are negative privacy and security implications when using Monero node not in your control.](https://www.getmonero.org/resources/moneropedia/remote-node.html)** Select a community node that you trust, or better yet, run your own node. If you'd like to manually specify a node to connect to, see [Advanced.](#advanced) **Warning: [There are negative privacy/security implications when using a Monero node not in your control.](https://www.getmonero.org/resources/moneropedia/remote-node.html)** Select a community node that you trust, or better yet, run your own node. If you'd like to manually specify a node to connect to, see [Advanced.](#advanced)
--- ---
@ -141,17 +142,17 @@ Gupax will automatically launch XMRig with administrator privileges to activate
**macOS/Linux:** **macOS/Linux:**
Gupax will prompt for your `sudo` password to start XMRig with and do all the things above. Gupax will prompt for your `sudo` password to start XMRig with and do all the things above.
XMRig Simple will always mine to your own local P2Pool (`localhost:3333`), if you'd like to manually specify a pool to mine to, see [Advanced](#advanced). XMRig Simple will always mine to your own local P2Pool (`127.0.0.1:3333`), if you'd like to manually specify a pool to mine to, see [Advanced](#advanced).
## Advanced ## Advanced
### Verifying ### Verifying
It is recommended to verify the hash and PGP signature of the download before using Gupax. It is recommended to verify the hash and PGP signature of the download before using Gupax.
Download the [`SHA256SUM`](https://github.com/hinto-janaiyo/gupax/releases/latest) file, download and import my [`PGP key`](https://github.com/hinto-janaiyo/gupax/blob/main/pgp/hinto-janaiyo.asc), and verify: Download the [`SHA256SUMS`](https://github.com/hinto-janaiyo/gupax/releases/latest) file, download and import my [`PGP key`](https://github.com/hinto-janaiyo/gupax/blob/main/pgp/hinto-janaiyo.asc), and verify:
```bash ```bash
sha256sum -c SHA256SUM sha256sum -c SHA256SUMS
gpg --import hinto-janaiyo.asc gpg --import hinto-janaiyo.asc
gpg --verify SHA256SUM gpg --verify SHA256SUMS
``` ```
Q: How can I be sure the P2Pool/XMRig bundled with Gupax hasn't been tampered with? Q: How can I be sure the P2Pool/XMRig bundled with Gupax hasn't been tampered with?
@ -277,11 +278,11 @@ RUST_LOG=debug ./gupax
``` ```
In general: In general:
- `ERROR` means something has gone wrong and that something will likely break - `ERROR` means something has gone wrong and that something will probably break
- `WARN` means something has gone wrong, but things will likely be fine - `WARN` means something has gone wrong, but things will be fine
- `INFO` logs are general info about what Gupax (the GUI thread) is currently doing - `INFO` logs are general info about what Gupax (the GUI thread) is currently doing
- `DEBUG` logs are much more verbose and include what EVERY thread is doing (not just the main GUI thread) - `DEBUG` logs are much more verbose and include what EVERY thread is doing (not just the main GUI thread)
- `TRACE` logs are insanely verbose and shows the logs of the libraries Gupax uses (HTTP connections, GUI polling, etc) - `TRACE` logs are insanely verbose and shows very low-level logs of the libraries Gupax uses (HTTP connections, GUI polling, etc)
--- ---
@ -464,6 +465,12 @@ You need [`cargo`](https://www.rust-lang.org/learn/get-started), Rust's build to
The `--release` profile in Gupax is set to prefer code performance & small binary sizes over compilation speed (see [`Cargo.toml`](https://github.com/hinto-janaiyo/gupax/blob/main/Cargo.toml)). Gupax itself (with all dependencies already built) takes around 1m30s to build (vs 10s on a normal `--release`) with a Ryzen 5950x. The `--release` profile in Gupax is set to prefer code performance & small binary sizes over compilation speed (see [`Cargo.toml`](https://github.com/hinto-janaiyo/gupax/blob/main/Cargo.toml)). Gupax itself (with all dependencies already built) takes around 1m30s to build (vs 10s on a normal `--release`) with a Ryzen 5950x.
There are `20` unit tests throughout the codebase files, you should probably run:
```
cargo test
```
before attempting a full build.
--- ---
### Linux ### Linux
@ -474,6 +481,17 @@ After that, run:
cargo build --release cargo build --release
``` ```
### Building for a distribution
Gupax has a build flag for use as a package in a Linux distribution:
```
cargo build --release --features distro
```
This is the same as the `--release` profile, but with some changes:
| Change | Reason |
|--------------------------------------------|--------|
| Built-in `Update` feature is disabled | Updates should be handled by the native package manager
| Default `P2Pool/XMRig` path is `/usr/bin/` | `P2Pool/XMRig` exist in _[some](https://aur.archlinux.org)_ repositories, which means they'll be installed in `/usr/bin/`
--- ---
### macOS ### macOS
@ -515,12 +533,12 @@ The latest versions are downloaded using the GitHub API.
* P2Pool [`https://github.com/SChernykh/p2pool`](https://github.com/SChernykh/p2pool) * P2Pool [`https://github.com/SChernykh/p2pool`](https://github.com/SChernykh/p2pool)
* XMRig [`https://github.com/xmrig/xmrig`](https://github.com/xmrig/xmrig) * XMRig [`https://github.com/xmrig/xmrig`](https://github.com/xmrig/xmrig)
GitHub's API blocks request that do not have an HTTP `User-Agent` header. [For privacy, Gupax randomly uses a recent version of a `Wget/Curl` user-agent.](https://github.com/hinto-janaiyo/gupax/blob/2b80aa027728ddd193bac2e77caa5ddb4323f8fd/src/update.rs#L134) GitHub's API blocks request that do not have an HTTP `User-Agent` header. [Gupax uses a random recent version of a `Wget/Curl` user-agent.](https://github.com/hinto-janaiyo/gupax/blob/2b80aa027728ddd193bac2e77caa5ddb4323f8fd/src/update.rs#L134)
--- ---
### Can I quit mid-update? ### Can I quit mid-update?
If you started an update, you should let it finish. If the update has been stuck for a *long* time, it may be worth quitting Gupax. The worst that can happen is that your `Gupax/P2Pool/XMRig` binaries may be moved/deleted. Those can be easily redownloaded. Your actual `Gupax` user data (settings, custom nodes, pools, etc) is never touched. If you started an update, you should let it finish. If the update has been stuck for a *long* time, quitting Gupax is probably okay. The worst that can happen is that your `Gupax/P2Pool/XMRig` binaries may be moved/deleted. Those can be easily redownloaded. Your actual `Gupax` user data (settings, custom nodes, pools, etc) is never touched.
Although Gupax uses a temporary folder (`gupax_update_[A-Za-z0-9]`) to store temporary downloaded files, there aren't measures in place to revert an upgrade once the file swapping has actually started. If you quit Gupax anytime before the `Upgrading packages` phase (after metadata, download, extraction), you will technically be safe but this is not recommended as it is risky, especially since these updates can be very fast. Although Gupax uses a temporary folder (`gupax_update_[A-Za-z0-9]`) to store temporary downloaded files, there aren't measures in place to revert an upgrade once the file swapping has actually started. If you quit Gupax anytime before the `Upgrading packages` phase (after metadata, download, extraction), you will technically be safe but this is not recommended as it is risky, especially since these updates can be very fast.
@ -536,7 +554,7 @@ Although Gupax uses a temporary folder (`gupax_update_[A-Za-z0-9]`) to store tem
### How much memory does Gupax use? ### How much memory does Gupax use?
Gupax itself uses around 100-300 megabytes of memory. Gupax itself uses around 100-300 megabytes of memory.
Gupax also holds up to [500,000 bytes](https://github.com/hinto-janaiyo/gupax/blob/2b80aa027728ddd193bac2e77caa5ddb4323f8fd/src/helper.rs#L63) of log data from `P2Pool/XMRig` to display in the GUI terminals. These logs are reset once over capacity which takes around 1-2 hours. Gupax also holds up to [500,000 bytes](https://github.com/hinto-janaiyo/gupax/blob/2b80aa027728ddd193bac2e77caa5ddb4323f8fd/src/helper.rs#L63) of log data from `P2Pool/XMRig` to display in the GUI terminals. These logs are reset once over capacity which takes around 1-4 hours.
Memory usage should *never* be above 500~ megabytes. If you see Gupax using more than this, please send a bug report. Memory usage should *never* be above 500~ megabytes. If you see Gupax using more than this, please send a bug report.

View file

@ -105,7 +105,7 @@ Exceptions (there are always exceptions...):
- P2Pool hashes are in UPPERCASE - P2Pool hashes are in UPPERCASE
## Sudo ## Sudo
Unlike Windows, Unix (macOS/Linux) have a userland program that handles all the dirty details of privilege escalation: `sudo`. Unlike Windows, Unix (macOS/Linux) has a userland program that handles all the dirty details of privilege escalation: `sudo`.
`sudo` is used in Gupax to execute XMRig, to enable MSR mods and hugepages. After every use of `sudo`, the memory holding the `String` buffer containing the password is wiped with 0's using [`zeroize`](https://docs.rs/zeroize/) to make sure the compiler doesn't optimize away the wipe. Although memory *should* be safe, this prevents passive accidents (core-dumps revealing plain-text password) and active attacks (attackers accessing live process memory) from happening. `sudo` is used in Gupax to execute XMRig, to enable MSR mods and hugepages. After every use of `sudo`, the memory holding the `String` buffer containing the password is wiped with 0's using [`zeroize`](https://docs.rs/zeroize/) to make sure the compiler doesn't optimize away the wipe. Although memory *should* be safe, this prevents passive accidents (core-dumps revealing plain-text password) and active attacks (attackers accessing live process memory) from happening.

View file

@ -15,11 +15,20 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
pub const GUPAX_VERSION: &str = concat!("v", env!("CARGO_PKG_VERSION")); pub const GUPAX_VERSION: &str = concat!("v", env!("CARGO_PKG_VERSION")); // e.g: Gupax v1.0.0
pub const P2POOL_VERSION: &str = "v2.5"; pub const P2POOL_VERSION: &str = "v2.5";
pub const XMRIG_VERSION: &str = "v6.18.0"; pub const XMRIG_VERSION: &str = "v6.18.0";
pub const COMMIT: &str = include_str!("../.git/refs/heads/main"); pub const COMMIT: &str = include_str!("../.git/refs/heads/main");
pub const GUPAX_VERSION_UNDERSCORE: &str = concat!("Gupax_v", env!("CARGO_PKG_VERSION")); // e.g: Gupax_v1_0_0
// Would have been [Gupax_v1.0.0] but P2Pool truncates everything after [.]
pub const GUPAX_VERSION_UNDERSCORE: &str = concat!(
"Gupax_v",
env!("CARGO_PKG_VERSION_MAJOR"),
"_",
env!("CARGO_PKG_VERSION_MINOR"),
"_",
env!("CARGO_PKG_VERSION_PATCH"),
);
// App frame resolution, [4:3] aspect ratio, [1.33:1] // App frame resolution, [4:3] aspect ratio, [1.33:1]
pub const APP_MIN_WIDTH: f32 = 640.0; pub const APP_MIN_WIDTH: f32 = 640.0;
@ -30,6 +39,11 @@ pub const APP_MAX_HEIGHT: f32 = 1920.0;
pub const APP_DEFAULT_WIDTH: f32 = 1280.0; pub const APP_DEFAULT_WIDTH: f32 = 1280.0;
pub const APP_DEFAULT_HEIGHT: f32 = 960.0; pub const APP_DEFAULT_HEIGHT: f32 = 960.0;
// Constants specific for Linux distro packaging of Gupax
#[cfg(feature = "distro")]
pub const DISTRO_NO_UPDATE: &str =
r#"This [Gupax] was compiled for use as a Linux distro package. Built-in updates are disabled. The below settings [Update-via-Tor] & [Auto-Update] will not do anything. Please use your package manager to update [Gupax/P2Pool/XMRig]."#;
// Use macOS shaped icon for macOS // Use macOS shaped icon for macOS
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub const BYTES_ICON: &[u8] = include_bytes!("../images/icons/icon@2x.png"); pub const BYTES_ICON: &[u8] = include_bytes!("../images/icons/icon@2x.png");

View file

@ -53,21 +53,33 @@ use log::*;
const ERROR: &str = "Disk error"; const ERROR: &str = "Disk error";
const PATH_ERROR: &str = "PATH for state directory could not be not found"; const PATH_ERROR: &str = "PATH for state directory could not be not found";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
const DIRECTORY: &'static str = r#"Gupax\"#; const DIRECTORY: &str = r#"Gupax\"#;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
const DIRECTORY: &'static str = "Gupax/"; const DIRECTORY: &str = "Gupax/";
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
const DIRECTORY: &str = "gupax/"; const DIRECTORY: &str = "gupax/";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub const DEFAULT_P2POOL_PATH: &'static str = r"P2Pool\p2pool.exe"; pub const DEFAULT_P2POOL_PATH: &str = r"P2Pool\p2pool.exe";
#[cfg(target_family = "unix")] #[cfg(target_os = "macos")]
pub const DEFAULT_P2POOL_PATH: &str = "p2pool/p2pool"; pub const DEFAULT_P2POOL_PATH: &str = "p2pool/p2pool";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub const DEFAULT_XMRIG_PATH: &'static str = r"XMRig\xmrig.exe"; pub const DEFAULT_XMRIG_PATH: &str = r"XMRig\xmrig.exe";
#[cfg(target_family = "unix")] #[cfg(target_os = "macos")]
pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig"; pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
// Default to [/usr/bin/] for Linux distro builds.
#[cfg(target_os = "linux")]
#[cfg(not(feature = "distro"))]
pub const DEFAULT_P2POOL_PATH: &str = "p2pool/p2pool";
#[cfg(target_os = "linux")]
#[cfg(not(feature = "distro"))]
pub const DEFAULT_XMRIG_PATH: &str = "xmrig/xmrig";
#[cfg(feature = "distro")]
pub const DEFAULT_P2POOL_PATH: &str = "/usr/bin/p2pool";
#[cfg(feature = "distro")]
pub const DEFAULT_XMRIG_PATH: &str = "/usr/bin/xmrig";
//---------------------------------------------------------------------------------------------------- General functions for all [File]'s //---------------------------------------------------------------------------------------------------- General functions for all [File]'s
// get_file_path() | Return absolute path to OS data path + filename // get_file_path() | Return absolute path to OS data path + filename
// read_to_string() | Convert the file at a given path into a [String] // read_to_string() | Convert the file at a given path into a [String]

View file

@ -93,7 +93,15 @@ impl Gupax {
let width = width - SPACE; let width = width - SPACE;
let updating = *update.lock().unwrap().updating.lock().unwrap(); let updating = *update.lock().unwrap().updating.lock().unwrap();
ui.vertical(|ui| { ui.vertical(|ui| {
// If [Gupax] is being built for a Linux distro,
// disable built-in updating completely.
#[cfg(feature = "distro")]
ui.set_enabled(false);
#[cfg(feature = "distro")]
ui.add_sized([width, height], Button::new("Updates are disabled")).on_disabled_hover_text(DISTRO_NO_UPDATE);
#[cfg(not(feature = "distro"))]
ui.set_enabled(!updating); ui.set_enabled(!updating);
#[cfg(not(feature = "distro"))]
if ui.add_sized([width, height], Button::new("Check for updates")).on_hover_text(GUPAX_UPDATE).clicked() { if ui.add_sized([width, height], Button::new("Check for updates")).on_hover_text(GUPAX_UPDATE).clicked() {
Update::spawn_thread(og, self, state_path, update, error_state, restart); Update::spawn_thread(og, self, state_path, update, error_state, restart);
} }

View file

@ -1724,6 +1724,18 @@ impl Hashrate {
//---------------------------------------------------------------------------------------------------- TESTS //---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)] #[cfg(test)]
mod test { mod test {
#[test]
fn reset_gui_output() {
let max = crate::helper::GUI_OUTPUT_LEEWAY;
let mut string = String::with_capacity(max);
for _ in 0..=max {
string.push('0');
}
crate::Helper::check_reset_gui_output(&mut string, crate::ProcessName::P2pool);
// Some text gets added, so just check for less than 500 bytes.
assert!(string.len() < 500);
}
#[test] #[test]
fn human_number() { fn human_number() {
use crate::HumanNumber; use crate::HumanNumber;

View file

@ -713,6 +713,7 @@ fn init_auto(app: &mut App) {
} }
// [Auto-Update] // [Auto-Update]
#[cfg(not(feature = "distro"))]
if app.state.gupax.auto_update { if app.state.gupax.auto_update {
Update::spawn_thread(&app.og, &app.state.gupax, &app.state_path, &app.update, &mut app.error_state, &app.restart); Update::spawn_thread(&app.og, &app.state.gupax, &app.state_path, &app.update, &mut app.error_state, &app.restart);
} else { } else {
@ -1563,12 +1564,6 @@ impl eframe::App for App {
//---------------------------------------------------------------------------------------------------- TESTS //---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)] #[cfg(test)]
mod test { mod test {
#[test]
fn build_app() {
let mut app = crate::App::new(std::time::Instant::now());
crate::init_auto(&mut app);
}
#[test] #[test]
fn build_regex() { fn build_regex() {
use regex::Regex; use regex::Regex;
@ -1587,9 +1582,4 @@ mod test {
assert!(!Regex::is_match(&r.port, "0")); assert!(!Regex::is_match(&r.port, "0"));
assert!(!Regex::is_match(&r.port, "65536")); assert!(!Regex::is_match(&r.port, "65536"));
} }
#[test]
fn build_images() {
crate::Images::new();
}
} }

View file

@ -285,6 +285,14 @@ impl Update {
// an update needs to happen (Gupax tab, auto-update), the // an update needs to happen (Gupax tab, auto-update), the
// code only needs to be edited once, here. // code only needs to be edited once, here.
pub fn spawn_thread(og: &Arc<Mutex<State>>, gupax: &crate::disk::Gupax, state_path: &Path, update: &Arc<Mutex<Update>>, error_state: &mut ErrorState, restart: &Arc<Mutex<Restart>>) { pub fn spawn_thread(og: &Arc<Mutex<State>>, gupax: &crate::disk::Gupax, state_path: &Path, update: &Arc<Mutex<Update>>, error_state: &mut ErrorState, restart: &Arc<Mutex<Restart>>) {
// We really shouldn't be in the function for
// the Linux distro Gupax (UI gets disabled)
// but if somehow get in here, just return.
#[cfg(feature = "distro")]
error!("Update | This is the [Linux distro] version of Gupax, updates are disabled");
#[cfg(feature = "distro")]
return;
// Check P2Pool path for safety // Check P2Pool path for safety
// Attempt relative to absolute path // Attempt relative to absolute path
let p2pool_path = match into_absolute_path(gupax.p2pool_path.clone()) { let p2pool_path = match into_absolute_path(gupax.p2pool_path.clone()) {
@ -383,6 +391,11 @@ impl Update {
// 5. extract, upgrade // 5. extract, upgrade
#[tokio::main] #[tokio::main]
pub async fn start(update: Arc<Mutex<Self>>, _og: Arc<Mutex<State>>, state_ver: Arc<Mutex<Version>>, restart: Arc<Mutex<Restart>>) -> Result<(), anyhow::Error> { pub async fn start(update: Arc<Mutex<Self>>, _og: Arc<Mutex<State>>, state_ver: Arc<Mutex<Version>>, restart: Arc<Mutex<Restart>>) -> Result<(), anyhow::Error> {
#[cfg(feature = "distro")]
error!("Update | This is the [Linux distro] version of Gupax, updates are disabled");
#[cfg(feature = "distro")]
return Err(anyhow!("This is the [Linux distro] version of Gupax, updates are disabled"));
//---------------------------------------------------------------------------------------------------- Init //---------------------------------------------------------------------------------------------------- Init
*update.lock().unwrap().updating.lock().unwrap() = true; *update.lock().unwrap().updating.lock().unwrap() = true;
// Set timer // Set timer