Skip to content

Commit

Permalink
[wicket] move cli-related code to its own directory (#4429)
Browse files Browse the repository at this point in the history
This code lives next to the "ui" and "state" directories.
  • Loading branch information
sunshowers authored Nov 6, 2023
1 parent cede9b3 commit 5d146dd
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 41 deletions.
55 changes: 55 additions & 0 deletions wicket/src/cli/command.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

//! Code that manages command dispatch from a shell for wicket.
use std::net::SocketAddrV6;

use anyhow::{Context, Result};
use clap::Parser;

use super::{
preflight::PreflightArgs, rack_setup::SetupArgs, upload::UploadArgs,
};

pub fn exec(
log: slog::Logger,
args: &str,
wicketd_addr: SocketAddrV6,
) -> Result<()> {
// The argument is in a quoted form, so split it using Unix shell semantics.
let args = shell_words::split(&args).with_context(|| {
format!("could not parse shell arguments from input {args}")
})?;

// parse_from uses the the first argument as the command name. Insert "wicket" as
// the command name.
let args = ShellCommand::parse_from(
std::iter::once("wicket".to_owned()).chain(args),
);
match args {
ShellCommand::UploadRepo(args) => args.exec(log, wicketd_addr),
ShellCommand::Setup(args) => args.exec(log, wicketd_addr),
ShellCommand::Preflight(args) => args.exec(log, wicketd_addr),
}
}

/// Arguments passed to wicket.
///
/// Wicket is designed to be used as a captive shell, set up via sshd
/// ForceCommand. If no arguments are specified, wicket behaves like a TUI.
/// However, if arguments are specified via SSH_ORIGINAL_COMMAND, wicketd
/// accepts an upload command.
#[derive(Debug, Parser)]
enum ShellCommand {
/// Upload a TUF repository to wicketd.
#[command(visible_alias = "upload")]
UploadRepo(UploadArgs),
/// Interact with rack setup configuration.
#[command(subcommand)]
Setup(SetupArgs),
/// Run checks prior to setting up the rack.
#[command(subcommand)]
Preflight(PreflightArgs),
}
18 changes: 18 additions & 0 deletions wicket/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

// Copyright 2023 Oxide Computer Company

//! Command-line interface to wicket.
//!
//! By default, the main interface to wicket is via a TUI. However, some
//! commands and use cases must be done via the CLI, and this module contains
//! support for that.
mod command;
mod preflight;
mod rack_setup;
mod upload;

pub use command::exec;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
40 changes: 2 additions & 38 deletions wicket/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,19 @@ use std::net::{Ipv6Addr, SocketAddrV6};

use anyhow::{bail, Context, Result};
use camino::{Utf8Path, Utf8PathBuf};
use clap::Parser;
use omicron_common::{address::WICKETD_PORT, FileKv};
use slog::Drain;

use crate::{
preflight::PreflightArgs, rack_setup::SetupArgs, upload::UploadArgs, Runner,
};
use crate::Runner;

pub fn exec() -> Result<()> {
let wicketd_addr =
SocketAddrV6::new(Ipv6Addr::LOCALHOST, WICKETD_PORT, 0, 0);

// SSH_ORIGINAL_COMMAND contains additional arguments, if any.
if let Ok(ssh_args) = std::env::var("SSH_ORIGINAL_COMMAND") {
// The argument is in a quoted form, so split it using Unix shell semantics.
let args = shell_words::split(&ssh_args).with_context(|| {
format!("could not parse shell arguments from input {ssh_args}")
})?;

let log = setup_log(&log_path()?, WithStderr::Yes)?;
// parse_from uses the the first argument as the command name. Insert "wicket" as
// the command name.
let args = ShellCommand::parse_from(
std::iter::once("wicket".to_owned()).chain(args),
);
match args {
ShellCommand::UploadRepo(args) => args.exec(log, wicketd_addr),
ShellCommand::Setup(args) => args.exec(log, wicketd_addr),
ShellCommand::Preflight(args) => args.exec(log, wicketd_addr),
}
crate::cli::exec(log, &ssh_args, wicketd_addr)
} else {
// Do not expose log messages via standard error since they'll show up
// on top of the TUI.
Expand All @@ -46,25 +29,6 @@ pub fn exec() -> Result<()> {
}
}

/// Arguments passed to wicket.
///
/// Wicket is designed to be used as a captive shell, set up via sshd
/// ForceCommand. If no arguments are specified, wicket behaves like a TUI.
/// However, if arguments are specified via SSH_ORIGINAL_COMMAND, wicketd
/// accepts an upload command.
#[derive(Debug, Parser)]
enum ShellCommand {
/// Upload a TUF repository to wicketd.
#[command(visible_alias = "upload")]
UploadRepo(UploadArgs),
/// Interact with rack setup configuration.
#[command(subcommand)]
Setup(SetupArgs),
/// Run checks prior to setting up the rack.
#[command(subcommand)]
Preflight(PreflightArgs),
}

fn setup_log(
path: &Utf8Path,
with_stderr: WithStderr,
Expand Down
4 changes: 1 addition & 3 deletions wicket/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
use std::time::Duration;

mod cli;
mod dispatch;
mod events;
mod keymap;
mod preflight;
mod rack_setup;
mod runner;
mod state;
mod ui;
mod upload;
mod wicketd;

pub const TICK_INTERVAL: Duration = Duration::from_millis(30);
Expand Down

0 comments on commit 5d146dd

Please sign in to comment.