void environment::start() { end(); m_time = 0; m_running = true; m_world.resize(settings::world_width, settings::world_height); m_world.generate(m_settings.seed()); spawn_player(m_world.spawn() * point2(settings::cell_width, settings::cell_height)); // ui tie_map(); m_ui->deactivate("title"); m_ui->activate("ingame"); // make chest auto chest = m_factory->produce(); chest->add_appearance('$', { 1, 1, 1 }); chest->add_location({ 2, 2 }); auto body = chest->add_body(250, 150); body->set_name("Iron chest"); chest->add_container(); m_terrain.add(*chest); auto ore = std::make_shared<body_component::item_type>(); ore->add({ rl::effect::ore_power, 0x00, 10 }); ore->add({ rl::effect::value, 0x00, 5 }); ore->add({ rl::effect::weight, 0x00, 1 }); ore->set_name("Copper ore"); ore->set_tag("ore_copper"); auto vein = m_factory->produce(); vein->add_appearance('0'); vein->add_location({ 3, 3 }); vein->add_body(); auto v = vein->add_resource(); v->deposit(ore); m_terrain.add(*vein); auto anvil = m_factory->produce(); anvil->add_appearance('t'); anvil->add_location({ 3, 0 }); anvil->add_body(); anvil->add_container(); m_terrain.add(*anvil); }
bool sinsp_container_manager::resolve_container(sinsp_threadinfo* tinfo, bool query_os_for_missing_info) { ASSERT(tinfo); bool valid_id = false; sinsp_container_info container_info; string rkt_podid, rkt_appname; // Start with cgroup based detection for(auto it = tinfo->m_cgroups.begin(); it != tinfo->m_cgroups.end(); ++it) { string cgroup = it->second; size_t pos; // // Non-systemd Docker // pos = cgroup.find_last_of("/"); if(pos != string::npos) { if(cgroup.length() - pos - 1 == 64 && cgroup.find_first_not_of("0123456789abcdefABCDEF", pos + 1) == string::npos) { container_info.m_type = CT_DOCKER; container_info.m_id = cgroup.substr(pos + 1, 12); valid_id = true; break; } } // // systemd Docker // pos = cgroup.find("docker-"); if(pos != string::npos) { size_t pos2 = cgroup.find(".scope"); if(pos2 != string::npos && pos2 - pos - sizeof("docker-") + 1 == 64) { container_info.m_type = CT_DOCKER; container_info.m_id = cgroup.substr(pos + sizeof("docker-") - 1, 12); valid_id = true; break; } } // // Non-systemd libvirt-lxc // pos = cgroup.find(".libvirt-lxc"); if(pos != string::npos && pos == cgroup.length() - sizeof(".libvirt-lxc") + 1) { size_t pos2 = cgroup.find_last_of("/"); if(pos2 != string::npos) { container_info.m_type = CT_LIBVIRT_LXC; container_info.m_id = cgroup.substr(pos2 + 1, pos - pos2 - 1); valid_id = true; break; } } // // systemd libvirt-lxc // pos = cgroup.find("-lxc\\x2"); if(pos != string::npos) { size_t pos2 = cgroup.find(".scope"); if(pos2 != string::npos && pos2 == cgroup.length() - sizeof(".scope") + 1) { container_info.m_type = CT_LIBVIRT_LXC; container_info.m_id = cgroup.substr(pos + sizeof("-lxc\\x2"), pos2 - pos - sizeof("-lxc\\x2")); valid_id = true; break; } } // // Legacy libvirt-lxc // pos = cgroup.find("/libvirt/lxc/"); if(pos != string::npos) { container_info.m_type = CT_LIBVIRT_LXC; container_info.m_id = cgroup.substr(pos + sizeof("/libvirt/lxc/") - 1); valid_id = true; break; } // // Non-systemd LXC // pos = cgroup.find("/lxc/"); if(pos != string::npos) { auto id_start = pos + sizeof("/lxc/") - 1; auto id_end = cgroup.find('/', id_start); container_info.m_type = CT_LXC; container_info.m_id = cgroup.substr(id_start, id_end - id_start); valid_id = true; break; } // // Mesos // pos = cgroup.find("/mesos/"); if(pos != string::npos) { container_info.m_type = CT_MESOS; container_info.m_id = cgroup.substr(pos + sizeof("/mesos/") - 1); // Consider a mesos container valid only if we find the mesos_task_id // this will exclude from the container itself the mesos-executor // but makes sure that we have task_id parsed properly. Otherwise what happens // is that we'll create a mesos container struct without a mesos_task_id // and for all other processes we'll use it valid_id = set_mesos_task_id(&container_info, tinfo); break; } // // systemd rkt // // rkt cgroups // 1. /system.slice/k8s_d1efb75a-ad42-458e-af65-2b378f42173f.service/system.slice/redis.service // 2. /machine.slice/machine-rkt\x2dc508ad4c\x2d7fa4\x2d4513\x2d9d53\x2d007628003805.scope/system.slice/redis.service static const string COREOS_PODID_VAR = "container_uuid="; static const string SYSTEMD_UUID_ARG = "--uuid="; static const string SERVICE_SUFFIX = ".service"; if(cgroup.rfind(SERVICE_SUFFIX) == cgroup.size() - SERVICE_SUFFIX.size()) { // check if there is a parent with pod uuid var sinsp_threadinfo::visitor_func_t visitor = [&rkt_podid](sinsp_threadinfo* ptinfo) { for(const auto& env_var : ptinfo->get_env()) { auto container_uuid_pos = env_var.find(COREOS_PODID_VAR); if(container_uuid_pos == 0) { rkt_podid = env_var.substr(COREOS_PODID_VAR.size()); return false; } } for(const auto& arg : ptinfo->m_args) { if(arg.find(SYSTEMD_UUID_ARG) != string::npos) { rkt_podid = arg.substr(SYSTEMD_UUID_ARG.size()); return false; } } return true; }; tinfo->traverse_parent_state(visitor); if(!rkt_podid.empty()) { auto last_slash = cgroup.find_last_of("/"); rkt_appname = cgroup.substr(last_slash + 1, cgroup.size() - last_slash - SERVICE_SUFFIX.size() - 1); char image_manifest_path[SCAP_MAX_PATH_SIZE]; snprintf(image_manifest_path, sizeof(image_manifest_path), "%s/var/lib/rkt/pods/run/%s/appsinfo/%s/manifest", scap_get_host_root(), rkt_podid.c_str(), rkt_appname.c_str()); // First lookup if the container exists in our table, otherwise only if we are live check if it has // an entry in /var/lib/rkt. In capture mode only the former will be used. // In live mode former will be used only if we already hit that container if( m_containers.find(rkt_podid + ":" + rkt_appname) != m_containers.end() || (query_os_for_missing_info && access(image_manifest_path, F_OK) == 0) ) { container_info.m_type = CT_RKT; container_info.m_id = rkt_podid + ":" + rkt_appname; container_info.m_name = rkt_appname; valid_id = true; break; } } } } // If anything has been found, try proc root based detection // right now used for rkt if(!valid_id) { // Try parsing from process root, // Strings used to detect rkt stage1-cores pods // TODO: detecting stage1-coreos rkt pods in this way is deprecated // we can remove it in the future static const string COREOS_PREFIX = "/opt/stage2/"; static const string COREOS_APP_SUFFIX = "/rootfs"; static const string COREOS_PODID_VAR = "container_uuid="; auto prefix = tinfo->m_root.find(COREOS_PREFIX); if(prefix == 0) { auto suffix = tinfo->m_root.find(COREOS_APP_SUFFIX, prefix); if(suffix != string::npos) { rkt_appname = tinfo->m_root.substr(prefix + COREOS_PREFIX.size(), suffix - prefix - COREOS_PREFIX.size()); // It is a rkt pod with stage1-coreos sinsp_threadinfo::visitor_func_t visitor = [&rkt_podid, &container_info, &rkt_appname, &valid_id] (sinsp_threadinfo *ptinfo) { for(const auto& env_var : ptinfo->get_env()) { auto container_uuid_pos = env_var.find(COREOS_PODID_VAR); if(container_uuid_pos == 0) { rkt_podid = env_var.substr(COREOS_PODID_VAR.size()); container_info.m_type = CT_RKT; container_info.m_id = rkt_podid + ":" + rkt_appname; container_info.m_name = rkt_appname; valid_id = true; return false; } } return true; }; // Try the current thread first. visitor returns true if no coreos pid // info was found. In this case we traverse the parents. if (visitor(tinfo)) { tinfo->traverse_parent_state(visitor); } } } else { // String used to detect stage1-fly pods static const string FLY_PREFIX = "/var/lib/rkt/pods/run/"; static const string FLY_PODID_SUFFIX = "/stage1/rootfs/opt/stage2/"; static const string FLY_APP_SUFFIX = "/rootfs"; auto prefix = tinfo->m_root.find(FLY_PREFIX); if(prefix == 0) { auto podid_suffix = tinfo->m_root.find(FLY_PODID_SUFFIX, prefix+FLY_PREFIX.size()); if(podid_suffix != string::npos) { rkt_podid = tinfo->m_root.substr(prefix + FLY_PREFIX.size(), podid_suffix - prefix - FLY_PREFIX.size()); auto appname_suffix = tinfo->m_root.find(FLY_APP_SUFFIX, podid_suffix+FLY_PODID_SUFFIX.size()); if(appname_suffix != string::npos) { rkt_appname = tinfo->m_root.substr(podid_suffix + FLY_PODID_SUFFIX.size(), appname_suffix-podid_suffix-FLY_PODID_SUFFIX.size()); container_info.m_type = CT_RKT; container_info.m_id = rkt_podid + ":" + rkt_appname; container_info.m_name = rkt_appname; valid_id = true; } } } } } if(!valid_id) { tinfo->m_container_id = ""; } else { tinfo->m_container_id = container_info.m_id; unordered_map<string, sinsp_container_info>::const_iterator it = m_containers.find(container_info.m_id); if(it == m_containers.end()) { switch(container_info.m_type) { case CT_DOCKER: #ifndef _WIN32 if(query_os_for_missing_info) { parse_docker(&container_info); } #endif break; case CT_LXC: container_info.m_name = container_info.m_id; break; case CT_LIBVIRT_LXC: container_info.m_name = container_info.m_id; break; case CT_MESOS: container_info.m_name = container_info.m_id; break; case CT_RKT: #ifndef _WIN32 if(query_os_for_missing_info) { parse_rkt(&container_info, rkt_podid, rkt_appname); } #endif break; default: ASSERT(false); } add_container(container_info); if(container_to_sinsp_event(container_to_json(container_info), &m_inspector->m_meta_evt)) { m_inspector->m_meta_evt_pending = true; } } } return valid_id; }