Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sidecar + gossip can listen to a custom ip:port #499

Merged
merged 2 commits into from
May 9, 2016
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions components/sup/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion components/sup/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ iron = "*"
router = "*"
time = "*"
temp_utp = "*"
rpassword = "*"
rand = "*"
threadpool = "*"
urlencoded = "*"
Expand Down
42 changes: 25 additions & 17 deletions components/sup/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,11 @@ pub struct Config {
archive: String,
bind: Vec<String>,
key: String,
password: Option<String>,
email: Option<String>,
expire_days: Option<u16>,
gossip_listen: String,
gossip_listen_ip: String,
gossip_listen_port: u16,
sidecar_listen: String,
userkey: Option<String>,
servicekey: Option<String>,
infile: Option<String>,
Expand Down Expand Up @@ -150,17 +151,6 @@ impl Config {
&self.key
}

/// Set the password
pub fn set_password(&mut self, password: String) -> &mut Config {
self.password = Some(password);
self
}

/// Return the password
pub fn password(&self) -> &Option<String> {
&self.password
}

/// Set the email address
pub fn set_email(&mut self, email: String) -> &mut Config {
self.email = Some(email);
Expand Down Expand Up @@ -281,12 +271,30 @@ impl Config {
&self.topology
}

pub fn gossip_listen(&self) -> &str {
&self.gossip_listen
pub fn gossip_listen_ip(&self) -> &str {
&self.gossip_listen_ip
}

pub fn set_gossip_listen_ip(&mut self, ip: String) -> &mut Config {
self.gossip_listen_ip = ip;
self
}

pub fn gossip_listen_port(&self) -> u16 {
self.gossip_listen_port
}

pub fn set_gossip_listen_port(&mut self, port: u16) -> &mut Config {
self.gossip_listen_port = port;
self
}

pub fn sidecar_listen(&self) -> &str {
&self.sidecar_listen
}

pub fn set_gossip_listen(&mut self, gl: String) -> &mut Config {
self.gossip_listen = gl;
pub fn set_sidecar_listen(&mut self, sl: String) -> &mut Config {
self.sidecar_listen = sl;
self
}

Expand Down
12 changes: 7 additions & 5 deletions components/sup/src/gossip/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ pub struct Server {
impl Server {
/// Creates a new Server. Creates our own entry in the census and membership lists, and writes
/// a rumor that this server is alive.
pub fn new(listen: String,
pub fn new(listen_ip: String,
listen_port: u16,
permanent: bool,
ring_key: Option<SymKey>,
service: String,
Expand All @@ -79,12 +80,13 @@ impl Server {
exposes: Option<Vec<String>>,
port: Option<String>)
-> Server {
let hostname = util::sys::hostname().unwrap_or(String::from("unknown"));
let ip = util::sys::ip().unwrap_or(String::from("127.0.0.1"));

let peer_listen = format!("{}:{}", ip, GOSSIP_DEFAULT_PORT);
let hostname = util::sys::hostname().unwrap_or(String::from("unknown"));
let listen = format!("{}:{}", listen_ip, listen_port);
let peer_listen = listen.clone();
let peer_listen2 = peer_listen.clone();
let member = Member::new(hostname, ip, peer_listen2, permanent);

let member = Member::new(hostname, listen_ip, peer_listen2, permanent);

let service_group = format!("{}.{}", service, group);
let mut ce = CensusEntry::new(service.clone(), group.clone(), member.id.clone());
Expand Down
1 change: 0 additions & 1 deletion components/sup/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ extern crate time;
extern crate wonder;
extern crate uuid;
extern crate utp;
extern crate rpassword;
extern crate rand;
extern crate threadpool;
extern crate urlencoded;
Expand Down
30 changes: 23 additions & 7 deletions components/sup/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ use sup::config::{Command, Config, UpdateStrategy};
use sup::error::{Error, Result, SupError};
use sup::command::*;
use sup::topology::Topology;
use sup::util::parse_ip_port_with_defaults;
use sup::util::sys::ip;

/// Our output key
static LOGKEY: &'static str = "MN";
Expand All @@ -44,7 +46,9 @@ const VERSION: &'static str = include_str!(concat!(env!("OUT_DIR"), "/VERSION"))

/// CLI defaults
static DEFAULT_GROUP: &'static str = "default";
static DEFAULT_GOSSIP_LISTEN: &'static str = "0.0.0.0:9634";
static DEFAULT_SIDECAR_LISTEN_IP_PORT: &'static str = "0.0.0.0:9631";

const DEFAULT_GOSSIP_LISTEN_PORT: u16 = 9634;

static RING_ENVVAR: &'static str = "HAB_RING";
static RING_KEY_ENVVAR: &'static str = "HAB_RING_KEY";
Expand All @@ -68,9 +72,6 @@ fn config_from_args(args: &ArgMatches, subcommand: &str, sub_args: &ArgMatches)
if let Some(key) = sub_args.value_of("key") {
config.set_key(key.to_string());
}
if let Some(password) = sub_args.value_of("password") {
config.set_password(password.to_string());
}
if let Some(email) = sub_args.value_of("email") {
config.set_email(email.to_string());
}
Expand Down Expand Up @@ -119,8 +120,19 @@ fn config_from_args(args: &ArgMatches, subcommand: &str, sub_args: &ArgMatches)
.to_string_lossy()
.as_ref())
.to_string());
config.set_gossip_listen(sub_args.value_of("listen-peer")
.unwrap_or(DEFAULT_GOSSIP_LISTEN)

let default_gossip_ip = try!(ip());
let (gossip_ip, gossip_port) = try!(parse_ip_port_with_defaults(
sub_args.value_of("listen-peer"),
&default_gossip_ip,
DEFAULT_GOSSIP_LISTEN_PORT));

debug!("Gossip IP = {}", &gossip_ip);
debug!("Gossip Port = {}", &gossip_port);
config.set_gossip_listen_ip(gossip_ip);
config.set_gossip_listen_port(gossip_port);
config.set_sidecar_listen(sub_args.value_of("listen-sidecar")
.unwrap_or(DEFAULT_SIDECAR_LISTEN_IP_PORT)
.to_string());
let gossip_peers = match sub_args.values_of("peer") {
Some(gp) => gp.map(|s| s.to_string()).collect(),
Expand Down Expand Up @@ -246,7 +258,11 @@ fn main() {
.arg(Arg::with_name("listen-peer")
.long("listen-peer")
.value_name("ip:port")
.help("The listen address [default: 0.0.0.0:9634]"))
.help("The listen address [default: ip_with_default_route:9634]"))
.arg(Arg::with_name("listen-sidecar")
.long("listen-sidecar")
.value_name("ip:port")
.help("The sidecar listen address [default: 0.0.0.0:9631]"))
.arg(Arg::with_name("permanent-peer")
.short("I")
.long("permanent-peer")
Expand Down
17 changes: 11 additions & 6 deletions components/sup/src/sidecar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,21 @@ use census::{CensusList, CensusEntry, CensusEntryId, Census};
use election::{Election, ElectionList};
use supervisor::Supervisor;

static LOGKEY: &'static str = "SC";
static LOGKEY: &'static str = "SI";
const GET_HEALTH: &'static str = "/health";
const GET_CONFIG: &'static str = "/config";
const GET_STATUS: &'static str = "/status";
const GET_GOSSIP: &'static str = "/gossip";
const GET_CENSUS: &'static str = "/census";
const GET_ELECTION: &'static str = "/election";
const LISTEN_ADDR: &'static str = "0.0.0.0:9631";

pub type SidecarActor = wonder::actor::Actor<SidecarMessage>;

pub struct Sidecar;

pub struct SidecarState {
/// The IP:Port where the sidecar listens
pub listen: String,
/// The package this sidecar is helping out
pub package: Arc<RwLock<Package>>,
/// The configuration of the supervised service
Expand All @@ -70,7 +71,8 @@ pub enum SidecarMessage {
}

impl SidecarState {
pub fn new(package: Arc<RwLock<Package>>,
pub fn new(listen: String,
package: Arc<RwLock<Package>>,
config: Arc<RwLock<ServiceConfig>>,
member_list: Arc<RwLock<MemberList>>,
rumor_list: Arc<RwLock<RumorList>>,
Expand All @@ -81,6 +83,7 @@ impl SidecarState {
gossip_file_list: Arc<RwLock<GossipFileList>>)
-> Self {
SidecarState {
listen: listen,
package: package,
config: config,
member_list: member_list,
Expand All @@ -96,7 +99,8 @@ impl SidecarState {

impl Sidecar {
/// Start the sidecar.
pub fn start(package: Arc<RwLock<Package>>,
pub fn start(listen: String,
package: Arc<RwLock<Package>>,
config: Arc<RwLock<ServiceConfig>>,
member_list: Arc<RwLock<MemberList>>,
rumor_list: Arc<RwLock<RumorList>>,
Expand All @@ -106,7 +110,8 @@ impl Sidecar {
supervisor: Arc<RwLock<Supervisor>>,
gossip_file_list: Arc<RwLock<GossipFileList>>)
-> SidecarActor {
let state = SidecarState::new(package,
let state = SidecarState::new(listen,
package,
config,
member_list,
rumor_list,
Expand Down Expand Up @@ -164,7 +169,7 @@ impl GenServer for Sidecar {
let el = state.election_list.clone();
router.get(GET_ELECTION, move |r: &mut Request| election(&el, r));

match Iron::new(router).http(LISTEN_ADDR) {
match Iron::new(router).http(state.listen.as_str()) {
Ok(_) => HandleResult::NoReply(None),
Err(_) => {
HandleResult::Stop(StopReason::Fatal("couldn't start router".to_string()), None)
Expand Down
6 changes: 4 additions & 2 deletions components/sup/src/topology/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ impl<'a> Worker<'a> {
None => None,
};

let gossip_server = gossip::server::Server::new(String::from(config.gossip_listen()),
let gossip_server = gossip::server::Server::new(String::from(config.gossip_listen_ip()),
config.gossip_listen_port(),
config.gossip_permanent(),
ring_key,
package_name.clone(),
Expand Down Expand Up @@ -195,7 +196,8 @@ impl<'a> Worker<'a> {
member_list: gossip_server.member_list.clone(),
gossip_server: gossip_server,
service_config: service_config_lock,
sidecar_actor: sidecar::Sidecar::start(pkg_lock_1,
sidecar_actor: sidecar::Sidecar::start(config.sidecar_listen().to_string(),
pkg_lock_1,
service_config_lock_1,
sidecar_ml,
sidecar_rl,
Expand Down
60 changes: 60 additions & 0 deletions components/sup/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,72 @@ pub mod path;
pub mod sys;
pub mod signals;

use std::net::Ipv4Addr;
use std::net::SocketAddrV4;
use std::str::FromStr;

use time;

use error::{Error, Result};
static LOGKEY: &'static str = "UT";

/// Gives us a time to stop for in seconds.
pub fn stop_time(duration: i64) -> time::Timespec {
let current_time = time::now_utc().to_timespec();
let wait_duration = time::Duration::seconds(duration as i64);
let stop_time = current_time + wait_duration;
stop_time
}

/// This function takes a string as an option.
/// - If you haven't sent a string, then we'll return (default_ip, default_port).
/// - If you sent Some(some_ip_without_port), we'll return (your IP, default_port).
/// - If you sent Some(some_ip_with_port), we'll just hand that back (your IP, your port).
pub fn parse_ip_port_with_defaults(s: Option<&str>,
default_ip: &str,
default_port: u16)
-> Result<(String, u16)> {
if let None = s {
// return the default IP:Port combo
return Ok((default_ip.to_string(), default_port));
}

let s = s.unwrap();

// is it an IP + Port combo?
match SocketAddrV4::from_str(s) {
Ok(sa) => return Ok((sa.ip().to_string(), sa.port())),
Err(_) => (),
}

// is it just an IP? if so, then append the default gossip port
if Ipv4Addr::from_str(s).is_ok() {
return Ok((s.to_string(), default_port));
}

return Err(sup_error!(Error::IPFailed));
}

#[cfg(test)]
mod tests {
use super::parse_ip_port_with_defaults;

#[test]
fn parse_ip_port_with_defaults_test() {
let default_ip = "192.168.1.11";
let default_port = 1234;
// no ip/port passed in, use default ip:port
assert!(("192.168.1.11".to_string(), 1234) ==
parse_ip_port_with_defaults(None, default_ip, default_port).unwrap());
// only IP passed in
assert!(("192.168.1.99".to_string(), 1234) ==
parse_ip_port_with_defaults(Some("192.168.1.99"), default_ip, default_port)
.unwrap());
// pass in IP and port
assert!(("192.168.1.99".to_string(), 5678) ==
parse_ip_port_with_defaults(Some("192.168.1.99:5678"), default_ip, default_port)
.unwrap());
// pass in something unparseable
assert!(parse_ip_port_with_defaults(Some("foo"), default_ip, default_port).is_err());
}
}
2 changes: 1 addition & 1 deletion components/sup/src/util/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use error::{Error, Result};
use std::process::Command;

static LOGKEY: &'static str = "US";
static LOGKEY: &'static str = "SY";

pub fn ip() -> Result<String> {
debug!("Shelling out to determine IP address");
Expand Down
1 change: 0 additions & 1 deletion components/sup/tests/bldr_build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use regex::Regex;

use hcore::fs;
use util;
use setup;

#[test]
fn builds_a_service() {
Expand Down