mirror of https://github.com/BOINC/boinc.git
fix and simplify docker detection
Signed-off-by: Vitalii Koshura <lestat.de.lionkur@gmail.com>
This commit is contained in:
parent
6c3d4eb832
commit
ecc6d7899c
|
@ -280,24 +280,15 @@ void CLIENT_STATE::show_host_info() {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
if (host_info.docker_use){
|
||||
if (host_info.docker_available) {
|
||||
msg_printf(NULL, MSG_INFO, "Docker is installed and available");
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
msg_printf(NULL, MSG_INFO, "Docker is not installed or is not available for running task");
|
||||
}
|
||||
|
||||
if (strlen(host_info.docker_compose_version)){
|
||||
if ((strstr(host_info.docker_compose_version, "v1")) && (strstr(host_info.docker_compose_version, "v2"))){
|
||||
msg_printf(NULL, MSG_INFO, "Docker compose (new and old versions: docker-compose and docker compose) is installed and available for running task");
|
||||
}else if (strstr(host_info.docker_compose_version, "v1")) {
|
||||
msg_printf(NULL, MSG_INFO, "Docker compose (old version: docker-compose) is installed and available for running task");
|
||||
}else if (strstr(host_info.docker_compose_version, "v2")){
|
||||
msg_printf(NULL, MSG_INFO, "Docker compose (new version: docker compose) is installed and available for running task");
|
||||
}
|
||||
else{
|
||||
msg_printf(NULL, MSG_INFO, "Docker compose is not installed or is not available for running task");
|
||||
}
|
||||
if (host_info.docker_compose_available) {
|
||||
msg_printf(NULL, MSG_INFO, "Docker compose is installed and available");
|
||||
} else {
|
||||
msg_printf(NULL, MSG_INFO, "Docker compose is not installed or is not available for running task");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2022 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -977,13 +977,6 @@ int CLIENT_STATE::parse_app_info(PROJECT* p, FILE* in) {
|
|||
delete avp;
|
||||
continue;
|
||||
}
|
||||
if (cc_config.dont_use_docker_compose && strstr(avp->plan_class, "docker")) {
|
||||
msg_printf(p, MSG_INFO,
|
||||
"skipping app with docker compose in app_info.xml; docker compose disabled in cc_config.xml"
|
||||
);
|
||||
delete avp;
|
||||
continue;
|
||||
}
|
||||
if (strlen(avp->platform) == 0) {
|
||||
safe_strcpy(avp->platform, get_primary_platform());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2021 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -20,7 +20,6 @@
|
|||
// Try to keep this well-organized and not nested.
|
||||
|
||||
#include "version.h" // version numbers from autoconf
|
||||
#include <fstream>
|
||||
#include "cpp.h"
|
||||
#include "config.h"
|
||||
|
||||
|
@ -1237,91 +1236,38 @@ int HOST_INFO::get_virtualbox_version() {
|
|||
//check if docker compose or docker-compose is installed on volunteer's host
|
||||
//
|
||||
int HOST_INFO::get_docker_compose_info(){
|
||||
FILE* fd;
|
||||
char buf[MAXPATHLEN];
|
||||
|
||||
std::ofstream compose_file ("docker-compose.yaml");
|
||||
compose_file << "version: \"2\"\nservices: \n hello: \n image: \"hello-world\" \n" << std::endl;
|
||||
|
||||
char* docker_command = "docker-compose up 2>&1";
|
||||
fd = popen(docker_command, "r");
|
||||
if (fd){
|
||||
while(!feof(fd)){
|
||||
if (fgets(buf, sizeof(buf), fd)){
|
||||
if (strstr(buf, "Hello from Docker!")){
|
||||
safe_strcat(docker_compose_version, "v1");
|
||||
break;
|
||||
}
|
||||
}
|
||||
FILE* f = popen(command_get_docker_compose_version, "r");
|
||||
if (f) {
|
||||
char buf[256];
|
||||
fgets(buf, 256, f);
|
||||
std::string version;
|
||||
if (get_docker_compose_version_string(buf, version)) {
|
||||
docker_compose_available = true;
|
||||
safe_strcpy(docker_compose_version, version.c_str());
|
||||
}
|
||||
pclose(fd);
|
||||
pclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
docker_command = "docker compose up 2>&1";
|
||||
fd = popen(docker_command, "r");
|
||||
if (fd){
|
||||
while(!feof(fd)){
|
||||
if (fgets(buf, sizeof(buf), fd)){
|
||||
if (strstr(buf, "Hello from Docker!")){
|
||||
safe_strcat(docker_compose_version, "v2");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pclose(fd);
|
||||
}
|
||||
|
||||
std::remove("docker-compose.yaml");
|
||||
|
||||
if (!(strstr(docker_compose_version, "v1"))){
|
||||
if (!(strstr(docker_compose_version, "v2"))){
|
||||
safe_strcat(docker_compose_version, "not_used");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//check if docker is installed on volunteer's host
|
||||
//
|
||||
int HOST_INFO::get_docker_info(bool& docker_use){
|
||||
char buf[256];
|
||||
char buf_command[256];
|
||||
FILE* fd;
|
||||
FILE* fd_1;
|
||||
char docker_cmd [256];
|
||||
|
||||
strcpy(docker_cmd, "which -a docker 2>&1");
|
||||
fd = popen(docker_cmd, "r");
|
||||
if (fd){
|
||||
while(!feof(fd)){
|
||||
if (fgets(buf, sizeof(buf), fd)){
|
||||
strip_whitespace(buf);
|
||||
if (!(access(buf, X_OK))){
|
||||
strcpy(docker_cmd, buf);
|
||||
strcat(docker_cmd, " run --rm hello-world 2>&1");
|
||||
fd_1 = popen(docker_cmd, "r");
|
||||
if (fd_1){
|
||||
while(!feof(fd_1)){
|
||||
if (fgets(buf_command, sizeof(buf_command), fd_1)){
|
||||
if (strstr(buf_command, "Hello from Docker!")){
|
||||
docker_use = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pclose(fd_1);
|
||||
}
|
||||
}
|
||||
if (docker_use){
|
||||
break;
|
||||
}
|
||||
}
|
||||
int HOST_INFO::get_docker_info(){
|
||||
FILE* f = popen(command_get_docker_version, "r");
|
||||
if (f) {
|
||||
char buf[256];
|
||||
fgets(buf, 256, f);
|
||||
std::string version;
|
||||
if (get_docker_version_string(buf, version)) {
|
||||
docker_available = true;
|
||||
safe_strcpy(docker_version, version.c_str());
|
||||
}
|
||||
pclose(fd);
|
||||
pclose(f);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1773,10 +1719,7 @@ int HOST_INFO::get_host_info(bool init) {
|
|||
}
|
||||
|
||||
if(!cc_config.dont_use_docker){
|
||||
get_docker_info(docker_use);
|
||||
}
|
||||
|
||||
if(!cc_config.dont_use_docker_compose){
|
||||
get_docker_info();
|
||||
get_docker_compose_info();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2018 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -29,8 +29,6 @@
|
|||
#include "str_util.h"
|
||||
#include "str_replace.h"
|
||||
#include "util.h"
|
||||
#include <fstream>
|
||||
|
||||
|
||||
#include "client_msgs.h"
|
||||
#include "client_types.h"
|
||||
|
@ -1552,98 +1550,6 @@ int get_network_usage_totals(unsigned int& total_received, unsigned int& total_s
|
|||
return iRetVal;
|
||||
}
|
||||
|
||||
//check if docker compose or docker-compose is installed on volunteer's host
|
||||
//
|
||||
int HOST_INFO::get_docker_compose_info(){
|
||||
FILE* fd;
|
||||
char buf[MAXPATHLEN];
|
||||
|
||||
std::ofstream compose_file ("docker-compose.yaml");
|
||||
compose_file << "version: \"2\"\nservices: \n hello: \n image: \"hello-world\" \n" << std::endl;
|
||||
|
||||
char* docker_command = "wsl docker-compose up 2>&1";
|
||||
fd = _popen(docker_command, "r");
|
||||
if (fd){
|
||||
while(!feof(fd)){
|
||||
if (fgets(buf, sizeof(buf), fd)){
|
||||
if (strstr(buf, "Hello from Docker!")){
|
||||
safe_strcat(docker_compose_version, "v1");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pclose(fd);
|
||||
}
|
||||
|
||||
docker_command = "wsl docker compose up 2>&1";
|
||||
fd = _popen(docker_command, "r");
|
||||
if (fd){
|
||||
while(!feof(fd)){
|
||||
if (fgets(buf, sizeof(buf), fd)){
|
||||
if (strstr(buf, "Hello from Docker!")){
|
||||
safe_strcat(docker_compose_version, "v2");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pclose(fd);
|
||||
}
|
||||
|
||||
std::remove("docker-compose.yaml");
|
||||
|
||||
if (!(strstr(docker_compose_version, "v1"))){
|
||||
if (!(strstr(docker_compose_version, "v2"))){
|
||||
safe_strcat(docker_compose_version, "not_used");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//check if docker is installed on volunteer's host
|
||||
//
|
||||
int HOST_INFO::get_docker_info(bool& docker_use){
|
||||
char buf[256];
|
||||
FILE* fd;
|
||||
FILE *fd_1;
|
||||
|
||||
char* docker_command = "wsl which -a docker 2>&1";
|
||||
fd = _popen(docker_command, "r");
|
||||
if (fd) {
|
||||
while (!feof(fd)){
|
||||
if (fgets(buf + 4, sizeof(buf), fd)){
|
||||
buf[0] = 'w';
|
||||
buf[1] = 's';
|
||||
buf[2] = 'l';
|
||||
buf[3] = ' ';
|
||||
int i, j;
|
||||
for (i = 0, j = 0; buf[i]; i++) {
|
||||
if (buf[i] != '\n') {
|
||||
buf[j++] = buf[i];
|
||||
}
|
||||
}
|
||||
buf[j] = '\0';
|
||||
docker_command = strcat(buf, " run --rm hello-world 2>&1");
|
||||
fd_1 = _popen(docker_command, "r");
|
||||
if (fd_1){
|
||||
while (!feof(fd_1)){
|
||||
if (fgets(buf, sizeof(buf), fd_1)){
|
||||
if (strstr(buf, "Hello from Docker!")){
|
||||
docker_use = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pclose(fd_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
_pclose(fd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// see if Virtualbox is installed
|
||||
//
|
||||
int HOST_INFO::get_virtualbox_version() {
|
||||
|
@ -1763,26 +1669,9 @@ int HOST_INFO::get_host_info(bool init) {
|
|||
if (!cc_config.dont_use_wsl) {
|
||||
OSVERSIONINFOEX osvi;
|
||||
if (get_OSVERSIONINFO(osvi) && osvi.dwMajorVersion >= 10) {
|
||||
get_wsl_information(wsl_available, wsls);
|
||||
get_wsl_information(wsl_available, wsls, !cc_config.dont_use_docker, docker_available, docker_compose_available);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!cc_config.dont_use_docker) && (!cc_config.dont_use_wsl)){
|
||||
if (wsl_available){
|
||||
for (size_t i = 0; i < wsls.wsls.size(); ++i){
|
||||
const WSL& wsl = wsls.wsls[i];
|
||||
if (wsl.is_default){
|
||||
if (wsl.version.find("WSL2") != std::string::npos){
|
||||
get_docker_info(docker_use);
|
||||
if (!cc_config.dont_use_docker_compose){
|
||||
get_docker_compose_info();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
if (!cc_config.dont_use_vbox) {
|
||||
get_virtualbox_version();
|
||||
|
|
|
@ -98,15 +98,74 @@ bool get_available_wsls(std::vector<std::pair<std::string, DWORD>>& wsls, std::s
|
|||
|
||||
typedef HRESULT(WINAPI *PWslLaunch)(PCWSTR, PCWSTR, BOOL, HANDLE, HANDLE, HANDLE, HANDLE*);
|
||||
|
||||
HINSTANCE wsl_lib = NULL;
|
||||
struct resource_helper {
|
||||
public:
|
||||
HINSTANCE wsl_lib = NULL;
|
||||
HANDLE in_read = NULL;
|
||||
HANDLE in_write = NULL;
|
||||
HANDLE out_read = NULL;
|
||||
HANDLE out_write = NULL;
|
||||
PWslLaunch pWslLaunch = NULL;
|
||||
|
||||
HANDLE in_read = NULL;
|
||||
HANDLE in_write = NULL;
|
||||
HANDLE out_read = NULL;
|
||||
HANDLE out_write = NULL;
|
||||
~resource_helper() {
|
||||
close_handle(in_read);
|
||||
close_handle(in_write);
|
||||
close_handle(out_read);
|
||||
close_handle(out_write);
|
||||
|
||||
PWslLaunch pWslLaunch = NULL;
|
||||
if (wsl_lib) {
|
||||
FreeLibrary(wsl_lib);
|
||||
}
|
||||
}
|
||||
|
||||
// prepare resources
|
||||
int prepare_resources() {
|
||||
wsl_lib = NULL;
|
||||
in_read = NULL;
|
||||
in_write = NULL;
|
||||
out_read = NULL;
|
||||
out_write = NULL;
|
||||
pWslLaunch = NULL;
|
||||
|
||||
wsl_lib = LoadLibrary("wslapi.dll");
|
||||
if (!wsl_lib) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pWslLaunch = (PWslLaunch)GetProcAddress(wsl_lib, "WslLaunch");
|
||||
|
||||
if (!pWslLaunch) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.bInheritHandle = TRUE;
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
|
||||
if (!CreatePipe(&out_read, &out_write, &sa, 0)) {
|
||||
return 1;
|
||||
}
|
||||
if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
|
||||
return 1;
|
||||
}
|
||||
if (!CreatePipe(&in_read, &in_write, &sa, 0)) {
|
||||
return 1;
|
||||
}
|
||||
if (!SetHandleInformation(in_write, HANDLE_FLAG_INHERIT, 0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
inline void close_handle(HANDLE handle) {
|
||||
if (handle) {
|
||||
CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//convert std::string to PCWSTR
|
||||
//taken from https://stackoverflow.com/questions/27220/how-to-convert-stdstring-to-lpcwstr-in-c-unicode
|
||||
|
@ -121,11 +180,11 @@ std::wstring s2ws(const std::string& s)
|
|||
return r;
|
||||
}
|
||||
|
||||
bool create_wsl_process(const std::string& wsl_distro_name, const std::string& command, HANDLE* handle, bool use_current_work_dir = false) {
|
||||
return (pWslLaunch(s2ws(wsl_distro_name).c_str(), s2ws(command).c_str(), use_current_work_dir, in_read, out_write, out_write, handle) == S_OK);
|
||||
bool create_wsl_process(const resource_helper& rs, const std::string& wsl_distro_name, const std::string& command, HANDLE* handle, bool use_current_work_dir = false) {
|
||||
return (rs.pWslLaunch(s2ws(wsl_distro_name).c_str(), s2ws(command).c_str(), use_current_work_dir, rs.in_read, rs.out_write, rs.out_write, handle) == S_OK);
|
||||
}
|
||||
|
||||
bool CreateWslProcess(const std::string& wsl_app, const std::string& command, HANDLE& handle) {
|
||||
bool CreateWslProcess(const HANDLE& out_write, const std::string& wsl_app, const std::string& command, HANDLE& handle) {
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
|
||||
|
@ -152,26 +211,7 @@ bool CreateWslProcess(const std::string& wsl_app, const std::string& command, HA
|
|||
return res;
|
||||
}
|
||||
|
||||
inline void close_handle(HANDLE handle) {
|
||||
if (handle) {
|
||||
CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
|
||||
int free_resources_and_exit(const int return_code) {
|
||||
close_handle(in_read);
|
||||
close_handle(in_write);
|
||||
close_handle(out_read);
|
||||
close_handle(out_write);
|
||||
|
||||
if (wsl_lib) {
|
||||
FreeLibrary(wsl_lib);
|
||||
}
|
||||
|
||||
return return_code;
|
||||
}
|
||||
|
||||
std::string read_from_pipe(HANDLE handle) {
|
||||
std::string read_from_pipe(const HANDLE& handle, const HANDLE& out_read) {
|
||||
DWORD avail, read, exitcode;
|
||||
const int bufsize = 256;
|
||||
char buf[bufsize];
|
||||
|
@ -222,14 +262,7 @@ void parse_sysctl_output(const std::vector<std::string>& lines, std::string& ost
|
|||
|
||||
// Returns the OS name and version for WSL when enabled
|
||||
//
|
||||
int get_wsl_information(bool& wsl_available, WSLS& wsls) {
|
||||
wsl_lib = NULL;
|
||||
in_read = NULL;
|
||||
in_write = NULL;
|
||||
out_read = NULL;
|
||||
out_write = NULL;
|
||||
pWslLaunch = NULL;
|
||||
|
||||
int get_wsl_information(bool& wsl_available, WSLS& wsls, bool detect_docker, bool& docker_available, bool& docker_compose_available) {
|
||||
std::vector<std::pair<std::string, DWORD>> distros;
|
||||
std::string default_distro;
|
||||
|
||||
|
@ -237,44 +270,25 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
wsl_lib = LoadLibrary("wslapi.dll");
|
||||
if (!wsl_lib) {
|
||||
resource_helper rs;
|
||||
|
||||
if (rs.prepare_resources()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pWslLaunch = (PWslLaunch) GetProcAddress(wsl_lib, "WslLaunch");
|
||||
|
||||
if (!pWslLaunch) {
|
||||
free_resources_and_exit(1);
|
||||
}
|
||||
|
||||
wsl_available = false;
|
||||
docker_available = false;
|
||||
docker_compose_available = false;
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
HANDLE handle;
|
||||
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.bInheritHandle = TRUE;
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
|
||||
if (!CreatePipe(&out_read, &out_write, &sa, 0)) {
|
||||
return 1;
|
||||
}
|
||||
if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
|
||||
return free_resources_and_exit(1);
|
||||
}
|
||||
if (!CreatePipe(&in_read, &in_write, &sa, 0)) {
|
||||
return free_resources_and_exit(1);
|
||||
}
|
||||
if (!SetHandleInformation(in_write, HANDLE_FLAG_INHERIT, 0)) {
|
||||
return free_resources_and_exit(1);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < distros.size(); ++i) {
|
||||
char wsl_dist_name[256];
|
||||
char wsl_dist_version[256];
|
||||
|
||||
const std::string& distro = distros[i].first;
|
||||
// skip 'docker-desktop-data'
|
||||
// Ref: https://stackoverflow.com/a/61431088/4210508
|
||||
if (distro == "docker-desktop-data"){
|
||||
continue;
|
||||
}
|
||||
|
@ -288,32 +302,32 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
|
|||
wsl.wsl_version = std::to_string(distros[i].second);
|
||||
|
||||
// lsbrelease
|
||||
if (!create_wsl_process(distro, command_lsbrelease, &handle)) {
|
||||
if (!create_wsl_process(rs, distro, command_lsbrelease, &handle)) {
|
||||
continue;
|
||||
}
|
||||
wsl_available = HOST_INFO::parse_linux_os_info(
|
||||
read_from_pipe(handle), lsbrelease, wsl_dist_name, sizeof(wsl_dist_name), wsl_dist_version, sizeof(wsl_dist_version));
|
||||
read_from_pipe(handle, rs.out_read), lsbrelease, wsl_dist_name, sizeof(wsl_dist_name), wsl_dist_version, sizeof(wsl_dist_version));
|
||||
CloseHandle(handle);
|
||||
|
||||
if (!wsl_available) {
|
||||
//osrelease
|
||||
const std::string command_osrelease = "cat " + std::string(file_osrelease);
|
||||
if (!create_wsl_process(distro, command_osrelease, &handle)) {
|
||||
if (!create_wsl_process(rs, distro, command_osrelease, &handle)) {
|
||||
continue;
|
||||
}
|
||||
wsl_available = HOST_INFO::parse_linux_os_info(
|
||||
read_from_pipe(handle), osrelease, wsl_dist_name, sizeof(wsl_dist_name), wsl_dist_version, sizeof(wsl_dist_version));
|
||||
read_from_pipe(handle, rs.out_read), osrelease, wsl_dist_name, sizeof(wsl_dist_name), wsl_dist_version, sizeof(wsl_dist_version));
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
//redhatrelease
|
||||
if (!wsl_available) {
|
||||
const std::string command_redhatrelease = "cat " + std::string(file_redhatrelease);
|
||||
if (!create_wsl_process(distro, command_redhatrelease, &handle)) {
|
||||
if (!create_wsl_process(rs, distro, command_redhatrelease, &handle)) {
|
||||
continue;
|
||||
}
|
||||
wsl_available = HOST_INFO::parse_linux_os_info(
|
||||
read_from_pipe(handle), redhatrelease, wsl_dist_name, sizeof(wsl_dist_name), wsl_dist_version, sizeof(wsl_dist_version));
|
||||
read_from_pipe(handle, rs.out_read), redhatrelease, wsl_dist_name, sizeof(wsl_dist_name), wsl_dist_version, sizeof(wsl_dist_version));
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
|
@ -326,16 +340,16 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
|
|||
|
||||
// sysctl -a
|
||||
const std::string command_sysctl = "sysctl -a";
|
||||
if (create_wsl_process(distro, command_sysctl, &handle)) {
|
||||
parse_sysctl_output(split(read_from_pipe(handle), '\n'), os_name, os_version_extra);
|
||||
if (create_wsl_process(rs, distro, command_sysctl, &handle)) {
|
||||
parse_sysctl_output(split(read_from_pipe(handle, rs.out_read), '\n'), os_name, os_version_extra);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
// uname -s
|
||||
if (os_name.empty()) {
|
||||
const std::string command_uname_s = "uname -s";
|
||||
if (create_wsl_process(distro, command_uname_s, &handle)) {
|
||||
os_name = read_from_pipe(handle);
|
||||
if (create_wsl_process(rs, distro, command_uname_s, &handle)) {
|
||||
os_name = read_from_pipe(handle, rs.out_read);
|
||||
strip_whitespace(os_name);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
@ -344,8 +358,8 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
|
|||
// uname -r
|
||||
if (os_version_extra.empty()) {
|
||||
const std::string command_uname_r = "uname -r";
|
||||
if (create_wsl_process(distro, command_uname_r ,&handle)) {
|
||||
os_version_extra = read_from_pipe(handle);
|
||||
if (create_wsl_process(rs, distro, command_uname_r ,&handle)) {
|
||||
os_version_extra = read_from_pipe(handle, rs.out_read);
|
||||
strip_whitespace(os_version_extra);
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
@ -363,10 +377,34 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
|
|||
else {
|
||||
wsl.os_version = wsl_dist_version;
|
||||
}
|
||||
|
||||
if (detect_docker) {
|
||||
if (create_wsl_process(rs, distro, command_get_docker_version, &handle)) {
|
||||
std::string raw = read_from_pipe(handle, rs.out_read);
|
||||
std::string version;
|
||||
wsl.is_docker_available = HOST_INFO::get_docker_version_string(raw, version);
|
||||
if (wsl.is_docker_available) {
|
||||
docker_available = true;
|
||||
wsl.docker_version = version;
|
||||
}
|
||||
CloseHandle(handle);
|
||||
}
|
||||
if (create_wsl_process(rs, distro, command_get_docker_compose_version, &handle)) {
|
||||
std::string raw = read_from_pipe(handle, rs.out_read);
|
||||
std::string version;
|
||||
wsl.is_docker_compose_available = HOST_INFO::get_docker_compose_version_string(raw, version);
|
||||
if (wsl.is_docker_compose_available) {
|
||||
docker_compose_available = true;
|
||||
wsl.docker_compose_version = version;
|
||||
}
|
||||
CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
|
||||
wsls.wsls.push_back(wsl);
|
||||
}
|
||||
|
||||
return free_resources_and_exit(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // _WIN64
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2018 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -198,11 +198,8 @@ void CC_CONFIG::show() {
|
|||
if (dont_use_wsl) {
|
||||
msg_printf(NULL, MSG_INFO, "Config: don't use the Windows Subsystem for Linux");
|
||||
}
|
||||
if (dont_use_docker){
|
||||
if (dont_use_docker) {
|
||||
msg_printf(NULL, MSG_INFO, "Config: don't use the Docker");
|
||||
}
|
||||
if (dont_use_docker_compose){
|
||||
msg_printf(NULL, MSG_INFO, "Config: don't use the Docker compose");
|
||||
}
|
||||
for (i=0; i<alt_platforms.size(); i++) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
|
@ -380,7 +377,6 @@ int CC_CONFIG::parse_options_client(XML_PARSER& xp) {
|
|||
if (xp.parse_bool("dont_use_vbox", dont_use_vbox)) continue;
|
||||
if (xp.parse_bool("dont_use_wsl", dont_use_wsl)) continue;
|
||||
if (xp.parse_bool("dont_use_docker", dont_use_docker)) continue;
|
||||
if (xp.parse_bool("dont_use_docker_compose", dont_use_docker_compose)) continue;
|
||||
if (xp.match_tag("exclude_gpu")) {
|
||||
EXCLUDE_GPU eg;
|
||||
retval = eg.parse(xp);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2023 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -376,7 +376,9 @@ struct HOST {
|
|||
WSLS wsls;
|
||||
|
||||
//Docker available
|
||||
bool docker_use;
|
||||
bool docker_available;
|
||||
bool docker_compose_available;
|
||||
char docker_version[256];
|
||||
char docker_compose_version[256];
|
||||
|
||||
// stuff from time_stats
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2018 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -216,7 +216,6 @@ void CC_CONFIG::defaults() {
|
|||
dont_use_vbox = false;
|
||||
dont_use_wsl = false;
|
||||
dont_use_docker = false;
|
||||
dont_use_docker_compose = false;
|
||||
exclude_gpus.clear();
|
||||
exclusive_apps.clear();
|
||||
exclusive_gpu_apps.clear();
|
||||
|
@ -350,7 +349,6 @@ int CC_CONFIG::parse_options(XML_PARSER& xp) {
|
|||
if (xp.parse_bool("dont_suspend_nci", dont_suspend_nci)) continue;
|
||||
if (xp.parse_bool("dont_use_vbox", dont_use_vbox)) continue;
|
||||
if (xp.parse_bool("dont_use_docker", dont_use_docker)) continue;
|
||||
if (xp.parse_bool("dont_use_docker_compose", dont_use_docker_compose)) continue;
|
||||
if (xp.parse_bool("dont_use_wsl", dont_use_wsl)) continue;
|
||||
if (xp.match_tag("exclude_gpu")) {
|
||||
EXCLUDE_GPU eg;
|
||||
|
@ -570,8 +568,7 @@ int CC_CONFIG::write(MIOFILE& out, LOG_FLAGS& log_flags) {
|
|||
" <dont_suspend_nci>%d</dont_suspend_nci>\n"
|
||||
" <dont_use_vbox>%d</dont_use_vbox>\n"
|
||||
" <dont_use_wsl>%d</dont_use_wsl>\n"
|
||||
" <dont_use_docker>%d</dont_use_docker>\n"
|
||||
" <dont_use_docker_compose>%d</dont_use_docker_compose>\n",
|
||||
" <dont_use_docker>%d</dont_use_docker>\n",
|
||||
disallow_attach,
|
||||
dont_check_file_sizes,
|
||||
dont_contact_ref_site,
|
||||
|
@ -579,8 +576,7 @@ int CC_CONFIG::write(MIOFILE& out, LOG_FLAGS& log_flags) {
|
|||
dont_suspend_nci,
|
||||
dont_use_vbox,
|
||||
dont_use_wsl,
|
||||
dont_use_docker,
|
||||
dont_use_docker_compose
|
||||
dont_use_docker
|
||||
);
|
||||
|
||||
for (i=0; i<exclude_gpus.size(); i++) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2018 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -168,7 +168,6 @@ struct CC_CONFIG {
|
|||
bool dont_use_vbox;
|
||||
bool dont_use_wsl;
|
||||
bool dont_use_docker;
|
||||
bool dont_use_docker_compose;
|
||||
std::vector<EXCLUDE_GPU> exclude_gpus;
|
||||
std::vector<std::string> exclusive_apps;
|
||||
std::vector<std::string> exclusive_gpu_apps;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2023 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -71,9 +71,15 @@ void HOST_INFO::clear_host_info() {
|
|||
safe_strcpy(os_name, "");
|
||||
safe_strcpy(os_version, "");
|
||||
|
||||
#ifdef _WIN64
|
||||
wsl_available = false;
|
||||
docker_use =false;
|
||||
#endif
|
||||
docker_available = false;
|
||||
docker_compose_available = false;
|
||||
#ifndef _WIN64
|
||||
safe_strcpy(docker_version, "");
|
||||
safe_strcpy(docker_compose_version, "");
|
||||
#endif
|
||||
#ifdef _WIN64
|
||||
wsls.clear();
|
||||
#endif
|
||||
|
@ -135,14 +141,17 @@ int HOST_INFO::parse(XML_PARSER& xp, bool static_items_only) {
|
|||
if (xp.parse_str("os_name", os_name, sizeof(os_name))) continue;
|
||||
if (xp.parse_str("os_version", os_version, sizeof(os_version))) continue;
|
||||
#ifdef _WIN64
|
||||
if (xp.parse_bool("os_wsl_enabled", wsl_available)) continue;
|
||||
if (xp.parse_bool("wsl_available", wsl_available)) continue;
|
||||
if (xp.match_tag("wsl")) {
|
||||
this->wsls.parse(xp);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (xp.parse_bool("docker_use", docker_use)) continue;
|
||||
if (xp.parse_bool("docker_available", docker_available)) continue;
|
||||
#ifndef _WIN64
|
||||
if (xp.parse_str("docker_version", docker_version, sizeof(docker_version))) continue;
|
||||
if (xp.parse_str("docker_compose_version", docker_compose_version, sizeof(docker_compose_version))) continue;
|
||||
#endif
|
||||
if (xp.parse_str("product_name", product_name, sizeof(product_name))) continue;
|
||||
if (xp.parse_str("virtualbox_version", virtualbox_version, sizeof(virtualbox_version))) continue;
|
||||
if (xp.match_tag("coprocs")) {
|
||||
|
@ -212,7 +221,7 @@ int HOST_INFO::write(
|
|||
" <os_version>%s</os_version>\n"
|
||||
" <n_usable_coprocs>%d</n_usable_coprocs>\n"
|
||||
" <wsl_available>%d</wsl_available>\n"
|
||||
" <docker_use>%d</docker_use>\n",
|
||||
" <docker_available>%d</docker_available>\n",
|
||||
host_cpid,
|
||||
p_ncpus,
|
||||
pv,
|
||||
|
@ -236,12 +245,26 @@ int HOST_INFO::write(
|
|||
#else
|
||||
0,
|
||||
#endif
|
||||
docker_use ? 1 : 0
|
||||
docker_available ? 1 : 0
|
||||
);
|
||||
#ifdef _WIN64
|
||||
if (wsl_available) {
|
||||
wsls.write_xml(out);
|
||||
}
|
||||
#endif
|
||||
#ifndef _WIN64
|
||||
if (strlen(docker_version)) {
|
||||
out.printf(
|
||||
" <docker_version>%s</docker_version>\n",
|
||||
docker_version
|
||||
);
|
||||
}
|
||||
if (strlen(docker_compose_version)) {
|
||||
out.printf(
|
||||
" <docker_compose_version>%s</docker_compose_version>\n",
|
||||
docker_compose_version
|
||||
);
|
||||
}
|
||||
#endif
|
||||
if (strlen(product_name)) {
|
||||
xml_escape(product_name, pn, sizeof(pn));
|
||||
|
@ -264,14 +287,20 @@ int HOST_INFO::write(
|
|||
buf
|
||||
);
|
||||
}
|
||||
if (strlen(docker_compose_version)){
|
||||
char buf[256];
|
||||
xml_escape(docker_compose_version, buf, sizeof(buf));
|
||||
#ifndef _WIN64
|
||||
if (docker_available){
|
||||
out.printf(
|
||||
" <docker_compose_version>%s</docker_compose_version>\n",
|
||||
buf
|
||||
" <docker_version>%s</docker_compose_version>\n",
|
||||
docker_version
|
||||
);
|
||||
}
|
||||
if (docker_compose_available){
|
||||
out.printf(
|
||||
" <docker_compose_version>%s</docker_compose_version>\n",
|
||||
docker_compose_version
|
||||
);
|
||||
}
|
||||
#endif
|
||||
if (include_coprocs) {
|
||||
this->coprocs.write_xml(out, false);
|
||||
}
|
||||
|
@ -331,3 +360,27 @@ int HOST_INFO::write_cpu_benchmarks(FILE* out) {
|
|||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool HOST_INFO::get_docker_version_string(std::string raw, std::string& parsed) {
|
||||
std::string prefix = "Docker version";
|
||||
size_t pos1 = raw.find(prefix);
|
||||
if (pos1 == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
size_t pos2 = raw.find(",");
|
||||
if (pos2 == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
parsed = raw.substr(pos1 + prefix.size() + 1, pos2 - pos1 - prefix.size() - 1);
|
||||
return true;
|
||||
}
|
||||
bool HOST_INFO::get_docker_compose_version_string(std::string raw, std::string& parsed) {
|
||||
std::string prefix = "Docker Compose version v";
|
||||
size_t pos1 = raw.find(prefix);
|
||||
if (pos1 == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
parsed = raw.substr(pos1 + prefix.size(), raw.size() - pos1 - prefix.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ enum LINUX_OS_INFO_PARSER {
|
|||
const char command_lsbrelease[] = "/usr/bin/lsb_release -a 2>&1";
|
||||
const char file_osrelease[] = "/etc/os-release";
|
||||
const char file_redhatrelease[] = "/etc/redhat-release";
|
||||
const char command_get_docker_version[] = "docker --version";
|
||||
const char command_get_docker_compose_version[] = "docker compose version";
|
||||
|
||||
// if you add fields, update clear_host_info()
|
||||
|
||||
|
@ -80,11 +82,19 @@ public:
|
|||
char os_name[256];
|
||||
char os_version[256];
|
||||
|
||||
bool docker_available;
|
||||
bool docker_compose_available;
|
||||
#ifndef _WIN64
|
||||
// on Windows we can have several docker installation within WSL
|
||||
// that is why it makes no sense to have this information put here
|
||||
// instead the information about the available 'docker' and 'docker compose'
|
||||
// installations should be taken from every particular WSL distro
|
||||
char docker_version[256];
|
||||
char docker_compose_version[256];
|
||||
#endif
|
||||
#ifdef _WIN64
|
||||
// WSL information for Win10 only
|
||||
bool wsl_available;
|
||||
bool docker_use;
|
||||
char docker_compose_version[256];
|
||||
#ifdef _WIN64
|
||||
WSLS wsls;
|
||||
#endif
|
||||
|
||||
|
@ -126,8 +136,14 @@ public:
|
|||
int get_host_battery_state();
|
||||
int get_local_network_info();
|
||||
int get_virtualbox_version();
|
||||
int get_docker_info(bool& docker_use);
|
||||
#ifndef _WIN64
|
||||
// on Windows we can have several docker installation within WSL
|
||||
// that is why it makes no sense to have this information put here
|
||||
// instead the information about the available 'docker' and 'docker compose'
|
||||
// installations should be taken from every particular WSL distro
|
||||
int get_docker_info();
|
||||
int get_docker_compose_info();
|
||||
#endif
|
||||
void make_random_string(const char* salt, char* out);
|
||||
void generate_host_cpid();
|
||||
static bool parse_linux_os_info(
|
||||
|
@ -146,6 +162,8 @@ public:
|
|||
char* os_name, const int os_name_size, char* os_version,
|
||||
const int os_version_size
|
||||
);
|
||||
static bool get_docker_version_string(std::string raw, std::string& parsed);
|
||||
static bool get_docker_compose_version_string(std::string raw, std::string& parsed);
|
||||
#ifdef _WIN32
|
||||
void win_get_processor_info();
|
||||
#endif
|
||||
|
@ -154,7 +172,7 @@ public:
|
|||
extern void make_secure_random_string(char*);
|
||||
|
||||
#ifdef _WIN64
|
||||
extern int get_wsl_information(bool& wsl_available, WSLS& wsls);
|
||||
extern int get_wsl_information(bool& wsl_available, WSLS& wsls, bool detect_docker, bool& docker_available, bool& docker_compose_available);
|
||||
extern int get_processor_group(HANDLE);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ void WSL::clear() {
|
|||
os_version = "";
|
||||
is_default = false;
|
||||
wsl_version = "1";
|
||||
is_docker_available = false;
|
||||
is_docker_compose_available = false;
|
||||
docker_version = "";
|
||||
docker_compose_version = "";
|
||||
}
|
||||
|
||||
void WSL::write_xml(MIOFILE& f) {
|
||||
|
@ -41,12 +45,20 @@ void WSL::write_xml(MIOFILE& f) {
|
|||
" <os_version>%s</os_version>\n"
|
||||
" <is_default>%d</is_default>\n"
|
||||
" <wsl_version>%s</wsl_version>\n"
|
||||
" <is_docker_available>%d</is_docker_available>\n"
|
||||
" <is_docker_compose_available>%d</is_docker_compose_available>\n"
|
||||
" <docker_version>%s</docker_version>\n"
|
||||
" <docker_compose_version>%s</docker_compose_version>\n"
|
||||
" </distro>\n",
|
||||
dn,
|
||||
n,
|
||||
v,
|
||||
is_default ? 1 : 0,
|
||||
wsl_version.c_str()
|
||||
wsl_version.c_str(),
|
||||
is_docker_available ? 1 : 0,
|
||||
is_docker_compose_available ? 1 : 0,
|
||||
docker_version.c_str(),
|
||||
docker_compose_version.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -61,6 +73,10 @@ int WSL::parse(XML_PARSER& xp) {
|
|||
if (xp.parse_string("os_version", os_version)) continue;
|
||||
if (xp.parse_bool("is_default", is_default)) continue;
|
||||
if (xp.parse_string("wsl_version", wsl_version)) continue;
|
||||
if (xp.parse_bool("is_docker_available", is_docker_available)) continue;
|
||||
if (xp.parse_bool("is_docker_compose_available", is_docker_compose_available)) continue;
|
||||
if (xp.parse_string("docker_version", docker_version)) continue;
|
||||
if (xp.parse_string("docker_compose_version", docker_compose_version)) continue;
|
||||
}
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,14 @@ struct WSL {
|
|||
std::string wsl_version;
|
||||
// flag indicating whether this is the default WSL distribution
|
||||
bool is_default;
|
||||
// flag indicating whether Docker is available in this WSL distribution
|
||||
bool is_docker_available;
|
||||
// flag indicating whether Docker Compose is available in this WSL distribution
|
||||
bool is_docker_compose_available;
|
||||
// version of Docker installed in this WSL distribution
|
||||
std::string docker_version;
|
||||
// version of Docker Compose installed in this WSL distribution
|
||||
std::string docker_compose_version;
|
||||
|
||||
WSL();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2023 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -456,23 +456,120 @@ bool PLAN_CLASS_SPEC::check(
|
|||
}
|
||||
|
||||
if (docker){
|
||||
if (sreq.core_client_major_version < 8) {
|
||||
add_no_work_message("BOINC client 8.0+ required for Docker jobs");
|
||||
return false;
|
||||
}
|
||||
if (!(sreq.host.docker_use)) {
|
||||
if (!(sreq.host.docker_available)) {
|
||||
add_no_work_message("Docker is not installed or is not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strstr(docker_compose_version, "v1")) && (!(strstr(sreq.host.docker_compose_version, "v1")))){
|
||||
add_no_work_message("Docker compose (older version: docker-compose) is required, but is not installed or is not available");
|
||||
if (docker_compose && !(sreq.host.docker_compose_available)) {
|
||||
add_no_work_message("Docker compose is not installed or is not available");
|
||||
return false;
|
||||
}
|
||||
if (sreq.host.wsl_available) {
|
||||
bool docker_found = false;
|
||||
bool docker_compose_found = false;
|
||||
for (int i = 0; i < sreq.host.wsls.wsls.size(); i++) {
|
||||
if (sreq.host.wsls.wsls[i].is_docker_available) {
|
||||
if (docker_compose && sreq.host.wsls.wsls[i].is_docker_compose_available) {
|
||||
int maj, min, rel;
|
||||
int n = sscanf(sreq.host.wsls.wsls[i].docker_version.c_str(), "%d.%d.%d", &maj, &min, &rel);
|
||||
if (n != 3) {
|
||||
if (config.debug_version_select) {
|
||||
log_messages.printf(MSG_NORMAL,
|
||||
"[version] plan_class_spec: can't parse docker version\n"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int v = maj*10000 + min*100 + rel;
|
||||
if (min_docker_version && v < min_docker_version) {
|
||||
if (config.debug_version_select) {
|
||||
log_messages.printf(MSG_NORMAL,
|
||||
"[version] plan_class_spec: docker version too low: %d < %d\n",
|
||||
v, min_docker_version
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
docker_found = true;
|
||||
}
|
||||
if (!docker_compose && docker_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (docker_compose && sreq.host.wsls.wsls[i].is_docker_compose_available) {
|
||||
int maj, min, rel;
|
||||
int n = sscanf(sreq.host.wsls.wsls[i].docker_compose_version.c_str(), "%d.%d.%d", &maj, &min, &rel);
|
||||
if (n != 3) {
|
||||
if (config.debug_version_select) {
|
||||
log_messages.printf(MSG_NORMAL,
|
||||
"[version] plan_class_spec: can't parse docker compose version\n"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
int v = maj*10000 + min*100 + rel;
|
||||
if (min_docker_compose_version && v < min_docker_compose_version) {
|
||||
if (config.debug_version_select) {
|
||||
log_messages.printf(MSG_NORMAL,
|
||||
"[version] plan_class_spec: docker compose version too low: %d < %d\n",
|
||||
v, min_docker_compose_version
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
docker_compose_found = true;
|
||||
}
|
||||
}
|
||||
if (!docker_found) {
|
||||
add_no_work_message("Suitable Docker is not installed or is not available");
|
||||
return false;
|
||||
}
|
||||
if (docker_compose && !docker_compose_found) {
|
||||
add_no_work_message("Suitable Docker compose is not installed or is not available");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
int maj, min, rel;
|
||||
int n = sscanf(sreq.host.docker_version, "%d.%d.%d", &maj, &min, &rel);
|
||||
if (n != 3) {
|
||||
if (config.debug_version_select) {
|
||||
log_messages.printf(MSG_NORMAL,
|
||||
"[version] plan_class_spec: can't parse docker version\n"
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int v = maj*10000 + min*100 + rel;
|
||||
if (min_docker_version && v < min_docker_version) {
|
||||
if (config.debug_version_select) {
|
||||
log_messages.printf(MSG_NORMAL,
|
||||
"[version] plan_class_spec: docker version too low: %d < %d\n",
|
||||
v, min_docker_version
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strstr(docker_compose_version, "v2")) && (!(strstr(sreq.host.docker_compose_version, "v2")))){
|
||||
add_no_work_message("Docker compose (newer version: docker compose) is required, but is not installed or is not available");
|
||||
return false;
|
||||
n = sscanf(sreq.host.docker_compose_version, "%d.%d.%d", &maj, &min, &rel);
|
||||
if (n != 3) {
|
||||
if (config.debug_version_select) {
|
||||
log_messages.printf(MSG_NORMAL,
|
||||
"[version] plan_class_spec: can't parse docker compose version\n"
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
v = maj*10000 + min*100 + rel;
|
||||
if (min_docker_compose_version && v < min_docker_compose_version) {
|
||||
if (config.debug_version_select) {
|
||||
log_messages.printf(MSG_NORMAL,
|
||||
"[version] plan_class_spec: docker compose version too low: %d < %d\n",
|
||||
v, min_docker_compose_version
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1121,7 +1218,9 @@ int PLAN_CLASS_SPEC::parse(XML_PARSER& xp) {
|
|||
if (xp.parse_bool("opencl", opencl)) continue;
|
||||
if (xp.parse_bool("virtualbox", virtualbox)) continue;
|
||||
if (xp.parse_bool("docker", docker)) continue;
|
||||
if (xp.parse_str("docker_compose_version", docker_compose_version, sizeof(docker_compose_version))) continue;
|
||||
if (xp.parse_bool("docker_compose", docker_compose)) continue;
|
||||
if (xp.parse_int("min_docker_version", min_docker_version)) continue;
|
||||
if (xp.parse_int("min_docker_compose_version", min_docker_compose_version)) continue;
|
||||
if (xp.parse_bool("is64bit", is64bit)) continue;
|
||||
if (xp.parse_str("cpu_feature", buf, sizeof(buf))) {
|
||||
cpu_features.push_back(" " + (string)buf + " ");
|
||||
|
@ -1269,7 +1368,9 @@ PLAN_CLASS_SPEC::PLAN_CLASS_SPEC() {
|
|||
opencl = false;
|
||||
virtualbox = false;
|
||||
docker = false;
|
||||
strcpy(docker_compose_version, "");
|
||||
docker_compose = false;
|
||||
min_docker_version = 0;
|
||||
min_docker_compose_version = 0;
|
||||
is64bit = false;
|
||||
min_ncpus = 0;
|
||||
max_threads = 1;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2023 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -33,7 +33,9 @@ struct PLAN_CLASS_SPEC {
|
|||
bool opencl;
|
||||
bool virtualbox;
|
||||
bool docker;
|
||||
char docker_compose_version[256];
|
||||
bool docker_compose;
|
||||
int min_docker_version;
|
||||
int min_docker_compose_version;
|
||||
bool is64bit;
|
||||
std::vector<std::string> cpu_features;
|
||||
double min_ncpus;
|
||||
|
|
|
@ -120,4 +120,16 @@
|
|||
<min_ncpus> 2 </min_ncpus>
|
||||
<max_threads> 2 </max_threads>
|
||||
</plan_class>
|
||||
<plan_class>
|
||||
<name> docker </name>
|
||||
<docker/>
|
||||
<min_docker_version> 270102 </min_docker_version>
|
||||
</plan_class>
|
||||
<plan_class>
|
||||
<name> docker_compose </name>
|
||||
<docker/>
|
||||
<docker_compose/>
|
||||
<min_docker_version> 270102 </min_docker_version>
|
||||
<min_docker_compose_version>32901 </min_docker_compose_version>
|
||||
</plan_class>
|
||||
</plan_classes>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2008 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -869,40 +869,27 @@ static inline bool app_plan_opencl(
|
|||
}
|
||||
}
|
||||
|
||||
// handles vbox[32|64][_[mt]|[hwaccel]]
|
||||
// "mt" is tailored to the needs of CERN:
|
||||
// use 1 or 2 CPUs
|
||||
|
||||
|
||||
//plan class for Docker jobs
|
||||
//
|
||||
static inline bool app_plan_docker(
|
||||
SCHEDULER_REQUEST& sreq, char* plan_class
|
||||
){
|
||||
if (sreq.core_client_major_version < 8) {
|
||||
add_no_work_message("BOINC client 8.0+ required for Docker jobs");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(sreq.host.docker_use)) {
|
||||
if (!(sreq.host.docker_available)) {
|
||||
add_no_work_message("Docker is not installed or is not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strstr(plan_class, "v1")) && (!(strstr(sreq.host.docker_compose_version, "v1")))){
|
||||
add_no_work_message("Docker compose (older version: docker-compose) is required, but is not installed or is not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((strstr(plan_class, "v2")) && (!(strstr(sreq.host.docker_compose_version, "v2")))){
|
||||
add_no_work_message("Docker compose (newer version: docker compose) is required, but is not installed or is not available");
|
||||
if (strstr(plan_class, "compose") && !(sreq.host.docker_compose_available)) {
|
||||
add_no_work_message("Docker compose is not installed or is not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// handles vbox[32|64][_[mt]|[hwaccel]]
|
||||
// "mt" is tailored to the needs of CERN:
|
||||
// use 1 or 2 CPUs
|
||||
|
||||
static inline bool app_plan_vbox(
|
||||
SCHEDULER_REQUEST& sreq, char* plan_class, HOST_USAGE& hu
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2023 University of California
|
||||
// https://boinc.berkeley.edu
|
||||
// Copyright (C) 2024 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
|
@ -1401,7 +1401,9 @@ int HOST::parse(XML_PARSER& xp) {
|
|||
if (xp.parse_double("n_bwup", n_bwup)) continue;
|
||||
if (xp.parse_double("n_bwdown", n_bwdown)) continue;
|
||||
if (xp.parse_str("p_features", p_features, sizeof(p_features))) continue;
|
||||
if (xp.parse_bool("docker_use", docker_use)) continue;
|
||||
if (xp.parse_bool("docker_available", docker_available)) continue;
|
||||
if (xp.parse_bool("docker_compose_available", docker_compose_available)) continue;
|
||||
if (xp.parse_str("docker_version", docker_version, sizeof(docker_version))) continue;
|
||||
if (xp.parse_str("docker_compose_version", docker_compose_version, sizeof(docker_compose_version))) continue;
|
||||
if (xp.parse_str("virtualbox_version", virtualbox_version, sizeof(virtualbox_version))) continue;
|
||||
if (xp.parse_bool("p_vm_extensions_disabled", p_vm_extensions_disabled)) continue;
|
||||
|
|
Loading…
Reference in New Issue