diff --git a/woodpecker-agent-sudo/.SRCINFO b/woodpecker-agent-sudo/.SRCINFO new file mode 100644 index 0000000..2bec635 --- /dev/null +++ b/woodpecker-agent-sudo/.SRCINFO @@ -0,0 +1,33 @@ +pkgbase = woodpecker-agent-sudo + pkgdesc = A simple CI engine with great extensibility (agent), patched to use sudo to run local pipelines + pkgver = 1.0.2 + pkgrel = 2 + url = https://woodpecker-ci.org + arch = x86_64 + license = Apache + makedepends = git + makedepends = go + depends = glibc + depends = sudo + optdepends = docker: Docker backend + optdepends = podman: Podman backend + conflicts = woodpecker-agent + replaces = woodpecker-agent + options = !lto + backup = etc/woodpecker/agent.env + source = woodpecker::git+https://github.com/woodpecker-ci/woodpecker#commit=d9e06696bf85f260a0550d58301ac396874b32e3 + source = agent-systemd.service + source = agent-sysusers.conf + source = agent-tmpfiles.conf + source = agent.env + source = sudo.patch + source = sudoers + b2sums = SKIP + b2sums = 6f5833c1d4db8f287f5a9877687fb0d8d66c91e80e9bbb0a78910f315e6dd4cba01131dfca20bcceaeb828833187ee6161b33272050967e3e1cea4cb2665cf57 + b2sums = 373a5889c899445c4b583a48e6d0ff67d4572e30e0dfd0842b389e9338712771ec053ee3771202fe2874ee8bbfb7cb5965a04cf10d4071100c4f7c89cf2a14f3 + b2sums = b6479a7f3b3cf1ecaf0fc4e0653de10176af29b780ff716bf038077d70b0440e45a649ccd5ad9a12d5f52c9eecf9b5d8b5a01510a53eec7b664162c8bb9153ab + b2sums = 9d64fa22d5fcfb8634926220aeb89b0fa914d8e04ee39fe14abf3f170292ab2dc875fe3fe14b054ca8173c167cec4d93518d15d5f08698bd70d86dec7728dee8 + b2sums = 3f7cb5620859d171b0fc9c177c09388a830bdc2343f8182bb794c18544070a78f6fd692c699c5c9fda262bf4919bb53a696ea7396c4e9c7e987788f052e9f19f + b2sums = 85b75986c0df0853126eb20ce80861337654646bb3df02666b6c77962090df12be35eac11dab724d96c4c4b1e6c373ce0a8d6b99843232be0311273bddb1141a + +pkgname = woodpecker-agent-sudo diff --git a/woodpecker-agent-sudo/PKGBUILD b/woodpecker-agent-sudo/PKGBUILD new file mode 100644 index 0000000..aaa9e31 --- /dev/null +++ b/woodpecker-agent-sudo/PKGBUILD @@ -0,0 +1,95 @@ +# Maintainer: Anthony Wang +# Contributor: George Rawlinson +# Contributor: Ersei + +_pkgname='woodpecker-agent' +pkgname=$_pkgname-sudo +pkgver=1.0.2 +pkgrel=2 +pkgdesc='A simple CI engine with great extensibility (agent), patched to use sudo to run local pipelines' +arch=('x86_64') +url='https://woodpecker-ci.org' +license=('Apache') +depends=('glibc' 'sudo') +optdepends=( + 'docker: Docker backend' + 'podman: Podman backend' +) +makedepends=('git' 'go') +options=('!lto') +_commit='d9e06696bf85f260a0550d58301ac396874b32e3' +replaces=($_pkgname) +conflicts=($_pkgname) +backup=('etc/woodpecker/agent.env') +source=( + "woodpecker::git+https://github.com/woodpecker-ci/woodpecker#commit=$_commit" + 'agent-systemd.service' + 'agent-sysusers.conf' + 'agent-tmpfiles.conf' + 'agent.env' + 'sudo.patch' + 'sudoers' +) +b2sums=('SKIP' + '6f5833c1d4db8f287f5a9877687fb0d8d66c91e80e9bbb0a78910f315e6dd4cba01131dfca20bcceaeb828833187ee6161b33272050967e3e1cea4cb2665cf57' + '373a5889c899445c4b583a48e6d0ff67d4572e30e0dfd0842b389e9338712771ec053ee3771202fe2874ee8bbfb7cb5965a04cf10d4071100c4f7c89cf2a14f3' + 'b6479a7f3b3cf1ecaf0fc4e0653de10176af29b780ff716bf038077d70b0440e45a649ccd5ad9a12d5f52c9eecf9b5d8b5a01510a53eec7b664162c8bb9153ab' + '9d64fa22d5fcfb8634926220aeb89b0fa914d8e04ee39fe14abf3f170292ab2dc875fe3fe14b054ca8173c167cec4d93518d15d5f08698bd70d86dec7728dee8' + '3f7cb5620859d171b0fc9c177c09388a830bdc2343f8182bb794c18544070a78f6fd692c699c5c9fda262bf4919bb53a696ea7396c4e9c7e987788f052e9f19f' + '85b75986c0df0853126eb20ce80861337654646bb3df02666b6c77962090df12be35eac11dab724d96c4c4b1e6c373ce0a8d6b99843232be0311273bddb1141a') + +pkgver() { + cd woodpecker + + git describe --tags | sed 's/^v//' +} + +prepare() { + cd woodpecker + + patch -p1 < ../sudo.patch + + # create directory for build output + mkdir -p build + + # download dependencies + export GOPATH="${srcdir}" + go mod download +} + +build() { + cd woodpecker + + # set Go flags + export CGO_CPPFLAGS="${CPPFLAGS}" + export CGO_CFLAGS="${CFLAGS}" + export CGO_CXXFLAGS="${CXXFLAGS}" + export GOPATH="${srcdir}" + + # build agent + go build -v \ + -buildmode=pie \ + -mod=readonly \ + -modcacherw \ + -ldflags "-compressdwarf=false \ + -linkmode external \ + -extldflags ${LDFLAGS}" \ + -o build \ + ./cmd/agent + + go clean -modcache +} + +package() { + # systemd integration + install -vDm644 agent-systemd.service "$pkgdir/usr/lib/systemd/system/$_pkgname.service" + install -vDm644 agent-sysusers.conf "$pkgdir/usr/lib/sysusers.d/$_pkgname.conf" + install -vDm644 agent-tmpfiles.conf "$pkgdir/usr/lib/tmpfiles.d/$_pkgname.conf" + install -vDm644 agent.env -t "$pkgdir/etc/woodpecker" + install -vDm644 sudoers "$pkgdir/etc/sudoers.d/99_woodpecker" + + cd woodpecker + + # binary + install -vDm755 build/agent "$pkgdir/usr/bin/$_pkgname" +} diff --git a/woodpecker-agent-sudo/agent-systemd.service b/woodpecker-agent-sudo/agent-systemd.service new file mode 100644 index 0000000..116fc90 --- /dev/null +++ b/woodpecker-agent-sudo/agent-systemd.service @@ -0,0 +1,19 @@ +[Unit] +Description=Woodpecker agent +Documentation=https://woodpecker-ci.org/docs/intro +Requires=network-online.target +After=network-online.target + +[Service] +User=woodpecker-agent +Group=woodpecker-agent +EnvironmentFile=/etc/woodpecker/agent.env +ExecStart=/usr/bin/woodpecker-agent +RestartSec=5 +Restart=on-failure +SyslogIdentifier=woodpecker-agent +WorkingDirectory=/var/lib/woodpecker-agent +ReadWritePaths=/var/lib/woodpecker-agent + +[Install] +WantedBy=multi-user.target diff --git a/woodpecker-agent-sudo/agent-sysusers.conf b/woodpecker-agent-sudo/agent-sysusers.conf new file mode 100644 index 0000000..fe12d44 --- /dev/null +++ b/woodpecker-agent-sudo/agent-sysusers.conf @@ -0,0 +1 @@ +u woodpecker-agent - "Woodpecker agent daemon user" /var/lib/woodpecker-agent diff --git a/woodpecker-agent-sudo/agent-tmpfiles.conf b/woodpecker-agent-sudo/agent-tmpfiles.conf new file mode 100644 index 0000000..9269d52 --- /dev/null +++ b/woodpecker-agent-sudo/agent-tmpfiles.conf @@ -0,0 +1 @@ +d /var/lib/woodpecker-agent 0750 woodpecker-agent woodpecker-agent diff --git a/woodpecker-agent-sudo/agent.env b/woodpecker-agent-sudo/agent.env new file mode 100644 index 0000000..1226ac5 --- /dev/null +++ b/woodpecker-agent-sudo/agent.env @@ -0,0 +1,59 @@ +# Configures gRPC address of the server. +# Default: localhost:9000 +#WOODPECKER_SERVER= + +# The gRPC username. +# Default: x-oauth-basic +#WOODPECKER_USERNAME= + +# A shared secret used by server and agents to authenticate communication. A secret can be generated by openssl rand -hex 32. +# Default: empty +#WOODPECKER_AGENT_SECRET= + +# Configures the logging level. Possible values are trace, debug, info, warn, error, fatal, panic, disabled and empty. +# Default: empty +#WOODPECKER_LOG_LEVEL= + +# Enable pretty-printed debug output. +# Default: false +#WOODPECKER_DEBUG_PRETTY= + +# Disable colored debug output. +# Default: true +#WOODPECKER_DEBUG_NOCOLOR= + +# Configures the agent hostname. +# Default: empty +#WOODPECKER_HOSTNAME= + +# Configures the number of parallel builds. +# Default: 1 +#WOODPECKER_MAX_PROCS= + +# Enable healthcheck endpoint. +# Default: true +#WOODPECKER_HEALTHCHECK= + +# After a duration of this time of no activity, the agent pings the server to check if the transport is still alive. +# Default: empty +#WOODPECKER_KEEPALIVE_TIME= + +# After pinging for a keepalive check, the agent waits for a duration of this time before closing the connection if no activity. +# Default: 20s +#WOODPECKER_KEEPALIVE_TIMEOUT= + +# Configures if the connection to WOODPECKER_SERVER should be made using a secure transport. +# Default: false +#WOODPECKER_GRPC_SECURE= + +# Configures if the gRPC server certificate should be verified, only valid when WOODPECKER_GRPC_SECURE is true. +# Default: true +#WOODPECKER_GRPC_VERIFY= + +# Configures the backend engine to run pipelines on. Possible values are auto-detect or docker. +# Default: auto-detect +#WOODPECKER_BACKEND= + +# Path to Docker or Podman socket. Can be an SSH address. +# Default: unix:///var/run/docker.sock +#DOCKER_HOST= diff --git a/woodpecker-agent-sudo/sudo.patch b/woodpecker-agent-sudo/sudo.patch new file mode 100644 index 0000000..6b5777a --- /dev/null +++ b/woodpecker-agent-sudo/sudo.patch @@ -0,0 +1,70 @@ +diff --git a/pipeline/backend/local/local.go b/pipeline/backend/local/local.go +index 2405c19bb..50321b8e7 100644 +--- a/pipeline/backend/local/local.go ++++ b/pipeline/backend/local/local.go +@@ -44,7 +44,7 @@ var notAllowedEnvVarOverwrites = []string{ + + type workflowState struct { + stepCMDs map[string]*exec.Cmd +- baseDir string ++ user string + homeDir string + workspaceDir string + } +@@ -79,23 +79,17 @@ func (e *local) Load(context.Context) error { + func (e *local) SetupWorkflow(_ context.Context, conf *types.Config, taskUUID string) error { + log.Trace().Str("taskUUID", taskUUID).Msg("create workflow environment") + +- baseDir, err := os.MkdirTemp("", "woodpecker-local-*") +- if err != nil { +- return err +- } ++ user := conf.Stages[0].Steps[0].Environment["CI_COMMIT_AUTHOR"] + + state := &workflowState{ + stepCMDs: make(map[string]*exec.Cmd), +- baseDir: baseDir, +- workspaceDir: filepath.Join(baseDir, "workspace"), +- homeDir: filepath.Join(baseDir, "home"), +- } +- +- if err := os.Mkdir(state.homeDir, 0o700); err != nil { +- return err ++ user: user, ++ workspaceDir: filepath.Join("/tmp", user, conf.Stages[0].Steps[0].Environment["CI_REPO_NAME"]), ++ homeDir: filepath.Join("/home", user), + } + +- if err := os.Mkdir(state.workspaceDir, 0o700); err != nil { ++ err := exec.Command("sudo", "-u", state.user, "mkdir", "-p", state.workspaceDir).Run() ++ if err != nil { + return err + } + +@@ -132,7 +126,8 @@ func (e *local) StartStep(ctx context.Context, step *types.Step, taskUUID string + // Set HOME + env = append(env, "HOME="+state.homeDir) + +- var command []string ++ // Run command as commit author user ++ command := []string{"sudo", "-E", "-u", state.user} + if step.Image == constant.DefaultCloneImage { + // Default clone step + // TODO: use tmp HOME and insert netrc and delete it after clone +@@ -209,16 +204,6 @@ func (e *local) TailStep(_ context.Context, step *types.Step, taskUUID string) ( + func (e *local) DestroyWorkflow(_ context.Context, conf *types.Config, taskUUID string) error { + log.Trace().Str("taskUUID", taskUUID).Msgf("delete workflow environment") + +- state, err := e.getWorkflowStateFromConfig(conf) +- if err != nil { +- return err +- } +- +- err = os.RemoveAll(state.baseDir) +- if err != nil { +- return err +- } +- + workflowID, err := e.getWorkflowIDFromConfig(conf) + if err != nil { + return err diff --git a/woodpecker-agent-sudo/sudoers b/woodpecker-agent-sudo/sudoers new file mode 100644 index 0000000..b65e439 --- /dev/null +++ b/woodpecker-agent-sudo/sudoers @@ -0,0 +1,2 @@ +# This is kinda hacky but I couldn't find a better way to do it +woodpecker-agent ALL=(#1000, #1001, #1002, #1003, #1004, #1005, #1006, #1007, #1008, #1009, #1010, #1011, #1012, #1013, #1014, #1015, #1016, #1017, #1018, #1019, #1020, #1021, #1022, #1023, #1024, #1025, #1026, #1027, #1028, #1029, #1030, #1031, #1032, #1033, #1034, #1035, #1036, #1037, #1038, #1039, #1040, #1041, #1042, #1043, #1044, #1045, #1046, #1047, #1048, #1049, #1050, #1051, #1052, #1053, #1054, #1055, #1056, #1057, #1058, #1059, #1060, #1061, #1062, #1063, #1064, #1065, #1066, #1067, #1068, #1069, #1070, #1071, #1072, #1073, #1074, #1075, #1076, #1077, #1078, #1079, #1080, #1081, #1082, #1083, #1084, #1085, #1086, #1087, #1088, #1089, #1090, #1091, #1092, #1093, #1094, #1095, #1096, #1097, #1098, #1099, #1100, #1101, #1102, #1103, #1104, #1105, #1106, #1107, #1108, #1109, #1110, #1111, #1112, #1113, #1114, #1115, #1116, #1117, #1118, #1119, #1120, #1121, #1122, #1123, #1124, #1125, #1126, #1127, #1128, #1129, #1130, #1131, #1132, #1133, #1134, #1135, #1136, #1137, #1138, #1139, #1140, #1141, #1142, #1143, #1144, #1145, #1146, #1147, #1148, #1149, #1150, #1151, #1152, #1153, #1154, #1155, #1156, #1157, #1158, #1159, #1160, #1161, #1162, #1163, #1164, #1165, #1166, #1167, #1168, #1169, #1170, #1171, #1172, #1173, #1174, #1175, #1176, #1177, #1178, #1179, #1180, #1181, #1182, #1183, #1184, #1185, #1186, #1187, #1188, #1189, #1190, #1191, #1192, #1193, #1194, #1195, #1196, #1197, #1198, #1199, #1200, #1201, #1202, #1203, #1204, #1205, #1206, #1207, #1208, #1209, #1210, #1211, #1212, #1213, #1214, #1215, #1216, #1217, #1218, #1219, #1220, #1221, #1222, #1223, #1224, #1225, #1226, #1227, #1228, #1229, #1230, #1231, #1232, #1233, #1234, #1235, #1236, #1237, #1238, #1239, #1240, #1241, #1242, #1243, #1244, #1245, #1246, #1247, #1248, #1249, #1250, #1251, #1252, #1253, #1254, #1255, #1256, #1257, #1258, #1259, #1260, #1261, #1262, #1263, #1264, #1265, #1266, #1267, #1268, #1269, #1270, #1271, #1272, #1273, #1274, #1275, #1276, #1277, #1278, #1279, #1280, #1281, #1282, #1283, #1284, #1285, #1286, #1287, #1288, #1289, #1290, #1291, #1292, #1293, #1294, #1295, #1296, #1297, #1298, #1299, #1300, #1301, #1302, #1303, #1304, #1305, #1306, #1307, #1308, #1309, #1310, #1311, #1312, #1313, #1314, #1315, #1316, #1317, #1318, #1319, #1320, #1321, #1322, #1323, #1324, #1325, #1326, #1327, #1328, #1329, #1330, #1331, #1332, #1333, #1334, #1335, #1336, #1337, #1338, #1339, #1340, #1341, #1342, #1343, #1344, #1345, #1346, #1347, #1348, #1349, #1350, #1351, #1352, #1353, #1354, #1355, #1356, #1357, #1358, #1359, #1360, #1361, #1362, #1363, #1364, #1365, #1366, #1367, #1368, #1369, #1370, #1371, #1372, #1373, #1374, #1375, #1376, #1377, #1378, #1379, #1380, #1381, #1382, #1383, #1384, #1385, #1386, #1387, #1388, #1389, #1390, #1391, #1392, #1393, #1394, #1395, #1396, #1397, #1398, #1399, #1400, #1401, #1402, #1403, #1404, #1405, #1406, #1407, #1408, #1409, #1410, #1411, #1412, #1413, #1414, #1415, #1416, #1417, #1418, #1419, #1420, #1421, #1422, #1423, #1424, #1425, #1426, #1427, #1428, #1429, #1430, #1431, #1432, #1433, #1434, #1435, #1436, #1437, #1438, #1439, #1440, #1441, #1442, #1443, #1444, #1445, #1446, #1447, #1448, #1449, #1450, #1451, #1452, #1453, #1454, #1455, #1456, #1457, #1458, #1459, #1460, #1461, #1462, #1463, #1464, #1465, #1466, #1467, #1468, #1469, #1470, #1471, #1472, #1473, #1474, #1475, #1476, #1477, #1478, #1479, #1480, #1481, #1482, #1483, #1484, #1485, #1486, #1487, #1488, #1489, #1490, #1491, #1492, #1493, #1494, #1495, #1496, #1497, #1498, #1499, #1500, #1501, #1502, #1503, #1504, #1505, #1506, #1507, #1508, #1509, #1510, #1511, #1512, #1513, #1514, #1515, #1516, #1517, #1518, #1519, #1520, #1521, #1522, #1523, #1524, #1525, #1526, #1527, #1528, #1529, #1530, #1531, #1532, #1533, #1534, #1535, #1536, #1537, #1538, #1539, #1540, #1541, #1542, #1543, #1544, #1545, #1546, #1547, #1548, #1549, #1550, #1551, #1552, #1553, #1554, #1555, #1556, #1557, #1558, #1559, #1560, #1561, #1562, #1563, #1564, #1565, #1566, #1567, #1568, #1569, #1570, #1571, #1572, #1573, #1574, #1575, #1576, #1577, #1578, #1579, #1580, #1581, #1582, #1583, #1584, #1585, #1586, #1587, #1588, #1589, #1590, #1591, #1592, #1593, #1594, #1595, #1596, #1597, #1598, #1599, #1600, #1601, #1602, #1603, #1604, #1605, #1606, #1607, #1608, #1609, #1610, #1611, #1612, #1613, #1614, #1615, #1616, #1617, #1618, #1619, #1620, #1621, #1622, #1623, #1624, #1625, #1626, #1627, #1628, #1629, #1630, #1631, #1632, #1633, #1634, #1635, #1636, #1637, #1638, #1639, #1640, #1641, #1642, #1643, #1644, #1645, #1646, #1647, #1648, #1649, #1650, #1651, #1652, #1653, #1654, #1655, #1656, #1657, #1658, #1659, #1660, #1661, #1662, #1663, #1664, #1665, #1666, #1667, #1668, #1669, #1670, #1671, #1672, #1673, #1674, #1675, #1676, #1677, #1678, #1679, #1680, #1681, #1682, #1683, #1684, #1685, #1686, #1687, #1688, #1689, #1690, #1691, #1692, #1693, #1694, #1695, #1696, #1697, #1698, #1699, #1700, #1701, #1702, #1703, #1704, #1705, #1706, #1707, #1708, #1709, #1710, #1711, #1712, #1713, #1714, #1715, #1716, #1717, #1718, #1719, #1720, #1721, #1722, #1723, #1724, #1725, #1726, #1727, #1728, #1729, #1730, #1731, #1732, #1733, #1734, #1735, #1736, #1737, #1738, #1739, #1740, #1741, #1742, #1743, #1744, #1745, #1746, #1747, #1748, #1749, #1750, #1751, #1752, #1753, #1754, #1755, #1756, #1757, #1758, #1759, #1760, #1761, #1762, #1763, #1764, #1765, #1766, #1767, #1768, #1769, #1770, #1771, #1772, #1773, #1774, #1775, #1776, #1777, #1778, #1779, #1780, #1781, #1782, #1783, #1784, #1785, #1786, #1787, #1788, #1789, #1790, #1791, #1792, #1793, #1794, #1795, #1796, #1797, #1798, #1799, #1800, #1801, #1802, #1803, #1804, #1805, #1806, #1807, #1808, #1809, #1810, #1811, #1812, #1813, #1814, #1815, #1816, #1817, #1818, #1819, #1820, #1821, #1822, #1823, #1824, #1825, #1826, #1827, #1828, #1829, #1830, #1831, #1832, #1833, #1834, #1835, #1836, #1837, #1838, #1839, #1840, #1841, #1842, #1843, #1844, #1845, #1846, #1847, #1848, #1849, #1850, #1851, #1852, #1853, #1854, #1855, #1856, #1857, #1858, #1859, #1860, #1861, #1862, #1863, #1864, #1865, #1866, #1867, #1868, #1869, #1870, #1871, #1872, #1873, #1874, #1875, #1876, #1877, #1878, #1879, #1880, #1881, #1882, #1883, #1884, #1885, #1886, #1887, #1888, #1889, #1890, #1891, #1892, #1893, #1894, #1895, #1896, #1897, #1898, #1899, #1900, #1901, #1902, #1903, #1904, #1905, #1906, #1907, #1908, #1909, #1910, #1911, #1912, #1913, #1914, #1915, #1916, #1917, #1918, #1919, #1920, #1921, #1922, #1923, #1924, #1925, #1926, #1927, #1928, #1929, #1930, #1931, #1932, #1933, #1934, #1935, #1936, #1937, #1938, #1939, #1940, #1941, #1942, #1943, #1944, #1945, #1946, #1947, #1948, #1949, #1950, #1951, #1952, #1953, #1954, #1955, #1956, #1957, #1958, #1959, #1960, #1961, #1962, #1963, #1964, #1965, #1966, #1967, #1968, #1969, #1970, #1971, #1972, #1973, #1974, #1975, #1976, #1977, #1978, #1979, #1980, #1981, #1982, #1983, #1984, #1985, #1986, #1987, #1988, #1989, #1990, #1991, #1992, #1993, #1994, #1995, #1996, #1997, #1998, #1999) NOPASSWD: ALL