<commit_before>#![warn(clippy::new_ret_no_self)]
#![allow(dead_code, clippy::trivially_copy_pass_by_ref)]

fn main(){}

trait R {
    type Item;
}

trait Q {
    type Item;
    type Item2;
}

struct S;

impl R for S {
    type Item = Self;
}

impl S {
    // should not trigger the lint
    pub fn new() -> impl R<Item = Self> {
        S
    }
}

struct S2;

impl R for S2 {
    type Item = Self;
}

impl S2 {
    // should not trigger the lint
    pub fn new(_: String) -> impl R<Item = Self> {
        S2
    }
}

struct S3;

impl R for S3 {
    type Item = u32;
}

impl S3 {
    // should trigger the lint
    pub fn new(_: String) -> impl R<Item = u32> {
        S3
    }
}

struct S4;

impl Q for S4 {
    type Item = u32;
    type Item2 = Self;
}

impl S4 {
    // should not trigger the lint
    pub fn new(_: String) -> impl Q<Item = u32, Item2 = Self> {
        S4
    }
}

struct T;

impl T {
    // should not trigger lint
    pub fn new() -> Self {
        unimplemented!();
    }
}

struct U;

impl U {
    // should trigger lint
    pub fn new() -> u32 {
        unimplemented!();
    }
}

struct V;

impl V {
    // should trigger lint
    pub fn new(_: String) -> u32 {
        unimplemented!();
    }
}

struct TupleReturnerOk;

impl TupleReturnerOk {
    // should not trigger lint
    pub fn new() -> (Self, u32) { unimplemented!(); }
}

struct TupleReturnerOk2;

impl TupleReturnerOk2 {
    // should not trigger lint (it doesn't matter which element in the tuple is Self)
    pub fn new() -> (u32, Self) { unimplemented!(); }
}

struct TupleReturnerOk3;

impl TupleReturnerOk3 {
    // should not trigger lint (tuple can contain multiple Self)
    pub fn new() -> (Self, Self) { unimplemented!(); }
}

struct TupleReturnerBad;

impl TupleReturnerBad {
    // should trigger lint
    pub fn new() -> (u32, u32) { unimplemented!(); }
}

struct MutPointerReturnerOk;

impl MutPointerReturnerOk {
    // should not trigger lint
    pub fn new() -> *mut Self { unimplemented!(); }
}

struct MutPointerReturnerOk2;

impl MutPointerReturnerOk2 {
    // should not trigger lint
    pub fn new() -> *const Self { unimplemented!(); }
}

struct MutPointerReturnerBad;

impl MutPointerReturnerBad {
    // should trigger lint
    pub fn new() -> *mut V { unimplemented!(); }
}

struct GenericReturnerOk;

impl GenericReturnerOk {
    // should not trigger lint
    pub fn new() -> Option<Self> { unimplemented!(); }
}

struct GenericReturnerBad;

impl GenericReturnerBad {
    // should trigger lint
    pub fn new() -> Option<u32> { unimplemented!(); }
}

struct NestedReturnerOk;

impl NestedReturnerOk {
    // should trigger lint
    pub fn new() -> (Option<Self>, u32) { unimplemented!(); }
}
<commit_msg>new_ret_no_self added test cases<commit_after>#![warn(clippy::new_ret_no_self)]
#![allow(dead_code, clippy::trivially_copy_pass_by_ref)]

fn main(){}

trait R {
    type Item;
}

trait Q {
    type Item;
    type Item2;
}

struct S;

impl R for S {
    type Item = Self;
}

impl S {
    // should not trigger the lint
    pub fn new() -> impl R<Item = Self> {
        S
    }
}

struct S2;

impl R for S2 {
    type Item = Self;
}

impl S2 {
    // should not trigger the lint
    pub fn new(_: String) -> impl R<Item = Self> {
        S2
    }
}

struct S3;

impl R for S3 {
    type Item = u32;
}

impl S3 {
    // should trigger the lint
    pub fn new(_: String) -> impl R<Item = u32> {
        S3
    }
}

struct S4;

impl Q for S4 {
    type Item = u32;
    type Item2 = Self;
}

impl S4 {
    // should not trigger the lint
    pub fn new(_: String) -> impl Q<Item = u32, Item2 = Self> {
        S4
    }
}

struct T;

impl T {
    // should not trigger lint
    pub fn new() -> Self {
        unimplemented!();
    }
}

struct U;

impl U {
    // should trigger lint
    pub fn new() -> u32 {
        unimplemented!();
    }
}

struct V;

impl V {
    // should trigger lint
    pub fn new(_: String) -> u32 {
        unimplemented!();
    }
}

struct TupleReturnerOk;

impl TupleReturnerOk {
    // should not trigger lint
    pub fn new() -> (Self, u32) { unimplemented!(); }
}

struct TupleReturnerOk2;

impl TupleReturnerOk2 {
    // should not trigger lint (it doesn't matter which element in the tuple is Self)
    pub fn new() -> (u32, Self) { unimplemented!(); }
}

struct TupleReturnerOk3;

impl TupleReturnerOk3 {
    // should not trigger lint (tuple can contain multiple Self)
    pub fn new() -> (Self, Self) { unimplemented!(); }
}

struct TupleReturnerBad;

impl TupleReturnerBad {
    // should trigger lint
    pub fn new() -> (u32, u32) { unimplemented!(); }
}

struct MutPointerReturnerOk;

impl MutPointerReturnerOk {
    // should not trigger lint
    pub fn new() -> *mut Self { unimplemented!(); }
}

struct MutPointerReturnerOk2;

impl MutPointerReturnerOk2 {
    // should not trigger lint
    pub fn new() -> *const Self { unimplemented!(); }
}

struct MutPointerReturnerBad;

impl MutPointerReturnerBad {
    // should trigger lint
    pub fn new() -> *mut V { unimplemented!(); }
}

struct GenericReturnerOk;

impl GenericReturnerOk {
    // should not trigger lint
    pub fn new() -> Option<Self> { unimplemented!(); }
}

struct GenericReturnerBad;

impl GenericReturnerBad {
    // should trigger lint
    pub fn new() -> Option<u32> { unimplemented!(); }
}

struct NestedReturnerOk;

impl NestedReturnerOk {
    // should not trigger lint
    pub fn new() -> (Option<Self>, u32) { unimplemented!(); }
}

struct NestedReturnerOk2;

impl NestedReturnerOk2 {
    // should not trigger lint
    pub fn new() -> ((Self, u32), u32) { unimplemented!(); }
}

struct NestedReturnerOk3;

impl NestedReturnerOk3 {
    // should not trigger lint
    pub fn new() -> Option<(Self, u32)> { unimplemented!(); }
}
<|endoftext|>


<commit_before>/* 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 http://mozilla.org/MPL/2.0/. */

use std::mem::size_of;
use style::properties::{PropertyDeclaration, specified_value_sizes};

#[test]
fn size_of_property_declaration() {
    let old = 48;
    let new = size_of::<PropertyDeclaration>();
    if new < old {
        panic!("Your changes have decreased the stack size of PropertyDeclaration enum from {} to {}. \
                Good work! Please update the size in tests/unit/style/size_of.rs.",
                old, new)
    } else if new > old {
        panic!("Your changes have increased the stack size of PropertyDeclaration enum from {} to {}. \
                These enum is present in large quantities in the style, and increasing the size \
                may dramatically affect our memory footprint. Please consider using `boxed=\"True\"` in \
                the longhand If you feel that the increase is necessary, update to the new size in \
                tests/unit/style/size_of.rs.",
                old, new)
    }
}

#[test]
fn size_of_specified_values() {
    let threshold = 40;
    let longhands = specified_value_sizes();

    let mut failing_messages = vec![];

    for specified_value in longhands {
        if specified_value.1 >= threshold && !specified_value.2 {
            failing_messages.push(
                format!("Your changes have increased the size of {} SpecifiedValue to {}. The threshold is \
                        currently {}. SpecifiedValues are affect size of PropertyDeclaration enum and \
                        increasing the size may dramatically affect our memory footprint. Please consider \
                        using `boxed=\"True\"` in this longhand.",
                        specified_value.0, specified_value.1, threshold));
        } else if specified_value.1 < threshold && specified_value.2 {
            failing_messages.push(
                format!("Your changes have decreased the size of {} SpecifiedValue to {}. Good work! \
                        The threshold is currently {}. Please consider removing `boxed=\"True\"` from this longhand.",
                        specified_value.0, specified_value.1, threshold));
        }
    }

    if !failing_messages.is_empty() {
        panic!("{}", failing_messages.join("\n\n"));
    }
}
<commit_msg>Tweak thresholds.<commit_after>/* 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 http://mozilla.org/MPL/2.0/. */

use std::mem::size_of;
use style::properties::{PropertyDeclaration, specified_value_sizes};

#[test]
fn size_of_property_declaration() {
    let old = 48;
    let new = size_of::<PropertyDeclaration>();
    if new < old {
        panic!("Your changes have decreased the stack size of PropertyDeclaration enum from {} to {}. \
                Good work! Please update the size in tests/unit/style/size_of.rs.",
                old, new)
    } else if new > old {
        panic!("Your changes have increased the stack size of PropertyDeclaration enum from {} to {}. \
                These enum is present in large quantities in the style, and increasing the size \
                may negatively affect style system performance. Please consider using `boxed=\"True\"` in \
                the longhand If you feel that the increase is necessary, update to the new size in \
                tests/unit/style/size_of.rs.",
                old, new)
    }
}

#[test]
fn size_of_specified_values() {
    let threshold = 32;
    let longhands = specified_value_sizes();

    let mut failing_messages = vec![];

    for specified_value in longhands {
        if specified_value.1 > threshold && !specified_value.2 {
            failing_messages.push(
                format!("Your changes have increased the size of {} SpecifiedValue to {}. The threshold is \
                        currently {}. SpecifiedValues affect size of PropertyDeclaration enum and \
                        increasing the size may negative affect style system performance. Please consider \
                        using `boxed=\"True\"` in this longhand.",
                        specified_value.0, specified_value.1, threshold));
        } else if specified_value.1 <= threshold && specified_value.2 {
            failing_messages.push(
                format!("Your changes have decreased the size of {} SpecifiedValue to {}. Good work! \
                        The threshold is currently {}. Please consider removing `boxed=\"True\"` from this longhand.",
                        specified_value.0, specified_value.1, threshold));
        }
    }

    if !failing_messages.is_empty() {
        panic!("{}", failing_messages.join("\n\n"));
    }
}
<|endoftext|>


<commit_before>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use anyhow::{Error, Result};
use std::path::Path;
use std::process::Command;

/// Executes a command, and returns the stdout as bytes.
pub fn execute(command: &mut Command) -> Result<Vec<u8>> {
    let output = command
        .output()
        .map_err(|e| Error::new(e).context(format!("Failed to execute command {:?}", command)))?;
    Ok(output.stdout)
}

/// Executes a command, and parses the stdout as a string.
pub fn execute_and_parse_stdout(command: &mut Command) -> Result<String> {
    let stdout = execute(command)?;
    String::from_utf8(stdout)
        .map_err(|e| Error::new(e).context("The stdout contains non-utf8 bytes."))
}

/// Writes content into a new file.
/// Returns error if a file already exists.
pub fn write_new_file(path: impl AsRef<Path>, content: impl AsRef<[u8]>) -> Result<()> {
    let path = path.as_ref();
    if path.exists() {
        Err(Error::msg(format!(
            "Cowardly refuse to overwrite {:?}",
            path
        )))
    } else {
        std::fs::write(path, content)?;
        Ok(())
    }
}

/// Tries to read the contents of given file; if the file does not exist,
/// generates a private key, and writes PEM to the file, and returns it.
pub fn read_or_create_private_key_pem(file: impl AsRef<Path>) -> Result<String> {
    if file.as_ref().exists() {
        println!("Reading private key from file {:?}", file.as_ref());
        std::fs::read_to_string(file).map_err(Error::new)
    } else {
        let privkey_pem = execute_and_parse_stdout(
            Command::new("openssl")
                .arg("ecparam")
                .arg("-outform")
                .arg("pem")
                .arg("-name")
                .arg("prime256v1")
                .arg("-genkey"),
        )
        .map_err(|e| e.context("Failed to use openssl to generate private key"))?;
        println!(
            "Writing private key to file {:?}, please keep it in a safe place.",
            file.as_ref()
        );
        write_new_file(file, &privkey_pem)?;
        Ok(privkey_pem)
    }
}

/// Generates a certificate request, and returns it in PEM format.
/// Writes PEM to `output_file`.
/// Overwrites if `output_file` already exists.
pub fn create_certificate_request_pem(
    domain: &str,
    private_key_file: impl AsRef<Path>,
    output_file: impl AsRef<Path>,
) -> Result<String> {
    let cert_csr_pem = execute_and_parse_stdout(
        Command::new("openssl")
            .arg("req")
            .arg("-new")
            .arg("-sha256")
            .arg("-key")
            .arg(private_key_file.as_ref().as_os_str())
            .arg("-subj")
            .arg(format!("/CN={}/O=Test/C=US", domain)),
    )?;
    std::fs::write(output_file, &cert_csr_pem)?;
    Ok(cert_csr_pem)
}

/// Create a certificate by signing the certificate request file
/// by the private key,
/// and returns the certificate in PEM format.
/// Writes PEM to `output_file`.
/// Returns error if `output_file` already exists.
pub fn create_certificate(
    private_key_file: impl AsRef<Path>,
    certificiate_request_file: impl AsRef<Path>,
    ext_file: impl AsRef<Path>,
    output_file: impl AsRef<Path>,
) -> Result<String> {
    let cert_pem = execute_and_parse_stdout(
        Command::new("openssl")
            .arg("x509")
            .arg("-req")
            .arg("-days")
            .arg("90")
            .arg("-in")
            .arg(certificiate_request_file.as_ref().as_os_str())
            .arg("-signkey")
            .arg(private_key_file.as_ref().as_os_str())
            .arg("-extfile")
            .arg(ext_file.as_ref().as_os_str()),
    )?;
    write_new_file(output_file, &cert_pem)?;
    Ok(cert_pem)
}

pub fn get_certificate_sha256(certificate_file: impl AsRef<Path>) -> Result<Vec<u8>> {
    let public_key_pem = execute_and_parse_stdout(
        Command::new("openssl")
            .arg("x509")
            .arg("-pubkey")
            .arg("-noout")
            .arg("-in")
            .arg(certificate_file.as_ref().as_os_str()),
    )?;
    let public_key_der = sxg_rs::crypto::get_der_from_pem(&public_key_pem, "PUBLIC KEY")?;
    Ok(sxg_rs::crypto::HashAlgorithm::Sha256.digest(&public_key_der))
}
<commit_msg>Create private key without writing to a file (#263)<commit_after>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use anyhow::{Error, Result};
use std::path::Path;
use std::process::Command;

/// Executes a command, and returns the stdout as bytes.
pub fn execute(command: &mut Command) -> Result<Vec<u8>> {
    let output = command
        .output()
        .map_err(|e| Error::new(e).context(format!("Failed to execute command {:?}", command)))?;
    Ok(output.stdout)
}

/// Executes a command, and parses the stdout as a string.
pub fn execute_and_parse_stdout(command: &mut Command) -> Result<String> {
    let stdout = execute(command)?;
    String::from_utf8(stdout)
        .map_err(|e| Error::new(e).context("The stdout contains non-utf8 bytes."))
}

/// Writes content into a new file.
/// Returns error if a file already exists.
pub fn write_new_file(path: impl AsRef<Path>, content: impl AsRef<[u8]>) -> Result<()> {
    let path = path.as_ref();
    if path.exists() {
        Err(Error::msg(format!(
            "Cowardly refuse to overwrite {:?}",
            path
        )))
    } else {
        std::fs::write(path, content)?;
        Ok(())
    }
}

/// Generates a private key, and returns it without writing to any files.
/// Care should be taken to prevent the private key being lost.
pub fn generate_private_key_pem() -> Result<String> {
    execute_and_parse_stdout(
        Command::new("openssl")
            .arg("ecparam")
            .arg("-outform")
            .arg("pem")
            .arg("-name")
            .arg("prime256v1")
            .arg("-genkey"),
    )
    .map_err(|e| e.context("Failed to use openssl to generate private key"))
}

/// Tries to read the contents of given file; if the file does not exist,
/// generates a private key, and writes PEM to the file, and returns it.
pub fn read_or_create_private_key_pem(file: impl AsRef<Path>) -> Result<String> {
    if file.as_ref().exists() {
        println!("Reading private key from file {:?}", file.as_ref());
        std::fs::read_to_string(file).map_err(Error::new)
    } else {
        let privkey_pem = generate_private_key_pem()?;
        println!(
            "Writing private key to file {:?}, please keep it in a safe place.",
            file.as_ref()
        );
        write_new_file(file, &privkey_pem)?;
        Ok(privkey_pem)
    }
}

/// Generates a certificate request, and returns it in PEM format.
/// Writes PEM to `output_file`.
/// Overwrites if `output_file` already exists.
pub fn create_certificate_request_pem(
    domain: &str,
    private_key_file: impl AsRef<Path>,
    output_file: impl AsRef<Path>,
) -> Result<String> {
    let cert_csr_pem = execute_and_parse_stdout(
        Command::new("openssl")
            .arg("req")
            .arg("-new")
            .arg("-sha256")
            .arg("-key")
            .arg(private_key_file.as_ref().as_os_str())
            .arg("-subj")
            .arg(format!("/CN={}/O=Test/C=US", domain)),
    )?;
    std::fs::write(output_file, &cert_csr_pem)?;
    Ok(cert_csr_pem)
}

/// Create a certificate by signing the certificate request file
/// by the private key,
/// and returns the certificate in PEM format.
/// Writes PEM to `output_file`.
/// Returns error if `output_file` already exists.
pub fn create_certificate(
    private_key_file: impl AsRef<Path>,
    certificiate_request_file: impl AsRef<Path>,
    ext_file: impl AsRef<Path>,
    output_file: impl AsRef<Path>,
) -> Result<String> {
    let cert_pem = execute_and_parse_stdout(
        Command::new("openssl")
            .arg("x509")
            .arg("-req")
            .arg("-days")
            .arg("90")
            .arg("-in")
            .arg(certificiate_request_file.as_ref().as_os_str())
            .arg("-signkey")
            .arg(private_key_file.as_ref().as_os_str())
            .arg("-extfile")
            .arg(ext_file.as_ref().as_os_str()),
    )?;
    write_new_file(output_file, &cert_pem)?;
    Ok(cert_pem)
}

pub fn get_certificate_sha256(certificate_file: impl AsRef<Path>) -> Result<Vec<u8>> {
    let public_key_pem = execute_and_parse_stdout(
        Command::new("openssl")
            .arg("x509")
            .arg("-pubkey")
            .arg("-noout")
            .arg("-in")
            .arg(certificate_file.as_ref().as_os_str()),
    )?;
    let public_key_der = sxg_rs::crypto::get_der_from_pem(&public_key_pem, "PUBLIC KEY")?;
    Ok(sxg_rs::crypto::HashAlgorithm::Sha256.digest(&public_key_der))
}
<|endoftext|>


<commit_before>use std::process::Command;

pub struct Output {
  pub status: i32,
  pub stdout: String,
  pub stderr: String,
}

/// Run an AppleScript.
///
/// * `script`: The AppleScript code to run.
///
pub fn run(script: &str) -> Output {
  let cmd_result = Command::new("osascript")
    .arg("-e")
    .arg(script)
    .output()
    .expect("failed to execute AppleScript");

  Output {
    status: cmd_result.status.code().unwrap_or(1),
    stdout: String::from_utf8(cmd_result.stdout).unwrap(),
    stderr: String::from_utf8(cmd_result.stderr).unwrap(),
  }
}
<commit_msg>Add a note about the similarity to std::process::ExitStatus<commit_after>use std::process::{Command, ExitStatus};

/// The output of a finished process.
///
/// This varies from Output in std::process in that stdout/stderr are
/// both strings rather than Vec<u8>.
pub struct Output {
  pub status: ExitStatus,
  pub stdout: String,
  pub stderr: String,
}

/// Run an AppleScript.
///
/// * `script`: The AppleScript code to run.
///
pub fn run(script: &str) -> Output {
  let cmd_result = Command::new("osascript")
    .arg("-e")
    .arg(script)
    .output()
    .expect("failed to execute AppleScript");

  Output {
    status: cmd_result.status,
    stdout: String::from_utf8(cmd_result.stdout).unwrap(),
    stderr: String::from_utf8(cmd_result.stderr).unwrap(),
  }
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate mmap;
extern crate time;
extern crate timely;
extern crate getopts;

use rand::{Rng, SeedableRng, StdRng};

use timely::progress::timestamp::RootTimestamp;
use timely::dataflow::*;
use timely::dataflow::operators::*;
use timely::dataflow::channels::pact::Exchange;
use timely::drain::DrainExt;

fn main () {

    let node_cnt = std::env::args().skip(1).next().unwrap().parse::<usize>().unwrap();
    let edge_cnt = std::env::args().skip(2).next().unwrap().parse::<usize>().unwrap();

    timely::execute_from_args(std::env::args(), move |root| {

        let index = root.index() as usize;
        let peers = root.peers() as usize;

        let start = time::precise_time_s();

        let mut edges = Vec::new();
        let mut ranks = vec![1.0; (node_cnt / peers) + 1];   // holds ranks
        if (node_cnt % peers) < index { ranks.push(1.0); }
        let mut degrs = vec![0; ranks.len()];

        let mut going = start;

        let mut input = root.scoped(|builder| {

            let (input, graph) = builder.new_input::<(u32, u32)>();
            let (cycle, loopz) = builder.loop_variable::<(u32, f32)>(20, 1);

            graph.binary_notify(&loopz,
                                Exchange::new(|x: &(u32,u32)| x.0 as u64),
                                Exchange::new(|x: &(u32,f32)| x.0 as u64),
                                "pagerank",
                                vec![RootTimestamp::new(0)],
                                move |input1, input2, output, notificator| {

                // receive incoming edges (should only be iter 0)
                while let Some((_index, data)) = input1.next() {
                    for (src,dst) in data.drain_temp() {
                        degrs[src as usize] += 1;
                        edges.push((src / (peers as u32),dst));
                    }
                }

                // all inputs received for iter, commence multiplication
                while let Some((iter, _)) = notificator.next() {

                    // record some timings in order to estimate per-iteration times
                    if iter.inner == 0 { println!("src: {}, dst: {}, edges: {}", ranks.len(), node_cnt, edges.len()); }
                    if iter.inner == 10 && index == 0 { going = time::precise_time_s(); }
                    if iter.inner == 20 && index == 0 { println!("average: {}", (time::precise_time_s() - going) / 10.0 ); }

                    // prepare src for transmitting to destinations
                    for s in 0..ranks.len() { ranks[s] = 0.15 + 0.85 * ranks[s] / degrs[s] as f32; }

                    // wander through destinations
                    let mut session = output.session(&iter);
                    for &(src,dst) in &edges {
                        unsafe {
                            session.give((dst, *ranks.get_unchecked(src as usize)));
                        }
                    }

                    for s in &mut ranks { *s = 0.0; }
                }

                // receive data from workers, accumulate in src
                while let Some((iter, data)) = input2.next() {
                    notificator.notify_at(&iter);
                    for &(node, rank) in data.iter() {
                        unsafe { *ranks.get_unchecked_mut(node as usize / peers) += rank; }
                    }
                }
            }).connect_loop(cycle);

            input
        });

        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng: StdRng = SeedableRng::from_seed(seed);

        for _index in 0..(edge_cnt / peers) {
            input.send((rng.gen_range(0, node_cnt as u32), rng.gen_range(0, node_cnt as u32)));
        }
    });
}<commit_msg>reduced size of ranks vector<commit_after>extern crate rand;
extern crate mmap;
extern crate time;
extern crate timely;
extern crate getopts;

use rand::{Rng, SeedableRng, StdRng};

use timely::progress::timestamp::RootTimestamp;
use timely::dataflow::*;
use timely::dataflow::operators::*;
use timely::dataflow::channels::pact::Exchange;
use timely::drain::DrainExt;

fn main () {

    let node_cnt = std::env::args().skip(1).next().unwrap().parse::<usize>().unwrap();
    let edge_cnt = std::env::args().skip(2).next().unwrap().parse::<usize>().unwrap();

    timely::execute_from_args(std::env::args(), move |root| {

        let index = root.index() as usize;
        let peers = root.peers() as usize;

        let start = time::precise_time_s();

        let mut edges = Vec::new();
        let mut ranks = vec![1.0; (node_cnt / peers) + 1];   // holds ranks
        if (node_cnt % peers) < index { ranks.push(1.0); }
        let mut degrs = vec![0; ranks.len()];

        let mut going = start;

        let mut input = root.scoped(|builder| {

            let (input, graph) = builder.new_input::<(u32, u32)>();
            let (cycle, loopz) = builder.loop_variable::<(u32, f32)>(20, 1);

            graph.binary_notify(&loopz,
                                Exchange::new(|x: &(u32,u32)| x.0 as u64),
                                Exchange::new(|x: &(u32,f32)| x.0 as u64),
                                "pagerank",
                                vec![RootTimestamp::new(0)],
                                move |input1, input2, output, notificator| {

                // receive incoming edges (should only be iter 0)
                while let Some((_index, data)) = input1.next() {
                    for (src,dst) in data.drain_temp() {
                        degrs[src as usize / peers] += 1;
                        edges.push((src / (peers as u32),dst));
                    }
                }

                // all inputs received for iter, commence multiplication
                while let Some((iter, _)) = notificator.next() {

                    // record some timings in order to estimate per-iteration times
                    if iter.inner == 0 { println!("src: {}, dst: {}, edges: {}", ranks.len(), node_cnt, edges.len()); }
                    if iter.inner == 10 && index == 0 { going = time::precise_time_s(); }
                    if iter.inner == 20 && index == 0 { println!("average: {}", (time::precise_time_s() - going) / 10.0 ); }

                    // prepare src for transmitting to destinations
                    for s in 0..ranks.len() { ranks[s] = 0.15 + 0.85 * ranks[s] / degrs[s] as f32; }

                    // wander through destinations
                    let mut session = output.session(&iter);
                    for &(src,dst) in &edges {
                        unsafe {
                            session.give((dst, *ranks.get_unchecked(src as usize)));
                        }
                    }

                    for s in &mut ranks { *s = 0.0; }
                }

                // receive data from workers, accumulate in src
                while let Some((iter, data)) = input2.next() {
                    notificator.notify_at(&iter);
                    for &(node, rank) in data.iter() {
                        unsafe { *ranks.get_unchecked_mut(node as usize / peers) += rank; }
                    }
                }
            }).connect_loop(cycle);

            input
        });

        let seed: &[_] = &[1, 2, 3, 4];
        let mut rng: StdRng = SeedableRng::from_seed(seed);

        for _index in 0..(edge_cnt / peers) {
            input.send((rng.gen_range(0, node_cnt as u32), rng.gen_range(0, node_cnt as u32)));
        }
    });
}<|endoftext|>


<commit_before>use std::env;

const DEFAULT_NGINX_VERSION: (u16, u16, u16) = (1, 7, 10);

pub fn nginx_version_string() -> String {
   let key = "NGINX_VERSION";

   match env::var(key) {
      Ok(val) => {
         val
      },
      Err(_) => {
         let (major, minor, patch) = DEFAULT_NGINX_VERSION;

         format!("{}.{}.{}", major, minor, patch)
      },
   }
}
<commit_msg>Bumping the Nginx version to 1.7.11.<commit_after>use std::env;

const DEFAULT_NGINX_VERSION: (u16, u16, u16) = (1, 7, 11);

pub fn nginx_version_string() -> String {
   let key = "NGINX_VERSION";

   match env::var(key) {
      Ok(val) => {
         val
      },
      Err(_) => {
         let (major, minor, patch) = DEFAULT_NGINX_VERSION;

         format!("{}.{}.{}", major, minor, patch)
      },
   }
}
<|endoftext|>


<commit_before>use std::path::{Path, PathBuf};
use std::fs::{self, File};
use std::error::Error;
use std::io;
use std::io::Write;
use std::io::ErrorKind;
use std::process::Command;

use {BookConfig, BookItem, theme, parse, utils};
use book::BookItems;
use renderer::{Renderer, HtmlHandlebars};

pub struct MDBook {
    config: BookConfig,
    pub content: Vec<BookItem>,
    renderer: Box<Renderer>,
}

impl MDBook {

    /// Create a new `MDBook` struct with root directory `root`
    ///
    /// - The default source directory is set to `root/src`
    /// - The default output directory is set to `root/book`
    ///
    /// They can both be changed by using [`set_src()`](#method.set_src) and [`set_dest()`](#method.set_dest)

    pub fn new(root: &Path) -> MDBook {

        if !root.exists() || !root.is_dir() {
            output!("{:?} No directory with that name", root);
        }

        MDBook {
            content: vec![],
            config: BookConfig::new(root)
                        .set_src(&root.join("src"))
                        .set_dest(&root.join("book"))
                        .to_owned(),
            renderer: Box::new(HtmlHandlebars::new()),
        }
    }

    /// Returns a flat depth-first iterator over the elements of the book, it returns an [BookItem enum](bookitem.html):
    /// `(section: String, bookitem: &BookItem)`
    ///
    /// ```no_run
    /// # extern crate mdbook;
    /// # use mdbook::MDBook;
    /// # use mdbook::BookItem;
    /// # use std::path::Path;
    /// # fn main() {
    /// # let mut book = MDBook::new(Path::new("mybook"));
    /// for item in book.iter() {
    ///     match item {
    ///         &BookItem::Chapter(ref section, ref chapter) => {},
    ///         &BookItem::Affix(ref chapter) => {},
    ///         &BookItem::Spacer => {},
    ///     }
    /// }
    ///
    /// // would print something like this:
    /// // 1. Chapter 1
    /// // 1.1 Sub Chapter
    /// // 1.2 Sub Chapter
    /// // 2. Chapter 2
    /// //
    /// // etc.
    /// # }
    /// ```

    pub fn iter(&self) -> BookItems {
        BookItems {
            items: &self.content[..],
            current_index: 0,
            stack: Vec::new(),
        }
    }

    /// `init()` creates some boilerplate files and directories to get you started with your book.
    ///
    /// ```text
    /// book-test/
    /// ├── book
    /// └── src
    ///     ├── chapter_1.md
    ///     └── SUMMARY.md
    /// ```
    ///
    /// It uses the paths given as source and output directories and adds a `SUMMARY.md` and a
    /// `chapter_1.md` to the source directory.

    pub fn init(&mut self) -> Result<(), Box<Error>> {

        debug!("[fn]: init");

        if !self.config.get_root().exists() {
            fs::create_dir_all(self.config.get_root()).unwrap();
            output!("{:?} created", self.config.get_root());
        }

        {
            let dest = self.config.get_dest();
            let src = self.config.get_src();

            if !dest.exists() {
                debug!("[*]: {:?} does not exist, trying to create directory", dest);
                try!(fs::create_dir(&dest));
            }

            if !src.exists() {
                debug!("[*]: {:?} does not exist, trying to create directory", src);
                try!(fs::create_dir(&src));
            }

            let summary = src.join("SUMMARY.md");

            if !summary.exists() {

                // Summary does not exist, create it

                debug!("[*]: {:?} does not exist, trying to create SUMMARY.md", src.join("SUMMARY.md"));
                let mut f = try!(File::create(&src.join("SUMMARY.md")));

                debug!("[*]: Writing to SUMMARY.md");

                try!(writeln!(f, "# Summary"));
                try!(writeln!(f, ""));
                try!(writeln!(f, "- [Chapter 1](./chapter_1.md)"));
            }
        }

        // parse SUMMARY.md, and create the missing item related file
        try!(self.parse_summary());

        debug!("[*]: constructing paths for missing files");
        for item in self.iter() {
            debug!("[*]: item: {:?}", item);
            match *item {
                BookItem::Spacer => continue,
                BookItem::Chapter(_, ref ch) | BookItem::Affix(ref ch) => {
                    if ch.path != PathBuf::new() {
                        let path = self.config.get_src().join(&ch.path);

                        if !path.exists() {
                            debug!("[*]: {:?} does not exist, trying to create file", path);
                            try!(::std::fs::create_dir_all(path.parent().unwrap()));
                            let mut f = try!(File::create(path));

                            //debug!("[*]: Writing to {:?}", path);
                            try!(writeln!(f, "# {}", ch.name));
                        }
                    }
                }
            }
        }

        debug!("[*]: init done");
        Ok(())
    }

    /// The `build()` method is the one where everything happens. First it parses `SUMMARY.md` to
    /// construct the book's structure in the form of a `Vec<BookItem>` and then calls `render()`
    /// method of the current renderer.
    ///
    /// It is the renderer who generates all the output files.

    pub fn build(&mut self) -> Result<(), Box<Error>> {
        debug!("[fn]: build");

        try!(self.init());

        // Clean output directory
        try!(utils::remove_dir_content(&self.config.get_dest()));

        try!(self.renderer.render(&self));

        Ok(())
    }

    pub fn copy_theme(&self) -> Result<(), Box<Error>> {
        debug!("[fn]: copy_theme");

        let theme_dir = self.config.get_src().join("theme");

        if !theme_dir.exists() {
            debug!("[*]: {:?} does not exist, trying to create directory", theme_dir);
            try!(fs::create_dir(&theme_dir));
        }

        // index.hbs
        let mut index = try!(File::create(&theme_dir.join("index.hbs")));
        try!(index.write_all(theme::INDEX));

        // book.css
        let mut css = try!(File::create(&theme_dir.join("book.css")));
        try!(css.write_all(theme::CSS));

        // book.js
        let mut js = try!(File::create(&theme_dir.join("book.js")));
        try!(js.write_all(theme::JS));

        // highlight.css
        let mut highlight_css = try!(File::create(&theme_dir.join("highlight.css")));
        try!(highlight_css.write_all(theme::HIGHLIGHT_CSS));

        // highlight.js
        let mut highlight_js = try!(File::create(&theme_dir.join("highlight.js")));
        try!(highlight_js.write_all(theme::HIGHLIGHT_JS));

        Ok(())
    }

    /// Parses the `book.json` file (if it exists) to extract the configuration parameters.
    /// The `book.json` file should be in the root directory of the book.
    /// The root directory is the one specified when creating a new `MDBook`
    ///
    /// ```no_run
    /// # extern crate mdbook;
    /// # use mdbook::MDBook;
    /// # use std::path::Path;
    /// # fn main() {
    /// let mut book = MDBook::new(Path::new("root_dir"));
    /// # }
    /// ```
    ///
    /// In this example, `root_dir` will be the root directory of our book and is specified in function
    /// of the current working directory by using a relative path instead of an absolute path.

    pub fn read_config(mut self) -> Self {
        let root = self.config.get_root().to_owned();
        self.config.read_config(&root);
        self
    }

    /// You can change the default renderer to another one by using this method. The only requirement
    /// is for your renderer to implement the [Renderer trait](../../renderer/renderer/trait.Renderer.html)
    ///
    /// ```no_run
    /// extern crate mdbook;
    /// use mdbook::MDBook;
    /// use mdbook::renderer::HtmlHandlebars;
    /// # use std::path::Path;
    ///
    /// fn main() {
    ///     let mut book = MDBook::new(Path::new("mybook"))
    ///                         .set_renderer(Box::new(HtmlHandlebars::new()));
    ///
    ///     // In this example we replace the default renderer by the default renderer...
    ///     // Don't forget to put your renderer in a Box
    /// }
    /// ```
    ///
    /// **note:** Don't forget to put your renderer in a `Box` before passing it to `set_renderer()`

    pub fn set_renderer(mut self, renderer: Box<Renderer>) -> Self {
        self.renderer = renderer;
        self
    }

    pub fn test(&mut self) -> Result<(), Box<Error>> {
        // read in the chapters
        try!(self.parse_summary());
        for item in self.iter() {

            match *item {
                BookItem::Chapter(_, ref ch) => {
                    if ch.path != PathBuf::new() {

                        let path = self.get_src().join(&ch.path);

                        println!("[*]: Testing file: {:?}", path);

                        let output_result = Command::new("rustdoc")
                            .arg(&path)
                            .arg("--test")
                            .output();
                        let output = try!(output_result);

                        if !output.status.success() {
                            return Err(Box::new(io::Error::new(ErrorKind::Other, format!(
                                            "{}\n{}",
                                            String::from_utf8_lossy(&output.stdout),
                                            String::from_utf8_lossy(&output.stderr)))) as Box<Error>);
                        }
                    }
                }
                _ => {}
            }
        }
        Ok(())
    }

    pub fn set_dest(mut self, dest: &Path) -> Self {

        // Handle absolute and relative paths
        match dest.is_absolute() {
            true => { self.config.set_dest(dest); },
            false => {
                let dest = self.config.get_root().join(dest).to_owned();
                self.config.set_dest(&dest);
            }
        }

        self
    }

    pub fn get_dest(&self) -> &Path {
        self.config.get_dest()
    }

    pub fn set_src(mut self, src: &Path) -> Self {

        // Handle absolute and relative paths
        match src.is_absolute() {
            true => { self.config.set_src(src); },
            false => {
                let src = self.config.get_root().join(src).to_owned();
                self.config.set_src(&src);
            }
        }

        self
    }

    pub fn get_src(&self) -> &Path {
        self.config.get_src()
    }

    pub fn set_title(mut self, title: &str) -> Self {
        self.config.title = title.to_owned();
        self
    }

    pub fn get_title(&self) -> &str {
        &self.config.title
    }

    pub fn set_author(mut self, author: &str) -> Self {
        self.config.author = author.to_owned();
        self
    }

    pub fn get_author(&self) -> &str {
        &self.config.author
    }

    // Construct book
    fn parse_summary(&mut self) -> Result<(), Box<Error>> {
        // When append becomes stable, use self.content.append() ...
        self.content = try!(parse::construct_bookitems(&self.config.get_src().join("SUMMARY.md")));
        Ok(())
    }

}
<commit_msg>Copy favicon on 'init --theme'<commit_after>use std::path::{Path, PathBuf};
use std::fs::{self, File};
use std::error::Error;
use std::io;
use std::io::Write;
use std::io::ErrorKind;
use std::process::Command;

use {BookConfig, BookItem, theme, parse, utils};
use book::BookItems;
use renderer::{Renderer, HtmlHandlebars};

pub struct MDBook {
    config: BookConfig,
    pub content: Vec<BookItem>,
    renderer: Box<Renderer>,
}

impl MDBook {

    /// Create a new `MDBook` struct with root directory `root`
    ///
    /// - The default source directory is set to `root/src`
    /// - The default output directory is set to `root/book`
    ///
    /// They can both be changed by using [`set_src()`](#method.set_src) and [`set_dest()`](#method.set_dest)

    pub fn new(root: &Path) -> MDBook {

        if !root.exists() || !root.is_dir() {
            output!("{:?} No directory with that name", root);
        }

        MDBook {
            content: vec![],
            config: BookConfig::new(root)
                        .set_src(&root.join("src"))
                        .set_dest(&root.join("book"))
                        .to_owned(),
            renderer: Box::new(HtmlHandlebars::new()),
        }
    }

    /// Returns a flat depth-first iterator over the elements of the book, it returns an [BookItem enum](bookitem.html):
    /// `(section: String, bookitem: &BookItem)`
    ///
    /// ```no_run
    /// # extern crate mdbook;
    /// # use mdbook::MDBook;
    /// # use mdbook::BookItem;
    /// # use std::path::Path;
    /// # fn main() {
    /// # let mut book = MDBook::new(Path::new("mybook"));
    /// for item in book.iter() {
    ///     match item {
    ///         &BookItem::Chapter(ref section, ref chapter) => {},
    ///         &BookItem::Affix(ref chapter) => {},
    ///         &BookItem::Spacer => {},
    ///     }
    /// }
    ///
    /// // would print something like this:
    /// // 1. Chapter 1
    /// // 1.1 Sub Chapter
    /// // 1.2 Sub Chapter
    /// // 2. Chapter 2
    /// //
    /// // etc.
    /// # }
    /// ```

    pub fn iter(&self) -> BookItems {
        BookItems {
            items: &self.content[..],
            current_index: 0,
            stack: Vec::new(),
        }
    }

    /// `init()` creates some boilerplate files and directories to get you started with your book.
    ///
    /// ```text
    /// book-test/
    /// ├── book
    /// └── src
    ///     ├── chapter_1.md
    ///     └── SUMMARY.md
    /// ```
    ///
    /// It uses the paths given as source and output directories and adds a `SUMMARY.md` and a
    /// `chapter_1.md` to the source directory.

    pub fn init(&mut self) -> Result<(), Box<Error>> {

        debug!("[fn]: init");

        if !self.config.get_root().exists() {
            fs::create_dir_all(self.config.get_root()).unwrap();
            output!("{:?} created", self.config.get_root());
        }

        {
            let dest = self.config.get_dest();
            let src = self.config.get_src();

            if !dest.exists() {
                debug!("[*]: {:?} does not exist, trying to create directory", dest);
                try!(fs::create_dir(&dest));
            }

            if !src.exists() {
                debug!("[*]: {:?} does not exist, trying to create directory", src);
                try!(fs::create_dir(&src));
            }

            let summary = src.join("SUMMARY.md");

            if !summary.exists() {

                // Summary does not exist, create it

                debug!("[*]: {:?} does not exist, trying to create SUMMARY.md", src.join("SUMMARY.md"));
                let mut f = try!(File::create(&src.join("SUMMARY.md")));

                debug!("[*]: Writing to SUMMARY.md");

                try!(writeln!(f, "# Summary"));
                try!(writeln!(f, ""));
                try!(writeln!(f, "- [Chapter 1](./chapter_1.md)"));
            }
        }

        // parse SUMMARY.md, and create the missing item related file
        try!(self.parse_summary());

        debug!("[*]: constructing paths for missing files");
        for item in self.iter() {
            debug!("[*]: item: {:?}", item);
            match *item {
                BookItem::Spacer => continue,
                BookItem::Chapter(_, ref ch) | BookItem::Affix(ref ch) => {
                    if ch.path != PathBuf::new() {
                        let path = self.config.get_src().join(&ch.path);

                        if !path.exists() {
                            debug!("[*]: {:?} does not exist, trying to create file", path);
                            try!(::std::fs::create_dir_all(path.parent().unwrap()));
                            let mut f = try!(File::create(path));

                            //debug!("[*]: Writing to {:?}", path);
                            try!(writeln!(f, "# {}", ch.name));
                        }
                    }
                }
            }
        }

        debug!("[*]: init done");
        Ok(())
    }

    /// The `build()` method is the one where everything happens. First it parses `SUMMARY.md` to
    /// construct the book's structure in the form of a `Vec<BookItem>` and then calls `render()`
    /// method of the current renderer.
    ///
    /// It is the renderer who generates all the output files.

    pub fn build(&mut self) -> Result<(), Box<Error>> {
        debug!("[fn]: build");

        try!(self.init());

        // Clean output directory
        try!(utils::remove_dir_content(&self.config.get_dest()));

        try!(self.renderer.render(&self));

        Ok(())
    }

    pub fn copy_theme(&self) -> Result<(), Box<Error>> {
        debug!("[fn]: copy_theme");

        let theme_dir = self.config.get_src().join("theme");

        if !theme_dir.exists() {
            debug!("[*]: {:?} does not exist, trying to create directory", theme_dir);
            try!(fs::create_dir(&theme_dir));
        }

        // index.hbs
        let mut index = try!(File::create(&theme_dir.join("index.hbs")));
        try!(index.write_all(theme::INDEX));

        // book.css
        let mut css = try!(File::create(&theme_dir.join("book.css")));
        try!(css.write_all(theme::CSS));

        // favicon.png
        let mut favicon = try!(File::create(&theme_dir.join("favicon.png")));
        try!(favicon.write_all(theme::FAVICON));

        // book.js
        let mut js = try!(File::create(&theme_dir.join("book.js")));
        try!(js.write_all(theme::JS));

        // highlight.css
        let mut highlight_css = try!(File::create(&theme_dir.join("highlight.css")));
        try!(highlight_css.write_all(theme::HIGHLIGHT_CSS));

        // highlight.js
        let mut highlight_js = try!(File::create(&theme_dir.join("highlight.js")));
        try!(highlight_js.write_all(theme::HIGHLIGHT_JS));

        Ok(())
    }

    /// Parses the `book.json` file (if it exists) to extract the configuration parameters.
    /// The `book.json` file should be in the root directory of the book.
    /// The root directory is the one specified when creating a new `MDBook`
    ///
    /// ```no_run
    /// # extern crate mdbook;
    /// # use mdbook::MDBook;
    /// # use std::path::Path;
    /// # fn main() {
    /// let mut book = MDBook::new(Path::new("root_dir"));
    /// # }
    /// ```
    ///
    /// In this example, `root_dir` will be the root directory of our book and is specified in function
    /// of the current working directory by using a relative path instead of an absolute path.

    pub fn read_config(mut self) -> Self {
        let root = self.config.get_root().to_owned();
        self.config.read_config(&root);
        self
    }

    /// You can change the default renderer to another one by using this method. The only requirement
    /// is for your renderer to implement the [Renderer trait](../../renderer/renderer/trait.Renderer.html)
    ///
    /// ```no_run
    /// extern crate mdbook;
    /// use mdbook::MDBook;
    /// use mdbook::renderer::HtmlHandlebars;
    /// # use std::path::Path;
    ///
    /// fn main() {
    ///     let mut book = MDBook::new(Path::new("mybook"))
    ///                         .set_renderer(Box::new(HtmlHandlebars::new()));
    ///
    ///     // In this example we replace the default renderer by the default renderer...
    ///     // Don't forget to put your renderer in a Box
    /// }
    /// ```
    ///
    /// **note:** Don't forget to put your renderer in a `Box` before passing it to `set_renderer()`

    pub fn set_renderer(mut self, renderer: Box<Renderer>) -> Self {
        self.renderer = renderer;
        self
    }

    pub fn test(&mut self) -> Result<(), Box<Error>> {
        // read in the chapters
        try!(self.parse_summary());
        for item in self.iter() {

            match *item {
                BookItem::Chapter(_, ref ch) => {
                    if ch.path != PathBuf::new() {

                        let path = self.get_src().join(&ch.path);

                        println!("[*]: Testing file: {:?}", path);

                        let output_result = Command::new("rustdoc")
                            .arg(&path)
                            .arg("--test")
                            .output();
                        let output = try!(output_result);

                        if !output.status.success() {
                            return Err(Box::new(io::Error::new(ErrorKind::Other, format!(
                                            "{}\n{}",
                                            String::from_utf8_lossy(&output.stdout),
                                            String::from_utf8_lossy(&output.stderr)))) as Box<Error>);
                        }
                    }
                }
                _ => {}
            }
        }
        Ok(())
    }

    pub fn set_dest(mut self, dest: &Path) -> Self {

        // Handle absolute and relative paths
        match dest.is_absolute() {
            true => { self.config.set_dest(dest); },
            false => {
                let dest = self.config.get_root().join(dest).to_owned();
                self.config.set_dest(&dest);
            }
        }

        self
    }

    pub fn get_dest(&self) -> &Path {
        self.config.get_dest()
    }

    pub fn set_src(mut self, src: &Path) -> Self {

        // Handle absolute and relative paths
        match src.is_absolute() {
            true => { self.config.set_src(src); },
            false => {
                let src = self.config.get_root().join(src).to_owned();
                self.config.set_src(&src);
            }
        }

        self
    }

    pub fn get_src(&self) -> &Path {
        self.config.get_src()
    }

    pub fn set_title(mut self, title: &str) -> Self {
        self.config.title = title.to_owned();
        self
    }

    pub fn get_title(&self) -> &str {
        &self.config.title
    }

    pub fn set_author(mut self, author: &str) -> Self {
        self.config.author = author.to_owned();
        self
    }

    pub fn get_author(&self) -> &str {
        &self.config.author
    }

    // Construct book
    fn parse_summary(&mut self) -> Result<(), Box<Error>> {
        // When append becomes stable, use self.content.append() ...
        self.content = try!(parse::construct_bookitems(&self.config.get_src().join("SUMMARY.md")));
        Ok(())
    }

}
<|endoftext|>


<commit_before>use common::types::FnType;
use common::types::StructType;
use common::link::*;

use common::entity::FromEntity;
use common::entity::Entity;

use std::collections::BTreeMap;
use common::tree_id::*;

#[derive(Debug, Clone)]
pub struct Node {
    id: i32,
    name: String,
    url: String,
    fn_type: FnType,
    links: Vec<Link>,
    nodes: Vec<Node>,
}

impl Node {
    fn push(&mut self, entity: &Entity) {
        match entity.struct_type {
            StructType::Link => {
                self.links.push(Link::from_entity(&entity));
            },
            StructType::Node => {
                self.nodes.push(Node::from_entity(&entity));
            }
        }
    }
}

impl FromEntity for Node {
    fn from_entity(entity: &Entity) -> Self {
        let clone = entity.clone();

        Node {
            id: clone.id,
            name: clone.name,
            url: clone.url,
            fn_type: clone.fn_type,
            links: Vec::new(),
            nodes: Vec::new()
        }
    }

    //TODO entity matcher for nodes
    fn from_entities(entities: Vec<Entity>) -> Vec<Self> {
        let mut node_map: BTreeMap<String, &Node> = BTreeMap::new();
        let mut roots: Vec<Node> = Vec::new();
        let mut lower = usize::max_value();

        for e in entities.iter() {
            let ref path = e.tree_id;

            if e.struct_type == StructType::Node {
                if path.level() < lower {
                    lower = path.level();
                }

                roots.push(Node::from_entity(e));
                node_map.insert(path.id(), roots.last());
            }
        }

        for e in entities.iter() {
            let inner = e.tree_id.level();

            let parent = match e.tree_id.key(inner - 1) {
                Some(p) => p,
                None => panic!("{:?}", e),
            };

            if let Some(node) = node_map.get_mut(&parent) {
                if e.struct_type == StructType::Link {
                    node.push(e);
                }
            }
        }

        let mut roots = Vec::new();
        for (key, node) in node_map.into_iter() {
            if level(&key) == lower {
                roots.push(node);
            }
        }

        roots;
        unimplemented!()
    }
}
<commit_msg>algorithm clue<commit_after>use common::types::FnType;
use common::types::StructType;
use common::link::*;

use common::entity::FromEntity;
use common::entity::Entity;

use std::collections::BTreeMap;
use common::tree_id::*;

#[derive(Debug, Clone)]
pub struct Node {
    id: i32,
    name: String,
    url: String,
    fn_type: FnType,
    links: Vec<Link>,
    nodes: Vec<Node>,
}

impl Node {
    fn push(&mut self, entity: &Entity) {
        match entity.struct_type {
            StructType::Link => {
                self.links.push(Link::from_entity(&entity));
            },
            StructType::Node => {
                self.nodes.push(Node::from_entity(&entity));
            }
        }
    }
}

impl FromEntity for Node {
    fn from_entity(entity: &Entity) -> Self {
        let clone = entity.clone();

        Node {
            id: clone.id,
            name: clone.name,
            url: clone.url,
            fn_type: clone.fn_type,
            links: Vec::new(),
            nodes: Vec::new()
        }
    }

    //TODO entity matcher for nodes
    fn from_entities(entities: Vec<Entity>) -> Vec<Self> {
        let mut node_map: BTreeMap<String, Node> = BTreeMap::new();
        let mut lower = usize::max_value();

        for e in entities.iter() {
            let ref path = e.tree_id;

            if e.struct_type == StructType::Node {
                if path.level() < lower {
                    lower = path.level();
                }

                node_map.insert(path.id(), Node::from_entity(e));
            }
        }

        for e in entities.iter() {
            let inner = e.tree_id.level();

            let parent = match e.tree_id.key(inner - 1) {
                Some(p) => p,
                None => panic!("{:?}", e),
            };

            if let Some(node) = node_map.get_mut(&parent) {
                node.push(e);
            }
        }

        let mut roots = Vec::new();
        println!("{:?}\n", node_map);
        for (key, node) in node_map.into_iter() {
            if level(&key) == lower {
                roots.push(node);
            }
        }

        roots
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#![allow(dead_code)]

/// Literal `Value` instances in the the "db" namespace.
///
/// Used through-out the transactor to match core DB constructs.

use edn::types::Value;
use edn::symbols;

/// Declare a lazy static `ident` of type `Value::NamespacedKeyword` with the given `namespace` and
/// `name`.
///
/// It may look surprising that we declare a new `lazy_static!` block rather than including
/// invocations inside an existing `lazy_static!` block.  The latter cannot be done, since macros
/// are expanded outside-in.  Looking at the `lazy_static!` source suggests that there is no harm in
/// repeating that macro, since internally a multi-`static` block is expanded into many
/// single-`static` blocks.
///
/// TODO: take just ":db.part/db" and define DB_PART_DB using "db.part" and "db".
macro_rules! lazy_static_namespaced_keyword_value (
    ($tag:ident, $namespace:expr, $name:expr) => (
        lazy_static! {
            pub static ref $tag: Value = {
                Value::NamespacedKeyword(symbols::NamespacedKeyword::new($namespace, $name))
            };
        }
    )
);

lazy_static_namespaced_keyword_value!(DB_ADD, "db", "add");
lazy_static_namespaced_keyword_value!(DB_ALTER_ATTRIBUTE, "db.alter", "attribute");
lazy_static_namespaced_keyword_value!(DB_CARDINALITY, "db", "cardinality");
lazy_static_namespaced_keyword_value!(DB_CARDINALITY_MANY, "db.cardinality", "many");
lazy_static_namespaced_keyword_value!(DB_CARDINALITY_ONE, "db.cardinality", "one");
lazy_static_namespaced_keyword_value!(DB_FULLTEXT, "db", "fulltext");
lazy_static_namespaced_keyword_value!(DB_IDENT, "db", "ident");
lazy_static_namespaced_keyword_value!(DB_INDEX, "db", "index");
lazy_static_namespaced_keyword_value!(DB_INSTALL_ATTRIBUTE, "db.install", "attribute");
lazy_static_namespaced_keyword_value!(DB_IS_COMPONENT, "db", "component");
lazy_static_namespaced_keyword_value!(DB_NO_HISTORY, "db", "noHistory");
lazy_static_namespaced_keyword_value!(DB_PART_DB, "db.part", "db");
lazy_static_namespaced_keyword_value!(DB_RETRACT, "db", "retract");
lazy_static_namespaced_keyword_value!(DB_TYPE_BOOLEAN, "db.type", "boolean");
lazy_static_namespaced_keyword_value!(DB_TYPE_DOUBLE, "db.type", "double");
lazy_static_namespaced_keyword_value!(DB_TYPE_INSTANT, "db.type", "instant");
lazy_static_namespaced_keyword_value!(DB_TYPE_KEYWORD, "db.type", "keyword");
lazy_static_namespaced_keyword_value!(DB_TYPE_LONG, "db.type", "long");
lazy_static_namespaced_keyword_value!(DB_TYPE_REF, "db.type", "ref");
lazy_static_namespaced_keyword_value!(DB_TYPE_STRING, "db.type", "string");
lazy_static_namespaced_keyword_value!(DB_TYPE_URI, "db.type", "uri");
lazy_static_namespaced_keyword_value!(DB_TYPE_UUID, "db.type", "uuid");
lazy_static_namespaced_keyword_value!(DB_UNIQUE, "db", "unique");
lazy_static_namespaced_keyword_value!(DB_UNIQUE_IDENTITY, "db.unique", "identity");
lazy_static_namespaced_keyword_value!(DB_UNIQUE_VALUE, "db.unique", "value");
lazy_static_namespaced_keyword_value!(DB_VALUE_TYPE, "db", "valueType");
<commit_msg>Fix merge conflict.<commit_after>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#![allow(dead_code)]

/// Literal `Value` instances in the the "db" namespace.
///
/// Used through-out the transactor to match core DB constructs.

use edn::types::Value;
use edn::symbols;

/// Declare a lazy static `ident` of type `Value::NamespacedKeyword` with the given `namespace` and
/// `name`.
///
/// It may look surprising that we declare a new `lazy_static!` block rather than including
/// invocations inside an existing `lazy_static!` block.  The latter cannot be done, since macros
/// are expanded outside-in.  Looking at the `lazy_static!` source suggests that there is no harm in
/// repeating that macro, since internally a multi-`static` block is expanded into many
/// single-`static` blocks.
///
/// TODO: take just ":db.part/db" and define DB_PART_DB using "db.part" and "db".
macro_rules! lazy_static_namespaced_keyword_value (
    ($tag:ident, $namespace:expr, $name:expr) => (
        lazy_static! {
            pub static ref $tag: Value = {
                Value::NamespacedKeyword(symbols::NamespacedKeyword::new($namespace, $name))
            };
        }
    )
);

lazy_static_namespaced_keyword_value!(DB_ADD, "db", "add");
lazy_static_namespaced_keyword_value!(DB_ALTER_ATTRIBUTE, "db.alter", "attribute");
lazy_static_namespaced_keyword_value!(DB_CARDINALITY, "db", "cardinality");
lazy_static_namespaced_keyword_value!(DB_CARDINALITY_MANY, "db.cardinality", "many");
lazy_static_namespaced_keyword_value!(DB_CARDINALITY_ONE, "db.cardinality", "one");
lazy_static_namespaced_keyword_value!(DB_FULLTEXT, "db", "fulltext");
lazy_static_namespaced_keyword_value!(DB_IDENT, "db", "ident");
lazy_static_namespaced_keyword_value!(DB_INDEX, "db", "index");
lazy_static_namespaced_keyword_value!(DB_INSTALL_ATTRIBUTE, "db.install", "attribute");
lazy_static_namespaced_keyword_value!(DB_IS_COMPONENT, "db", "isComponent");
lazy_static_namespaced_keyword_value!(DB_NO_HISTORY, "db", "noHistory");
lazy_static_namespaced_keyword_value!(DB_PART_DB, "db.part", "db");
lazy_static_namespaced_keyword_value!(DB_RETRACT, "db", "retract");
lazy_static_namespaced_keyword_value!(DB_TYPE_BOOLEAN, "db.type", "boolean");
lazy_static_namespaced_keyword_value!(DB_TYPE_DOUBLE, "db.type", "double");
lazy_static_namespaced_keyword_value!(DB_TYPE_INSTANT, "db.type", "instant");
lazy_static_namespaced_keyword_value!(DB_TYPE_KEYWORD, "db.type", "keyword");
lazy_static_namespaced_keyword_value!(DB_TYPE_LONG, "db.type", "long");
lazy_static_namespaced_keyword_value!(DB_TYPE_REF, "db.type", "ref");
lazy_static_namespaced_keyword_value!(DB_TYPE_STRING, "db.type", "string");
lazy_static_namespaced_keyword_value!(DB_TYPE_URI, "db.type", "uri");
lazy_static_namespaced_keyword_value!(DB_TYPE_UUID, "db.type", "uuid");
lazy_static_namespaced_keyword_value!(DB_UNIQUE, "db", "unique");
lazy_static_namespaced_keyword_value!(DB_UNIQUE_IDENTITY, "db.unique", "identity");
lazy_static_namespaced_keyword_value!(DB_UNIQUE_VALUE, "db.unique", "value");
lazy_static_namespaced_keyword_value!(DB_VALUE_TYPE, "db", "valueType");
<|endoftext|>


<commit_before>// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! azure metadata fetcher

mod crypto;

use self::crypto::x509;

use metadata::Metadata;

use hyper::client::Client;
use hyper::header;
use hyper::mime;

use pnet;

use serde_xml_rs::deserialize;

use std::net::{IpAddr, Ipv4Addr};
use std::fs::File;
use std::path::Path;
use std::io::{BufRead, BufReader, Read};

header! {(MSAgentName, "x-ms-agent-name") => [String]}
header! {(MSVersion, "x-ms-version") => [String]}
header! {(MSCipherName, "x-ms-cipher-name") => [String]}
header! {(MSCert, "x-ms-guest-agent-public-x509-cert") => [String]}

const OPTION_245: &str = "OPTION_245";
const MS_AGENT_NAME: &str = "com.coreos.metadata";
const MS_VERSION: &str = "2012-11-30";
const SMIME_HEADER: &str = "\
MIME-Version:1.0
Content-Disposition: attachment; filename=/home/core/encrypted-ssh-cert.pem
Content-Type: application/x-pkcs7-mime; name=/home/core/encrypted-ssh-cert.pem
Content-Transfer-Encoding: base64

";

#[derive(Debug, Deserialize)]
struct GoalState {
    #[serde(rename = "Container")]
    pub container: Container
}

#[derive(Debug, Deserialize)]
struct Container {
    #[serde(rename = "RoleInstanceList")]
    pub role_instance_list: RoleInstanceList
}

#[derive(Debug, Deserialize)]
struct RoleInstanceList {
    #[serde(rename = "RoleInstance")]
    pub role_instances: Vec<RoleInstance>
}

#[derive(Debug, Deserialize)]
struct RoleInstance {
    #[serde(rename = "Configuration")]
    pub configuration: Configuration
}

#[derive(Debug, Deserialize)]
struct Configuration {
    #[serde(rename = "Certificates", default)]
    pub certificates: String
}

#[derive(Debug, Deserialize)]
struct CertificatesFile {
    #[serde(rename = "Data", default)]
    pub data: String
}

struct Azure {
    client: Client,
}

impl Azure {
    fn new() -> Self {
        Azure {
            client: Client::new(),
        }
    }

    // I don't really understand why this is how we need to get this ip
    // address but this is how it works in the original implementation
    // and nobody complains about it, so w/e
    fn get_fabric_address(&self) -> Result<IpAddr, String> {
        // get the interfaces on the machine
        let interfaces = pnet::datalink::interfaces();
        trace!("interfaces - {:?}", interfaces);

        for interface in interfaces {
            trace!("looking at interface {:?}", interface);
            let lease_path = format!("/run/systemd/netif/leases/{}", interface.index);
            let lease_path = Path::new(&lease_path);
            if lease_path.exists() {
                debug!("found lease file - {:?}", lease_path);
                let lease = File::open(&lease_path)
                    .map_err(wrap_error!("failed to open lease file ({:?})", lease_path))?;
                let lease = BufReader::new(&lease);

                // find the OPTION_245 flag
                for line in lease.lines() {
                    let line = line
                        .map_err(wrap_error!("failed to read from lease file ({:?})", lease_path))?;
                    let option: Vec<&str> = line.split('=').collect();
                    if option.len() > 1 && option[0] == OPTION_245 {
                        // value is an 8 digit hex value. convert it to u32 and
                        // then parse that into an ip. Ipv4Addr::from(u32)
                        // performs conversion from big-endian
                        trace!("found fabric address in hex - {:?}", option[1]);
                        let dec = u32::from_str_radix(option[1], 16)
                            .map_err(wrap_error!("failed to convert '{}' from hex", option[1]))?;
                        return Ok(IpAddr::V4(Ipv4Addr::from(dec)));
                    }
                }

                debug!("failed to get fabric address from existing lease file '{:?}'", lease_path);
            }
        }

        Err(format!("failed to retrieve fabric address"))
    }

    fn get_certs_endpoint(&self) -> Result<String, String> {
        // get the address that we need to call to get the goalstate
        let addr = self.get_fabric_address()
            .map_err(wrap_error!("failed to get fabric address"))?;

        // make the request to the goalstate endpoint
        let mut res = self.client.get(&format!("http://{}/machine/?comp=goalstate", addr))
            .header(MSAgentName(MS_AGENT_NAME.to_owned()))
            .header(MSVersion(MS_VERSION.to_owned()))
            .header(header::ContentType(mime::Mime(mime::TopLevel::Text, mime::SubLevel::Xml, vec![(mime::Attr::Charset, mime::Value::Utf8)])))
            .send()
            .map_err(wrap_error!("failed to request goal state"))?;

        // read the goalstate body
        let mut body = String::new();
        res.read_to_string(&mut body)
            .map_err(wrap_error!("failed to read goal state response body"))?;

        // then deserialize the response into xml
        let goalstate: GoalState = deserialize(body.as_bytes())
            .map_err(wrap_error!("failed to deserialize xml into goalstate struct"))?;

        // grab the certificates endpoint from the xml and return it
        let cert_endpoint: &str = &goalstate.container.role_instance_list.role_instances[0].configuration.certificates;
        Ok(String::from(cert_endpoint))
    }

    fn get_certs(&self, endpoint: String, mangled_pem: String) -> Result<String, String> {
        // we need to make the request to the endpoint we got earlier to get the
        // certificates file.
        let mut res = self.client.get(&endpoint)
            .header(MSAgentName(MS_AGENT_NAME.to_owned()))
            .header(MSVersion(MS_VERSION.to_owned()))
            .header(header::ContentType(mime::Mime(mime::TopLevel::Text, mime::SubLevel::Xml, vec![(mime::Attr::Charset, mime::Value::Utf8)])))
            .header(MSCipherName("DES_EDE3_CBC".to_owned()))
            .header(MSCert(mangled_pem))
            .send()
            .map_err(wrap_error!("failed to fetch certificates"))?;

        let mut body = String::new();
        res.read_to_string(&mut body)
            .map_err(wrap_error!("failed to read certificates file from response body"))?;

        // deserialize that too.
        let certs: CertificatesFile = deserialize(body.as_bytes())
            .map_err(wrap_error!("failed to deserialize xml into CertificatesFile struct"))?;

        // the cms decryption expects it to have MIME information on the top
        // since cms is really for email attachments...don't tell the cops.
        let mut smime = String::from(SMIME_HEADER);
        smime.push_str(&certs.data);

        Ok(smime)
    }

    // put it all together
    fn get_ssh_pubkey(&self) -> Result<String, String> {
        // first we have to get the certificates endoint.
        let certs_endpoint = self.get_certs_endpoint()
            .map_err(wrap_error!("failed to get certs endpoint"))?;

        // we have to generate the rsa public/private keypair and the x509 cert
        // that we use to make the request. this is equivalent to
        // `openssl req -x509 -nodes -subj /CN=LinuxTransport -days 365 -newkey rsa:2048 -keyout private.pem -out cert.pem`
        let (x509, pkey) = x509::generate_cert(x509::Config::new(2048, 365))
            .map_err(wrap_error!("failed to generate keys"))?;

        // mangle the pem file for the request
        let mangled_pem = crypto::mangle_pem(&x509)
            .map_err(wrap_error!("failed to mangle pem"))?;

        // fetch the encrypted cms blob from the certs endpoint
        let smime = self.get_certs(certs_endpoint, mangled_pem)
            .map_err(wrap_error!("failed to get certs"))?;

        // decrypt the cms blob
        let p12 = crypto::decrypt_cms(smime.as_bytes(), &pkey, &x509)
            .map_err(wrap_error!("failed to decrypt cms blob"))?;

        // convert that to the OpenSSH public key format
        let ssh_pubkey = crypto::p12_to_ssh_pubkey(&p12)
            .map_err(wrap_error!("failed to convert pkcs12 blob to ssh pubkey"))?;

        Ok(ssh_pubkey)
    }
}

pub fn fetch_metadata() -> Result<Metadata, String> {
    let provider = Azure::new();

    let ssh_pubkey = provider.get_ssh_pubkey()
        .map_err(wrap_error!("azure: failed to get ssh pubkey"))?;

    Ok(Metadata::builder()
       .add_ssh_key(ssh_pubkey)
       .build())
}
<commit_msg>azure: validate fabric version<commit_after>// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! azure metadata fetcher

mod crypto;

use self::crypto::x509;

use metadata::Metadata;

use hyper::client::Client;
use hyper::header;
use hyper::mime;

use pnet;

use serde_xml_rs::deserialize;

use std::net::{IpAddr, Ipv4Addr};
use std::fs::File;
use std::path::Path;
use std::io::{BufRead, BufReader, Read};

header! {(MSAgentName, "x-ms-agent-name") => [String]}
header! {(MSVersion, "x-ms-version") => [String]}
header! {(MSCipherName, "x-ms-cipher-name") => [String]}
header! {(MSCert, "x-ms-guest-agent-public-x509-cert") => [String]}

const OPTION_245: &str = "OPTION_245";
const MS_AGENT_NAME: &str = "com.coreos.metadata";
const MS_VERSION: &str = "2012-11-30";
const SMIME_HEADER: &str = "\
MIME-Version:1.0
Content-Disposition: attachment; filename=/home/core/encrypted-ssh-cert.pem
Content-Type: application/x-pkcs7-mime; name=/home/core/encrypted-ssh-cert.pem
Content-Transfer-Encoding: base64

";

#[derive(Debug, Deserialize)]
struct GoalState {
    #[serde(rename = "Container")]
    pub container: Container
}

#[derive(Debug, Deserialize)]
struct Container {
    #[serde(rename = "RoleInstanceList")]
    pub role_instance_list: RoleInstanceList
}

#[derive(Debug, Deserialize)]
struct RoleInstanceList {
    #[serde(rename = "RoleInstance")]
    pub role_instances: Vec<RoleInstance>
}

#[derive(Debug, Deserialize)]
struct RoleInstance {
    #[serde(rename = "Configuration")]
    pub configuration: Configuration
}

#[derive(Debug, Deserialize)]
struct Configuration {
    #[serde(rename = "Certificates", default)]
    pub certificates: String
}

#[derive(Debug, Deserialize)]
struct CertificatesFile {
    #[serde(rename = "Data", default)]
    pub data: String
}

#[derive(Debug, Deserialize)]
struct Versions {
    #[serde(rename = "Supported")]
    pub supported: Supported
}

#[derive(Debug, Deserialize)]
struct Supported {
    #[serde(rename = "Version", default)]
    pub versions: Vec<String>
}

struct Azure {
    client: Client,
    endpoint: IpAddr,
}

impl Azure {
    fn new() -> Result<Self, String> {
        let addr = Azure::get_fabric_address()
            .map_err(wrap_error!("failed to get fabric address"))?;
        let azure = Azure {
            client: Client::new(),
            endpoint: addr,
        };
        azure.is_fabric_compatible(MS_VERSION)
            .map_err(wrap_error!("failed version compatibility check"))?;
        Ok(azure)
    }

    // I don't really understand why this is how we need to get this ip
    // address but this is how it works in the original implementation
    // and nobody complains about it, so w/e
    fn get_fabric_address() -> Result<IpAddr, String> {
        // get the interfaces on the machine
        let interfaces = pnet::datalink::interfaces();
        trace!("interfaces - {:?}", interfaces);

        for interface in interfaces {
            trace!("looking at interface {:?}", interface);
            let lease_path = format!("/run/systemd/netif/leases/{}", interface.index);
            let lease_path = Path::new(&lease_path);
            if lease_path.exists() {
                debug!("found lease file - {:?}", lease_path);
                let lease = File::open(&lease_path)
                    .map_err(wrap_error!("failed to open lease file ({:?})", lease_path))?;
                let lease = BufReader::new(&lease);

                // find the OPTION_245 flag
                for line in lease.lines() {
                    let line = line
                        .map_err(wrap_error!("failed to read from lease file ({:?})", lease_path))?;
                    let option: Vec<&str> = line.split('=').collect();
                    if option.len() > 1 && option[0] == OPTION_245 {
                        // value is an 8 digit hex value. convert it to u32 and
                        // then parse that into an ip. Ipv4Addr::from(u32)
                        // performs conversion from big-endian
                        trace!("found fabric address in hex - {:?}", option[1]);
                        let dec = u32::from_str_radix(option[1], 16)
                            .map_err(wrap_error!("failed to convert '{}' from hex", option[1]))?;
                        return Ok(IpAddr::V4(Ipv4Addr::from(dec)));
                    }
                }

                debug!("failed to get fabric address from existing lease file '{:?}'", lease_path);
            }
        }

        Err(format!("failed to retrieve fabric address"))
    }

    fn is_fabric_compatible(&self, version: &str) -> Result<(), String> {
        let mut res = self.client.get(&format!("http://{}/?comp=versions", self.endpoint))
            .header(MSAgentName(MS_AGENT_NAME.to_owned()))
            .header(MSVersion(MS_VERSION.to_owned()))
            .header(header::ContentType(mime::Mime(mime::TopLevel::Text, mime::SubLevel::Xml, vec![(mime::Attr::Charset, mime::Value::Utf8)])))
            .send()
            .map_err(wrap_error!("failed to request versions"))?;

        let mut body = String::new();
        res.read_to_string(&mut body)
            .map_err(wrap_error!("failed to read versions response body"))?;

        let versions: Versions = deserialize(body.as_bytes())
            .map_err(wrap_error!("failed to deserialize xml into versions struct"))?;

        if versions.supported.versions.iter().any(|v| v == version) {
            Ok(())
        } else {
            Err(format!("fabric version {} not compatible with fabric address {}", MS_VERSION, self.endpoint))
        }
    }

    fn get_certs_endpoint(&self) -> Result<String, String> {
        // make the request to the goalstate endpoint
        let mut res = self.client.get(&format!("http://{}/machine/?comp=goalstate", self.endpoint))
            .header(MSAgentName(MS_AGENT_NAME.to_owned()))
            .header(MSVersion(MS_VERSION.to_owned()))
            .header(header::ContentType(mime::Mime(mime::TopLevel::Text, mime::SubLevel::Xml, vec![(mime::Attr::Charset, mime::Value::Utf8)])))
            .send()
            .map_err(wrap_error!("failed to request goal state"))?;

        // read the goalstate body
        let mut body = String::new();
        res.read_to_string(&mut body)
            .map_err(wrap_error!("failed to read goal state response body"))?;

        // then deserialize the response into xml
        let goalstate: GoalState = deserialize(body.as_bytes())
            .map_err(wrap_error!("failed to deserialize xml into goalstate struct"))?;

        // grab the certificates endpoint from the xml and return it
        let cert_endpoint: &str = &goalstate.container.role_instance_list.role_instances[0].configuration.certificates;
        Ok(String::from(cert_endpoint))
    }

    fn get_certs(&self, endpoint: String, mangled_pem: String) -> Result<String, String> {
        // we need to make the request to the endpoint we got earlier to get the
        // certificates file.
        let mut res = self.client.get(&endpoint)
            .header(MSAgentName(MS_AGENT_NAME.to_owned()))
            .header(MSVersion(MS_VERSION.to_owned()))
            .header(header::ContentType(mime::Mime(mime::TopLevel::Text, mime::SubLevel::Xml, vec![(mime::Attr::Charset, mime::Value::Utf8)])))
            .header(MSCipherName("DES_EDE3_CBC".to_owned()))
            .header(MSCert(mangled_pem))
            .send()
            .map_err(wrap_error!("failed to fetch certificates"))?;

        let mut body = String::new();
        res.read_to_string(&mut body)
            .map_err(wrap_error!("failed to read certificates file from response body"))?;

        // deserialize that too.
        let certs: CertificatesFile = deserialize(body.as_bytes())
            .map_err(wrap_error!("failed to deserialize xml into CertificatesFile struct"))?;

        // the cms decryption expects it to have MIME information on the top
        // since cms is really for email attachments...don't tell the cops.
        let mut smime = String::from(SMIME_HEADER);
        smime.push_str(&certs.data);

        Ok(smime)
    }

    // put it all together
    fn get_ssh_pubkey(&self) -> Result<String, String> {
        // first we have to get the certificates endoint.
        let certs_endpoint = self.get_certs_endpoint()
            .map_err(wrap_error!("failed to get certs endpoint"))?;

        // we have to generate the rsa public/private keypair and the x509 cert
        // that we use to make the request. this is equivalent to
        // `openssl req -x509 -nodes -subj /CN=LinuxTransport -days 365 -newkey rsa:2048 -keyout private.pem -out cert.pem`
        let (x509, pkey) = x509::generate_cert(x509::Config::new(2048, 365))
            .map_err(wrap_error!("failed to generate keys"))?;

        // mangle the pem file for the request
        let mangled_pem = crypto::mangle_pem(&x509)
            .map_err(wrap_error!("failed to mangle pem"))?;

        // fetch the encrypted cms blob from the certs endpoint
        let smime = self.get_certs(certs_endpoint, mangled_pem)
            .map_err(wrap_error!("failed to get certs"))?;

        // decrypt the cms blob
        let p12 = crypto::decrypt_cms(smime.as_bytes(), &pkey, &x509)
            .map_err(wrap_error!("failed to decrypt cms blob"))?;

        // convert that to the OpenSSH public key format
        let ssh_pubkey = crypto::p12_to_ssh_pubkey(&p12)
            .map_err(wrap_error!("failed to convert pkcs12 blob to ssh pubkey"))?;

        Ok(ssh_pubkey)
    }
}

pub fn fetch_metadata() -> Result<Metadata, String> {
    let provider = Azure::new()
        .map_err(wrap_error!("azure: failed create metadata client"))?;

    let ssh_pubkey = provider.get_ssh_pubkey()
        .map_err(wrap_error!("azure: failed to get ssh pubkey"))?;

    Ok(Metadata::builder()
       .add_ssh_key(ssh_pubkey)
       .build())
}
<|endoftext|>


<commit_before>#![feature(core_intrinsics)]

use std::intrinsics;
use std::mem::{size_of, size_of_val};

struct Bomb;

impl Drop for Bomb {
    fn drop(&mut self) {
        eprintln!("BOOM!");
    }
}

fn main() {
    assert_eq!(size_of::<Option<i32>>(), 8);
    assert_eq!(size_of_val(&()), 0);
    assert_eq!(size_of_val(&42), 4);
    assert_eq!(size_of_val(&[] as &[i32]), 0);
    assert_eq!(size_of_val(&[1, 2, 3] as &[i32]), 12);
    assert_eq!(size_of_val("foobar"), 6);

    assert_eq!(intrinsics::type_name::<Option<i32>>(), "core::option::Option<i32>");

    assert_eq!(intrinsics::likely(false), false);
    assert_eq!(intrinsics::unlikely(true), true);

    unsafe { intrinsics::forget(Bomb); }
}
<commit_msg>Auto merge of #1429 - RalfJung:discriminant_value, r=RalfJung<commit_after>#![feature(core_intrinsics)]

use std::intrinsics;
use std::mem::{size_of, size_of_val};

struct Bomb;

impl Drop for Bomb {
    fn drop(&mut self) {
        eprintln!("BOOM!");
    }
}

fn main() {
    assert_eq!(size_of::<Option<i32>>(), 8);
    assert_eq!(size_of_val(&()), 0);
    assert_eq!(size_of_val(&42), 4);
    assert_eq!(size_of_val(&[] as &[i32]), 0);
    assert_eq!(size_of_val(&[1, 2, 3] as &[i32]), 12);
    assert_eq!(size_of_val("foobar"), 6);

    assert_eq!(intrinsics::type_name::<Option<i32>>(), "core::option::Option<i32>");

    assert_eq!(intrinsics::likely(false), false);
    assert_eq!(intrinsics::unlikely(true), true);

    unsafe { intrinsics::forget(Bomb); }

    let _v = intrinsics::discriminant_value(&Some(()));
    let _v = intrinsics::discriminant_value(&0);
    let _v = intrinsics::discriminant_value(&true);
    let _v = intrinsics::discriminant_value(&vec![1,2,3]);
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2020 Fabian Schuiki

use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{
    parse::{Parse, ParseStream},
    DeriveInput,
};

pub(crate) fn node(args: TokenStream, input: TokenStream) -> TokenStream {
    // Parse the input.
    let _args = syn::parse_macro_input!(args as NodeConfig);
    let mut input = syn::parse_macro_input!(input as DeriveInput);

    // Extract the name of the node.
    let vis = input.vis.clone();
    let generics = input.generics.clone();
    let node_name = input.ident.clone();
    let node_name_str = node_name.to_string();

    // Rename the node.
    let data_name = format_ident!("{}{}", node_name, "Data");
    input.ident = data_name.clone();

    // Generate the wrapper node.
    let mut output = proc_macro2::TokenStream::new();
    output.extend(quote! {
        #[moore_derive::walk_visitor]
        #vis type #node_name #generics = Node<'a, #data_name #generics>;
    });

    // Emit the modified data.
    output.extend(quote! {
        #[derive(moore_derive::AcceptVisitor)]
        #input
    });

    // Schedule the node for inclusion in `AllNode`.
    crate::all_node::add_node(&node_name, &generics);

    // Implement the `BasicNode` trait for this node.
    output.extend(quote! {
        impl<'a> BasicNode<'a> for #node_name #generics {
            fn type_name(&self) -> &'static str {
                #node_name_str
            }

            fn as_all(&'a self) -> AllNode<'a> {
                AllNode::from(self)
            }

            fn as_any(&'a self) -> &'a AnyNode<'a> {
                self
            }
        }
    });

    // match &input.data {
    //     syn::Data::Struct(input) => println!("found struct {:?}", input),
    //     syn::Data::Enum(input) => println!("found enum {:?}", input),
    //     _ => panic!("unsupported item"),
    // }

    output.into()
}

struct NodeConfig {}

impl Parse for NodeConfig {
    fn parse(_input: ParseStream) -> syn::Result<Self> {
        Ok(NodeConfig {})
    }
}
<commit_msg>derive: Fix lifetimes of certain nodes<commit_after>// Copyright (c) 2016-2020 Fabian Schuiki

use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{
    parse::{Parse, ParseStream},
    DeriveInput,
};

pub(crate) fn node(args: TokenStream, input: TokenStream) -> TokenStream {
    // Parse the input.
    let _args = syn::parse_macro_input!(args as NodeConfig);
    let mut input = syn::parse_macro_input!(input as DeriveInput);

    // Extract the name of the node.
    let vis = input.vis.clone();
    let generics = input.generics.clone();
    let node_name = input.ident.clone();
    let node_name_str = node_name.to_string();

    // Rename the node.
    let data_name = format_ident!("{}{}", node_name, "Data");
    input.ident = data_name.clone();

    // Ensure the new type alias has at least one lifetime.
    let mut impl_generics = generics.clone();
    let lt = crate::first_lifetime(&mut impl_generics);

    // Generate the wrapper node.
    let mut output = proc_macro2::TokenStream::new();
    output.extend(quote! {
        #[moore_derive::walk_visitor]
        #vis type #node_name #impl_generics = Node<#lt, #data_name #generics>;
    });

    // Emit the modified data.
    output.extend(quote! {
        #[derive(moore_derive::AcceptVisitor)]
        #input
    });

    // Schedule the node for inclusion in `AllNode`.
    crate::all_node::add_node(&node_name, &impl_generics);

    // Implement the `BasicNode` trait for this node.
    output.extend(quote! {
        impl #impl_generics BasicNode<#lt> for #node_name #impl_generics {
            fn type_name(&self) -> &'static str {
                #node_name_str
            }

            fn as_all(&#lt self) -> AllNode<#lt> {
                AllNode::from(self)
            }

            fn as_any(&#lt self) -> &#lt AnyNode<#lt> {
                self
            }
        }
    });

    // match &input.data {
    //     syn::Data::Struct(input) => println!("found struct {:?}", input),
    //     syn::Data::Enum(input) => println!("found enum {:?}", input),
    //     _ => panic!("unsupported item"),
    // }

    output.into()
}

struct NodeConfig {}

impl Parse for NodeConfig {
    fn parse(_input: ParseStream) -> syn::Result<Self> {
        Ok(NodeConfig {})
    }
}
<|endoftext|>