Skip to content
This repository has been archived by the owner on Jan 25, 2024. It is now read-only.

feat: provide start command #2

Merged
merged 3 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 17 additions & 1 deletion .github/workflows/merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on: pull_request
env:
RUST_BACKTRACE: 1
RUSTFLAGS: "-D warnings"
WINSW_URL: https://github.com/winsw/winsw/releases/download/v3.0.0-alpha.11/WinSW-x64.exe

jobs:
build:
Expand Down Expand Up @@ -58,7 +59,8 @@ jobs:
with:
toolchain: nightly
override: true

- name: install rustfmt for nightly toolchain
run: rustup component add rustfmt --toolchain nightly-x86_64-unknown-linux-gnu
- name: Run cargo-udeps
uses: aig787/cargo-udeps-action@v1
with:
Expand Down Expand Up @@ -116,6 +118,20 @@ jobs:
override: true

- shell: bash
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
run: |
${{ matrix.elevated }} rustup default stable
${{ matrix.elevated }} cargo test --release --test e2e -- --nocapture

# A simple test seemed to confirm that the Powershell step runs as admin by default.
- name: run integration test in powershell
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
curl -L -o WinSW.exe $env:WINSW_URL

New-Item -ItemType Directory -Force -Path "$env:GITHUB_WORKSPACE\bin"
Move-Item -Path WinSW.exe -Destination "$env:GITHUB_WORKSPACE\bin"
$env:PATH += ";$env:GITHUB_WORKSPACE\bin"

cargo test --release --test e2e -- --nocapture
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Cargo.lock
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb


# Added by cargo

/target

/.vagrant
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@ name="safenode-manager"
clap = { version = "4.4.6", features = ["derive", "env"]}
color-eyre = "~0.6"
indicatif = { version = "0.17.5", features = ["tokio"] }
libp2p-identity = { version="0.2.7", features = ["rand"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
service-manager = "0.4.0"
service-manager = "0.5.1"
sn_node_rpc_client = "0.1.43"
sn-releases = "0.1.1"
sysinfo = "0.29.10"
tokio = { version = "1.26", features = ["full"] }
uuid = { version = "1.5.0", features = ["v4"] }

[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies]
nix = { version = "0.27.1", features = ["fs", "user"] }
users = "0.11"

[dev-dependencies]
assert_cmd = "2.0.12"
assert_fs = "1.0.13"
assert_matches = "1.5.0"
async-trait = "0.1"
mockall = "0.11.3"
predicates = "2.0"
56 changes: 56 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Vagrant.configure("2") do |config|
config.vm.box = "generic/ubuntu2204"
config.vm.provider :libvirt do |libvirt|
libvirt.memory = 4096
end
config.vm.synced_folder ".",
"/vagrant",
type: "9p",
accessmode: "mapped",
mount_options: ['rw', 'trans=virtio', 'version=9p2000.L']
config.vm.provision "file", source: "~/.ssh/id_rsa", destination: "/home/vagrant/.ssh/id_rsa"
config.vm.provision "shell", inline: "apt-get update -y"
config.vm.provision "shell", inline: "apt-get install -y build-essential"
config.vm.provision "shell", privileged: false, inline: <<-SHELL
curl -L -O https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init
chmod +x rustup-init
./rustup-init --default-toolchain stable --no-modify-path -y
echo "source ~/.cargo/env" >> ~/.bashrc
SHELL
config.vm.provision "shell", privileged: false, inline: <<-SHELL
mkdir -p ~/.vim/tmp/ ~/.vim/backup
cat <<'EOF' > ~/.vimrc
set nocompatible

let mapleader=" "
syntax on

set background=dark
set backspace=indent,eol,start
set backupdir=~/.vim/tmp//
set directory=~/.vim/backup
set expandtab
set foldlevel=1
set foldmethod=indent
set foldnestmax=10
set hlsearch
set ignorecase
set incsearch
set laststatus=2
set nobackup
set nofoldenable
set nowrap
set number relativenumber
set ruler
set shiftwidth=4
set smartindent
set showcmd
set shortmess+=A
set tabstop=4
set viminfo+=!

nnoremap j gj
nnoremap k gk
EOF
SHELL
end
99 changes: 99 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use color_eyre::Result;
use std::path::{Path, PathBuf};

#[cfg(unix)]
pub fn get_node_manager_path() -> Result<PathBuf> {
// This needs to be a system-wide location rather than a user directory because the `install`
// command will run as the root user. However, it should be readable by non-root users, because
// other commands, e.g., requesting status, shouldn't require root.
use std::os::unix::fs::PermissionsExt;

let path = Path::new("/var/safenode-manager/");
if !path.exists() {
std::fs::create_dir_all(path)?;
let mut perm = std::fs::metadata(path)?.permissions();
perm.set_mode(0o755); // set permissions to rwxr-xr-x
std::fs::set_permissions(path, perm)?;
}

Ok(path.to_path_buf())
}

#[cfg(unix)]
pub fn get_node_registry_path() -> Result<PathBuf> {
let path = get_node_manager_path()?;
Ok(path.join("node_registry.json"))
}

#[cfg(unix)]
pub fn get_service_data_dir_path(custom_path: Option<PathBuf>, owner: &str) -> Result<PathBuf> {
let path = match custom_path {
Some(p) => p,
None => PathBuf::from("/var/safenode-manager/services"),
};
create_owned_dir(path.clone(), owner)?;
Ok(path)
}

#[cfg(windows)]
pub fn get_service_data_dir_path(custom_path: Option<PathBuf>, _owner: &str) -> Result<PathBuf> {
let path = match custom_path {
Some(p) => p,
None => PathBuf::from("C:\\ProgramData\\safenode\\data"),
};
std::fs::create_dir_all(&path)?;
Ok(path)
}

#[cfg(unix)]
pub fn get_service_log_dir_path(custom_path: Option<PathBuf>, owner: &str) -> Result<PathBuf> {
let path = match custom_path {
Some(p) => p,
None => PathBuf::from("/var/log/safenode"),
};
create_owned_dir(path.clone(), owner)?;
Ok(path)
}

#[cfg(windows)]
pub fn get_service_log_dir_path(custom_path: Option<PathBuf>, _owner: &str) -> Result<PathBuf> {
let path = match custom_path {
Some(p) => p,
None => PathBuf::from("C:\\ProgramData\\safenode\\logs"),
};
std::fs::create_dir_all(&path)?;
Ok(path)
}

#[cfg(unix)]
pub fn create_owned_dir(path: PathBuf, owner: &str) -> Result<()> {
use color_eyre::eyre::eyre;
use nix::unistd::{chown, Gid, Uid};
use std::os::unix::fs::PermissionsExt;
use users::get_user_by_name;

std::fs::create_dir_all(&path)?;
let permissions = std::fs::Permissions::from_mode(0o755);
std::fs::set_permissions(&path, permissions)?;

let user = get_user_by_name(owner).ok_or_else(|| eyre!("User '{owner}' does not exist"))?;
let uid = Uid::from_raw(user.uid());
let gid = Gid::from_raw(user.primary_group_id());
chown(&path, Some(uid), Some(gid))?;
Ok(())
}

#[cfg(windows)]
pub fn create_owned_dir(path: PathBuf, _owner: &str) -> Result<()> {
std::fs::create_dir_all(&path)?;
Ok(())
}

#[cfg(windows)]
pub fn get_node_registry_path() -> Result<PathBuf> {
let path = Path::new("C:\\ProgramData\\safenode-manager");
if !path.exists() {
std::fs::create_dir_all(&path)?;
}
Ok(path.join("node_registry.json"))
}