From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from shymkent.ilbers.de ([unix socket]) by shymkent (Cyrus 2.5.10-Debian-2.5.10-3+deb9u2) with LMTPA; Wed, 18 Feb 2026 12:59:11 +0100 X-Sieve: CMU Sieve 2.4 Received: from mail-qt1-f187.google.com (mail-qt1-f187.google.com [209.85.160.187]) by shymkent.ilbers.de (8.15.2/8.15.2/Debian-8+deb9u1) with ESMTPS id 61IBx83K023635 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 18 Feb 2026 12:59:09 +0100 Received: by mail-qt1-f187.google.com with SMTP id d75a77b69052e-5033b62efa7sf430535141cf.1 for ; Wed, 18 Feb 2026 03:59:09 -0800 (PST) ARC-Seal: i=3; a=rsa-sha256; t=1771415943; cv=pass; d=google.com; s=arc-20240605; b=cR76Ni54qoQJjG9CiEXgdRZ8VlIihpL8dwpwOW2k3JHSyQ2JQ0NsjHq1zo3cj3/fCV dmAsRjni+ZcttYmtQezPoKr1kMGfnkZl9y6V1quMIfjJKdacKWhnQSgZ8/o+wP2fCB+h Y08sBsoZbgzvbkP9t6H4uxlbxzBCe5SKBhcDskAI+E2cTBrN6wfTsJADCSQRAYKtBcb/ z0Jl4EQ7+LNIPn4yXUkzWSTKMizxX/vOOtzEvcLMJ3zoO3ewZ4pxXwBkgAAtAvYHBNtP FgnP4QXfenaGXlfCy9dzq8usPIVJvsylJcSIXK4+rSpAZUp1Q6QrKmWzbkXTy4lK49g4 iL5g== ARC-Message-Signature: i=3; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=dp9FdXT7IHhAUm/rbvZJbjYi7cuSd9kz2Fz6h9aXviY=; fh=DMhHJWzlDWS880CDDPGpq28zGP/PWZ8sAm1Wd2Keois=; b=kYEAHW9rHcV3jTU+a5HMJ9RBVa2dsI9n8AjK68UrDraq4lHzYjZvkeaML/CulTIoKf cjECR+/wz6o493oqynN947ypjYH3LMeKesgJXKxrv53KlNNi1Lg+f/GarJzoWazpVSJZ H8Ki0Ao/pjpdwiI5Eo4KX6N3W8Rrgvc/mFcC1gwBwDwyUAD3fQdQ7/nP1XjxriUXgWZI jA3GJqvLZk4/lRhnLyyU5w+Wlam/YaWrkOLhUU0DPhNvYL9Ms43JPMLHImHL1bEX1TNW fghoRu65AkjwpxCE+waHOkrQMPs2wbT9EjFVRvKT9p2ct1Dk17FS387DJgxyw27jdzm/ BNeA==; darn=ilbers.de ARC-Authentication-Results: i=3; gmr-mx.google.com; dkim=pass header.i=@siemens.com header.s=selector2 header.b=fXmtyDn1; arc=pass (i=1 spf=pass spfdomain=siemens.com dkim=pass dkdomain=siemens.com dmarc=pass fromdomain=siemens.com); spf=pass (google.com: domain of felix.moessbauer@siemens.com designates 2a01:111:f403:c207::3 as permitted sender) smtp.mailfrom=felix.moessbauer@siemens.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=siemens.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20230601; t=1771415943; x=1772020743; darn=ilbers.de; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=dp9FdXT7IHhAUm/rbvZJbjYi7cuSd9kz2Fz6h9aXviY=; b=cuTcQ8H/fnhazPLVC2HopF+3uvOL3Ho+FUP5hZPUjcO1X8dpc1OiAo2m7PXfJZ+dVi SGMD/fqlBXURJw/r/SX20ymwm0WDIxrNLfuVP6op9zTOn/Uj3x7ik0z8yVMka4tg+pIk f50XF6/rqtqERpsRUOZD8rd6YU8C9R3ka4Wd7r7noPKMtmr3px2o3taxolet4iOHtkhk Z4OER2P+lj3czSQeOcC+D0lf/2AMrclbkb6Yxdur2JqPFB8ofYayBPHxi8tWMXddIL8w Kqq+tYNYCfxAlZcEakAUvZM2xny0jfwsG2UhzAsfBFAYg4PvobGSvUfOD/e9NiuLwA2u M/KA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771415943; x=1772020743; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :x-beenthere:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=dp9FdXT7IHhAUm/rbvZJbjYi7cuSd9kz2Fz6h9aXviY=; b=vLE3seUo/n4UF5SuD/xyK3hbWlZ1LmJzAafhEn5RMFgiSfM6M61mTKv62qgW2rJSH0 bQFDB/F/lY9b/bfJC/eJkZUDgnHsADrpWUsGIwNlxILOhHPGBPF1cvnq7bqCp56CwCEt fIXyYlVAP89na+s4qzSgI8+Za1tpFrMlFHTJNJxTttThdOaubkx5CJdYpXlR9614L2wf lYouUFtbuevXDfpEPBdmt1Aj7mcTN5Xy9hn2W3keauZmZgHloljYr3jnhdnLEqM02F8+ gwrc9zIf2T0cj6Ick/GfGBK9/tbwZSlSCcOCqZYZnSAwQ6X59p1XgD5+MYZ7rG00slp1 7m5Q== X-Forwarded-Encrypted: i=3; AJvYcCVqNzlwvQ3ayUi8mOq7bQqmjyu1Y+ia0rhU6OFSs1/HjmTkY6HxhekZwqIVoC04tAr3rmhx@ilbers.de X-Gm-Message-State: AOJu0YyuZlP4hM1WNTEpJzx90lBOyLmMW7k6bT9+QhXUFpqWG2qKQq// cGDmz0OHkcb8XxyXM8PUUj8N65th6Oqw16p9Sb3gXZjSm4UKUyrKpXCd X-Received: by 2002:ac8:7f96:0:b0:501:48e9:68f with SMTP id d75a77b69052e-506e9232d8amr16989881cf.62.1771415942861; Wed, 18 Feb 2026 03:59:02 -0800 (PST) X-BeenThere: isar-users@googlegroups.com; h="AV1CL+HjFtzqgapWRSZxTKjqxrylwVHfVsYFk+GeVdSqK1fLgA==" Received: by 2002:ac8:5f11:0:b0:4ed:9424:fa31 with SMTP id d75a77b69052e-506a8ef303els89422841cf.2.-pod-prod-01-us; Wed, 18 Feb 2026 03:59:01 -0800 (PST) X-Received: by 2002:a05:622a:1308:b0:503:2f41:aba6 with SMTP id d75a77b69052e-506e9216b26mr18671021cf.47.1771415941713; Wed, 18 Feb 2026 03:59:01 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1771415941; cv=pass; d=google.com; s=arc-20240605; b=dHEAGUum/qZA81hBQxkBWPU09w6580TqsU4p1KHXv5jOhaH4UCRMT4FXiBmsTwYYJW 4P0PfOLloAx8j2upjms4/6/iDX+K0vrV6ddG3hvGrlXZ+5GC/U0CNCBOWYAhJQoJzJPx IIh2d3LdqvKwsLxFKw82k9T0AyIBHowJqEYrZ3U1bz7UZp9xM3X/N4PLrlwlqfbunYsz 6Jo7jfpT2XxyjBwmtxz3uHRCmGXzCbpUkQ6tdB5fSKTL1ARu/enAYarQMm0UrR1HSSVF OEUvVTDg2LfFdjmlAyuV5jPyBxIXM8eWh1OZS94fKjJQDp4L6j8tLQPRHqqiEiy+aIN1 LCDQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=mime-version:content-transfer-encoding:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=7teM9JjGUjIbvdx+WuxN5tdgbfhg5WD287cemnqlF4c=; fh=dWFKumMb31C26+PJa6vcB2ftw6NwdNo52k0UEVGombI=; b=NJZDzUa/r+UPQXFqB5mRBuD/rWIH2Dz13f/roUVuRsWjkpRAkhfeK2hEIOiAIlFh2D UVHnmOW5HKdGYIW+2LpzxqJS72n/8QVHAIGO3p2pA6StcFIoarlMvzETZBz6cMY4cByu 5vAXaR4gexVFxhlIw0Aq4kCQBWQeg1RMu0BVRScMlMBskRrPb71SCtZEFZsrpY1hgkMo AsYgWZx11sCtCkAmLupBf+43XA5SFzkIlI/90WNLtCMWj9cXbtciq21Har1aFCQuatya 7a55hB/3E/cBDfijy5A9rTlkXsqs83pOyfiwOiiuK63/X7Dii6ukC476mjV/eglDkVrC WHqw==; dara=google.com ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@siemens.com header.s=selector2 header.b=fXmtyDn1; arc=pass (i=1 spf=pass spfdomain=siemens.com dkim=pass dkdomain=siemens.com dmarc=pass fromdomain=siemens.com); spf=pass (google.com: domain of felix.moessbauer@siemens.com designates 2a01:111:f403:c207::3 as permitted sender) smtp.mailfrom=felix.moessbauer@siemens.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=siemens.com Received: from MRWPR03CU001.outbound.protection.outlook.com (mail-francesouthazlp170110003.outbound.protection.outlook.com. [2a01:111:f403:c207::3]) by gmr-mx.google.com with ESMTPS id d75a77b69052e-506846aa643si7938151cf.0.2026.02.18.03.59.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Feb 2026 03:59:01 -0800 (PST) Received-SPF: pass (google.com: domain of felix.moessbauer@siemens.com designates 2a01:111:f403:c207::3 as permitted sender) client-ip=2a01:111:f403:c207::3; ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=PP/6BDrQ1/rPo0iIKkFwmPphGvl5hg2EauQmBzyf2+0Gdmt+3uWRGWOETCuI3rqREdu06P32xdCgdvGV4DwcWib6dg4QZxD7B/sEVvWYs8oKHanzTTii7oS1D7cqOXSiLmPoUZzEsaiLl4ZhorvhUNx7EwDFKNgo23RWvak17HkjP0gFNoYIT9YKVv8FQ553pX8AcvHW6Bn8Ws23ToYwkJ+pxHjzMwH6PmNJUDWbCdypr4UdiKLrXYkzP029wFL3hPpEEwQmn6i+KQ63j6LlUPcVBd4jP0+bsy1LhdkWXtkufQZ2yEFTgZkE+QBAM4g+bp+I2yZBQI8mrANvt+eGbQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=7teM9JjGUjIbvdx+WuxN5tdgbfhg5WD287cemnqlF4c=; b=IuM23+mvZKbSVtta9vbEb17GdgRLHu7ZayRCq5c2JBEnAYh2+Z2eH/irpkyGhOh+bQOvjYsd3UKc9KHY5a2Lq18Ox+PKhK/mZl5zcLnwe8unfWMhXZ3IOBts1L7XqO6jwmVU3j+QzM4aBdo/bYoC0Q9THltKR6DjiqjSMIQY4CRm3Y8ZRbEEx3+SrouwSbZWZC1/3NvWaQIFt7Cf7Ja1l369GpeYDDxsQTtI4P07LK6m8R1hzN+C4z/Xw3nazOXq/K6afVhwHa3QhmrFN2ZCOBK2Of0v980K3o7Ota+em7mT95/x5uGZsq/a7Id/vJPmoyH6ZXmKkjg0Q3CT7we8GA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=siemens.com; dmarc=pass action=none header.from=siemens.com; dkim=pass header.d=siemens.com; arc=none Received: from DU0PR10MB6828.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:10:47f::13) by FRWPR10MB9395.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:d10:1a1::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9632.13; Wed, 18 Feb 2026 11:58:58 +0000 Received: from DU0PR10MB6828.EURPRD10.PROD.OUTLOOK.COM ([fe80::9412:cd7f:3f72:92ab]) by DU0PR10MB6828.EURPRD10.PROD.OUTLOOK.COM ([fe80::9412:cd7f:3f72:92ab%3]) with mapi id 15.20.9632.010; Wed, 18 Feb 2026 11:58:58 +0000 From: "'Felix Moessbauer' via isar-users" To: isar-users@googlegroups.com Cc: quirin.gylstorff@siemens.com, Felix Moessbauer Subject: [RFC 11/12] add support for fully rootless builds Date: Wed, 18 Feb 2026 12:58:26 +0100 Message-ID: <20260218115827.3947145-12-felix.moessbauer@siemens.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260218115827.3947145-1-felix.moessbauer@siemens.com> References: <20260218115827.3947145-1-felix.moessbauer@siemens.com> Content-Type: text/plain; charset="UTF-8" X-ClientProxiedBy: CH5P220CA0022.NAMP220.PROD.OUTLOOK.COM (2603:10b6:610:1ef::28) To DU0PR10MB6828.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:10:47f::13) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU0PR10MB6828:EE_|FRWPR10MB9395:EE_ X-MS-Office365-Filtering-Correlation-Id: 0b1e5a70-b47a-42d8-829c-08de6ee518fa X-MS-Exchange-AtpMessageProperties: SA X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|1800799024|366016; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?rJezne4cTh0GmWyzg6oa48B5NLv7Br90vj/0okiW9q9r3fTadH14tV/9rRc0?= =?us-ascii?Q?HumBzTellIEoJH16le9y6NX3008pRkvKf77ukWZTUK7weXAWb4LC1oeuEjC7?= =?us-ascii?Q?iyN4P06nkAoS+dsKxxlEEgiMCX27VEeL+7QU81Exr2mC0WQAVDRh0PUHsOxg?= =?us-ascii?Q?IGVWjEO7E4AQHT+sYsdTQc3MnEnD9lp9JCLC8M+3bWbAKi+sjLHSrWgbbN0W?= =?us-ascii?Q?Gx/o92wMfNIqP5QU9ndsvkmJU2x2KPo2JxlOVxwd3aipVnFnwnntknrwJXDP?= =?us-ascii?Q?ZwjL8lWm7eWusi7WMybVEt6wSztuR4Qr0iKIXxRo1dQ4MeMAydtk7NscodQG?= =?us-ascii?Q?tfyOwdJxhrubxF9Mdp4OoqRNBWajL0LlzDffu1wF9rtyFll1CgDj4yqqh9YB?= =?us-ascii?Q?4p9X81W3tuoM6AMK/1j2/LrpFVcSLpyu66vTsGxqxwGrDbWrW9wMXALxBE13?= =?us-ascii?Q?2zE29ZE3jwi6R52txTJ2i78DZ/y6z4S0Dzq0fadbC7CKQfdZT9TvMamBbqJB?= =?us-ascii?Q?263GmDPlvqi8I0k4xxEl1UXHFKrZbC4GlUP+h3U6uiFEOYxTg8GUDRFtYWqH?= =?us-ascii?Q?XgppJvBwlN0FzggTAt9w/SSJ4vx0vWgtdHES7OdP5HnfMm+WkcBpApxfIYxO?= =?us-ascii?Q?lcZkcLwcF6cJeCaeemRJAjxRzhJ3A74/5zL+2Mi5xpkjZGURlnRD6XS/opQY?= =?us-ascii?Q?qNVFcZtaWwR0GnXPzntj7jmnPE5UI0wdAza7t3M9pJsgkNF+xjOZyfwqFnPD?= =?us-ascii?Q?cQ4B800DQvzBSqeRg3OA+vaGMUXkQo1tryAmSMw9dSaxS3CoKmRifeUV67Om?= =?us-ascii?Q?SVzpl9gui5xc+ZNqkraWM+2t6hFitq8ACLhDBi5QlhdTowQ6JDd29HEbxbsF?= =?us-ascii?Q?Z7fGmuBBfzuTbFXHvE7hnQSeZfCHMv/TV+3WMq5FgAuNsqxhog/0IoDsV/07?= =?us-ascii?Q?myv9ayS5p5ra0d21065PtfscsZNi50c+NNahMSSFigl+V8vJOzTht16J6CtJ?= =?us-ascii?Q?taqBCGipg+KH9SOc2766s9oKO/NP3lWrwUQfKYXuFwinQv7R06tWalWYEiIk?= =?us-ascii?Q?F/Smurfk8+GMcdp2gQ+vA9BA60Y1OT0xsVEVLM7FQcbgO5YpWoUBWh7d5cSl?= =?us-ascii?Q?4jH7zOuZBGrxoWRsgjmXXDCCMerSkS+1pjPo5NIw6mIYvdjyC4QtQ7BZfiol?= =?us-ascii?Q?NLWTN9h/dyd8YUWi6f0fo6E+oWHkhG7xMrh47Pe34bHjfXZiTEDsM9VvT5IU?= =?us-ascii?Q?bxcViGVOwkgBfQJDXrBCyCkGHBdOQBSy/+IR0hlyILdNQfWaVfo+1Zzx/Qyz?= =?us-ascii?Q?YabkjV05UocG9vPYZ9YDSG8C1QM6sVBTXmZfVCJk7y0S4jKJKPAw/qfN6G24?= =?us-ascii?Q?+nlaJh3IpMDd9ssfIkw/E6ORhzHRzrP+etVc5lw+Qxb8PrhpHAV8YJUcHGC+?= =?us-ascii?Q?/REjy+I57C7nOUtfdGoIC5JpggRy4EQ2vfmiKk2OyDz75f0zAQjR37HcxKo0?= =?us-ascii?Q?kWrGECeS6nfS2WdM+h8u7THRXijSora4bapiRNVCReo3gwZ1ElSEdmHZk837?= =?us-ascii?Q?po4li0o2XZ/pzfEWsBI=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DU0PR10MB6828.EURPRD10.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230040)(376014)(1800799024)(366016);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?3jskAA6+AF1Jy2W4zj6NSoj1m2yVwH5LPTLL160yKHLL10kF8AwZhYeuhfuq?= =?us-ascii?Q?N33mknfnNB39gGG2VPN2AJDXKKvR6xCHYo13WRXxJVZuZJQ1t+FeBQ4SxTfJ?= =?us-ascii?Q?kmaFZGDIFyF+FB4Px0VBWNoC5+308HoYSc5hZkT2UQgCsMh5LF7yH0qgRsxo?= =?us-ascii?Q?cEZDXHtAsM/vTtKlLriHOz9W2PhbSrrbuwiJXkByK+1WhWNpPTaEjZMicHm+?= =?us-ascii?Q?c1368YVNOFfMggXCQfeauO2jiAYTL0dZGRyEuEMOJZTvSLTzOfTNfN+Daajv?= =?us-ascii?Q?HEvBvlMIbjjv3j5/BAmMJ4IPyjXPLXb6de09BFpA3/m1We8nSdCZGOPIfeGf?= =?us-ascii?Q?TLV3U9+vnWQsvocIkB5aDZ8nll0bCXPzgRwZU/ULH3qw91rTIVCztbQGRMEg?= =?us-ascii?Q?aEBgkgEWpDbcsZxgco+/MoFNl45yrmpthG97mHW/i2K46OIMEaxDtXH7s6wJ?= =?us-ascii?Q?2q7552dTnQ7B2Cc/uK3GppjirRROXPH0AWY54UhUmVDtW+2ahYh02upS0aot?= =?us-ascii?Q?gp87zt7X0IXkQ6XA2SPSDAvS540bW7lfCsFAB0p361ADxZFlgtdh6kNoDNPc?= =?us-ascii?Q?nu/0FYIGtBBgcmQat/bZMFPcPbwdghNfLOOfkpeVxttxjjYkWGvhecQNIscv?= =?us-ascii?Q?uE6yKRAincJz8H7tL3cH9C1aBk/jHkQ/4liFbQfvY18Nb0hK4NcQHvzDmU8y?= =?us-ascii?Q?PDGjsQbSYRuJEI9I+1ywgZvJeM1keOcur4KjPAm4F0oG8PDobZa1KGgS8uix?= =?us-ascii?Q?8wSQ2mecHfe13eRym+B40zgMpU9Lev47sHNcwPq1Rdwt1l8yeNNLGPfx5+M9?= =?us-ascii?Q?YxleH4o7vBI/N0fZLGCIG3g5ZWZbDc1sXM1vhAA+I9rOqi87DUm5x+o5DF6T?= =?us-ascii?Q?lNmKexu+GgHxyrrseO4ELQkxNLyE0DDtA8me6CN3AAls87LBbz3dqgmX0xrX?= =?us-ascii?Q?5vfqgbdWrPXQkc+Y3U0Jl6ep2+ZrseTYPmwWfLI+quZ8Wyoo9upsoNl+eZqX?= =?us-ascii?Q?kjja+99bq/Lok7A/Ncz4KpJUh7f2rR1JFNyWCETh8zXNPJL7jB/+zPWtH+SR?= =?us-ascii?Q?0veOc3IQmBUW4JK2hs6teSpy5jL0cPpWJqD+qadQVJ/RYQ5YGtMNnVITIu19?= =?us-ascii?Q?BLePkp689JEm9LUlwUAPRjXmtheaN6/KnaPUXnxfjhlgcN7JjKv9RW0B2yUI?= =?us-ascii?Q?ev2H+Z03Rt7NPGuIawnsMjFJ39QnENB/Wnc7OVNMQaQKxH9zBRgxpZJbWfb0?= =?us-ascii?Q?vYSG8/FO92xJB6oBGfdXEjXxu0oIhpqpFFEzFf8aJlo6E6sD6+VQgA0DMAB8?= =?us-ascii?Q?nPQNENeZO7mdH7ZOVatULjvxy91nihyEqbmktgXy4MtSdpfYAYf8UdN0Oons?= =?us-ascii?Q?770F/0uctYuM6+EciDjlLiZg9/5aBFWirKK3NzMBENvAS6V9HB0jmwXtDdN8?= =?us-ascii?Q?Ml40KMuLnbtDNoaR0+I8n0kCttKNdJd8ciJ535P2KbPJlb5WSdF5B/gQjmFb?= =?us-ascii?Q?ZvOSkNAujKqaEl+Mk9M3VqghzM0qd0ntWXYBzsqz4bziWYkI73kaIA5Otbn+?= =?us-ascii?Q?6cc13DWVDZolhggcGXfRDy2e+0hye/kJx1ug9/9eR6BcvBNTww9uRo7tmFtQ?= =?us-ascii?Q?pgozoxKLkTlGuTDPiePnTADXhRG/KkidalJ9/lCfUy9AzTaoObIbzQkqjg4P?= =?us-ascii?Q?OzUjytNDHUh/5FMwndk6C3wwINqfKUMzNk8WNubotWK/1xdcPX/OmhD5Dz3Z?= =?us-ascii?Q?DgodCu6I5Jz0A15ScbNHXDvV4j8BGCI=3D?= X-OriginatorOrg: siemens.com X-MS-Exchange-CrossTenant-Network-Message-Id: 0b1e5a70-b47a-42d8-829c-08de6ee518fa X-MS-Exchange-CrossTenant-AuthSource: DU0PR10MB6828.EURPRD10.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Feb 2026 11:58:58.2708 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 38ae3bcd-9579-4fd4-adda-b42e1495d55a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: /vvNpnmbcv6m5zBlnvP/JAZqMotFVUnb3SWtlu8O1VChc1T5NIOJgAUknRztmGYTbuUIIB/U+3MTveCNtnMqw6ktIA33uIGbpGeHnwVSl1s= X-MS-Exchange-Transport-CrossTenantHeadersStamped: FRWPR10MB9395 X-Original-Sender: felix.moessbauer@siemens.com X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@siemens.com header.s=selector2 header.b=fXmtyDn1; arc=pass (i=1 spf=pass spfdomain=siemens.com dkim=pass dkdomain=siemens.com dmarc=pass fromdomain=siemens.com); spf=pass (google.com: domain of felix.moessbauer@siemens.com designates 2a01:111:f403:c207::3 as permitted sender) smtp.mailfrom=felix.moessbauer@siemens.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=siemens.com X-Original-From: Felix Moessbauer Reply-To: Felix Moessbauer Precedence: list Mailing-list: list isar-users@googlegroups.com; contact isar-users+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: isar-users@googlegroups.com X-Google-Group-Id: 914930254986 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , X-Spam-Status: No, score=-4.9 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, RCVD_IN_RP_CERTIFIED,RCVD_IN_RP_RNBL,RCVD_IN_RP_SAFE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on shymkent.ilbers.de X-TUID: zqCamQ2+Y0DR Currently isar requires passwordless sudo and an environment where mounting file systems is possible. This has proven problematic for security reasons, both when running in a privileged container or locally. To solve this, we implement fully rootless builds that rely on the unshare syscall which allows us to avoid sudo and instead operate in temporary kernel namespaces as a user that is just privileged within that namespace. This comes with some challenges regarding the handling of mounts (they are cleared when leaving the namespace), as well as cross namespace deployments (the outer user might not be able to access the inner data). For that, we rework the handling of mounts and artifact passing to make it compatible with both chroot modes (schroot and unshare). Signed-off-by: Felix Moessbauer --- Kconfig | 2 +- RECIPE-API-CHANGELOG.md | 29 +++++++ doc/user_manual.md | 2 + meta/classes-global/base.bbclass | 67 ++++++++++++++- meta/classes-recipe/deb-dl-dir.bbclass | 9 +- meta/classes-recipe/dpkg-base.bbclass | 16 +++- meta/classes-recipe/dpkg.bbclass | 14 +++- .../image-locales-extension.bbclass | 9 +- .../image-tools-extension.bbclass | 82 +++++++++++++++++++ meta/classes-recipe/rootfs.bbclass | 53 +++++++++--- meta/classes-recipe/sbuild.bbclass | 27 +++++- meta/classes-recipe/sdk.bbclass | 11 ++- meta/conf/bitbake.conf | 7 +- .../isar-mmdebstrap/isar-mmdebstrap.inc | 12 ++- .../sbuild-chroot/sbuild-chroot.inc | 24 +++++- 15 files changed, 332 insertions(+), 32 deletions(-) diff --git a/Kconfig b/Kconfig index 683c0da5..5ef2bfcb 100644 --- a/Kconfig +++ b/Kconfig @@ -14,7 +14,7 @@ config KAS_INCLUDE_MAIN config KAS_BUILD_SYSTEM string - default "isar" + default "isar-rootless" source "kas/machine/Kconfig" source "kas/distro/Kconfig" diff --git a/RECIPE-API-CHANGELOG.md b/RECIPE-API-CHANGELOG.md index f80630a0..29bf7590 100644 --- a/RECIPE-API-CHANGELOG.md +++ b/RECIPE-API-CHANGELOG.md @@ -990,3 +990,32 @@ rootless builds. For that, the deployment of images happens in two steps: Conversion commands need to follow this strategy as well, but can read the image (prior to conversion) from `${IMAGE_FILE_CHROOT}`. + +### Rootless isar execution + +Isar is able to run without the need for `sudo` in an environment that +allows unprivileged users to unshare the kernels `user namespace`. Further, +a sufficiently large set of sub ids needs to be configured in `/etc/subuid` / `etc/subgid`. +This range should be `> 65536`, but smaller ranges might work as well, depending on the +ids used in the rootfs. + +A simple check if rootless is supported can be done by running: + +```bash +mmdebstrap --unshare-helper /bin/echo "rootless supported" || echo "rootless not supported" +``` + +On many systems, setting the following settings is sufficent, but no general guidance +can be provided. + +```bash +echo 0 | sudo tee -a /proc/sys/kernel/apparmor_restrict_unprivileged_userns +echo 1 | sudo tee -a /proc/sys/kernel/unprivileged_userns_clone +``` + +To enable rootless builds, set the bitbake variable `ISAR_ROOTLESS = "1"`. +This internally switches the chroot mode from `schroot` to `unshare`. + +When using kas, the `build_system` needs to be set to `isar-rootless`, but the final +interfaces still need to be clarified. Further, kas patches are needed (for details, +check the kas mailing list). diff --git a/doc/user_manual.md b/doc/user_manual.md index 7520854b..77a37e9b 100644 --- a/doc/user_manual.md +++ b/doc/user_manual.md @@ -74,6 +74,7 @@ Building `debian-trixie` requires host system >= bookworm. Install the following packages: ``` apt install \ + acl \ binfmt-support \ bubblewrap \ bzip2 \ @@ -88,6 +89,7 @@ apt install \ qemu-user-static \ reprepro \ sudo \ + uidmap \ unzip \ xz-utils \ git-buildpackage \ diff --git a/meta/classes-global/base.bbclass b/meta/classes-global/base.bbclass index 16939f64..26d1ee22 100644 --- a/meta/classes-global/base.bbclass +++ b/meta/classes-global/base.bbclass @@ -388,11 +388,54 @@ do_unpack[prefuncs] += "deprecation_checking" # Helpers for privileged execution. Only the non-underscore functions # shall be used outside of this class. +def get_subid_range(idmap, d): + with open(idmap, 'r') as f: + entries = f.readlines() + for e in entries: + user, base, cnt = e.split(':') + if user == os.getuid() or user == os.getlogin(): + return base, cnt + bb.error("No sub-id range specified in %s" % idmap) + def run_privileged_cmd(d): - cmd = 'sudo -E' + """ + In unshare mode we need to map the rootfs uid/gid range into the + subuid/subgid range of the parent namespace. As we usually only + get 65534 ids, we cannot map the whole range, as two ids are already + used by the calling environment (root and builder user). Hence, map + as much as we can but also map the highest id (nobody / nogroup) as + these are used within the rootfs. It would be easier to use + mmdebstrap --unshare-helper as command (which is also internally used + by sbuild), but this only maps linear ranges, hence it cannot map the + nobody / nogroup on the default subid range. By that, we have to avoid + the nobody / nogroup when building packages in this case. + """ + if d.getVar('ISAR_CHROOT_MODE') == 'unshare': + noone_id = 65534 + uid_base = int(d.getVar('UNSHARE_SUBUID_BASE')) + uid_cnt = int(d.getVar('UNSHARE_SUBUID_COUNT')) - 2 + nobody_subid = uid_base + uid_cnt + gid_base = int(d.getVar('UNSHARE_SUBGID_BASE')) + gid_cnt = int(d.getVar('UNSHARE_SUBGID_COUNT')) - 2 + nogroup_subid = gid_base + gid_cnt + cmd = 'unshare --mount --user --pid' \ + ' --setuid 0 --setgid 0 --fork' \ + f' --map-users 0:{uid_base}:{uid_cnt}' \ + f' --map-groups 0:{gid_base}:{gid_cnt}' + if uid_cnt < noone_id: + cmd += f' --map-users {noone_id}:{nobody_subid}:1' + if gid_cnt < noone_id: + cmd += f' --map-groups {noone_id}:{nogroup_subid}:1' + else: + cmd = 'sudo -E' bb.debug(1, "privileged cmd: %s" % cmd) return cmd +UNSHARE_SUBUID_BASE := "${@get_subid_range('/etc/subuid', d)[0]}" +UNSHARE_SUBUID_COUNT := "${@get_subid_range('/etc/subuid', d)[1]}" +UNSHARE_SUBGID_BASE := "${@get_subid_range('/etc/subgid', d)[0]}" +UNSHARE_SUBGID_COUNT := "${@get_subid_range('/etc/subgid', d)[1]}" +# store in variable to only compute once and make available to fetcher RUN_PRIVILEGED_CMD := "${@run_privileged_cmd(d)}" run_privileged() { @@ -404,9 +447,29 @@ run_privileged_here() { } # create a directory that is suitable to be the -# parent of a rootfs +# parent of a rootfs. In unshare mode, we further need to +# give the inner user the right to create a directory there. +# This is needed, as the inner user needs to extract the +# rootfs tarball and owns the '.' dir. +create_chroot_parent_dir() { + mkdir -p "$@" + if [ "${ISAR_CHROOT_MODE}" = "unshare" ]; then + setfacl -m u:${UNSHARE_SUBUID_BASE}:rwX "$@" + fi +} + +# get the base of the calling users subuid range +get_base_subuid() { + grep $(whoami) /etc/subuid | cut -d ':' -f 2 +} + +# create the directory and prepare permissions to untar +# a rootfs into an inner directory create_chroot_parent_dir() { mkdir -p "$@" + if [ "${ISAR_CHROOT_MODE}" = "unshare" ]; then + setfacl -m u:$(get_base_subuid):rwX "$@" + fi } run_in_chroot() { diff --git a/meta/classes-recipe/deb-dl-dir.bbclass b/meta/classes-recipe/deb-dl-dir.bbclass index fc0cd915..2020cdd0 100644 --- a/meta/classes-recipe/deb-dl-dir.bbclass +++ b/meta/classes-recipe/deb-dl-dir.bbclass @@ -121,8 +121,13 @@ deb_dl_dir_import() { # let our unprivileged user place downloaded packages in /var/cache/apt/archives/ run_privileged_here << ' EOSUDO' - mkdir -p "${rootfs}"/var/cache/apt/archives/partial/ - chown -R ${uid}:${gid} "${rootfs}"/var/cache/apt/archives/ + if [ "${ISAR_CHROOT_MODE}" = "unshare" ]; then + mkdir -p "${rootfs}"/var/cache/apt/archives + chmod 777 "${rootfs}"/var/cache/apt/archives + else + mkdir -p "${rootfs}"/var/cache/apt/archives/partial/ + chown -R ${uid}:${gid} "${rootfs}"/var/cache/apt/archives/ + fi EOSUDO # nothing to copy if download directory does not exist just yet diff --git a/meta/classes-recipe/dpkg-base.bbclass b/meta/classes-recipe/dpkg-base.bbclass index 5841d6ee..e4e72f80 100644 --- a/meta/classes-recipe/dpkg-base.bbclass +++ b/meta/classes-recipe/dpkg-base.bbclass @@ -168,12 +168,24 @@ dpkg_schroot_create_configs() { EOSUDO } +dpkg_chroot_prepare() { + if [ "${ISAR_CHROOT_MODE}" = "schroot" ]; then + dpkg_schroot_create_configs + fi +} + +dpkg_chroot_finalize() { + if [ "${ISAR_CHROOT_MODE}" = "schroot" ]; then + schroot_delete_configs + fi +} + python do_dpkg_build() { - bb.build.exec_func('dpkg_schroot_create_configs', d) + bb.build.exec_func('dpkg_chroot_prepare', d) try: bb.build.exec_func("dpkg_runbuild", d) finally: - bb.build.exec_func('schroot_delete_configs', d) + bb.build.exec_func('dpkg_chroot_finalize', d) } do_dpkg_build[network] = "${TASK_USE_NETWORK_AND_SUDO}" diff --git a/meta/classes-recipe/dpkg.bbclass b/meta/classes-recipe/dpkg.bbclass index 8d7ff092..9fda58af 100644 --- a/meta/classes-recipe/dpkg.bbclass +++ b/meta/classes-recipe/dpkg.bbclass @@ -78,6 +78,7 @@ dpkg_runbuild() { distro="${HOST_BASE_DISTRO}-${BASE_DISTRO_CODENAME}" fi + create_chroot_parent_dir ${WORKDIR} deb_dl_dir_import "${WORKDIR}/rootfs" "${distro}" deb_dir="/var/cache/apt/archives" @@ -85,7 +86,10 @@ dpkg_runbuild() { ext_deb_dir="${ext_root}${deb_dir}" if [ ${USE_CCACHE} -eq 1 ]; then - schroot_configure_ccache + ${ISAR_CHROOT_MODE}_configure_ccache + fi + if [ "${ISAR_CHROOT_MODE}" = "unshare" ]; then + sbuild_add_unshare_mounts fi profiles="${@ isar_deb_build_profiles(d)}" @@ -110,12 +114,13 @@ dpkg_runbuild() { DSC_FILE=$(find ${WORKDIR} -maxdepth 1 -name "${DEBIAN_SOURCE}_*.dsc" -print) sbuild -A -n -c ${SBUILD_CHROOT} \ + --chroot-mode=${ISAR_CHROOT_MODE} \ --host=${PACKAGE_ARCH} --build=${BUILD_ARCH} ${profiles} \ --no-run-lintian --no-run-piuparts --no-run-autopkgtest --resolve-alternatives \ --bd-uninstallable-explainer=apt \ --no-apt-update --apt-distupgrade \ --chroot-setup-commands="echo \"Package: *\nPin: release n=${DEBDISTRONAME}\nPin-Priority: 1000\" > /etc/apt/preferences.d/isar-apt" \ - --chroot-setup-commands="echo \"APT::Get::allow-downgrades 1;\" > /etc/apt/apt.conf.d/50isar-apt" \ + --chroot-setup-commands="echo \"APT::Get::allow-downgrades 1;${@'\nAPT::Sandbox::User root;' if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''}\" > /etc/apt/apt.conf.d/50isar-apt" \ --chroot-setup-commands="rm -f /var/log/dpkg.log" \ --chroot-setup-commands="mkdir -p ${deb_dir}" \ --chroot-setup-commands="find ${ext_deb_dir} -maxdepth 1 -name '*.deb' -exec ln -t ${deb_dir}/ -sf {} +" \ @@ -125,7 +130,10 @@ dpkg_runbuild() { --finished-build-commands="cp /var/log/dpkg.log ${ext_root}/dpkg_partial.log" \ --build-path="" --build-dir=${WORKDIR} --dist="${DEBDISTRONAME}" ${DSC_FILE} - sbuild_dpkg_log_export "${WORKDIR}/rootfs/dpkg_partial.log" + # TODO: unclear if needed under unshare + if [ "${ISAR_CHROOT_MODE}" = "schroot" ]; then + sbuild_dpkg_log_export "${WORKDIR}/rootfs/dpkg_partial.log" + fi deb_dl_dir_export "${WORKDIR}/rootfs" "${distro}" # Cleanup apt artifacts diff --git a/meta/classes-recipe/image-locales-extension.bbclass b/meta/classes-recipe/image-locales-extension.bbclass index f4eb3718..f0683996 100644 --- a/meta/classes-recipe/image-locales-extension.bbclass +++ b/meta/classes-recipe/image-locales-extension.bbclass @@ -29,8 +29,15 @@ ROOTFS_INSTALL_COMMAND_BEFORE_EXPORT += "image_install_localepurge_download" image_install_localepurge_download[weight] = "40" image_install_localepurge_download[network] = "${TASK_USE_NETWORK_AND_SUDO}" image_install_localepurge_download() { - run_in_chroot '${ROOTFSDIR}' \ + run_privileged_here <<'EOF' + set -e + if [ "${ISAR_CHROOT_MODE}" = "unshare" ]; then + mount -o bind,private '${REPO_ISAR_DIR}/${DISTRO}' '${ROOTFSDIR}/isar-apt' + fi + + chroot ${ROOTFSDIR} \ /usr/bin/apt-get ${ROOTFS_APT_ARGS} -oDebug::NoLocking=1 --download-only localepurge +EOF } ROOTFS_INSTALL_COMMAND += "image_install_localepurge_install" diff --git a/meta/classes-recipe/image-tools-extension.bbclass b/meta/classes-recipe/image-tools-extension.bbclass index 2eac3619..addc514a 100644 --- a/meta/classes-recipe/image-tools-extension.bbclass +++ b/meta/classes-recipe/image-tools-extension.bbclass @@ -16,6 +16,9 @@ do_image_tools[depends] += " \ SCHROOT_MOUNTS = "${WORKDIR}:${PP_WORK} ${IMAGE_ROOTFS}:${PP_ROOTFS} ${DEPLOY_DIR_IMAGE}:${PP_DEPLOY}" SCHROOT_MOUNTS += "${REPO_ISAR_DIR}/${DISTRO}:/isar-apt" +# only used on unshare +ROOTFS_IMAGETOOLS ?= "${WORKDIR}/rootfs-imgtools-${BB_CURRENTTASK}" + imager_run() { IMAGE_STAGE_DIR=$(dirname $IMAGE_STAGE_HOST) create_chroot_parent_dir $IMAGE_STAGE_DIR @@ -114,3 +117,82 @@ generate_imager_sbom() { --timestamp $TIMESTAMP ${SBOM_DEBSBOM_EXTRA_ARGS} \ < ${WORKDIR}/imager.manifest } + +imager_run_unshare() { + exec 3<&0 + + # ignore everything before '--'. If the remaining list is empty, + # assume a here document is passed via stdin + while [ "$#" -gt 0 ]; do + case "$1" in + --) shift 1; break ;; + *) shift 1 ;; + esac + done + + if [ "$#" -eq 0 ]; then + set -- "$@" '/bin/bash' '-s' + fi + + local_install="${@(d.getVar("INSTALL_%s" % d.getVar("BB_CURRENTTASK")) or '').strip()}" + + create_chroot_parent_dir $(realpath -m "${ROOTFS_IMAGETOOLS}/..") + + run_privileged_here <<'EOF' + set -e + mkdir -p ${ROOTFS_IMAGETOOLS} + tar -xf "${SBUILD_CHROOT}" -C "${ROOTFS_IMAGETOOLS}" + mkdir -p ${ROOTFS_IMAGETOOLS}/isar-apt + cp -rL /etc/resolv.conf "${ROOTFS_IMAGETOOLS}/etc" +EOF + + # setting up error handler + imager_cleanup() { + run_privileged rm -rf ${ROOTFS_IMAGETOOLS} + } + trap 'exit 1' INT HUP QUIT TERM ALRM USR1 + trap 'imager_cleanup' EXIT + + if [ -n "${local_install}" ]; then + echo "Installing imager deps: ${local_install}" + + distro="${BASE_DISTRO}-${BASE_DISTRO_CODENAME}" + if [ ${ISAR_CROSS_COMPILE} -eq 1 ]; then + distro="${HOST_BASE_DISTRO}-${BASE_DISTRO_CODENAME}" + fi + + E="${@ isar_export_proxies(d)}" + deb_dl_dir_import ${ROOTFS_IMAGETOOLS} ${distro} + ${SCRIPTSDIR}/lockrun.py -r -f "${REPO_ISAR_DIR}/isar.lock" -s <<'EOAPT' + local_install=$local_install ${@run_privileged_cmd(d)} /bin/bash -s <<'EOF' + set -e + mount -o bind,private ${REPO_ISAR_DIR}/${DISTRO} ${ROOTFS_IMAGETOOLS}/isar-apt + chroot ${ROOTFS_IMAGETOOLS} apt-get update \ + -o Dir::Etc::SourceList='sources.list.d/isar-apt.list' \ + -o Dir::Etc::SourceParts='-' \ + -o APT::Get::List-Cleanup='0' + chroot ${ROOTFS_IMAGETOOLS} apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends -y \ + --allow-unauthenticated --allow-downgrades --download-only install \ + $local_install +EOF +EOAPT + + deb_dl_dir_export ${ROOTFS_IMAGETOOLS} ${distro} + local_install=$local_install run_privileged_here <<'EOF' + set -e + mount -o bind,private ${REPO_ISAR_DIR}/${DISTRO} ${ROOTFS_IMAGETOOLS}/isar-apt + chroot ${ROOTFS_IMAGETOOLS} apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends -y \ + --allow-unauthenticated --allow-downgrades install \ + $local_install +EOF + fi + + run_privileged_here <<'EOF' "$@" + set -e + mkdir -p ${ROOTFS_IMAGETOOLS}/${SCRIPTSDIR} + ${@insert_isar_mounts(d, d.getVar('ROOTFS_IMAGETOOLS'), d.getVar('SCHROOT_MOUNTS'))} + chroot ${ROOTFS_IMAGETOOLS} "$@" <&3 +EOF + + run_privileged rm -rf ${ROOTFS_IMAGETOOLS} +} diff --git a/meta/classes-recipe/rootfs.bbclass b/meta/classes-recipe/rootfs.bbclass index 5a7c2a93..4d1f542f 100644 --- a/meta/classes-recipe/rootfs.bbclass +++ b/meta/classes-recipe/rootfs.bbclass @@ -164,7 +164,12 @@ rootfs_cmd() { } rootfs_do_mounts[weight] = "3" -rootfs_do_mounts() { +python rootfs_do_mounts() { + if d.getVar('ISAR_CHROOT_MODE') == 'schroot': + bb.build.exec_func('rootfs_do_mounts_priv', d) +} + +rootfs_do_mounts_priv() { run_privileged_here <<'EOSUDO' set -e mountpoint -q '${ROOTFSDIR}/dev' || \ @@ -187,7 +192,12 @@ rootfs_do_mounts() { EOSUDO } -rootfs_do_umounts() { +python rootfs_do_umounts() { + if d.getVar('ISAR_CHROOT_MODE') == 'schroot': + bb.build.exec_func('rootfs_do_umounts_priv', d) +} + +rootfs_do_umounts_priv() { run_privileged_here <<'EOSUDO' set -e @@ -234,7 +244,12 @@ ROOTFS_EXTRA_IMPORTED := "${@rootfs_extra_import(d)}" rootfs_prepare[weight] = "25" rootfs_prepare(){ - run_privileged tar -xf "${BOOTSTRAP_SRC}" -C "${ROOTFSDIR}" --exclude="./dev/console" + create_chroot_parent_dir $(realpath "${ROOTFSDIR}/..") + rm -rf ${ROOTFSDIR} + run_privileged_here << 'EOF' + mkdir -p ${ROOTFSDIR} + tar -xf "${BOOTSTRAP_SRC}" -C "${ROOTFSDIR}" --exclude="./dev/console" +EOF # setup chroot run_privileged "${ROOTFSDIR}/chroot-setup.sh" "setup" "${ROOTFSDIR}" @@ -304,10 +319,14 @@ rootfs_install_pkgs_update[weight] = "5" rootfs_install_pkgs_update[isar-apt-lock] = "acquire-before" rootfs_install_pkgs_update[network] = "${TASK_USE_NETWORK_AND_SUDO}" rootfs_install_pkgs_update() { - run_in_chroot '${ROOTFSDIR}' /usr/bin/apt-get update \ - -o Dir::Etc::SourceList="sources.list.d/isar-apt.list" \ - -o Dir::Etc::SourceParts="-" \ - -o APT::Get::List-Cleanup="0" + run_privileged_here <<'EOF' + set -e + ${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS')) if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} + chroot '${ROOTFSDIR}' /usr/bin/apt-get update \ + -o Dir::Etc::SourceList="sources.list.d/isar-apt.list" \ + -o Dir::Etc::SourceParts="-" \ + -o APT::Get::List-Cleanup="0" +EOF } ROOTFS_INSTALL_COMMAND += "rootfs_install_resolvconf" @@ -335,9 +354,12 @@ rootfs_install_pkgs_download[isar-apt-lock] = "release-after" rootfs_install_pkgs_download[network] = "${TASK_USE_NETWORK}" rootfs_install_pkgs_download() { # download packages using apt in a non-privileged namespace - rootfs_cmd --bind "${ROOTFSDIR}/var/cache/apt/archives" /var/cache/apt/archives \ - ${ROOTFSDIR} \ - -- /usr/bin/apt-get ${ROOTFS_APT_ARGS} -oDebug::NoLocking=1 --download-only ${ROOTFS_PACKAGES} + run_privileged_here <<'EOF' + set -e + ${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS')) if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} + chroot ${ROOTFSDIR} \ + /usr/bin/apt-get ${ROOTFS_APT_ARGS} -oDebug::NoLocking=1 --download-only ${ROOTFS_PACKAGES} +EOF } ROOTFS_INSTALL_COMMAND_BEFORE_EXPORT ??= "" @@ -364,8 +386,12 @@ rootfs_install_pkgs_install[weight] = "8000" rootfs_install_pkgs_install[progress] = "custom:rootfs_progress.PkgsInstallProgressHandler" rootfs_install_pkgs_install[network] = "${TASK_USE_SUDO}" rootfs_install_pkgs_install() { - run_in_chroot "${ROOTFSDIR}" \ + run_privileged_here <<'EOF' + set -e + ${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS')) if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} + chroot "${ROOTFSDIR}" \ /usr/bin/apt-get ${ROOTFS_APT_ARGS} ${ROOTFS_PACKAGES} +EOF } ROOTFS_INSTALL_COMMAND += "rootfs_restore_initrd_tooling" @@ -669,8 +695,11 @@ rootfs_install_sstate_finalize() { # - after building the rootfs, the tar won't be there, but we also don't need to unpack # - after restoring from cache, there will be a tar which we unpack and then delete if [ -f rootfs.tar ]; then + create_chroot_parent_dir $(realpath -m "${ROOTFSDIR}/..") + run_privileged_here <<'EOF' mkdir -p ${ROOTFSDIR} - run_privileged tar -C ${ROOTFSDIR} -xp ${SSTATE_TAR_ATTR_FLAGS} < rootfs.tar + tar -C ${ROOTFSDIR} -xp ${SSTATE_TAR_ATTR_FLAGS} -f rootfs.tar +EOF rm rootfs.tar fi } diff --git a/meta/classes-recipe/sbuild.bbclass b/meta/classes-recipe/sbuild.bbclass index f0757891..d2d333ed 100644 --- a/meta/classes-recipe/sbuild.bbclass +++ b/meta/classes-recipe/sbuild.bbclass @@ -7,7 +7,8 @@ SCHROOT_MOUNTS ?= "" inherit crossvars -SBUILD_CHROOT ?= "${DEBDISTRONAME}-${SCHROOT_USER}-${ISAR_BUILD_UUID}-${@os.getpid()}" +SBUILD_CHROOT:unshare ?= "${SCHROOT_DIR}.tar.zst" +SBUILD_CHROOT:schroot ?= "${DEBDISTRONAME}-${SCHROOT_USER}-${ISAR_BUILD_UUID}-${@os.getpid()}" SBUILD_CONF_DIR ?= "${SCHROOT_CONF}/${SBUILD_CHROOT}" SCHROOT_CONF_FILE ?= "${SCHROOT_CONF}/chroot.d/${SBUILD_CHROOT}" @@ -144,6 +145,14 @@ END EOSUDO } +unshare_configure_ccache() { + # ccache must be below /build for file permissions to work properly + cat <<'EOF' >> ${SBUILD_CONFIG} +$build_environment = { "CCACHE_DIR" => "/ccache" }; +$path = "/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"; +EOF +} + sbuild_dpkg_log_export() { export dpkg_partial_log="${1}" @@ -152,3 +161,19 @@ sbuild_dpkg_log_export() { cat ${dpkg_partial_log} >> ${SCHROOT_DIR}/tmp/dpkg_common.log ) 9>"${SCHROOT_DIR}/tmp/dpkg_common.log.lock" } + +# additional mounts managed by sbuild +sbuild_add_unshare_mounts() { + mkdir -p "${CCACHE_DIR}" + # sbuild id from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1110942 + setfacl -m u:${UNSHARE_SUBUID_BASE}:rwX -m u:${@int(d.getVar('UNSHARE_SUBUID_BASE')) + 999}:rwx "${CCACHE_DIR}" + + cat <<'EOF' >> ${SBUILD_CONFIG} +$unshare_bind_mounts = [ + { directory => '${WORKDIR}/rootfs', mountpoint => '${PP}/rootfs' }, + { directory => '${WORKDIR}/isar-apt/${DISTRO}-${DISTRO_ARCH}/apt/${DISTRO}', mountpoint => '/isar-apt' }, + { directory => '${REPO_BASE_DIR}', mountpoint => '/base-apt' }, + { directory => "${CCACHE_DIR}", mountpoint => "/ccache" } +]; +EOF +} diff --git a/meta/classes-recipe/sdk.bbclass b/meta/classes-recipe/sdk.bbclass index 074f5ef8..64a501d2 100644 --- a/meta/classes-recipe/sdk.bbclass +++ b/meta/classes-recipe/sdk.bbclass @@ -74,13 +74,20 @@ rootfs_configure_isar_apt_dir() { ROOTFS_POSTPROCESS_COMMAND:prepend:class-sdk = "sdkchroot_configscript " sdkchroot_configscript () { - run_in_chroot ${ROOTFSDIR} /configscript.sh ${DISTRO_ARCH} + run_privileged_here <<'EOF' + set -e + ${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), d.getVar('ROOTFS_MOUNTS')) if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} + cp -rL /etc/resolv.conf '${ROOTFSDIR}/etc' + chroot ${ROOTFSDIR} /configscript.sh ${DISTRO_ARCH} +EOF } ROOTFS_POSTPROCESS_COMMAND:append:class-sdk = " sdkchroot_finalize" sdkchroot_finalize() { - rootfs_do_umounts + if [ "${ISAR_CHROOT_MODE}" = "schroot" ]; then + rootfs_do_umounts_priv + fi # Remove setup scripts run_privileged rm -f ${ROOTFSDIR}/chroot-setup.sh ${ROOTFSDIR}/configscript.sh diff --git a/meta/conf/bitbake.conf b/meta/conf/bitbake.conf index 0f84e715..1c3a6f4a 100644 --- a/meta/conf/bitbake.conf +++ b/meta/conf/bitbake.conf @@ -72,7 +72,7 @@ KERNEL_FILE:arm64 ?= "vmlinux" MACHINEOVERRIDES ?= "${MACHINE}" DISTROOVERRIDES ?= "${DISTRO}" -OVERRIDES = "${PACKAGE_ARCH}:${MACHINEOVERRIDES}:${DISTROOVERRIDES}:${BASE_DISTRO_CODENAME}:forcevariable" +OVERRIDES = "${PACKAGE_ARCH}:${MACHINEOVERRIDES}:${DISTROOVERRIDES}:${BASE_DISTRO_CODENAME}:${ISAR_CHROOT_MODE}:forcevariable" FILESOVERRIDES = "${PACKAGE_ARCH}:${MACHINE}" # Setting default QEMU_ARCH variables for different DISTRO_ARCH: @@ -151,6 +151,10 @@ ISAR_APT_RETRIES ??= "${@'10' if bb.utils.to_boolean(d.getVar('ISAR_USE_APT_SNAP ISAR_APT_DELAY_MAX ??= "${@'600' if bb.utils.to_boolean(d.getVar('ISAR_USE_APT_SNAPSHOT')) else ''}" ISAR_APT_SNAPSHOT_TIMESTAMP ??= "${SOURCE_DATE_EPOCH}" +# Rootless build execution +ISAR_ROOTLESS ??= "0" +ISAR_CHROOT_MODE ??= "${@'unshare' if bb.utils.to_boolean(d.getVar('ISAR_ROOTLESS')) else 'schroot'}" + # Default parallelism and resource usage for xz XZ_MEMLIMIT ?= "50%" XZ_THREADS ?= "${@oe.utils.cpu_count(at_least=2)}" @@ -206,6 +210,7 @@ CCACHE_DEBUG ?= "0" # Variables for tasks marking # Long term TODO: get rid of sudo marked tasks TASK_USE_NETWORK = "1" +# nested namespacing requires this as well TASK_USE_SUDO = "1" TASK_USE_NETWORK_AND_SUDO = "1" diff --git a/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc b/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc index 8ca295b7..c90bc59c 100644 --- a/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc +++ b/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc @@ -178,6 +178,8 @@ do_bootstrap() { umount \$1/$base_apt_tmp && rm ${WORKDIR}/mmtmpdir && \ umount $base_apt_tmp && rm -rf --one-file-system $base_apt_tmp" else + # prepare dl_dir for access from both sides (local and rootfs) + create_chroot_parent_dir ${WORKDIR}/dl_dir deb_dl_dir_import "${WORKDIR}/dl_dir" "${BOOTSTRAP_BASE_DISTRO}-${BASE_DISTRO_CODENAME}" bootstrap_list="${WORKDIR}/sources.list.d/bootstrap.list" @@ -197,6 +199,7 @@ do_bootstrap() { -o Dir::State="$1/var/lib/apt" \ -o Dir::Etc="$1/etc/apt" \ -o Dir::Cache="$1/var/cache/apt" \ + ${@'-o APT::Sandbox::User=root' if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} \ -o Apt::Architecture="${BOOTSTRAP_DISTRO_ARCH}" \ ${@get_apt_opts(d, '-o')}' extra_essential="$extra_essential && $syncout" @@ -214,13 +217,14 @@ do_bootstrap() { # Cleanup mounts if fails trap 'exit 1' INT HUP QUIT TERM ALRM USR1 - trap 'bootstrap_cleanup' EXIT + trap ${@'true' if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else 'bootstrap_cleanup'} EXIT # Create lock file so that it is owned by the user running the build (not root) mkdir -p ${DEBDIR} touch ${DEB_DL_LOCK} - run_privileged TMPDIR="${BOOTSTRAP_TMPDIR}" mmdebstrap $bootstrap_args \ + ${@'' if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else 'run_privileged'} \ + TMPDIR="${BOOTSTRAP_TMPDIR}" mmdebstrap $bootstrap_args \ $arch_param \ --mode=unshare \ ${MMHOOKS} \ @@ -239,6 +243,7 @@ do_bootstrap() { --customize-hook='sed -i "/en_US.UTF-8 UTF-8/s/^#//g" "$1/etc/locale.gen"' \ --customize-hook='chroot "$1" /usr/sbin/locale-gen' \ --customize-hook='chroot "$1" /usr/bin/apt-get -y clean' \ + ${@'--skip=output/dev' if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else ''} \ --skip=cleanup/apt \ --skip=download/empty \ ${@get_apt_opts(d, '--aptopt')} \ @@ -252,7 +257,8 @@ do_bootstrap() { if [ "${ISAR_USE_CACHED_BASE_REPO}" != "1" ]; then deb_dl_dir_export "${WORKDIR}/dl_dir" "${BOOTSTRAP_BASE_DISTRO}-${BASE_DISTRO_CODENAME}" - run_privileged rm -rf --one-file-system "${WORKDIR}/dl_dir" + run_privileged find ${WORKDIR}/dl_dir -maxdepth 1 -mindepth 1 -exec rm -rf --one-file-system "{}" \; + rmdir ${WORKDIR}/dl_dir fi } addtask bootstrap before do_build after do_generate_keyrings diff --git a/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc b/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc index 61d37760..7a778d8c 100644 --- a/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc +++ b/meta/recipes-devtools/sbuild-chroot/sbuild-chroot.inc @@ -66,8 +66,28 @@ ROOTFS_POSTPROCESS_COMMAND:remove = "rootfs_cleanup_base_apt" DEPLOY_SCHROOT = "${@d.getVar('SCHROOT_' + d.getVar('SBUILD_VARIANT').upper() + '_DIR')}${SBUILD_SCHROOT_SUFFIX}" -do_sbuildchroot_deploy[dirs] = "${DEPLOY_DIR}/schroot-${SBUILD_VARIANT}" -do_sbuildchroot_deploy() { +sbuildchroot_deploy_tree() { ln -Tfsr "${ROOTFSDIR}" "${DEPLOY_SCHROOT}" } +sbuildchroot_deploy_tar() { + lopts="--one-file-system --exclude=var/cache/apt/archives --exclude=isar-apt" + # we cannot use pzstd, as this results in a different magic + # (zstd skippable frame) which is not detected by sbuild + # https://salsa.debian.org/debian/sbuild/-/blob/d975d388a98627a0d7d112791e441c27a6d529df/lib/Sbuild/ChrootUnshare.pm#L608 + ZSTD="zstd -${SSTATE_ZSTD_CLEVEL} -T${ZSTD_THREADS}" + run_privileged \ + tar -C ${ROOTFSDIR} -cpS $lopts ${ROOTFS_TAR_ATTR_FLAGS} . \ + | $ZSTD > ${DEPLOY_SCHROOT}.tar.zst + # cleanup extracted rootfs + run_privileged rm -rf ${ROOTFSDIR} +} + +do_sbuildchroot_deploy[network] = "${TASK_USE_SUDO}" +do_sbuildchroot_deploy[dirs] += "${DEPLOY_DIR}/schroot-${SBUILD_VARIANT}" +python do_sbuildchroot_deploy() { + if d.getVar('ISAR_CHROOT_MODE') == 'unshare': + bb.build.exec_func('sbuildchroot_deploy_tar', d) + else: + bb.build.exec_func('sbuildchroot_deploy_tree', d) +} addtask sbuildchroot_deploy before do_build after do_rootfs -- 2.51.0 -- You received this message because you are subscribed to the Google Groups "isar-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to isar-users+unsubscribe@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/isar-users/20260218115827.3947145-12-felix.moessbauer%40siemens.com.