Commit 51fed28b authored by AdamSimpson's avatar AdamSimpson
Browse files
parents e83fcda8 2414f24c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -10,8 +10,8 @@
class BuilderQueue {
public:
    explicit BuilderQueue(asio::io_service &io_service) : io_service(io_service),
                                                          max_builders(1),
                                                          max_available_builders(max_builders),
                                                          max_builders(20),
                                                          max_available_builders(5),
                                                          pending_requests(0)
                                                          {}

+9 −8
Original line number Diff line number Diff line
@@ -12,7 +12,12 @@ void BuilderQueue::tick(asio::yield_context yield) {
    auto all_builders = OpenStackBuilder::get_builders(io_service, yield);
    std::set<Builder> unavailable_builders;

    // Process reservations
    // Delete reservations that are completed
    reservations.remove_if([](const auto &reservation) {
        return reservation.finalized();
    });

    // Process existing reservations
    for (auto &reservation : reservations) {
        // Set unavailable builders, that is builders which are attached to a reservation
        if (reservation.builder) {
@@ -30,18 +35,13 @@ void BuilderQueue::tick(asio::yield_context yield) {
        }
    }

    // Delete reservations that are completed
    reservations.remove_if([](const auto &reservation) {
        return reservation.finalized();
    });

    // Available_builders = all_builders - unavailable_builders
    std::set<Builder> available_builders;
    std::set_difference(all_builders.begin(), all_builders.end(),
                        unavailable_builders.begin(), unavailable_builders.end(),
                        std::inserter(available_builders, available_builders.begin()));

    // Assign builders to any pending reservations
    // Assign any available builders to any pending reservations
    for (auto &reservation : reservations) {
        if (reservation.pending() && !available_builders.empty()) {
            reservation.ready(*available_builders.begin());
@@ -50,7 +50,8 @@ void BuilderQueue::tick(asio::yield_context yield) {
    }

    // Request new builders if slots are open
    // Care must be taken as all_builders may include the the pending request before it's returned(open_slots, open_available_slots may be negative)
    // Care must be taken as all_builders may include a builder from a pending request that hasn't completely returned yet
    // that is to say open_slots, open_available_slots may be negative
    int open_slots = max_builders - all_builders.size() - pending_requests;
    int open_available_slots = max_available_builders - available_builders.size() - pending_requests;
    int request_count = std::min(open_slots, open_available_slots);
+6 −1
Original line number Diff line number Diff line
@@ -53,7 +53,6 @@ set(HARDENING_FLAGS "-Wall -Wextra -fstack-protector-strong -D_FORTIFY_SOURCE=2
# https://github.com/boostorg/coroutine/issues/30
# -fsanitize=address,undefined -fno-sanitize=vptr -Wl,-z,noexecstack,-z,now,-z,relro,-z,nodlopen


set_target_properties(BuilderQueue PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${HARDENING_FLAGS}")
set_target_properties(BuilderQueue PROPERTIES LINK_FLAGS "${LINK_FLAGS} ${HARDENING_FLAGS}")
set_target_properties(ContainerBuilder PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} ${HARDENING_FLAGS}")
@@ -73,4 +72,10 @@ target_link_libraries(BuilderQueue ${Boost_LIBRARIES})
target_link_libraries(ContainerBuilder ${Boost_LIBRARIES})
target_link_libraries(ContainerBuilderClient ${Boost_LIBRARIES})

# RPATH settings: https://cmake.org/Wiki/CMake_RPATH_handling
SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH "")
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)

install(TARGETS BuilderQueue ContainerBuilder ContainerBuilderClient RUNTIME DESTINATION bin)
 No newline at end of file
+62 −30
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
#include <boost/asio.hpp>
#include <iostream>
#include "Messenger.h"
#include <memory>


namespace asio = boost::asio;
using asio::ip::tcp;
@@ -28,6 +28,34 @@ std::string queue_port() {
    }
    return std::string(env);
}
/*
void display_spinner(asio::io_service &io_service, asio::yield_context &yield, bool display) {
    static bool should_display;
    static boost::asio::deadline_timer timer(io_service);

    should_display = display;

    auto expire_time = boost::posix_time::milliseconds(250);

    asio::spawn(io_service,
                [&](asio::yield_context yield) {
                    while (should_display) {
                        std::cout << "\b--" << std::flush;
                        timer.expires_from_now(expire_time);
                        timer.async_wait(yield);
                        std::cout << "\b\\" << std::flush;
                        timer.expires_from_now(expire_time);
                        timer.async_wait(yield);
                        std::cout << "\b|" << std::flush;
                        timer.expires_from_now(expire_time);
                        timer.async_wait(yield);
                        timer.expires_from_now(expire_time);
                        std::cout << "\b/" << std::flush;
                        timer.async_wait(yield);
                    }
                });
}
*/

int main(int argc, char *argv[]) {

@@ -41,32 +69,38 @@ int main(int argc, char *argv[]) {
        std::string definition_path(argv[1]);
        std::string container_path(argv[2]);

        std::cout << "Attempting to connect to BuilderQueue: " << queue_host() << ":" << queue_port() << std::endl;

        asio::io_service io_service;

        asio::spawn(io_service,
                    [&](asio::yield_context yield) {

                        std::cout << "Attempting to connect to BuilderQueue: " << queue_host() << ":" << queue_port()
                                  << std::endl;

                        tcp::socket queue_socket(io_service);
                        tcp::resolver queue_resolver(io_service);
                        boost::system::error_code ec;
        asio::connect(queue_socket, queue_resolver.resolve({queue_host(), queue_port()}));

                        asio::async_connect(queue_socket, queue_resolver.resolve({queue_host(), queue_port()}), yield);

                        std::cout << "Connected to BuilderQueue: " << queue_host() << ":" << queue_port() << std::endl;

                        Messenger queue_messenger(queue_socket);

                        // Initiate a build request
        queue_messenger.send("checkout_builder_request");
                        queue_messenger.async_send("checkout_builder_request", yield);

        // Receive an available builder
        auto builder = queue_messenger.receive_builder();
                        // Wait on a builder from the queue
                        auto builder = queue_messenger.async_receive_builder(yield);

        std::cout << "Attempting to connect to build host: " << builder.host << ":" << builder.port << std::endl;
                        std::cout << "Attempting to connect to build host: " << builder.host << ":" << builder.port
                                  << std::endl;

        // Block until the initial connection to the builder is made
                        tcp::socket builder_socket(io_service);
                        tcp::resolver builder_resolver(io_service);
                        do {
            asio::connect(builder_socket, builder_resolver.resolve({builder.host, builder.port}), ec);
                            asio::async_connect(builder_socket, builder_resolver.resolve({builder.host, builder.port}),
                                                yield[ec]);
                        } while (ec != boost::system::errc::success);

                        std::cout << "Connected to builder host: " << builder.host << ":" << builder.port << std::endl;
@@ -74,14 +108,12 @@ int main(int argc, char *argv[]) {
                        Messenger builder_messenger(builder_socket);

                        // Once we're connected to the builder start the client process
        asio::spawn(io_service,
                    [&](asio::yield_context yield) {
                        std::cout << "Sending definition: " << definition_path << std::endl;

                        // Send the definition file
                        builder_messenger.async_send_file(definition_path, yield, true);

                        std::cout << "Start reading builder output:" << std::endl;
                        std::cout << "Start of Singularity builder output:" << std::endl;

                        // Hide the cursor and disable buffering for cleaner output
                        std::cout << "\e[?25l" << std::flush;
@@ -94,11 +126,11 @@ int main(int argc, char *argv[]) {
                        } while (!line.empty());

                        // Read the container image
                        std::cout << "Begin receive of container: " << container_path << std::endl;
                        std::cout << "Sending finished container: " << container_path << std::endl;

                        builder_messenger.async_receive_file(container_path, yield, true);

                        std::cout << "End receive of container: " << container_path << std::endl;
                        std::cout << "Container received: " << container_path << std::endl;

                        // Inform the queue we're done
                        queue_messenger.async_send(std::string("checkout_builder_complete"), yield);