From 2af2c4f092aa7efffe839ec615c06d22cf43cc3b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 16 Mar 2021 20:21:59 +0300 Subject: Add support for interactive builds --- bbot/agent/agent.cxx | 80 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 5 deletions(-) (limited to 'bbot/agent/agent.cxx') diff --git a/bbot/agent/agent.cxx b/bbot/agent/agent.cxx index 6c2e0d9..d85ecf5 100644 --- a/bbot/agent/agent.cxx +++ b/bbot/agent/agent.cxx @@ -8,6 +8,7 @@ #include // signal() #include // rand_r() #include // sleep(), getuid(), fsync(), [f]stat() +#include // getifaddrs(), freeifaddrs() #include // stat #include // [f]stat() #include // flock() @@ -62,6 +63,7 @@ namespace bbot uint16_t offset; string hname; + string hip; uid_t uid; string uname; } @@ -179,7 +181,8 @@ bootstrap_machine (const dir_path& md, mm, obmm ? obmm->machine.mac : nullopt, ops.bridge (), - tftpd.port ())); + tftpd.port (), + false /* pub_vnc */)); { // If we are terminating with an exception then force the machine down. @@ -888,7 +891,8 @@ try mm.machine, mm.machine.mac, ops.bridge (), - tftpd.port ())); + tftpd.port (), + tm.interactive.has_value ())); // Note: the machine handling logic is similar to bootstrap. // @@ -947,7 +951,9 @@ try // size_t to; const size_t startup_to (120); - const size_t build_to (ops.build_timeout ()); + const size_t build_to (tm.interactive + ? ops.intactive_timeout () + : ops.build_timeout ()); // Wait periodically making sure the machine is still alive. // @@ -1093,6 +1099,8 @@ try uid = getuid (); uname = getpwuid (uid)->pw_name; + // Obtain our hostname. + // { char buf[HOST_NAME_MAX + 1]; @@ -1103,6 +1111,44 @@ try hname = buf; } + // Obtain our IP address as a first discovered non-loopback IPv4 address. + // + // Note: Linux-specific implementation. + // + { + ifaddrs* i; + if (getifaddrs (&i) == -1) + fail << "unable to obtain IP addresses: " + << system_error (errno, std::generic_category ()); // Sanitize. + + unique_ptr deleter (i, freeifaddrs); + + for (; i != nullptr; i = i->ifa_next) + { + sockaddr* sa (i->ifa_addr); + + if (sa != nullptr && // Configured. + (i->ifa_flags & IFF_LOOPBACK) == 0 && // Not a loopback interface. + (i->ifa_flags & IFF_UP) != 0 && // Up. + sa->sa_family == AF_INET) // Ignore IPv6 for now. + { + char buf[INET_ADDRSTRLEN]; // IPv4 address. + if (inet_ntop (AF_INET, + &reinterpret_cast (sa)->sin_addr, + buf, + sizeof (buf)) == nullptr) + fail << "unable to obtain IPv4 address: " + << system_error (errno, std::generic_category ()); // Sanitize. + + hip = buf; + break; + } + } + + if (hip.empty ()) + fail << "no IPv4 address configured"; + } + // On POSIX ignore SIGPIPE which is signaled to a pipe-writing process if // the pipe reading end is closed. Note that by default this signal // terminates a process. Also note that there is no way to disable this @@ -1246,6 +1292,15 @@ try return std::uniform_int_distribution (50, 60) (g); }; + optional imode; + optional ilogin; + + if (ops.interactive () != interactive_mode::false_) + { + imode = ops.interactive (); + ilogin = machine_vnc (true /* public */); + } + for (unsigned int sleep (0);; ::sleep (sleep), sleep = 0) { bootstrapped_machines ms (enumerate_machines (ops.machines ())); @@ -1256,6 +1311,8 @@ try hname, tc_name, tc_ver, + imode, + ilogin, fingerprint, machine_header_manifests {} }; @@ -1379,6 +1436,19 @@ try continue; } + // Make sure that the task interactivity matches the requested mode. + // + if (( t.interactive && !imode) || + (!t.interactive && imode && *imode == interactive_mode::true_)) + { + if (t.interactive) + error << "interactive task from " << u << ": " << *t.interactive; + else + error << "non-interactive task from " << u; + + continue; + } + l2 ([&]{trace << "task for " << t.name << '/' << t.version << " " << "on " << t.machine << " " << "from " << u;}); @@ -1558,7 +1628,7 @@ namespace bbot iface_addr (const string& i) { if (i.size () >= IFNAMSIZ) - throw invalid_argument ("interface nama too long"); + throw invalid_argument ("interface name too long"); auto_fd fd (socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)); @@ -1572,7 +1642,7 @@ namespace bbot if (ioctl (fd.get (), SIOCGIFADDR, &ifr) == -1) throw_system_error (errno); - char buf[3 * 4 + 3 + 1]; // IPv4 address. + char buf[INET_ADDRSTRLEN]; // IPv4 address. if (inet_ntop (AF_INET, &reinterpret_cast (&ifr.ifr_addr)->sin_addr, buf, -- cgit v1.1