#intecture #api-server #server #api

intecture/intecture_api

配置服务器核心 API

1 个不稳定版本

使用旧的 Rust 2015

0.2.1 2016 年 8 月 11 日

#53#api-server

30 星 & 3 关注者

MPL-2.0 许可证

150KB
3K SLoC

核心 API

核心 API 包含用于配置主机的端点和它们所依赖的底层 OS 抽象。通常,您会使用 Intecture Proj (proj/) 代替,它导出核心 API,尽管对于某些应用程序,核心 API 就足够了。

项目结构

核心 API 按端点组织成一系列目录(例如 command/host/ 等)。每个端点内部有一个 providers/ 目录,其中包含底层抽象。

用法

有关 API 用法,请参阅 示例


lib.rs:

Intecture 是一个用于管理服务器的 API。您可以将其视为 DevOps 工具,但没有复杂的生态系统和专有垃圾。

核心 API 是 Intecture 的核心。它包含所有用于配置主机的端点以及它们所依赖的底层 OS 抽象。通常,您将通过 intecture_proj 消费此 API,它导出 intecture_api,尽管对于不需要正式结构的项目(例如安装程序),此 API 就足够了。

项目结构

核心 API 组织成一系列模块(称为“端点”,例如 commandpackage 等),这些模块代表您通常手动执行的基本配置任务。每个端点内部有一个 providers 模块,其中包含为端点执行繁重工作的特定于 OS 的抽象。

例如,package 端点有一个名为 Package 的结构体。这是一个跨平台的抽象,用于管理服务器上的软件包。在这个抽象背后是特定软件包 提供者 的具体实现,例如 Yum 或 Apt。如果您通过 Package::new() 函数实例化一个新的 Package 对象,系统将自动选择最适合您服务器的提供者。所有端点都适用此规则。

主机

到目前为止,我们讨论了如何使用端点来自动化配置任务,但 Intecture 如何知道我们想要与哪个服务器通信呢?这就是我们需要的 host 端点。所有事物都从主机开始!顺便提一下——如果我们做“商品”,那可能就是 T 恤。不过,抛开糟糕的市场决策不谈,您需要创建一个主机才能进行任何操作。

主机分为 LocalPlain 两种类型。Local 类型指向您的本地机器,而 Plain 类型是一种远程主机类型,通过网络连接到远程机器。无论您选择哪种类型,只需将其作为所需内容传递给端点即可,Intecture 会完成其余的工作。

“为什么是 Plain?”您可能会问。嗯,因为 Plain 主机类型是一个使用 TCP 发送/接收 纯文本 数据的远程主机。

示例

以下是 examples/ 文件夹中的 基本示例 的复制版

extern crate futures;
extern crate intecture_api;
extern crate tokio_core;

use futures::{Future, Stream};
use intecture_api::prelude::*;
use tokio_core::reactor::Core;

fn main() {
    // These two lines are part of `tokio-core` and can be safely ignored. So
    // long as they appear at the top of your code, all is fine with the world.
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    // Here's the meat of your project. In this example we're talking to our
    // local machine, so we use the `Local` host type.
    let host = Local::new(&handle).and_then(|host| {
        // Ok, we're in! Now we can pass our `host` handle to other endpoints,
        // which informs them of the server we mean to talk to.

        // Let's start with something basic - a shell command.
        let cmd = Command::new(&host, "whoami", None);
        cmd.exec().and_then(|mut status| {
            // At this point, our command is running. As the API is
            // asynchronous, we don't have to wait for it to finish before
            // inspecting its output. This is called "streaming".

            // First let's grab the stream from `CommandStatus`. This stream is
            // a stream of strings, each of which represents a line of command
            // output. We can use the `for_each` combinator to print these
            // lines to stdout.
            //
            // If printing isn't your thing, you are also free to lick them or
            // whatever you're into. I'm not here to judge.
            let stream = status.take_stream()
                .unwrap() // Unwrap is fine here as we haven't called it before
                .for_each(|line| { println!("{}", line); Ok(()) });

            // Next, let's check on the result of our command.
            // `CommandStatus` is a `Future` that represents the command's
            // exit status. We can use the `map` combinator to print it out.*
            //
            // * Same caveat as above RE: printing. This is a safe
            //   place.
            let status = status.map(|s| println!("This command {} {}",
                if s.success { "succeeded" } else { "failed" },
                if let Some(e) = s.code { format!("with code {}", e) } else { String::new() }));

            // Finally, we need to return these two `Future`s (stream and
            // status) so that they will be executed by the event loop. Sadly
            // we can't return them both as a tuple, so we use the join
            // combinator instead to turn them into a single `Future`. Easy!
            stream.join(status)
        })
    });

    // This line is part of `tokio-core` and is used to execute the
    // chain of futures you've created above. You'll need to call
    // `core.run()` for each host you interact with, otherwise your
    // project will not run at all!
    core.run(host).unwrap();
}

API 预览。

依赖关系

~16MB
~302K SLoC