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; Thu, 26 Feb 2026 17:29:15 +0100 X-Sieve: CMU Sieve 2.4 Received: from mail-qt1-f190.google.com (mail-qt1-f190.google.com [209.85.160.190]) by shymkent.ilbers.de (8.15.2/8.15.2/Debian-8+deb9u1) with ESMTPS id 61QGTD0W009717 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 26 Feb 2026 17:29:13 +0100 Received: by mail-qt1-f190.google.com with SMTP id d75a77b69052e-506a81bbb50sf13468691cf.1 for ; Thu, 26 Feb 2026 08:29:13 -0800 (PST) ARC-Seal: i=3; a=rsa-sha256; t=1772123348; cv=pass; d=google.com; s=arc-20240605; b=WY+ER0+ED/axYBZ558t6i5J/nwLRqq3DyVZc0rHMo/qrsuFYf5AIQf+4CjgT6H4Lwr KPcj1tEaYZ96ULiPbqtt4F7UuwPSKf4KCITryufsxtUsKbSm6fdswZkV/JayDbP4zYAJ Qi3eX2VkylFQvp4EqtewDTyfxoziYl/eU1q036ptQgtC7IUwh5LwWPjSnLJjpQZYPmbj pC2ytxT8LeNhy1exMNWTLs4+g2F4FFXKjLMHiquFiYrWfixg4p4LMox52M59HwqIESK3 y438leBYGK9CN5gJi5yYASNOoTF2kMnsuC/0KfQUqNkpKJtrhC1VkmuOODUxd8uMVL7v nfCg== 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=I17hvXNtkiEzOuFw5fGKsYKjYhL+r+WVpTIfieI+W5o=; fh=8p45gUIDb5zflfj/UWuLmNaBTiGDeSXqA3eCRKs4sAk=; b=fzm3zSyzaMCLmKRH8V4j8QfLrlZ2l2IJ5WMmzKskCqP3LDrALsgFYb3HzCkSTVp2Hb aEneHdOFmbeqHj3J68heYJLCsc1gd3e77PWcCzbEH19WcrrlhmnXJzWdEOJgEgB3jKzB YlTG3+R2llDi48tNmYbRsn4f6AqpEwuCn2XV1gmNo924IPnj02XC+O0xSWnw1Ddt1Hv7 V3KYwRY+SqefSGM7SljHFBOEFUy/FBejiiWw9DaP7aRe30OsCOcqT1rP1pSCFLJwZVmv 4lG5B80HRq8VDHAIS1hItqNwEEBErcHM0HhGl5jg7yk0rQg4nX377aNx9KBqIuH9irNj +zEw==; darn=ilbers.de ARC-Authentication-Results: i=3; gmr-mx.google.com; dkim=pass header.i=@siemens.com header.s=selector2 header.b=uVBaNWWW; 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:c201::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=1772123348; x=1772728148; 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=I17hvXNtkiEzOuFw5fGKsYKjYhL+r+WVpTIfieI+W5o=; b=OfHmC+WaihYgcDQ8bIL/QtgMlP8W8R7df3wxaV4U92JC7+smcLa41RlkXu2de67HYi eOrRthVv28iIP8FiyIS/Gg3A2b6nstXrwoRNMpc3OKxBnGMBJSIx7mympHfm/RXsyThU v4wIkwKitYy9SlREeXWueX7aIQyAI0ONn3lq3eD0j3QVgFUy3aZpug3CA0/tyZRk4RUR HLx9agbg9/Jk2Ob88ZNCAIrQDtmfer50x1xJiSmjkSwx2A+jcCjhRhsUmiEogjNtEgXl 9Vx/IcBHlRA/jK485GPpYMF9x9XGu5DsvtsBYl3InkeCNcQXTxoYj0T10mVtXybp4uzU 4B4g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772123348; x=1772728148; 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=I17hvXNtkiEzOuFw5fGKsYKjYhL+r+WVpTIfieI+W5o=; b=QIZ3HXEMLRspnSOiJDvhAC8PAtApEXTw4yGjzIkuLgekKDU6/h+0XQWT/qZUQjlO/F fj+k74iqfE0Fkk829rru6glZKjFWw8amhNNEtSLky+kPcO1UXNmJ8X3m1juBI/inTuRT 7ZzNhQqRd99wRPOHFgqndEU4z7UgbgmmGxO2wvaIhZHjX4xhIgVdNHXZ8c4vxSKsCezV ofV8Yo2xYFTYS2ZXJAdF3qzUeh3TrGAYBFdNnvWojdNSaRMCsaqZjCXQ6kN+DX6qZgX1 /y+83i+MrI7GdcF2J9o1IDd2VY2I0hclIcA3p0Yy/q1ClYbHkKbDDt8Gh4Cx4KgDMuQD spDg== X-Forwarded-Encrypted: i=3; AJvYcCXSIMIUoGJ6AqkLkZflciOycbZd7+uoqJwU0J7ed175v2l4WBHQRVJlM+r3xjUNZiiwWxkR@ilbers.de X-Gm-Message-State: AOJu0Yzsj5mW8fM2zBuakPhhwt9yn9X7lcjH2fEqbeVqKUYX9B2Blv7h 2Ir8dsVJpyOcvBmi9ZWagJfMaW0hIbDzz2W2OLANChkvC/QxZdZ3KD+3 X-Received: by 2002:a05:622a:94:b0:501:51fb:622c with SMTP id d75a77b69052e-50745fa0dfcmr29397541cf.37.1772123347650; Thu, 26 Feb 2026 08:29:07 -0800 (PST) X-BeenThere: isar-users@googlegroups.com; h="AV1CL+Erx24iqkOwl/2iFQWPUshVie5dKvlSQS3VD+SmEKJElg==" Received: by 2002:a05:622a:147:b0:505:e7a5:2c02 with SMTP id d75a77b69052e-5073c129270ls34072001cf.2.-pod-prod-08-us; Thu, 26 Feb 2026 08:29:06 -0800 (PST) X-Received: by 2002:a05:622a:2c7:b0:506:a5f1:e5eb with SMTP id d75a77b69052e-507460dbdd5mr34869961cf.76.1772123346480; Thu, 26 Feb 2026 08:29:06 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1772123346; cv=pass; d=google.com; s=arc-20240605; b=eI+fYYG9FuJnZ9XSxzThE9DvNs95xqNffOvxumL+sL8P91AJg/WCA5kpqrB5X7CXxM mWCQCWmZZ85UmybJyPUzGZEG6T9+WnXppOujK9hPv3aB4g2rHNl6RMUlI0dVHKLr1DN4 yDH1xMKtoqBzDKxjKXsOZAkDloP5HrX4ZZbOGB0fYVderjr9KcusUOXWXUouav5JVv5A wMkQzG1/pmQIQUjNvHHxhEkPYrov2CY+L8/jIPbacerKKn4r0By++Ii9Li8+X7F8jApn 7BFa1Hn2EnIgSokTrgb/ReSLhEc4/zDieH9GjUOd7yTiTe4DFoDNEpIQD7JokYUhlrTq ZBOg== 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=5Vx5NDgZ5rBBfHSMLI+YFcg2nJ06cbiJiex5UAwRm/U=; fh=WkhL8kaJc+l2wQon1t06Ej3uvBGj9sVhNcE8PaS/XbI=; b=bKx8JJazKk6yqrj0KT+64C7UD9+FQxB04UB3kWUinoSRlypZtfVkGvt/fIsYBIrS6a PgDDeTcLGnf0JpIYKs2iAp4W547e9hcYrB3F+zOczyo5SocL8gvfetYhADuWPNHnVRYl iPrZPrVEC8Tky1ohfRC1gyjHYagvwjH9TaR+tPRIe69aDlivG9LZWSzEQMsbePqgLbVP w+bgzoq7+XaYlTYRtGoZaPXLoGUuQZmVZC/2b4heRWxwnr+6+5vyYZpPSxypEeku6Ia9 7zSK6gnLKCUmELT6MhKCx42OxKnwqfxLxLKy0WZjI7eOf8xSra+QKJqNQ0Jj6o9iWBnx KEfw==; dara=google.com ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@siemens.com header.s=selector2 header.b=uVBaNWWW; 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:c201::3 as permitted sender) smtp.mailfrom=felix.moessbauer@siemens.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=siemens.com Received: from AS8PR04CU009.outbound.protection.outlook.com (mail-westeuropeazlp170110003.outbound.protection.outlook.com. [2a01:111:f403:c201::3]) by gmr-mx.google.com with ESMTPS id 6a1803df08f44-899c7160d0fsi738116d6.3.2026.02.26.08.29.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 Feb 2026 08:29:06 -0800 (PST) Received-SPF: pass (google.com: domain of felix.moessbauer@siemens.com designates 2a01:111:f403:c201::3 as permitted sender) client-ip=2a01:111:f403:c201::3; ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=dB7CReJ/5kn7UYuSaQPjyYdxjtB9fG+cyhLMKFouO/LRyoPmzH5eM2hMCKgixZg81DKOSAaUZapaM+nYCfI9APSx6hn2LpSz1KbLGF7Nosct8uK/j1n7rjV7BmZhf92gyjqB7YHO3FjedswewIml0lFHU1bQPYBKUrwz0rvOVSesTgb5WMlwmvPL9aaXieLTz4ybjOAec5DejQdlwE4ykfD08SNi4zwk7Gc31Zjk38UUiqdhGSjGOzVNqHmsQQAUEVLUbMLKU8/HMvkrB+/YGpluo2qmo0YBwjmB+qybk5g3OESlbU0lKk6j/mVFKg+8ZYKab38dQyi1VbfvFySJCg== 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=5Vx5NDgZ5rBBfHSMLI+YFcg2nJ06cbiJiex5UAwRm/U=; b=kW1s0kCqOMFuqfiVIYIO5uCWjxxbkY2RYBHupBwMCV8lZN3BZlhO8cBTx9L3za2ORD4wqi4w5F377IeapMJbwmQGJX6iHz60vU/yyCK/5eWHttzSM5Pdqtkk22LqxuP2SwIHnydyIZBkjHhWM28vEZofV+heniaql6AhgsoteT6sWnGi4rYIr9WAzhOeeisa30R6Ivcrh7iUi/FDZWmbIDkoPQI+8QUQ+gXt/uMJvEg5BYaxdZHlVBYl/rh7o2hDWoUOdT9zeIUTKY50MJiaOvFFh3CqfjhEYfX3CMn0vYRsgOOixO4ElVk/D7UtnYUEqDsmeGoeSAgzact82/xMSA== 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 AS4PR10MB5669.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:20b:4f0::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9632.23; Thu, 26 Feb 2026 16:29:03 +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.9654.014; Thu, 26 Feb 2026 16:29:03 +0000 From: "'Felix Moessbauer' via isar-users" To: isar-users@googlegroups.com Cc: jan.kiszka@siemens.com, quirin.gylstorff@siemens.com, Felix Moessbauer Subject: [PATCH v1 10/15] add support for fully rootless builds Date: Thu, 26 Feb 2026 17:28:35 +0100 Message-ID: <20260226162843.1642329-11-felix.moessbauer@siemens.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260226162843.1642329-1-felix.moessbauer@siemens.com> References: <20260226162843.1642329-1-felix.moessbauer@siemens.com> Content-Type: text/plain; charset="UTF-8" X-ClientProxiedBy: FR4P281CA0218.DEUP281.PROD.OUTLOOK.COM (2603:10a6:d10:e4::12) To DU0PR10MB6828.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:10:47f::13) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU0PR10MB6828:EE_|AS4PR10MB5669:EE_ X-MS-Office365-Filtering-Correlation-Id: e8597f4e-4337-42df-3340-08de755426ed X-MS-Exchange-AtpMessageProperties: SA X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|10070799003|1800799024; X-Microsoft-Antispam-Message-Info: enfbKdQVqnj3mfbX9xHDgKD+PLq3+m6eN2YIQ41qRkA985fuXTX4Y32u1NqYiGq7eR1ydkkBZDIcyvt/KNRZKE4Tf1EU5qcQRbr8w25UFWRYaageEqyS6hm8Yxoppww5V3ZUSuzbAV9iv4PtrVIXsFEkq00gPsjoa7R2STrvUpH3xZfT/ZWddWKJ6exrIiwXR04cfifcFui5hSiGRgEuTZj49rMHXF4GZuAKkuLlpxSOpPf6xtsZd0H70N/pDpBwhkukY9bunO4zZzamo+HM7iBKTeFLDIB2b1C87XpvxkfwXmXPdx8w6Q25LbNKr/ja0Zb0W8oipvo76Wn9k++xibtLqeOWkTHdEhxrbNAabXtT0n9Y+X/nnl9D4mowdaWzJl7mJP3C2q0SQES31CRssJkiTANSjx78ctjsa8E20MB9VU1OLf+7QHde3bY56/Fj8fJ6ntiAk/kU2bOor3JoXUcqA3K1Ec3P0ywpeCfaIKXpntRyOCOXQ4EdqeVE384/u7VflYVXbxqLUkGnBqJs42g06ydIAPV/XyKI/hZ53hT5FhXwbhW3hpAb0Q1HZ2bQgah2FoePWSEcrO9mQB90ODXTtzT8SaSJ5EF/5T/MqV0UW6izLVQn02hWZS8S6LnkYrwoCqWH68t6tAX5y0wLEwI6srErCvm2j5FOAki7sHSGZVi3deOMB/ea70FiEDXm 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)(366016)(10070799003)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 2 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?AzBXZOSecxFMwxWTHZw5cISFKYP6iz72gAxepfrykbd6s00hlOPv4fUbjc7S?= =?us-ascii?Q?YlpfuQ7ZJAS8t94mTxsXncl41uv1p6MSyN4q0nOK5mHR/irMnT/3HQcZOrnC?= =?us-ascii?Q?Ock8BGuKiqFcQdPrhhz/kZpg2naXvj1OEVacnHHRa+jACFzwcxcVMlJGHjcy?= =?us-ascii?Q?6ufKhLYtdY8EXlzvymyRaTG+qxR2GPbLAl6dr/2yLzMsPc95SATzJFZuSCII?= =?us-ascii?Q?3vfCAR09BdmjkKsZfmII1JUQiBHNR6jr9QRi16dalBBDTleQlHzJ64OKvKVI?= =?us-ascii?Q?S+7s9nj1HHxrKMSjEbDF1hFsdmrGRTkU5Jjy5Fj8sDbw9kyYvXDhTmuB8ij1?= =?us-ascii?Q?ssE+pcG2UAO9XqYkmuhlVw888wIQsi2njIwMIAhUdEmbmN4xeyVWNiyFY0zJ?= =?us-ascii?Q?ISjEJ9USol6zDQo4bEUdN/9JDWMg3ShG3aOUq2eaHt0iCOibgW2SaKx4g89i?= =?us-ascii?Q?9JPrZXFmFSplNhVoJu81vBc4Gn/6fUlNEM21IpdbjAP9a6Th26lm2Fu6Hzuh?= =?us-ascii?Q?gGSDbLtC/DJd2kguhdKMkPDNc7WMnChn7yO6gXWMz4XCRvm7V+VQ3OSdnZR7?= =?us-ascii?Q?nN8Bme8c8S9Gf4s36W+JGfqXW99ANBd4bTV6ZgzeTnbZGJ2aOVmORNSWO8FO?= =?us-ascii?Q?AEUP7mYsgcNOSuFFiprb40dA3mT0YJqzlOA60/DqCJJ7CtUr55Q5uInjZyZW?= =?us-ascii?Q?UbGo/Y+YLbRBf2GDOLmAbwrXUEFZDY1nHWDImkd1DQzZXmX8GJDyGwRF+Am/?= =?us-ascii?Q?smOTFqdXZX49lesqdSMA4WQ4WvBn/kkB7iAaRzvNNP8hk3AW+AGUUxehVOoV?= =?us-ascii?Q?q57WxCmxmI+h9X6R0Xa31vkDSeptGvK6vkVmAlMTs0jZ0ohpdFgEsfiyStIk?= =?us-ascii?Q?T9k/6Zu4bTLa6MsaG6PX4NKhn29whKShXMzOpcKog65sBn8OJ8J2Z3z8+ZKE?= =?us-ascii?Q?bdOhXryke/tFPUmyLF0lXVt3uDXQ8Q3udaNg0xrTg5+O6YzGWBgl2y/JcGle?= =?us-ascii?Q?P5OnOtnsPbvgowuoPhQPBiOd/GG0TrELtGDK/sCZ0xxFBqT9fzXc0SOlB20Y?= =?us-ascii?Q?z8ob7EHvp0/Glb+khPo2ZOav/a7VStn81KueFTCzqPF3IdYK6DnDKa+i3PpV?= =?us-ascii?Q?Rb+i4X1Ky44E/FT3v8XEtYcBHLGvg7l7o3YrIs77T88V96ss4SuAsuuj4Rp4?= =?us-ascii?Q?TZiIPHske6CKjZtX32kgXPPOxBIcsU8Si0XEiGfJHC2xnoLCKBv1kMPYCT0H?= =?us-ascii?Q?ZmRi2yNqu1+A+XOIleFdFmoz52QdDnJhA8mbehuwQJhqN6VOxWMXtxFBwJlp?= =?us-ascii?Q?YERfU1eG9/VjjiPxomhewj7/53csbuNf8M0z95bMju4VLDDCFrKIo0mhND5p?= =?us-ascii?Q?s9tB8AnHpBM9VUUowMB2yGGcAPCA6zqdifrQkXTtrK+afO9bz5/1SWPMsoqG?= =?us-ascii?Q?c4eFlPpmqZv0Yplv63jUsPmUDFIEU7IYsbJDyRgz9qNwvoSFjJOOMR2swrNE?= =?us-ascii?Q?5hAQBBbvNturfWFZ5LmE8e/Tsn8AWI7dzpxNqzd89wnUKV0o3kUYQRBx/tfu?= =?us-ascii?Q?bKvncBGULo6MFPO46yrDszjzzgS2DYzsxIFNRo7Pz2+0CgMwI0GSr4Gqxf84?= =?us-ascii?Q?INKx3UY14CMbzD9ejPhg9TUvipWso2GxxfRhpKZp+wVznGTJX+rtMMFa3kha?= =?us-ascii?Q?7zeizVcHGAeZSQEhHErOWON6gqNT5CAJEdco/9wdY7gdoy2d9m94KiEPxljD?= =?us-ascii?Q?iH+/jzpBUhDkdRP3NtNc8I3g2e94r1CXMqdE/ocdxzANb1hsbHXUPFwQgpkU?= X-MS-Exchange-AntiSpam-MessageData-1: NL1mgaZ3iYJm5tnmSlO6MJXZfwffQi/gN+g= X-OriginatorOrg: siemens.com X-MS-Exchange-CrossTenant-Network-Message-Id: e8597f4e-4337-42df-3340-08de755426ed X-MS-Exchange-CrossTenant-AuthSource: DU0PR10MB6828.EURPRD10.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Feb 2026 16:29:02.6186 (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: 83/ykaoLFWXusfA+7/dkAXyvHjKSJjIz/n/zr6d4CJvlbgvWwlBFSRGv4mq/taB4voCvuEnSUkBhim6bwqoIL9kuncv6/ahO6QNfiuMdrAE= X-MS-Exchange-Transport-CrossTenantHeadersStamped: AS4PR10MB5669 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=uVBaNWWW; 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:c201::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: rF1yhWgUEREG 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 | 21 +++++ doc/user_manual.md | 2 + kas/isar.yaml | 2 +- meta/classes-global/base.bbclass | 82 +++++++++++++++++- meta/classes-recipe/deb-dl-dir.bbclass | 9 +- meta/classes-recipe/dpkg-base.bbclass | 22 ++++- meta/classes-recipe/dpkg.bbclass | 15 +++- .../image-locales-extension.bbclass | 9 +- .../image-tools-extension.bbclass | 84 +++++++++++++++++++ meta/classes-recipe/image.bbclass | 7 +- .../imagetypes_container.bbclass | 4 +- meta/classes-recipe/imagetypes_wic.bbclass | 6 +- meta/classes-recipe/rootfs.bbclass | 52 +++++++++--- meta/classes-recipe/sbuild.bbclass | 24 +++++- meta/classes-recipe/sdk.bbclass | 10 ++- meta/conf/bitbake.conf | 7 +- .../isar-mmdebstrap/isar-mmdebstrap.inc | 11 ++- .../sbuild-chroot/sbuild-chroot.inc | 24 +++++- 19 files changed, 353 insertions(+), 40 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 ad03ed68..7640d87d 100644 --- a/RECIPE-API-CHANGELOG.md +++ b/RECIPE-API-CHANGELOG.md @@ -978,3 +978,24 @@ specifies the rootfs path. Using these helpers instead of direct `sudo` invocations centralizes platform-specific privileged execution logic in `base.bbclass`. Direct use of `sudo` is discouraged in downstream layers. + +### 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" +``` + +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/kas/isar.yaml b/kas/isar.yaml index 16ce8b42..3cfc4f96 100644 --- a/kas/isar.yaml +++ b/kas/isar.yaml @@ -4,7 +4,7 @@ header: version: 14 -build_system: isar +build_system: isar-rootless repos: isar: diff --git a/meta/classes-global/base.bbclass b/meta/classes-global/base.bbclass index 5f82b241..8f4b1189 100644 --- a/meta/classes-global/base.bbclass +++ b/meta/classes-global/base.bbclass @@ -380,7 +380,28 @@ def deb_list_beautify(d, varname): # shall be used outside of this class. def insert_isar_mounts(d, rootfs, mounts): + """ + In unshare mode, all mounts must be created after unsharing the + mount namespace. As needs to happen within the unshared session, + we implement it as a code generator. Note, that the random and urandom + mounts are needed for DDI images. + """ lines = [] + to_touch = ['/dev/null', '/dev/random', '/dev/urandom'] + to_mkdir = ['/dev/pts', '/dev/shm'] + if d.getVar('ISAR_CHROOT_MODE') == 'unshare': + lines.append('touch ' + ' '.join(['{}/{}'.format(rootfs, f) for f in to_touch])) + lines.append('mkdir -p ' + ' '.join(['{}/{}'.format(rootfs, f) for f in to_mkdir])) + lines.append('mount -o bind,private,mode=666 /dev/null {}/dev/null'.format(rootfs)) + lines.append('mount -t devpts -o noexec,nosuid,uid=5,mode=620,ptmxmode=666 none {}/dev/pts'.format(rootfs)) + lines.append('( cd {}/dev; ln -sf pts/ptmx . )'.format(rootfs)) + lines.append('mount -t tmpfs none {}/dev/shm'.format(rootfs)) + lines.append('mount -o bind /dev/random {}/dev/random'.format(rootfs)) + lines.append('mount -o bind /dev/urandom {}/dev/urandom'.format(rootfs)) + lines.append('mount -t proc none {}/proc'.format(rootfs)) + # we do not unshare the network namespace, so we cannot create a sysfs, hence bind-mount + lines.append('mount -o rbind /sys {}/sys'.format(rootfs)) + for m in mounts.split(): host, inner = m.split(':') if ':' in m else (m, m) inner_full = os.path.join(rootfs, inner[1:]) @@ -389,7 +410,18 @@ def insert_isar_mounts(d, rootfs, mounts): return '\n'.join(lines) def insert_isar_umounts(d, rootfs, mounts): + """ + In unshare mount we don't unmount the system mounts but just + remove the mountpoints. + """ lines = [] + to_unlink = ['/dev/null', '/dev/random', '/dev/urandom', '/dev/ptmx'] + to_rmdir = ['/dev/pts', '/dev/shm'] + if d.getVar('ISAR_CHROOT_MODE') == 'unshare': + lines.append('rm -f ' + ' '.join(['{}/{}'.format(rootfs, f) for f in to_unlink])) + for d in ['{}/{}'.format(rootfs, _d) for _d in to_rmdir]: + lines.append('[ -d {} ] && rmdir {}'.format(d, d)) + for m in mounts.split(): host, inner = m.split(':') if ':' in m else (m, m) mp = '{}/{}'.format(rootfs, inner) @@ -397,11 +429,52 @@ def insert_isar_umounts(d, rootfs, mounts): lines.append('[ -d {} ] && rmdir --ignore-fail-on-non-empty {}'.format(mp, mp)) return '\n'.join(lines) +def get_subid_range(idmap, d): + import getpass + with open(idmap, 'r') as f: + entries = f.readlines() + for e in entries: + user, base, cnt = e.split(':') + if user == os.getuid() or user == getpass.getuser(): + return int(base), int(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': + nobody_id = 65534 + uid_base, uid_cnt = get_subid_range('/etc/subuid', d) + nobody_subid = uid_base + uid_cnt - 1 + gid_base, gid_cnt = get_subid_range('/etc/subgid', d) + nogroup_subid = gid_base + gid_cnt - 1 + cmd = 'unshare --mount --pid --uts --ipc --user' \ + ' --kill-child' \ + ' --setuid 0 --setgid 0 --fork' \ + f' --map-users 1:{uid_base+1}:{uid_cnt-2}' \ + f' --map-groups 1:{gid_base+1}:{gid_cnt-2}' + if uid_cnt < nobody_id: + cmd += f' --map-users {nobody_id}:{nobody_subid}:1' + if gid_cnt < nobody_id: + cmd += f' --map-groups {nobody_id}:{nogroup_subid}:1' + cmd += " --map-root-user" + else: + cmd = 'sudo -E' bb.debug(1, "privileged cmd: %s" % cmd) return cmd +UNSHARE_SUBUID_BASE := "${@get_subid_range('/etc/subuid', d)[0] if d.getVar('ISAR_CHROOT_MODE') == 'unshare' else '0'}" +# store in variable to only compute once and make available to fetcher RUN_PRIVILEGED_CMD := "${@run_privileged_cmd(d)}" run_privileged() { @@ -415,5 +488,10 @@ run_privileged_heredoc() { run_in_chroot() { rootfs="$1" shift - ${RUN_PRIVILEGED_CMD} chroot "$rootfs" "$@" + + rootfs=$rootfs run_privileged_heredoc <<'EORIC' "$@" + set -e + ${@insert_isar_mounts(d, '$rootfs', '')} + chroot "$rootfs" "$@" +EORIC } diff --git a/meta/classes-recipe/deb-dl-dir.bbclass b/meta/classes-recipe/deb-dl-dir.bbclass index 05a16585..dc83edad 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_heredoc << ' 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 b3f4caad..c34c96bf 100644 --- a/meta/classes-recipe/dpkg-base.bbclass +++ b/meta/classes-recipe/dpkg-base.bbclass @@ -168,12 +168,30 @@ 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 +} + +dpkg_prepare_unshare_ccache() { + 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}" +} + 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..09dfab7e 100644 --- a/meta/classes-recipe/dpkg.bbclass +++ b/meta/classes-recipe/dpkg.bbclass @@ -85,7 +85,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,22 +113,26 @@ 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 {} +" \ --chroot-setup-commands="apt-get update -o Dir::Etc::SourceList=\"sources.list.d/isar-apt.list\" -o Dir::Etc::SourceParts=\"-\" -o APT::Get::List-Cleanup=\"0\"" \ --finished-build-commands="rm -f ${deb_dir}/sbuild-build-depends-*-dummy_*.deb" \ --finished-build-commands="find ${deb_dir} -maxdepth 1 -type f -name '*.deb' -print -exec cp ${CP_FLAGS} -t ${ext_deb_dir}/ {} +" \ - --finished-build-commands="cp /var/log/dpkg.log ${ext_root}/dpkg_partial.log" \ + ${@ '--finished-build-commands="cp /var/log/dpkg.log $ext_root/dpkg_partial.log"' if d.getVar('ISAR_CHROOT_MODE') == 'schroot' else '' } \ --build-path="" --build-dir=${WORKDIR} --dist="${DEBDISTRONAME}" ${DSC_FILE} - sbuild_dpkg_log_export "${WORKDIR}/rootfs/dpkg_partial.log" + # TODO: port to unshare backend + 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 c1e8c175..bdaa55fb 100644 --- a/meta/classes-recipe/image-locales-extension.bbclass +++ b/meta/classes-recipe/image-locales-extension.bbclass @@ -29,8 +29,12 @@ 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_heredoc <<'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 localepurge +EOF } ROOTFS_INSTALL_COMMAND += "image_install_localepurge_install" @@ -62,6 +66,9 @@ __EOF__ # Install configuration into image: run_privileged_heredoc <<'EOSUDO' set -e + + ${@insert_isar_mounts(d, d.getVar('ROOTFSDIR'), '')} + localepurge_state='i' if chroot '${ROOTFSDIR}' dpkg -s localepurge 2>/dev/null >&2 then diff --git a/meta/classes-recipe/image-tools-extension.bbclass b/meta/classes-recipe/image-tools-extension.bbclass index e88557f6..3fff4972 100644 --- a/meta/classes-recipe/image-tools-extension.bbclass +++ b/meta/classes-recipe/image-tools-extension.bbclass @@ -16,7 +16,14 @@ 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() { + imager_run_${ISAR_CHROOT_MODE} "$@" +} + +imager_run_schroot() { local_install="${@(d.getVar("INSTALL_%s" % d.getVar("BB_CURRENTTASK")) or '').strip()}" local_bom="${@(d.getVar("BOM_%s" % d.getVar("BB_CURRENTTASK")) or '').strip()}" @@ -103,3 +110,80 @@ 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()}" + + run_privileged_heredoc <<'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 + ${@insert_isar_mounts(d, d.getVar('ROOTFS_IMAGETOOLS'), d.getVar('SCHROOT_MOUNTS'))} + 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_heredoc <<'EOF' + set -e + ${@insert_isar_mounts(d, d.getVar('ROOTFS_IMAGETOOLS'), d.getVar('SCHROOT_MOUNTS'))} + chroot ${ROOTFS_IMAGETOOLS} apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends -y \ + --allow-unauthenticated --allow-downgrades install \ + $local_install +EOF + fi + + run_privileged_heredoc <<'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/image.bbclass b/meta/classes-recipe/image.bbclass index 4a250964..48a96a9e 100644 --- a/meta/classes-recipe/image.bbclass +++ b/meta/classes-recipe/image.bbclass @@ -188,6 +188,7 @@ SUDO_CHROOT = "imager_run -d ${PP_ROOTFS} -u root --" python() { image_types = (d.getVar('IMAGE_FSTYPES') or '').split() conversions = set(d.getVar('IMAGE_CONVERSIONS').split()) + chroot_mode = d.getVar('ISAR_CHROOT_MODE') basetypes = {} typedeps = {} @@ -263,7 +264,8 @@ python() { if image_cmd: localdata.setVar('type', bt) cmds.append(localdata.expand(image_cmd)) - cmds.append(localdata.expand('\tsudo chown $(id -u):$(id -g) ${IMAGE_FILE_HOST}')) + if chroot_mode == 'schroot': + cmds.append(localdata.expand('\tsudo chown $(id -u):$(id -g) ${IMAGE_FILE_HOST}')) else: bb.fatal("No IMAGE_CMD for %s" % bt) vardeps.add('IMAGE_CMD:' + bt_clean) @@ -293,7 +295,8 @@ python() { cmd = '\t' + localdata.getVar('CONVERSION_CMD:' + c) if cmd not in cmds: cmds.append(cmd) - cmds.append(localdata.expand('\tsudo chown $(id -u):$(id -g) ${IMAGE_FILE_HOST}.%s' % c)) + if chroot_mode == 'schroot': + cmds.append(localdata.expand('\tsudo chown $(id -u):$(id -g) ${IMAGE_FILE_HOST}.%s' % c)) vardeps.add('CONVERSION_CMD:' + c) for dep in (localdata.getVar('CONVERSION_DEPS:' + c) or '').split(): conversion_install.add(dep) diff --git a/meta/classes-recipe/imagetypes_container.bbclass b/meta/classes-recipe/imagetypes_container.bbclass index b6cc4a14..09f13a17 100644 --- a/meta/classes-recipe/imagetypes_container.bbclass +++ b/meta/classes-recipe/imagetypes_container.bbclass @@ -68,7 +68,9 @@ do_containerize() { run_privileged rm -rf "${oci_img_dir}_unpacked" # no root needed anymore - run_privileged chown --recursive $(id -u):$(id -g) "${oci_img_dir}" + if [ "${ISAR_CHROOT_MODE}" = "schroot" ]; then + run_privileged chown --recursive $(id -u):$(id -g) "${oci_img_dir}" + fi } convert_container() { diff --git a/meta/classes-recipe/imagetypes_wic.bbclass b/meta/classes-recipe/imagetypes_wic.bbclass index 63974a3e..9f1e3de4 100644 --- a/meta/classes-recipe/imagetypes_wic.bbclass +++ b/meta/classes-recipe/imagetypes_wic.bbclass @@ -193,8 +193,10 @@ generate_wic_image() { fi EOIMAGER - run_privileged chown -R $(stat -c "%U" ${LAYERDIR_core}) ${LAYERDIR_core} ${LAYERDIR_isar} ${SCRIPTSDIR} || true - run_privileged chown -R $(id -u):$(id -g) "${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.wic"* + if [ "${ISAR_CHROOT_MODE}" = "schroot" ]; then + run_privileged chown -R $(stat -c "%U" ${LAYERDIR_core}) ${LAYERDIR_core} ${LAYERDIR_isar} ${SCRIPTSDIR} || true + run_privileged chown -R $(id -u):$(id -g) "${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.wic"* + fi rm -rf ${IMAGE_ROOTFS}/../pseudo cat ${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.manifest \ diff --git a/meta/classes-recipe/rootfs.bbclass b/meta/classes-recipe/rootfs.bbclass index 6823c610..9044bf93 100644 --- a/meta/classes-recipe/rootfs.bbclass +++ b/meta/classes-recipe/rootfs.bbclass @@ -145,7 +145,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_heredoc <<'EOSUDO' set -e mountpoint -q '${ROOTFSDIR}/dev' || \ @@ -168,7 +173,13 @@ rootfs_do_mounts() { EOSUDO } -rootfs_do_umounts() { +python rootfs_do_umounts() { + # unconditionally run the unmount code as this ignores missing + # mountpoints but also does the cleanup of the directories + bb.build.exec_func('rootfs_do_umounts_priv', d) +} + +rootfs_do_umounts_priv() { run_privileged_heredoc <<'EOSUDO' set -e @@ -215,7 +226,11 @@ ROOTFS_EXTRA_IMPORTED := "${@rootfs_extra_import(d)}" rootfs_prepare[weight] = "25" rootfs_prepare(){ - run_privileged tar -xf "${BOOTSTRAP_SRC}" -C "${ROOTFSDIR}" --exclude="./dev/console" + rm -rf ${ROOTFSDIR} + run_privileged_heredoc << 'EOF' + mkdir -p ${ROOTFSDIR} + tar -xf "${BOOTSTRAP_SRC}" -C "${ROOTFSDIR}" --exclude="./dev/console" +EOF # setup chroot run_privileged "${ROOTFSDIR}/chroot-setup.sh" "setup" "${ROOTFSDIR}" @@ -285,10 +300,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_heredoc <<'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" @@ -316,9 +335,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_heredoc <<'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 ??= "" @@ -345,8 +367,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_heredoc <<'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" @@ -652,8 +678,10 @@ 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 + run_privileged_heredoc <<'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 ea0c5841..1fa70bd8 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,13 @@ END EOSUDO } +unshare_configure_ccache() { + # ccache must be below /build for file permissions to work properly + cat <<'EOF' >> ${SBUILD_CONFIG} +$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 +160,17 @@ 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() { + dpkg_prepare_unshare_ccache + + 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..6086e9ce 100644 --- a/meta/classes-recipe/sdk.bbclass +++ b/meta/classes-recipe/sdk.bbclass @@ -74,13 +74,17 @@ 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_heredoc <<'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 + rootfs_do_umounts_priv # 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 ea63ec79..de6c43bf 100644 --- a/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc +++ b/meta/recipes-core/isar-mmdebstrap/isar-mmdebstrap.inc @@ -177,6 +177,7 @@ 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) deb_dl_dir_import "${WORKDIR}/dl_dir" "${BOOTSTRAP_BASE_DISTRO}-${BASE_DISTRO_CODENAME}" bootstrap_list="${WORKDIR}/sources.list.d/bootstrap.list" @@ -196,6 +197,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" @@ -213,13 +215,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} \ @@ -238,6 +241,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')} \ @@ -251,7 +255,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/20260226162843.1642329-11-felix.moessbauer%40siemens.com.