index : website | |
Archlinux32 website - obsolete | gitolite user |
summaryrefslogtreecommitdiff |
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6bfe6b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +log diff --git a/buildmaster/blacklist.php b/buildmaster/blacklist.php new file mode 100644 index 0000000..24247e8 --- /dev/null +++ b/buildmaster/blacklist.php @@ -0,0 +1,63 @@ +<?php +require_once "../init.php"; + +require_once BASE . "/lib/mysql.php"; + + $result = mysql_run_query( + "SELECT DISTINCT" . + " GROUP_CONCAT(`architectures`.`name`) AS `architectures`," . + "`package_sources`.`pkgbase`," . + "`build_assignments`.`is_black_listed` " . + "FROM `build_assignments` " . + mysql_join_build_assignments_architectures() . + mysql_join_build_assignments_package_sources() . + "WHERE `build_assignments`.`is_black_listed` IS NOT NULL " . + "GROUP BY CONCAT(to_base64(`package_sources`.`pkgbase`),\" - \",to_base64(`build_assignments`.`is_black_listed`)) " . + "ORDER BY `package_sources`.`pkgbase`" + ); + +?> +<html> + <head> + <title>Blacklisted packages</title> + <link rel="stylesheet" type="text/css" href="/static/style.css"> + </head> + <body> +<?php show_warning_on_offline_slave(); ?> + <table> + <tr> + <th>architectures</th> + <th>package</th> + <th>reason</th> + </tr> +<?php + +if ($result -> num_rows > 0) { + while($row = $result->fetch_assoc()) { + print " <tr>\n"; + print " <td>"; + print $row["architectures"]; + print "</td>\n"; + print " <td>"; + print $row["pkgbase"]; + print "</td>\n"; + print " <td>"; + print preg_replace( + array ( + "/FS32#(\\d+)/", + "/FS#(\\d+)/" + ), + array ( + "<a href=\"https://bugs.archlinux32.org/index.php?do=details&task_id=$1\">$0</a>", + "<a href=\"https://bugs.archlinux.org/task/$1\">$0</a>" + ), + $row["is_black_listed"] + ); + print "</td>\n"; + print " </tr>\n"; + } +} +?> + </table> + </body> +</html> diff --git a/buildmaster/build-list-links.php b/buildmaster/build-list-links.php new file mode 100644 index 0000000..e3d2779 --- /dev/null +++ b/buildmaster/build-list-links.php @@ -0,0 +1,231 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + +$edges = ""; +$knots = ""; + +if (!isset($_GET["raw"])) + $limit = " LIMIT 150"; + +$query = + "CREATE TEMPORARY TABLE `ba` (" . + "`id` BIGINT, " . + "`group` VARCHAR(256), " . + "`color` VARCHAR(7), " . + "UNIQUE KEY `id` (`id`), " . + "KEY `group` (`group`)" . + ")"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "INSERT IGNORE INTO `ba` (`id`,`color`)" . + " SELECT DISTINCT" . + " `build_assignments`.`id`," . + "IF(`build_assignments`.`is_broken`,\"#ff0000\",IF(`build_assignments`.`is_blocked` IS NULL,\"#000000\",\"#800000\"))" . + " FROM `binary_packages_in_repositories`" . + mysql_join_binary_packages_in_repositories_binary_packages() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_binary_packages_build_assignments() . + " WHERE `repositories`.`name`=\"build-list\"" . + $limit; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "CREATE TEMPORARY TABLE `ba_copy` (" . + "`id` BIGINT, " . + "`group` VARCHAR(256), " . + "`color` VARCHAR(7), " . + "UNIQUE KEY `id` (`id`)" . + ")"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "INSERT IGNORE INTO `ba_copy` (`id`,`color`)" . + " SELECT `ba`.`id`,`ba`.`color`" . + " FROM `ba`"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "CREATE TEMPORARY TABLE `ba_links` (" . + "`from` BIGINT, " . + "`to` BIGINT, " . + "`type` MEDIUMINT, " . + "UNIQUE KEY `content` (`from`,`to`,`type`)" . + ")"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "INSERT IGNORE INTO `ba_links` (`from`,`to`,`type`)" . + "SELECT `i_bp`.`build_assignment`," . + "`d_bp`.`build_assignment`," . + "`dependencies`.`dependency_type`" . + " FROM `ba`" . + mysql_join_build_assignments_binary_packages('ba','d_bp') . + mysql_join_binary_packages_dependencies('d_bp') . + mysql_join_dependencies_install_target_providers() . + mysql_join_install_target_providers_binary_packages('','i_bp') . + " JOIN `ba_copy` ON `i_bp`.`build_assignment`=`ba_copy`.`id`" . + " WHERE `d_bp`.`build_assignment`!=`i_bp`.`build_assignment`"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "CREATE TEMPORARY TABLE `ba_links_copy` (" . + "`from` BIGINT, " . + "`to` BIGINT, " . + "`type` MEDIUMINT, " . + "UNIQUE KEY `content` (`from`,`to`,`type`)" . + ")"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "INSERT IGNORE INTO `ba_links_copy` (`from`,`to`,`type`)" . + " SELECT `ba_links`.`from`,`ba_links`.`to`,`ba_links`.`type` FROM `ba_links`"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "UPDATE `ba`" . + " JOIN (" . + "SELECT" . + " `ba_copy`.`id`," . + "SHA2(" . + "GROUP_CONCAT(CONCAT(" . + "IFNULL(`ba_copy`.`color`,\"0\"),\":\"," . + "IFNULL(`ba_links`.`to`,\"0\"),\":\"," . + "IFNULL(`ba_links`.`type`,\"0\"),\":\"," . + "IFNULL(`ba_links_copy`.`from`,\"0\"),\":\"," . + "IFNULL(`ba_links_copy`.`type`,\"0\")" . + "))" . + ",256) AS `hash`" . + " FROM `ba_copy`" . + " LEFT JOIN `ba_links` ON `ba_links`.`from`=`ba_copy`.`id`" . + " LEFT JOIN `ba_links_copy` ON `ba_links_copy`.`to`=`ba_copy`.`id`" . + " GROUP BY `ba_copy`.`id`" . + ") AS `grouped_ba` ON `grouped_ba`.`id`=`ba`.`id`" . + " SET `ba`.`group`=`grouped_ba`.`hash`"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "UPDATE `ba_copy`" . + " JOIN `ba` ON `ba`.`id`=`ba_copy`.`id`" . + " SET `ba_copy`.`group`=`ba`.`group`"; +if (isset($_GET["raw"])) + print $query . ";\n"; +mysql_run_query($query); + +$query = + "SELECT MAX(`build_assignments`.`id`) AS `id`," . + "GROUP_CONCAT(CONCAT(" . + "`architectures`.`name`,\"/\"," . + "`package_sources`.`pkgbase`" . + ") SEPARATOR \",\n\") AS `name`," . + " `ba`.`color`" . + " FROM `ba`" . + " JOIN `build_assignments` ON `ba`.`id`=`build_assignments`.`id`" . + mysql_join_build_assignments_package_sources() . + mysql_join_build_assignments_architectures() . + " GROUP BY `ba`.`group`"; +if (isset($_GET["raw"])) + print $query . ";\n"; +$result = mysql_run_query($query); + +while ($row = $result->fetch_assoc()) + $knots .= + "\"ba" . + $row["id"] . + "\" [label = \"" . + $row["name"] . + "\", + fontcolor = \"" . + $row["color"] . + "\"];\n"; + +$query = + "SELECT MAX(`ba_links`.`to`) AS `dependent`," . + "`dependency_types`.`name` AS `dep_type`," . + "MAX(`ba_links`.`from`) AS `depending_on`" . + " FROM `ba_links`" . + " JOIN `dependency_types` ON `ba_links`.`type`=`dependency_types`.`id`" . + " JOIN `ba` ON `ba_links`.`from`=`ba`.`id`" . + " JOIN `ba_copy` ON `ba_links`.`to`=`ba_copy`.`id`" . + " GROUP BY CONCAT(`ba`.`group`,\"-\",`ba_copy`.`group`)"; +if (isset($_GET["raw"])) + print $query . ";\n"; +$result = mysql_run_query($query); + +while ($row = $result->fetch_assoc()) { + $edges .= + "\"ba" . + $row["depending_on"] . + "\" -> \"ba" . + $row["dependent"] . + "\" [color = \""; + switch ($row["dep_type"]) { + case "run": + $edges .= "#000000"; + break; + case "make": + $edges .= "#0000ff"; + break; + case "link": + $edges .= "#008000"; + break; + case "check": + $edges .= "#000080"; + break; + default: + $edges .= "#ff00ff"; + } + $edges .= + "#000080"; + $edges .= + "\"];\n"; +} + +if (isset($_GET["raw"])) { + print + "digraph dependencies {\n" . + "rankdir=LR;\n" . + "fontname=dejavu;\n" . + $knots . + $edges . + "}\n"; +} else { + $input_file = tempnam("/tmp", "build-list-links."); + + $handle = fopen($input_file,"w"); + fwrite($handle, + "digraph dependencies {\n" . + "rankdir=LR;\n" . + "fontname=dejavu;\n" . + $knots . + $edges . + "}\n" + ); + fclose($handle); + + header ("Content-type: image/png"); + passthru( + "timeout 30 dot -Tpng -o/dev/stdout " . $input_file + ); + + unlink($input_file); +} diff --git a/buildmaster/build-list.php b/buildmaster/build-list.php new file mode 100644 index 0000000..79313e4 --- /dev/null +++ b/buildmaster/build-list.php @@ -0,0 +1,583 @@ +<?php +require_once "../init.php"; + +require_once BASE . "/lib/helper.php"; +require_once BASE . "/lib/mysql.php"; +require_once BASE . "/lib/style.php"; + +$filter = " WHERE "; + +if (isset($_GET["invq"])) + $filter .= "NOT "; + +if (isset($_GET["q"])) + $filter .= "`ba_q`.`pkgbase` LIKE from_base64(\"".base64_encode("%".$_GET["q"]."%")."\")"; +else + $filter .= "1"; + +$multi_select_search_criteria = array( + "arch" => array( + "name" => "arch", + "title" => "CPU architecture", + "label" => "Arch", + "source_table" => "architectures", + "query_pre" => "`ba_q`.`arch` IN (", + "query_in_pre" => "\"", + "query_in_post" => "\",", + "query_post" => "\"\")", + "values" => array() + ), + "repo" => array( + "name" => "repo", + "title" => "Repository", + "label" => "Repo", + "source_table" => "upstream_repositories", + "query_pre" => "`ba_q`.`package_repository` IN (", + "query_in_pre" => "\"", + "query_in_post" => "\",", + "query_post" => "\"\")", + "values" => array() + ), + "failures" => array( + "name" => "failures", + "title" => "Fail Reasons", + "label" => "Failures", + "source_table" => "fail_reasons", + "query_pre" => "(0", + "query_in_pre" => " OR `fr_q`.`fail_reasons_raw` LIKE \"%,", + "query_in_post" => ",%\"", + "query_post" => ")", + "values" => array() + ) +); + +foreach ( $multi_select_search_criteria as $criterium => $content ) { + $result = mysql_run_query( + "SELECT `name` FROM `" . $content["source_table"] . "` ORDER BY `name`" + ); + while ($row = $result -> fetch_assoc()) + $multi_select_search_criteria[$criterium]["values"][] = $row["name"]; +} + +foreach ( $multi_select_search_criteria as $criterium ) { + if (isset($_GET[$criterium["name"]])) { + $filter .= " AND " . $criterium["query_pre"]; + foreach ($criterium["values"] as $value) + if (strpos("&" . $_SERVER["QUERY_STRING"] . "&", "&" . $criterium["name"] . "=" . urlencode($value) . "&") !== false) + $filter .= $criterium["query_in_pre"] . $value . $criterium["query_in_post"]; + $filter .= $criterium["query_post"]; + } +} +$single_select_search_criteria = array( + "broken" => array( + "name" => "broken", + "label" => "Is Broken", + "title" => "is broken", + "options" => array( + "All" => "1", + "Broken" => "(`ba_q`.`is_broken` OR `ba_q`.`is_blocked` IS NOT NULL)", + "Not Broken" => "NOT (`ba_q`.`is_broken` OR `ba_q`.`is_blocked` IS NOT NULL)" + ) + ), + "next" => array( + "name" => "next", + "label" => "Can Be Built", + "title" => "can be built", + "options" => array( + "All" => "1", + "Can" => "(`l_q`.`loops` IS NOT NULL OR (`rd_q`.`run_dependencies_pending` IS NULL AND `md_q`.`make_dependencies_pending` IS NULL))", + "Can't" => "NOT (`l_q`.`loops` IS NOT NULL OR (`rd_q`.`run_dependencies_pending` IS NULL AND `md_q`.`make_dependencies_pending` IS NULL))" + ) + ) +); + +foreach ($single_select_search_criteria as $criterium) + if (isset($_GET[$criterium["name"]]) && + isset($criterium["options"][$_GET[$criterium["name"]]])) + $filter .= " AND " . $criterium["options"][$_GET[$criterium["name"]]]; + +$columns = array( + "priority" => array( + "label" => "Priority", + "mysql_name" => "priority", + "mysql_query" => "`ba_q`.`priority`", + "sort" => "priority", + "title" => "priority" + ), + "deps" => array( + "label" => "Deps", + "mysql_name" => "dependencies_pending", + "mysql_query" => "IFNULL(`rd_q`.`run_dependencies_pending`,0)+IFNULL(`md_q`.`make_dependencies_pending`,0)", + "sort" => "deps", + "title" => "number of dependencies on the build-list" + ), + "arch" => array( + "label" => "Arch", + "mysql_name" => "arch", + "mysql_query" => "`ba_q`.`arch`", + "sort" => "arch", + "title" => "arch" + ), + "pkgbase" => array( + "label" => "Package", + "mysql_name" => "pkgbase_print", + "mysql_query" => + "CONCAT(" . + "\"<a href=\\\"/buildmaster/dependencies.php?b=\"," . + mysql_url_encode("`ba_q`.`pkgbase`") . "," . + "\"&a=\"," . + mysql_url_encode("`ba_q`.`arch`") . ",". + "\"&r=build-list\\\">\"," . + "`ba_q`.`pkgbase`," . + "\"</a>\"" . + ")", + "sort" => "pkgbase", + "title" => "package" + ), + "git_rev" => array( + "label" => "Git Revision", + "mysql_name" => "git_revision_print", + "mysql_query" => + "IF(`ba_q`.`uses_upstream`," . + "CONCAT(" . + "\"<a href=\\\"https://git.archlinux.org/svntogit/\"," . + mysql_url_encode("`ba_q`.`git_repository`") . "," . + "\".git/tree/\"," . + mysql_url_encode("`ba_q`.`pkgbase`") . "," . + "\"/repos/\"," . + mysql_url_encode("`ba_q`.`package_repository`") . "," . + "\"-\"," . + mysql_url_encode("IF(`ba_q`.`arch`=\"any\",\"any\",\"x86_64\")") . "," . + "\"?id=\"," . + mysql_url_encode("`ba_q`.`git_revision`") . "," . + "\"\\\">\"," . + "`ba_q`.`git_revision`," . + "\"</a>\"" . + ")," . + "`ba_q`.`git_revision`" . + ")", + "sort" => "git_rev", + "title" => "revision hash of upstream git repository" + ), + "mod_git_rev" => array( + "label" => "Modification Git Revision", + "mysql_name" => "mod_git_revision_print", + "mysql_query" => + "IF(`ba_q`.`uses_modification`," . + "CONCAT(" . + "\"<a href=\\\"" . + git_url( + "packages", + "tree", + "\"," . mysql_url_encode("`ba_q`.`mod_git_revision`") . ",\"", + "\"," . mysql_url_encode("`ba_q`.`package_repository`") . ",\"/\"," . + mysql_url_encode("`ba_q`.`pkgbase`") . ",\"", + null, + true + ) . + "\\\">\"," . + "`ba_q`.`mod_git_revision`," . + "\"</a>\"" . + ")," . + "`ba_q`.`mod_git_revision`" . + ")" , + "sort" => "mod_git_rev", + "title" => "revision hash of modification git repository" + ), + "repo" => array( + "label" => "Repository", + "mysql_name" => "package_repository", + "mysql_query" => "`ba_q`.`package_repository`", + "sort" => "repo", + "title" => "package repository" + ), + "commit_time" => array( + "label" => "Commit Time", + "mysql_name" => "commit_time", + "mysql_query" => "`ba_q`.`commit_time`", + "sort" => "commit_time", + "title" => "commit time of the source" + ), + "trials" => array( + "label" => "Compilations", + "mysql_name" => "trials", + "mysql_query" => "IFNULL(`t_q`.`trials`,0)", + "sort" => "trials", + "title" => "number of compilations" + ), + "loops" => array( + "label" => "Loops", + "mysql_name" => "loops", + "mysql_query" => "IFNULL(`l_q`.`loops`,0)", + "sort" => "loops", + "title" => "number of loops" + ), + "failure" => array( + "label" => "Failures", + "mysql_name" => "fail_reasons", + "mysql_query" => "`fr_q`.`fail_reasons_print`", + "sort" => "failure", + "title" => "reason of build failure" + ), + "blocked" => array( + "label" => "Blocked", + "mysql_name" => "is_blocked", + "mysql_query" => "`ba_q`.`is_blocked`", + "sort" => "blocked", + "title" => "block reason" + ), + "build_slave" => array( + "label" => "Build Slave", + "mysql_name" => "build_slave", + "mysql_query" => "`bs_q`.`build_slave`", + "sort" => "build_slave", + "title" => "whom it is handed out to" + ) +); + +if (!isset($_GET["sort"])) + $_GET["sort"]="trials"; + +if (substr($_GET["sort"],0,1) == "-") { + $direction = " DESC"; + $sort = substr($_GET["sort"],1); +} else { + $direction = " ASC"; + $sort = $_GET["sort"]; +} + +if (isset($columns[$sort])) + $order = "IFNULL(" . $columns[$sort]["mysql_name"] . ",0) " . $direction . ","; +else + $order = ""; + +function combine_fields($cln) { + return $cln["mysql_query"] . " AS `" . $cln["mysql_name"] . "`"; +} + +$result = mysql_run_query( + "SELECT " . + implode(",",array_map("combine_fields",$columns)) . + " FROM" . + " (" . + "SELECT DISTINCT " . + "`build_assignments`.`id`," . + "`build_assignments`.`is_blocked`," . + "`build_assignments`.`is_broken`," . + "`build_assignments`.`priority`," . + "`package_sources`.`pkgbase`," . + "`package_sources`.`git_revision`," . + "`package_sources`.`mod_git_revision`," . + "`package_sources`.`uses_upstream`," . + "`package_sources`.`uses_modification`," . + "`package_sources`.`commit_time`," . + "`upstream_repositories`.`name` AS `package_repository`," . + "`git_repositories`.`name` AS `git_repository`," . + "`architectures`.`name` AS `arch`" . + " FROM `build_assignments`" . + mysql_join_build_assignments_architectures() . + mysql_join_build_assignments_package_sources() . + mysql_join_package_sources_upstream_repositories() . + mysql_join_upstream_repositories_git_repositories() . + mysql_join_build_assignments_binary_packages() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + " WHERE `repositories`.`name`=\"build-list\"" . + ") AS `ba_q`". + " LEFT JOIN" . + " (" . + "SELECT " . + "`dependent_bp`.`build_assignment`," . + "COUNT(DISTINCT `dependency_bp`.`build_assignment`) AS `run_dependencies_pending`" . + " FROM `binary_packages` AS `dependent_bp`" . + mysql_join_binary_packages_dependencies('dependent_bp') . + mysql_join_dependencies_dependency_types() . + mysql_join_dependencies_install_target_providers() . + mysql_join_install_target_providers_binary_packages('','dependency_bp') . + mysql_join_binary_packages_binary_packages_in_repositories('dependency_bp') . + mysql_join_binary_packages_build_assignments('dependent_bp','dependent_ba') . + mysql_join_binary_packages_build_assignments('dependency_bp','dependency_ba') . + " JOIN `architecture_compatibilities` AS `ac_a`". + " ON `ac_a`.`fully_compatible`". + " AND `ac_a`.`built_for`=`dependency_ba`.`architecture`". + " JOIN `architecture_compatibilities` AS `ac_b`". + " ON `ac_b`.`fully_compatible`". + " AND `ac_b`.`built_for`=`dependent_ba`.`architecture`". + " AND `ac_b`.`runs_on`=`ac_a`.`runs_on`". + mysql_join_binary_packages_in_repositories_repositories() . + " WHERE `dependency_bp`.`build_assignment` != `dependent_bp`.`build_assignment`" . + " AND `dependency_types`.`relevant_for_building`" . + " AND `dependency_types`.`relevant_for_binary_packages`" . + " AND `repositories`.`name`=\"build-list\"" . + " GROUP BY `dependent_bp`.`build_assignment`" . + ") AS `rd_q` ON `rd_q`.`build_assignment`=`ba_q`.`id`" . + " LEFT JOIN" . + " (" . + "SELECT " . + "`dependent_bp`.`build_assignment`," . + "COUNT(DISTINCT `dependencies`.`id`) AS `make_dependencies_pending`" . + " FROM `binary_packages` AS `dependent_bp`" . + mysql_join_binary_packages_dependencies('dependent_bp') . + mysql_join_dependencies_dependency_types() . + mysql_join_binary_packages_build_assignments('dependent_bp','dependent_ba') . + " JOIN `architecture_compatibilities` AS `ac_b`". + " ON `ac_b`.`fully_compatible`". + " AND `ac_b`.`built_for`=`dependent_ba`.`architecture`". + " WHERE NOT EXISTS(" . + "SELECT 1 FROM `install_target_providers`" . + mysql_join_install_target_providers_binary_packages('','dependency_bp') . + mysql_join_binary_packages_binary_packages_in_repositories('dependency_bp','dependency_bpir') . + mysql_join_binary_packages_in_repositories_repositories('dependency_bpir') . + mysql_join_binary_packages_build_assignments('dependency_bp','dependency_ba') . + " JOIN `architecture_compatibilities` AS `ac_a`". + " ON `ac_a`.`fully_compatible`". + " AND `ac_a`.`built_for`=`dependency_ba`.`architecture`". + " WHERE `install_target_providers`.`install_target` = `dependencies`.`depending_on`" . + " AND `repositories`.`is_on_master_mirror`" . + " AND `ac_b`.`runs_on`=`ac_a`.`runs_on`". + ")" . + " AND `dependency_types`.`relevant_for_building`" . + " AND NOT `dependency_types`.`relevant_for_binary_packages`" . + " GROUP BY `dependent_bp`.`build_assignment`" . + ") AS `md_q` ON `md_q`.`build_assignment`=`ba_q`.`id`" . + " LEFT JOIN" . + " (" . + "SELECT " . + "`build_dependency_loops`.`build_assignment`," . + "COUNT(1) AS `loops`" . + " FROM `build_dependency_loops`" . + " GROUP BY `build_dependency_loops`.`build_assignment`" . + ") AS `l_q` ON `l_q`.`build_assignment`=`ba_q`.`id`" . + " LEFT JOIN" . + " (" . + "SELECT " . + "`rfb`.`build_assignment`," . + "GROUP_CONCAT(" . + "CONCAT(" . + "\"<a href=\\\"https://buildmaster.archlinux32.org/build-logs/error/\"," . + mysql_url_encode("`rfb`.`log_file`") . "," . + "\"\\\">\"," . + "`fail_reasons`.`name`," . + "\"</a>\"" . + ")" . + " ORDER BY `fail_reasons`.`name`" . + ") AS `fail_reasons_print`," . + "CONCAT(" . + "\",\"," . + "GROUP_CONCAT(" . + "`fail_reasons`.`name`" . + ")," . + "\",\"" . + ") AS `fail_reasons_raw`" . + " FROM (" . + "SELECT " . + "`failed_builds`.`build_assignment`," . + "`failed_builds`.`reason`," . + "MAX(`failed_builds`.`date`) AS `max_date`" . + " FROM `failed_builds`" . + " GROUP BY `failed_builds`.`build_assignment`,`failed_builds`.`reason`" . + ") AS `cfb`" . + " JOIN" . + " (" . + "SELECT DISTINCT " . + "`failed_builds`.*" . + " FROM `failed_builds`" . + " GROUP BY `failed_builds`.`build_assignment`,`failed_builds`.`reason`,`failed_builds`.`date`" . + ") AS `rfb`" . + " ON `cfb`.`build_assignment`=`rfb`.`build_assignment`" . + " AND `cfb`.`reason`=`rfb`.`reason`" . + " AND `cfb`.`max_date`=`rfb`.`date`" . + mysql_join_failed_builds_fail_reasons('rfb') . + " GROUP BY `rfb`.`build_assignment`" . + ") AS `fr_q` ON `fr_q`.`build_assignment`=`ba_q`.`id`" . + " LEFT JOIN" . + " (" . + "SELECT " . + "`failed_builds`.`build_assignment`," . + "COUNT(`failed_builds`.`id`) AS `trials`" . + " FROM `failed_builds`" . + " GROUP BY `failed_builds`.`build_assignment`" . + ") AS `t_q` ON `t_q`.`build_assignment`=`ba_q`.`id`" . + " LEFT JOIN" . + " (" . + "SELECT " . + "`build_slaves`.`currently_building`," . + "GROUP_CONCAT(`build_slaves`.`name`) AS `build_slave`" . + " FROM `build_slaves`" . + " GROUP BY `build_slaves`.`currently_building`" . + ") AS `bs_q` ON `bs_q`.`currently_building`=`ba_q`.`id`" . + $filter . + " ORDER BY " . $order . "`trials` " . $direction . ",`dependencies_pending` " . $direction . ",`is_blocked` " . $direction . ",`pkgbase` " . $direction +); + +$count = 0; + +while($row = $result->fetch_assoc()) { + + foreach ($row as $name => $value) { + if (!isset($row[$name])) + $rows[$count][$name] = " "; + elseif ($name == "is_blocked") + $rows[$count][$name] = preg_replace( + array ( + "/FS32#(\\d+)/", + "/FS#(\\d+)/" + ), + array ( + "<a href=\"https://bugs.archlinux32.org/index.php?do=details&task_id=$1\">$0</a>", + "<a href=\"https://bugs.archlinux.org/task/$1\">$0</a>" + ), + $value + ); + else + $rows[$count][$name] = $value; + } + + $count++; +} + +print_header("List of Package Builds"); + +?> + <a href="https://buildmaster.archlinux32.org/build-logs/">build logs</a> + <div id="pkglist-search" class="box filter-criteria"> + <h2>Package Build Search</h2> + <form id="pkg-search" method="get" action="/buildmaster/build-list.php"> + <p><input id="id_sort" name="sort" type="hidden" /></p> + <fieldset> + <legend>Enter search criteria</legend> +<?php + +foreach ($multi_select_search_criteria as $criterium) { + print " <div>\n"; + print " <label for=\"id_" . $criterium["name"] . "\" title=\"Limit results to a specific " . $criterium["title"] . "\">"; + print $criterium["label"]; + print "</label>\n"; + print " <select multiple=\"multiple\" id=\"id_" . $criterium["name"] . "\" name=\"" . $criterium["name"] . "\">\n"; + foreach ($criterium["values"] as $value) { + print " <option value=\"" . $value . "\""; + if (strpos( "&" . $_SERVER["QUERY_STRING"] . "&", "&" . $criterium["name"] . "=" . urlencode($value) . "&") !== false) + print " selected=\"selected\""; + print ">" . $value . "</option>\n"; + } + print " </select>\n"; + print " </div>\n"; +} + +?> + <div> + <label for="id_q" title="Enter keywords as desired">Keywords</label> + <input id="id_q" name="q" size="30" type="text" <?php +if (isset($_GET["q"])) + print "value=\"".$_GET["q"]."\""; +?>/><br> + <input id="id_invq" name="invq" type="checkbox" value="invq" title="list all non-matching package builds"<?php +if (isset($_GET["invq"])) + print " checked"; +?>> + invert match + </div> +<?php + +foreach ($single_select_search_criteria as $criterium) { + print " <div>\n"; + print " <label for=\"id_"; + print $criterium["name"]; + print "\" title=\"Limit results based on "; + print $criterium["title"]; + print "\">"; + print $criterium["label"]; + print "</label><select id=\"id_"; + print $criterium["name"]; + print "\" name=\""; + print $criterium["name"]; + print "\">\n"; + foreach ($criterium["options"] as $label => $option) { + print " <option value=\""; + if ($label != "All") + print $label; + print "\""; + if (array_key_exists($criterium["name"],$_GET) && ($_GET[$criterium["name"]]==$label)) + print " selected=\"selected\""; + print ">" . $label . "</option>\n"; + } + print " </select>\n"; + print " </div>\n"; +} +?> + <div> + <label> </label> + <input title="Search for packages using this criteria" type="submit" value="Search"> + </div> + </fieldset> + </form> + </div> +<?php + +if ($count > 0) { + +?> + <div id="pkglist-results" class="box"> + <table class="results"> + <thead> + <tr> +<?php + +foreach ($columns as $column) { + + print " <th>\n"; + print " <a href=\"?"; + print substr( + str_replace( + "&sort=".$_GET["sort"]."&", + "&", + "&" . $_SERVER["QUERY_STRING"] . "&" + ), + 1 + ) . "sort="; + if ($column["sort"] == $_GET["sort"]) + print "-"; + print $column["sort"] . "\" "; + print "title=\"Sort build assignments by " . $column["title"] . "\">\n"; + print " " . $column["label"] . "\n"; + print " </a>\n"; + print " </th>\n"; + +} + +?> + </tr> + </thead> + <tbody> +<?php + +$oddity = "odd"; + +foreach($rows as $row) { + + print " <tr class=\"" . $oddity . "\">\n"; + + foreach ($columns as $column) { + + print " <td>\n"; + print " " . $row[$column["mysql_name"]] . "\n"; + print " </td>\n"; + + } + print " </tr>\n"; + + if ($oddity == "odd" ) + $oddity = "even"; + else + $oddity = "odd"; + +} + +?> + </tbody> + </table> + </div> +<?php +} + +print_footer(); diff --git a/buildmaster/build-slaves.php b/buildmaster/build-slaves.php new file mode 100644 index 0000000..36a1522 --- /dev/null +++ b/buildmaster/build-slaves.php @@ -0,0 +1,216 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/style.php"; +require_once BASE . "/lib/mysql.php"; + +$columns = array( + "name" => array( + "label" => "name", + "mysql_name" => "name", + "mysql_query" => "`build_slaves`.`name`", + "sort" => "name", + "title" => "name" + ), + "operator" => array( + "label" => "operator", + "mysql_name" => "operator", + "mysql_query" => "`persons`.`name`", + "sort" => "operator", + "title" => "operator" + ), + "currently_building" => array( + "label" => "currently building", + "mysql_name" => "cb", + "mysql_query" => "`ba_q`.`cb`", + "mysql_ba_q_name" => "cb", + "mysql_ba_q_query" => "CONCAT(`architectures`.`name`,\"/\",`package_sources`.`pkgbase`)", + "sort" => "currently_building", + "title" => "pkgbase of currently building package" + ), + "last_connection" => array( + "label" => "last connection", + "mysql_name" => "lc", + "mysql_query" => "`sl_q`.`lc`", + "mysql_sl_q_name" => "lc", + "mysql_sl_q_query" => "MAX(`ssh_log`.`date`)", + "sort" => "last_connection", + "title" => "time of last connection" + ), + "building_since" => array( + "label" => "building since", + "mysql_name" => "bs", + "mysql_query" => "`sl_q`.`bs`", + "mysql_sl_q_name" => "bs", + "mysql_sl_q_query" => "MAX(IF(`ssh_log`.`action`=\"get-assignment\",`ssh_log`.`date`,NULL))", + "sort" => "building_since", + "title" => "start of build" + ), + "trials" => array( + "label" => "trials", + "mysql_name" => "trials", + "mysql_query" => "`build_slaves`.`trials`", + "sort" => "trials", + "title" => "number of trials" + ), + "logged_lines" => array( + "label" => "logged lines", + "mysql_name" => "ll", + "mysql_query" => "`build_slaves`.`logged_lines`", + "sort" => "logged_lines", + "title" => "number of logged lines so far" + ), + "last_action" => array( + "label" => "last action", + "mysql_name" => "la", + "mysql_query" => "`build_slaves`.`last_action`", + "sort" => "last_action", + "title" => "last action" + ) +); + +if (!isset($_GET["sort"])) + $_GET["sort"]="-last_connection"; + +if (substr($_GET["sort"],0,1) == "-") { + $direction = " DESC"; + $sort = substr($_GET["sort"],1); +} else { + $direction = " ASC"; + $sort = $_GET["sort"]; +} + +if (isset($columns[$sort])) + $order = "IFNULL(`sub_query`.`" . $columns[$sort]["mysql_name"] . "`,0) " . $direction . ","; +else + $order = ""; + +function combine_fields($cln) { + return $cln["mysql_query"] . " AS `" . $cln["mysql_name"] . "`"; +} + +function combine_ba_q_fields($cln) { + if (isset($cln["mysql_ba_q_query"]) && isset($cln["mysql_ba_q_name"])) + return $cln["mysql_ba_q_query"] . " AS `" . $cln["mysql_ba_q_name"] . "`"; +} + +function combine_sl_q_fields($cln) { + if (isset($cln["mysql_sl_q_query"]) && isset($cln["mysql_sl_q_name"])) + return $cln["mysql_sl_q_query"] . " AS `" . $cln["mysql_sl_q_name"] . "`"; +} + +function non_empty($val) { + return ! empty($val); +} + +$result = mysql_run_query( + "SELECT `sub_query`.* FROM (" . + "SELECT " . + implode(",",array_map("combine_fields",$columns)) . + " FROM `build_slaves`" . + mysql_join_build_slaves_ssh_keys() . + mysql_join_ssh_keys_persons(). + + " LEFT JOIN (" . + "SELECT " . + "`build_assignments`.`id` AS `id`," . + implode(",",array_filter(array_map("combine_ba_q_fields",$columns),"non_empty")) . + " FROM `build_assignments`" . + mysql_join_build_assignments_package_sources() . + mysql_join_build_assignments_architectures() . + ") AS `ba_q`" . + " ON `ba_q`.`id`=`build_slaves`.`currently_building`" . + + " LEFT JOIN (" . + "SELECT " . + "`ssh_log`.`build_slave` AS `build_slave`," . + implode(",",array_filter(array_map("combine_sl_q_fields",$columns),"non_empty")) . + " FROM `ssh_log`" . + " WHERE `ssh_log`.`date`>=ADDDATE(NOW(),\"-5 00:00:00\")" . + " GROUP BY `ssh_log`.`build_slave`" . + ") AS `sl_q`" . + " ON `sl_q`.`build_slave`=`build_slaves`.`id`" . + ") AS `sub_query`" . + " ORDER BY " . $order . "`sub_query`.`name`" +); + +$count = 0; + +while($row = $result->fetch_assoc()) { + + foreach ($row as $name => $value) { + if (!isset($row[$name])) + $rows[$count][$name] = " "; + else + $rows[$count][$name] = $value; + } + $rows[$count]["name"] = + "<a href=\"/buildmaster/log.php?show=ssh&slave=" . + $row["name"] . + "\">" . + $row["name"] . + "</a>"; + + $count++; +} + +print_header("List of Build Slaves"); + +if ($count > 0) { + +?> + <div id="buildslaveslist-results" class="box"> + <table class="results"> + <thead> + <tr> +<?php + +foreach ($columns as $column) { + + print " <th>\n"; + print " <a href=\"?sort="; + if ($column["sort"] == $_GET["sort"]) + print "-"; + print $column["sort"] . "\" "; + print "title=\"Sort build assignments by " . $column["title"] . "\">\n"; + print " " . $column["label"] . "\n"; + print " </a>\n"; + print " </th>\n"; + +} + +?> + </tr> + </thead> + <tbody> +<?php + +$oddity = "odd"; + +foreach($rows as $row) { + + print " <tr class=\"" . $oddity . "\">\n"; + + foreach ($columns as $column) { + + print " <td>\n"; + print " " . $row[$column["mysql_name"]] . "\n"; + print " </td>\n"; + + } + print " </tr>\n"; + + if ($oddity == "odd" ) + $oddity = "even"; + else + $oddity = "odd"; + +} + +?> + </tbody> + </table> + </div> +<?php +} + +print_footer(); diff --git a/buildmaster/deletion-links.php b/buildmaster/deletion-links.php new file mode 100644 index 0000000..066bf8d --- /dev/null +++ b/buildmaster/deletion-links.php @@ -0,0 +1,246 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + +$edges = ""; +$knots = ""; + +if (isset($_GET["show_all"])) + $available_filter = " LEFT"; +else + $available_filter = ""; + +if (isset($_GET["pkgname"])) + $filter = " AND `binary_packages`.`pkgname` REGEXP from_base64(\"" . base64_encode($_GET["pkgname"]) . "\")"; +else + $filter = ""; + +$memcache = new Memcache; +$memcache->connect('localhost', 11211) or die ('Memcached Connection Error'); +$available_upstream_packages = $memcache->get('available_upstream_packages'); +if ($available_upstream_packages === false) { + $available_upstream_packages = explode( + "\n", + shell_exec( + "find /var/lib/pacman/ -name '*.db' -exec tar -tzf {} \; " . + "| sed -n 's,-[^-]\+-[^-]\+/$,,;T;p' " . + "| sort -u" + ) + ); + $memcache->set('available_upstream_packages',$available_upstream_packages,0,1800); +} + +mysql_run_query( + "CREATE TEMPORARY TABLE `available` (" . + "`pkgname` VARCHAR(88), " . + "UNIQUE KEY `name` (`pkgname`)" . + ")" +); + +mysql_run_query( + "INSERT INTO `available` (`pkgname`) VALUES (\"" . + implode(array_map("base64_encode", $available_upstream_packages), "\"),(\"") . + "\")" +); + +mysql_run_query( + "DELETE FROM `available` WHERE `available`.`pkgname`=\"\"" +); + +mysql_run_query( + "UPDATE `available` SET `available`.`pkgname`=from_base64(`available`.`pkgname`)" +); + +mysql_run_query( + "CREATE TEMPORARY TABLE `d_bpir` (" . + "`id` BIGINT, " . + "`group` VARCHAR(256), " . + "`color` VARCHAR(7), " . + "UNIQUE KEY `id` (`id`)" . + ")" +); + +mysql_run_query( + "INSERT IGNORE INTO `d_bpir` (`id`,`color`)" . + " SELECT" . + " `binary_packages_in_repositories`.`id`," . + "IF(" . + "`available`.`pkgname` IS NULL," . + "\"#00ff00\"," . + "IF(" . + "`build_assignments`.`is_black_listed` IS NULL," . + "\"#800000\"," . + "\"#ff0000\"" . + ")" . + ") AS `color`" . + " FROM `binary_packages_in_repositories`" . + mysql_join_binary_packages_in_repositories_binary_packages() . + mysql_join_binary_packages_build_assignments() . + $available_filter . + " JOIN `available` ON `available`.`pkgname`=`binary_packages`.`pkgname`" . + " WHERE `binary_packages_in_repositories`.`is_to_be_deleted`" . + " AND `binary_packages`.`pkgname` NOT LIKE \"lib32-%\"" . + $filter +); + +mysql_run_query( + "CREATE TEMPORARY TABLE `d_bpir_copy` (" . + "`id` BIGINT, " . + "`group` VARCHAR(256), " . + "`color` VARCHAR(7), " . + "UNIQUE KEY `id` (`id`)" . + ")" +); + +mysql_run_query( + "INSERT IGNORE INTO `d_bpir_copy` (`id`,`color`)" . + " SELECT `d_bpir`.`id`,`d_bpir`.`color`" . + " FROM `d_bpir`" +); + +mysql_run_query( + "CREATE TEMPORARY TABLE `d_bpir_links` (" . + "`dependent` BIGINT, " . + "`depending_on` BIGINT, " . + "`dep_type` SMALLINT, " . + "UNIQUE KEY `content` (`dependent`,`depending_on`,`dep_type`)" . + ")" +); + +mysql_run_query( + "INSERT IGNORE INTO `d_bpir_links` (`dependent`,`depending_on`,`dep_type`)" . + " SELECT `d_bpir`.`id`," . + " `itp_bpir`.`id`," . + " `dependencies`.`dependency_type`" . + " FROM `d_bpir`" . + " JOIN `binary_packages_in_repositories` ON `d_bpir`.`id`=`binary_packages_in_repositories`.`id`" . + mysql_join_binary_packages_in_repositories_dependencies() . + mysql_join_dependencies_install_target_providers() . + mysql_join_install_target_providers_binary_packages_in_repositories('','itp_bpir') . + " JOIN `d_bpir_copy` ON `itp_bpir`.`id`=`d_bpir_copy`.`id`" . + " WHERE `dependencies`.`dependent`!=`install_target_providers`.`package`" +); + +mysql_run_query( + "CREATE TEMPORARY TABLE `d_bpir_links_copy` (" . + "`dependent` BIGINT, " . + "`depending_on` BIGINT, " . + "`dep_type` SMALLINT, " . + "UNIQUE KEY `content` (`dependent`,`depending_on`,`dep_type`)" . + ")" +); + +mysql_run_query( + "INSERT IGNORE INTO `d_bpir_links_copy` (`dependent`,`depending_on`,`dep_type`)" . + " SELECT `d_bpir_links`.`dependent`,`d_bpir_links`.`depending_on`,`d_bpir_links`.`dep_type`" . + " FROM `d_bpir_links`" +); + +mysql_run_query( + "UPDATE `d_bpir`" . + " JOIN (" . + "SELECT" . + " `d_bpir_copy`.`id`," . + "SHA2(" . + "GROUP_CONCAT(CONCAT(" . + "IFNULL(`d_bpir_copy`.`color`,\"0\"),\":\"," . + "IFNULL(`d_bpir_links`.`depending_on`,\"0\"),\":\"," . + "IFNULL(`d_bpir_links`.`dep_type`,\"0\"),\":\"," . + "IFNULL(`d_bpir_links_copy`.`dependent`,\"0\"),\":\"," . + "IFNULL(`d_bpir_links_copy`.`dep_type`,\"0\")" . + "))" . + ",256) AS `hash`" . + " FROM `d_bpir_copy`" . + " LEFT JOIN `d_bpir_links` ON `d_bpir_links`.`dependent`=`d_bpir_copy`.`id`" . + " LEFT JOIN `d_bpir_links_copy` ON `d_bpir_links_copy`.`depending_on`=`d_bpir_copy`.`id`" . + " GROUP BY `d_bpir_copy`.`id`" . + ") AS `grouped_d_bpir` ON `grouped_d_bpir`.`id`=`d_bpir`.`id`" . + " SET `d_bpir`.`group`=`grouped_d_bpir`.`hash`" +); + +mysql_run_query( + "UPDATE `d_bpir_copy`" . + " JOIN `d_bpir` ON `d_bpir`.`id`=`d_bpir_copy`.`id`" . + " SET `d_bpir_copy`.`group`=`d_bpir`.`group`" +); + +$result = mysql_run_query( + "SELECT MAX(`d_bpir`.`id`) AS `id`," . + "GROUP_CONCAT(CONCAT(" . + "`architectures`.`name`,\"/\"," . + "`repositories`.`name`,\"/\"," . + "`binary_packages`.`pkgname`" . + ") SEPARATOR \",\n\") AS `name`," . + "`d_bpir`.`color`" . + " FROM `d_bpir`" . + " JOIN `binary_packages_in_repositories` ON `d_bpir`.`id`=`binary_packages_in_repositories`.`id`" . + mysql_join_binary_packages_in_repositories_binary_packages() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_architectures() . + " GROUP BY `d_bpir`.`group`" +); + +while ($row = $result->fetch_assoc()) + $knots .= + "\"p" . + $row["id"] . + "\" [label = \"" . + $row["name"] . + "\", + fontcolor = \"" . + $row["color"] . + "\"];\n"; + +$result = mysql_run_query( + "SELECT MAX(`d_bpir_links`.`dependent`) AS `dependent`," . + "`dependency_types`.`name` AS `dep_type`," . + "MAX(`d_bpir_links`.`depending_on`) AS `depending_on`" . + " FROM `d_bpir_links`" . + " JOIN `dependency_types` ON `d_bpir_links`.`dep_type`=`dependency_types`.`id`" . + " JOIN `d_bpir` ON `d_bpir`.`id`=`d_bpir_links`.`dependent`" . + " JOIN `d_bpir_copy` ON `d_bpir_copy`.`id`=`d_bpir_links`.`depending_on`" . + " GROUP BY CONCAT(`d_bpir`.`group`,\"-\",`d_bpir_copy`.`group`)" +); + +while ($row = $result->fetch_assoc()) { + $edges .= + "\"p" . + $row["depending_on"] . + "\" -> \"p" . + $row["dependent"] . + "\" [color = \""; + switch ($row["dep_type"]) { + case "run": + $edges .= "#000000"; + break; + case "make": + $edges .= "#0000ff"; + break; + case "link": + $edges .= "#008000"; + break; + case "check": + $edges .= "#000080"; + break; + default: + $edges .= "#ff00ff"; + } + $edges .= + "#000080"; + $edges .= + "\"];\n"; +} + +header ("Content-type: image/png"); +passthru( + "echo '" . base64_encode( + "digraph dependencies {\n" . + "rankdir=LR;\n" . + "fontname=dejavu;\n" . + $knots . + $edges . + "}\n" + ) . "' | " . + "base64 -d | " . + "timeout 30 dot -Tpng -o/dev/stdout /dev/stdin" +); diff --git a/buildmaster/dependencies.php b/buildmaster/dependencies.php new file mode 100644 index 0000000..a8beb5d --- /dev/null +++ b/buildmaster/dependencies.php @@ -0,0 +1,190 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + +$match = ""; + +function dependency_arch_join($name) { + if (isset($_GET["ba_a"])) { + return + " JOIN `architecture_compatibilities`" . + " ON `architecture_compatibilities`.`fully_compatible`" . + " AND `architecture_compatibilities`.`built_for`=`" . $name . "`.`architecture`" . + " JOIN `architectures` AS `ba_a`" . + " ON `architecture_compatibilities`.`runs_on`=`ba_a`.`id`" . + " AND `ba_a`.`name`=from_base64(\"" . base64_encode($_GET["ba_a"]) . "\")"; + } elseif (isset($_GET["a"])) { + return + " JOIN `architecture_compatibilities` AS `ac_1`" . + " ON `ac_1`.`fully_compatible`" . + " AND `ac_1`.`built_for`=`" . $name . "`.`architecture`" . + " JOIN `architecture_compatibilities` AS `ac_2`" . + " ON `ac_2`.`fully_compatible`" . + " AND `ac_1`.`runs_on`=`ac_2`.`runs_on`" . + " AND `ac_2`.`built_for`=`architectures`.`id`"; + } else + return ""; +} + +if (isset($_GET["a"])) + $match .= " AND `architectures`.`name`=from_base64(\"" . base64_encode($_GET["a"]) . "\")"; +if (isset($_GET["b"])) + $match .= " AND `package_sources`.`pkgbase`=from_base64(\"" . base64_encode($_GET["b"]) . "\")"; +if (isset($_GET["p"])) + $match .= " AND `binary_packages`.`pkgname`=from_base64(\"" . base64_encode($_GET["p"]) . "\")"; +if (isset($_GET["r"])) + $match .= " AND `repositories`.`name`=from_base64(\"" . base64_encode($_GET["r"]) . "\")"; + +$ignore_install_targets = " AND NOT `install_targets`.`name` IN (\"base\",\"base-devel\")"; + +$colors["stable"]="#000000"; +$colors["testing"]="#008000"; +$colors["staging"]="#00ff00"; +$colors["standalone"]="#000000"; +$colors["unbuilt"]="#ff0000"; +$colors["forbidden"]="#808080"; +$colors["virtual"]="#800080"; + +$limit=200; + +mysql_run_query( + "CREATE TEMPORARY TABLE `cons` (" . + "`dep` BIGINT, " . + "`itp` BIGINT, " . + "UNIQUE KEY `content` (`dep`,`itp`)" . + ")" +); + +mysql_run_query( + "INSERT IGNORE INTO `cons` (`dep`,`itp`)" . + " SELECT `dependencies`.`id`,`install_target_providers`.`id`". + " FROM `binary_packages`" . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_repository_stabilities() . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_build_assignments() . + mysql_join_build_assignments_package_sources() . + $match . + mysql_join_binary_packages_dependencies() . + mysql_join_dependencies_dependency_types() . + mysql_join_dependencies_install_targets() . + $ignore_install_targets . + mysql_join_dependencies_install_target_providers() . + mysql_join_install_target_providers_binary_packages('','itp_bp') . + dependency_arch_join('itp_bp') . + " WHERE (`dependency_types`.`relevant_for_binary_packages` OR `repository_stabilities`.`name`=\"unbuilt\")" . + " LIMIT " . $limit +); + +mysql_run_query( + "INSERT IGNORE INTO `cons` (`dep`,`itp`)" . + " SELECT `dependencies`.`id`,`install_target_providers`.`id`". + " FROM `binary_packages`" . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_build_assignments() . + mysql_join_build_assignments_package_sources() . + $match . + mysql_join_binary_packages_install_target_providers() . + mysql_join_install_target_providers_dependencies() . + mysql_join_dependencies_binary_packages('','d_bp') . + dependency_arch_join('d_bp') . + mysql_join_binary_packages_binary_packages_in_repositories('d_bp','d_bpir') . + mysql_join_binary_packages_in_repositories_repositories('d_bpir','d_r') . + mysql_join_repositories_repository_stabilities('d_r','d_rs') . + mysql_join_dependencies_dependency_types() . + " WHERE (`dependency_types`.`relevant_for_binary_packages` OR `d_rs`.`name`=\"unbuilt\")" . + " LIMIT " . $limit +); + +$edges = ""; +$knots = ""; + +$result = mysql_run_query( + "SELECT DISTINCT `install_target_providers`.`install_target`,`install_target_providers`.`package`" . + " FROM `cons`" . + " JOIN `install_target_providers` ON `cons`.`itp`=`install_target_providers`.`id`" +); + +while ($row = $result->fetch_assoc()) + $edges .= "\"p" . $row["package"] . "\" -> \"i" . $row["install_target"] . "\" [color = \"#000080\"];\n"; + +$result = mysql_run_query( + "SELECT DISTINCT `dependencies`.`dependent`,`dependencies`.`depending_on`,`dependency_types`.`name`" . + " FROM `cons`" . + " JOIN `dependencies` ON `cons`.`dep`=`dependencies`.`id`" . + mysql_join_dependencies_dependency_types() +); + +while ($row = $result->fetch_assoc()) + $edges .= "\"i" . $row["depending_on"] . "\" -> \"p" . $row["dependent"] . "\" [taillabel = \"" . $row["name"] . "\"];\n"; + +$result = mysql_run_query( + "SELECT DISTINCT `install_targets`.`id`,`install_targets`.`name`" . + " FROM `cons`" . + " JOIN `dependencies` ON `cons`.`dep`=`dependencies`.`id`" . + mysql_join_dependencies_install_targets() +); + +while ($row = $result->fetch_assoc()) + $knots .= "\"i" . $row["id"] . "\" [label = \"" . $row["name"] . "\", fontcolor = \"#000080\"];\n"; + +$pkgfile_query = + "CONCAT(". + "`repositories`.`name`,\"/\"," . + "`binary_packages`.`pkgname`,\"-\"," . + mysql_query_package_version("binary_packages") . + ",\"-\"," . + "`architectures`.`name`" . + ") AS `filename`"; + +$result = mysql_run_query( + "SELECT DISTINCT " . + "`binary_packages`.`id`," . + "`repository_stabilities`.`name` AS `stability`," . + $pkgfile_query . + " FROM `cons`" . + " JOIN `dependencies` ON `cons`.`dep`=`dependencies`.`id`" . + mysql_join_dependencies_binary_packages() . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_repository_stabilities() +); + +while ($row = $result->fetch_assoc()) + $knots .= "\"p" . $row["id"] . "\" [label = \"" . $row["filename"] . "\", fontcolor = \"" . $colors[$row["stability"]] . "\"];\n"; + +$result = mysql_run_query( + "SELECT DISTINCT " . + "`binary_packages`.`id`," . + "`repository_stabilities`.`name` AS `stability`," . + $pkgfile_query . + " FROM `cons`" . + " JOIN `install_target_providers` ON `cons`.`itp`=`install_target_providers`.`id`" . + mysql_join_install_target_providers_binary_packages() . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_repository_stabilities() +); + +while ($row = $result->fetch_assoc()) + $knots .= "\"p" . $row["id"] . "\" [label = \"" . $row["filename"] . "\", fontcolor = \"" . $colors[$row["stability"]] . "\"];\n"; + +$knots = str_replace("\$","\\\$",$knots); +$edges = str_replace("\$","\\\$",$edges); + +header ("Content-type: image/png"); +passthru( + "timeout 30 dot -Tpng -o/dev/stdout /dev/stdin <<EOF\n" . + "digraph dependencies {\n" . + "rankdir=LR;\n" . + "fontname=dejavu;\n" . + $knots . + $edges . + "}\n" . + "EOF\n" +); diff --git a/buildmaster/gpg-keys.php b/buildmaster/gpg-keys.php new file mode 100644 index 0000000..db990c2 --- /dev/null +++ b/buildmaster/gpg-keys.php @@ -0,0 +1,48 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + + $result = mysql_run_query( + "SELECT" . + " GROUP_CONCAT(`email_actions`.`name`) AS `action`," . + "`persons`.`name` AS `person`," . + "`gpg_keys`.`fingerprint`" . + " FROM `email_actions`" . + mysql_join_email_actions_allowed_email_actions() . + " RIGHT" . mysql_join_allowed_email_actions_gpg_keys() . + mysql_join_gpg_keys_persons() . + " GROUP BY `gpg_keys`.`id`" . + " ORDER BY `persons`.`name`" + ); + +?> +<html> + <head> + <title>list of gpg-keys</title> + </head> + <body> +<?php +show_warning_on_offline_slave(); + + print "<table border=1>\n"; + if ($result->num_rows > 0) { + print "<tr><th>person</th><th>action</th><th>fingerprint</th></tr>\n"; + while ($row = $result -> fetch_assoc()) { + foreach ($row as $key => $value) { + if ($value=="") { + $row[$key]=" "; + } + } + print "<tr>"; + print "<td>" . $row["person"] . "</td>"; + print "<td>" . $row["action"] . "</td>"; + print "<td><a href=\"http://pgp.mit.edu/pks/lookup?op=get&search=0x" . + substr($row["fingerprint"],-16) . + "\">" . $row["fingerprint"] . "</a></td>"; + print "</tr>\n"; + } + } + print "</table>\n"; + +?> +</body></html> diff --git a/buildmaster/index.php b/buildmaster/index.php new file mode 100644 index 0000000..0ea0376 --- /dev/null +++ b/buildmaster/index.php @@ -0,0 +1,80 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + +if (array_key_exists("arch",$_GET)) { + $archs = array(); + foreach (explode("&",$_SERVER["QUERY_STRING"]) as $param) { + if (strpos($param,"arch=")!==0) + continue; + $param = substr($param,5); + if ($param == "") + continue; + $archs[$param] = $param; + } + if (count($archs)==0) { + $archs = array("i486" => "i486", "i686" => "i686", "any" => "any"); + } +} else { + $archs = array("i686" => "i686", "any" => "any"); +} + +function encode_arch($a) { + return "arch=" . urlencode($a); +} + +$sarch_param = implode("&",array_map('encode_arch',$archs)); +$march_param = ""; +if ($sarch_param != "") { + $march_param = "&" . $sarch_param; + $sarch_param = "?" . $sarch_param; +} + +?> +<html> + <head> + <title>Buildmaster for Archlinux32 packages (<?php print implode(", ",$archs); ?>)</title> + </head> + <body> +<?php show_warning_on_offline_slave(); ?> + <a href="/buildmaster/build-list.php<?php print $sarch_param; ?>">build list</a> + as <a href="/buildmaster/build-list-links.php">graph</a> -- + <a href="/buildmaster/build-list.php?broken=Broken<?php print $march_param; ?>">broken packages</a> -- + <a href="/buildmaster/build-list.php?next=Can<?php print $march_param; ?>">buildable packages</a><br> + <a href="/buildmaster/build-slaves.php">build-slaves</a> -- + <a href="/buildmaster/gpg-keys.php">gpg-keys</a> -- + <a href="/buildmaster/status.php">status</a><br> + <a href="https://buildmaster.archlinux32.org/build-logs/">build logs</a> -- + <a href="/buildmaster/log.php?show=ssh">ssh-log</a> -- + <a href="/buildmaster/log.php?show=email">email-log</a><br> + sanity: of <a href="https://buildmaster.archlinux32.org/master-sanity.html">state files</a>, + of <a href="https://buildmaster.archlinux32.org/mysql-sanity.html">mysql database</a> and + <a href="/buildmaster/mysql-issues.php?ignore-i486">broken dependencies in the database</a><br> + <a href="/buildmaster/todos.php">todos</a> + as <a href="/buildmaster/todos.php?graph">graph</a><br> + <a href="https://buildmaster.archlinux32.org/database-layout.png">database layout</a><br> + <a href="/buildmaster/blacklist.php">blacklisted packages</a> -- + <a href="/buildmaster/to-delete.php">packages to be deleted</a> + and <a href="/buildmaster/deletion-links.php">links between them</a><br> + <img src="/buildmaster/statistics.php?log<?php print $march_param; ?>"><br> +<?php + +foreach (array("any", "i486", "i686", "") as $a) { + print " <a href=\"?arch=" . $a . "\">"; + switch ($a) { + case "": + print "all packages"; + break; + case "any": + print "architecture independent packages"; + break; + default: + print "packages for " . $a; + } + print "</a>\n"; +} + +?><br> + <img src="https://buildmaster.archlinux32.org/vnstat.png"><br> + </body> +</html> diff --git a/buildmaster/log.php b/buildmaster/log.php new file mode 100644 index 0000000..f6de94b --- /dev/null +++ b/buildmaster/log.php @@ -0,0 +1,93 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + + + $filter = ""; + if (isset($_GET["show"]) && + ($_GET["show"] == "ssh")) { + $to_show = "ssh"; + $columns = array( + "date" => "`ssh_log`.`date`", + "build slave" => "`build_slaves`.`name`", + "action" => "`ssh_log`.`action`", + "parameters" => "`ssh_log`.`parameters`" + ); + $join = " LEFT" . mysql_join_ssh_log_build_slaves(); + if (isset($_GET["action"])) + $filter .= " AND `ssh_log`.`action` LIKE from_base64(\"" . base64_encode($_GET["action"]) . "\")"; + if (isset($_GET["slave"])) + $filter .= " AND `build_slaves`.`name` LIKE from_base64(\"" . base64_encode($_GET["slave"]) . "\")"; + } else { + $to_show = "email"; + $columns = array( + "date" => "`email_log`.`date`", + "action" => "`email_actions`.`name`", + "count" => "`email_log`.`count`", + "success" => "`email_log`.`success`", + "person" => "`persons`.`name`", + "comment" => "`email_log`.`comment`" + ); + $join = + " LEFT" . mysql_join_email_log_email_actions() . + " LEFT JOIN (" . + "`gpg_keys`" . + mysql_join_gpg_keys_persons() . + ") ON `email_log`.`gpg_key`=`gpg_keys`.`id`"; + } + + if (isset($_GET["from"])) + $min_time = $_GET["from"]; + elseif ($to_show == "email") + $min_time = "1 00:00:00"; + else + $min_time = "00:42:00"; + + $query = "SELECT "; + foreach ($columns as $name => $column) + $query .= $column . " AS `".$name."`,"; + + $query = substr($query,0,-1); + $query .= " FROM `" . $to_show . "_log`" . $join . + " WHERE TIMEDIFF((" . + // NOW() is wrong here - due to differing time zones O.o + "SELECT MAX(`l`.`date`) FROM `" . $to_show . "_log` AS `l`" . + "),`" . $to_show . "_log`.`date`) < from_base64(\"" . base64_encode( $min_time ) . "\")" . + $filter . + " ORDER BY `" . $to_show . "_log`.`date` DESC"; + + $result = mysql_run_query($query); + +?> +<html> + <head> + <title><?php print $to_show; ?>-log</title> + <link rel="stylesheet" type="text/css" href="/static/style.css"> + </head> + <body> + <table> + <tr> +<?php + foreach ($columns as $label => $column) { + print " <th>\n"; + print " " . $label . "\n"; + print " </th>\n"; + } +?> + </tr> +<?php + + while ($row = $result -> fetch_assoc()) { + print " <tr>\n"; + foreach ($row as $val) { + print " <td>\n"; + print " " . $val . "\n"; + print " </td>\n"; + } + print " </tr>\n"; + } + +?> + </table> + </body> +</html> diff --git a/buildmaster/mysql-issues.php b/buildmaster/mysql-issues.php new file mode 100644 index 0000000..1397141 --- /dev/null +++ b/buildmaster/mysql-issues.php @@ -0,0 +1,183 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + + $ignore = ""; + + if (isset($_GET["ignore-haskell"])) + $ignore .= " AND `install_targets`.`name` NOT LIKE \"libHS%\""; + + if (isset($_GET["ignore-i486"])) + $ignore .= " AND `r_a`.`name` != \"i486\""; + + ob_start(); + +?> +<html> + <head> + <title>More and less critical issues with the database</title> + <link rel="stylesheet" type="text/css" href="/static/style.css"> + </head> + <body> +<?php show_warning_on_offline_slave(); ?> + <a href="https://buildmaster.archlinux32.org/">Start page</a><br> +<?php + + $limit = " LIMIT 10001"; + + $result = mysql_run_query( + "SELECT CONCAT(" . + "`r_a`.`name`,\"/\"," . + "`repositories`.`name`,\"/\"," . + "`binary_packages`.`pkgname`,\"-\"," . + mysql_query_package_version("binary_packages") . + ",\"-\"," . + "`architectures`.`name`) AS `pkgfile`," . + "`install_targets`.`name` AS `install_target`," . + "IF(`binary_packages_in_repositories`.`is_to_be_deleted`,1,0) AS `is_to_be_deleted`," . + "`subst_r`.`name` AS `subst_repository`," . + "`subst_buildlist_bp`.`id` AS `subst_buildlist`" . + " FROM `binary_packages`" . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + " AND `repositories`.`is_on_master_mirror`" . + mysql_join_repositories_architectures('','r_a') . + mysql_join_binary_packages_dependencies() . + mysql_join_dependencies_dependency_types() . + " AND `dependency_types`.`relevant_for_binary_packages`" . + mysql_join_dependencies_install_targets() . + mysql_join_binary_packages_architectures() . + " LEFT JOIN (" . + "`binary_packages` AS `subst_bp`" . + mysql_join_binary_packages_binary_packages_in_repositories('subst_bp','subst_bpir') . + mysql_join_binary_packages_in_repositories_repositories('subst_bpir','subst_r') . + " JOIN `repository_stability_relations` ON `repository_stability_relations`.`less_stable`=`subst_r`.`stability`" . + ")" . + " ON `subst_bp`.`pkgname`=`binary_packages`.`pkgname`" . + " AND `subst_bp`.`id`!=`binary_packages`.`id`" . + " AND `repository_stability_relations`.`more_stable`=`repositories`.`stability`" . + " AND `subst_r`.`architecture`=`repositories`.`architecture`" . + " LEFT JOIN (" . + "`binary_packages` AS `subst_buildlist_bp`" . + mysql_join_binary_packages_binary_packages_in_repositories('subst_buildlist_bp','subst_buildlist_bpir') . + mysql_join_binary_packages_in_repositories_repositories('subst_buildlist_bpir','subst_buildlist_r') . + " AND `subst_buildlist_r`.`name`=\"build-list\"". + ") ON `subst_buildlist_bp`.`pkgname`=`binary_packages`.`pkgname`" . + " AND `subst_bp`.`architecture`=`binary_packages`.`architecture`" . + " WHERE NOT EXISTS (" . + "SELECT 1 FROM `install_target_providers`" . + mysql_join_install_target_providers_binary_packages_in_repositories('','i_bpir') . + mysql_join_binary_packages_in_repositories_repositories('i_bpir','i_r') . + " JOIN `architecture_compatibilities` ON `architecture_compatibilities`.`fully_compatible`" . + " AND `architecture_compatibilities`.`built_for`=`i_r`.`architecture`" . + " WHERE `install_target_providers`.`install_target`=`dependencies`.`depending_on`" . + " AND `repositories`.`architecture`=`architecture_compatibilities`.`runs_on`" . + ")" . + $ignore . + " ORDER BY " . + "`binary_packages_in_repositories`.`is_to_be_deleted`," . + "`repositories`.`name`," . + "`binary_packages`.`pkgname`," . + "`install_targets`.`name`" . + $limit + ); + + if ($result -> num_rows > 10000) + print " Found >10000 serious issues.<br>\n"; + else + print " Found " . $result -> num_rows . " serious issues.<br>\n"; + + while ( $row = $result -> fetch_assoc() ) { + if ($row["is_to_be_deleted"]==1) + print " <font color=\"#00ff00\">(marked as to-be-deleted) "; + else + print " <font color=\"#ff0000\">"; + print $row["pkgfile"] . " depends on " . htmlspecialchars($row["install_target"]) . " which is not provided by any package"; + if (isset($row["subst_repository"])) + print " - but can be replaced by the one in " . $row["subst_repository"]; + elseif (isset($row["subst_buildlist"])) + print " - but is already rescheduled"; + print ".<br>"; + print "</font>\n"; + unset($row); + } + + $result = mysql_run_query( + "SELECT CONCAT(" . + "`r_a`.`name`,\"/\"," . + "`repositories`.`name`,\"/\"," . + "`binary_packages`.`pkgname`,\"-\"," . + mysql_query_package_version("binary_packages") . + ",\"-\"," . + "`architectures`.`name`) AS `pkgfile`," . + "`install_targets`.`name` AS `install_target`," . + "`repository_stabilities`.`name` AS `stability`," . + "IF(`binary_packages_in_repositories`.`is_to_be_deleted`,1,0) AS `is_to_be_deleted`" . + " FROM `binary_packages`" . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + " AND `repositories`.`is_on_master_mirror`" . + mysql_join_repositories_architectures('','r_a') . + mysql_join_repositories_repository_stabilities() . + mysql_join_binary_packages_dependencies() . + mysql_join_dependencies_dependency_types() . + " AND `dependency_types`.`relevant_for_binary_packages`" . + mysql_join_dependencies_install_targets() . + mysql_join_binary_packages_architectures() . + " WHERE EXISTS (" . + "SELECT 1 FROM `install_target_providers`" . + mysql_join_install_target_providers_binary_packages_in_repositories('','prov_bpir') . + mysql_join_binary_packages_in_repositories_repositories('prov_bpir','prov_r') . + " JOIN `architecture_compatibilities` ON `architecture_compatibilities`.`built_for`=`prov_r`.`architecture`" . + " AND `architecture_compatibilities`.`fully_compatible`" . + " WHERE `install_target_providers`.`install_target` = `dependencies`.`depending_on`" . + " AND `architecture_compatibilities`.`runs_on`=`repositories`.`architecture`" . + ")" . + " AND NOT EXISTS (" . + "SELECT 1 FROM `install_target_providers`" . + mysql_join_install_target_providers_binary_packages('','prov_bp') . + mysql_join_binary_packages_binary_packages_in_repositories('prov_bp','prov_bpir') . + mysql_join_binary_packages_in_repositories_repositories('prov_bpir','prov_r') . + " JOIN `repository_stability_relations` ON `prov_r`.`stability`=`repository_stability_relations`.`more_stable`" . + " WHERE `install_target_providers`.`install_target` = `dependencies`.`depending_on`" . + " AND `repositories`.`stability`=`repository_stability_relations`.`less_stable`" . + " AND `repositories`.`architecture`=`prov_r`.`architecture`" . + " AND NOT EXISTS (" . + "SELECT 1 FROM `binary_packages` AS `sup_bp`" . + mysql_join_binary_packages_binary_packages_in_repositories('sup_bp','sup_bpir') . + mysql_join_binary_packages_in_repositories_repositories('sup_bpir','sup_r') . + " JOIN `repository_stability_relations` AS `sup_rra` ON `sup_r`.`stability`=`sup_rra`.`more_stable`" . + " JOIN `repository_stability_relations` AS `sup_rrb` ON `sup_r`.`stability`=`sup_rrb`.`less_stable`" . + " WHERE `sup_bp`.`pkgname` = `prov_bp`.`pkgname`" . + " AND `sup_bp`.`architecture` = `prov_bp`.`architecture`" . + " AND `sup_bp`.`id` != `prov_bp`.`id`" . + " AND `repositories`.`stability`=`sup_rra`.`less_stable`" . + " AND `prov_r`.`stability`=`sup_rrb`.`more_stable`" . + " AND `prov_r`.`architecture`=`sup_r`.`architecture`" . + ")" . + ")" . + $ignore . + " ORDER BY `binary_packages_in_repositories`.`is_to_be_deleted`,`binary_packages`.`pkgname`,`install_targets`.`name`" . + $limit + ); + + if ($result -> num_rows > 10000) + print " Found >10000 stability issues.<br>\n"; + else + print " Found " . $result -> num_rows . " stability issues.<br>\n"; + + while ( $row = $result -> fetch_assoc() ) { + if ($row["is_to_be_deleted"]==1) + print " <font color=\"#00ff00\">(marked as to-be-deleted) "; + else + print " <font color=\"#800000\">"; + print $row["pkgfile"] . " depends on " . htmlspecialchars($row["install_target"]) . " which is not provided by any package installable from enabled " . $row["stability"] . " repositories.<br>"; + print "</font>\n"; + unset($row); + } + + ob_end_flush(); + +?> + </body> +</html> diff --git a/buildmaster/statistics.php b/buildmaster/statistics.php new file mode 100644 index 0000000..4f2398b --- /dev/null +++ b/buildmaster/statistics.php @@ -0,0 +1,200 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + +if (array_key_exists("from",$_GET)) + $min_time="from_base64(\"" . base64_encode("-".$_GET["from"]) . "\")"; +else + $min_time="\"-7 00:00:00\""; + +if (array_key_exists("arch",$_GET)) { + $arch_filter="`architectures`.`name` IN (\"\""; + foreach (explode("&",$_SERVER["QUERY_STRING"]) as $param) { + if (strpos($param,"arch=")!==0) + continue; + $arch_filter .= ",from_base64(\"" . base64_encode(substr($param,5)) . "\")"; + } + $arch_filter .= ")"; + $combiner_left=""; + $combiner_right=""; + $grouper=""; + $joiner=" JOIN `architectures` ON `statistics`.`architecture`=`architectures`.`id`"; +} else { + $arch_filter="1"; + $combiner_left="SUM("; + $combiner_right=")"; + $grouper=" GROUP BY `statistics`.`date`"; + $joiner=""; +}; + +$column_list = array( + "pending_tasks_count", + "pending_packages_count", + "staging_packages_count", + "testing_packages_count", + "tested_packages_count", + "broken_tasks_count", + "dependency_loops_count", + "dependency_looped_tasks_count", + "locked_tasks_count", + "blocked_tasks_count", + "next_tasks_count" +); + +function combine_column($name) { + global $combiner_left; + global $combiner_right; + return $combiner_left . "`statistics`.`" . $name . "`" . $combiner_right . " AS `" . $name . "`"; +} + +$result = mysql_run_query( + "SELECT DISTINCT ". + "UNIX_TIMESTAMP(`statistics`.`date`) AS `date`," . + implode(",",array_map("combine_column",$column_list)) . + "FROM `statistics` " . + $joiner . + "WHERE `statistics`.`date`>=ADDDATE(NOW()," . $min_time . ") " . + "AND " . $arch_filter . + $grouper . + "ORDER BY `statistics`.`date`" +); + +$t_min = -1; +$t_max = -1; +$val_max = -1; + +while($vals = $result->fetch_assoc()) { + if ($t_min == -1) + $t_min = $vals["date"]; + $t_max = $vals["date"]; + foreach ($vals as $column => $val) + if ($column != "date") { + $values[$column][$vals["date"]] = $val; + $val_max = max($val_max,$val); + } +}; +$print_columns = array_keys($values); + +$max_len = 0; +foreach ($print_columns as $column) { + $len = strlen($values[$column][$t_max])+1; + if ($len > $max_len) + $max_len = $len; +} + +$width = 1600; +$height = 600; +$border = 5; +$legend_line_length = 10; +$legend_height = 2 * ImageFontHeight(5) + $legend_line_length; + +$im = @ImageCreate ($width + $legend_line_length + $max_len * ImageFontWidth(5), $height + $legend_height) + or die ("Cannot create new gd-image-stream"); + +$background_color = ImageColorAllocate ($im, 255, 255, 255); +$foreground_color = ImageColorAllocate ($im, 0, 0, 0); + +$colors['stable_packages_count'] = ImageColorAllocate ($im, 0, 0, 0); +$colors['pending_tasks_count'] = ImageColorAllocate ($im, 0, 0, 128); +$colors['pending_packages_count'] = ImageColorAllocate ($im, 0, 0, 255); +$colors['staging_packages_count'] = ImageColorAllocate ($im, 0, 100, 0); +$colors['testing_packages_count'] = ImageColorAllocate ($im, 0, 200, 0); +$colors['tested_packages_count'] = ImageColorAllocate ($im, 100, 255, 0); +$colors['broken_tasks_count'] = ImageColorAllocate ($im, 255, 0, 0); +$colors['dependency_loops_count'] = ImageColorAllocate ($im, 128, 128, 0); +$colors['dependency_looped_tasks_count'] = ImageColorAllocate ($im, 255, 128, 128); +$colors['locked_tasks_count'] = ImageColorAllocate ($im, 128, 128, 128); +$colors['blocked_tasks_count'] = ImageColorAllocate ($im, 128, 0, 0); +$colors['next_tasks_count'] = ImageColorAllocate ($im, 0, 255, 255); + +function scale($x, $x_min, $x_max, $scale, $log) { + if ($log) { + $x = log($x + 10); + $x_min = log($x_min + 10); + $x_max = log($x_max + 10); + }; + if ($x_max == $x_min) + $frac = 0; + else + $frac = ($x - $x_min)/($x_max - $x_min); + if ($scale < 0) + return ($frac-1) * $scale; + else + return $frac * $scale; +}; + +function print_graph($data, $color) { + global $width, $height, $im, $t_min, $t_max, $val_max, $border, $legend_line_length; + ksort($data); + $last_t = -1; + $last_val = -1; + foreach ($data as $t => $val) { + if ($last_t != -1) + ImageLine( + $im, + scale($last_t,$t_min,$t_max,$width-2*$border,false)+$border+$legend_line_length, + scale($last_val,0,$val_max,-$height+2*$border,isset($_GET["log"]))+$border, + scale($t,$t_min,$t_max,$width-2*$border,false)+$border+$legend_line_length, + scale($val,0,$val_max,-$height+2*$border,isset($_GET["log"]))+$border, + $color + ); + $last_t = $t; + $last_val = $val; + } + ImageString( + $im, + 5, + $width+$legend_line_length, + scale($last_val,0,$val_max,-$height+2*$border,isset($_GET["log"]))+$border - ImageFontHeight(5)/2, + " ".$data[$t_max], + $color + ); +}; + +ImageRectangle($im, $legend_line_length, 0, $width-1+$legend_line_length, $height-1, $foreground_color); + +$xpos = $legend_line_length; +foreach ($print_columns as $column) { + print_graph($values[$column], $colors[$column]); + ImageString($im, 5, $xpos, $height + $legend_line_length + ImageFontHeight(5), substr($column,0,-strlen("_count")), $colors[$column]); + $xpos += (strlen($column) - strlen("_count") + 1.75) * ImageFontWidth(5); +} + +ImageString($im, 5, $legend_line_length, $height + $legend_line_length, date('Y-m-d H:i', $t_min), $foreground_color); +$s = date('Y-m-d H:i', $t_max); +ImageString($im, 5, $width+$legend_line_length - strlen($s)*ImageFontWidth(5), $height + $legend_line_length, $s, $foreground_color); + +for ($t=ceil($t_min/24/60/60); $t<=floor($t_max/24/60/60); $t++) + ImageLine( + $im, + scale($t*24*60*60,$t_min,$t_max,$width-2*$border,false)+$border+$legend_line_length, + $height, + scale($t*24*60*60,$t_min,$t_max,$width-2*$border,false)+$border+$legend_line_length, + $height+$legend_line_length, + $foreground_color + ); + +for ($val=0; $val<=$val_max;) { + ImageLine( + $im, + 0, + scale($val,0,$val_max,-$height+2*$border,isset($_GET["log"]))+$border, + $legend_line_length, + scale($val,0,$val_max,-$height+2*$border,isset($_GET["log"]))+$border, + $foreground_color + ); + if (! isset($_GET["log"])) + $val+=pow(10,round(log($val_max)/log(10))-1); + elseif ($val==0) + $val++; + else + $val=$val*10; +} + +// ImageString ($im, 1, 5, 5, "Test-String ".rand(), $foreground_color); + +header ("Content-type: image/png"); + +ImagePNG ($im); + +?> diff --git a/buildmaster/status.php b/buildmaster/status.php new file mode 100644 index 0000000..05a4455 --- /dev/null +++ b/buildmaster/status.php @@ -0,0 +1,144 @@ +<?php +require_once "../init.php"; +include BASE . "/lib/mysql.php"; +include BASE . "/lib/style.php"; +include BASE . "/lib/helper.php"; + +$result = mysql_run_query( + "SELECT MAX(`package_sources`.`commit_time`) AS `last_commit`" . + " FROM `package_sources`" +); + +if ($result -> num_rows > 0) { + $result = $result->fetch_assoc(); + $last_commit = $result["last_commit"]; +} + +$result = mysql_run_query( + "SELECT MAX(`build_assignments`.`return_date`) AS `last_return`" . + " FROM `build_assignments`" +); + +if ($result -> num_rows > 0) { + $result = $result->fetch_assoc(); + $last_return = $result["last_return"]; +} + +$result = mysql_run_query( + "SELECT MAX(`binary_packages_in_repositories`.`last_moved`) AS `last_moved`" . + " FROM `binary_packages`" . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_build_assignments() . + " WHERE `binary_packages_in_repositories`.`last_moved`>`build_assignments`.`return_date`" +); + +if ($result -> num_rows > 0) { + $result = $result->fetch_assoc(); + $last_moved = $result["last_moved"]; +} + +$age_queries = array( + array( + "label" => "age of build-list-packages", + "column" => "`package_sources`.`commit_time`", + "table" => + "`package_sources`" . + " JOIN (" . + "SELECT " . + "`build_assignments`.`package_source`" . + " FROM `build_assignments`" . + mysql_join_build_assignments_binary_packages() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + " WHERE `repositories`.`name`=\"build-list\"" . + " AND `build_assignments`.`is_blocked` IS NULL" . + " GROUP BY `build_assignments`.`package_source`" . + ") AS `build_assignments_grouped`" . + " ON `build_assignments_grouped`.`package_source`=`package_sources`.`id`" + ), + array( + "label" => "age of staging-packages", + "column" => "`binary_packages_in_repositories`.`first_last_moved`", + "table" => + "`binary_packages`" . + " JOIN (" . + "SELECT " . + "`binary_packages_in_repositories`.`package`," . + "MIN(`binary_packages_in_repositories`.`last_moved`) AS `first_last_moved`" . + " FROM `binary_packages_in_repositories`" . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_repository_stabilities() . + " WHERE `repository_stabilities`.`name`=\"staging\"" . + " GROUP BY `binary_packages_in_repositories`.`package`" . + ") AS `binary_packages_in_repositories`" . + " ON `binary_packages_in_repositories`.`package`=`binary_packages`.`id`" + ), + array( + "label" => "age of testing-packages", + "column" => "`binary_packages_in_repositories`.`first_last_moved`", + "table" => + "`binary_packages`" . + " JOIN (" . + "SELECT " . + "`binary_packages_in_repositories`.`package`," . + "MIN(`binary_packages_in_repositories`.`last_moved`) AS `first_last_moved`" . + " FROM `binary_packages_in_repositories`" . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_repository_stabilities() . + " WHERE `repository_stabilities`.`name`=\"testing\"" . + " GROUP BY `binary_packages_in_repositories`.`package`" . + ") AS `binary_packages_in_repositories`" . + " ON `binary_packages_in_repositories`.`package`=`binary_packages`.`id`" . + " WHERE NOT `binary_packages`.`has_issues`" . + " AND NOT `binary_packages`.`is_tested`" + ), + array( + "label" => "age of tested-packages", + "column" => "`binary_packages_in_repositories`.`first_last_moved`", + "table" => + "`binary_packages`" . + " JOIN (" . + "SELECT " . + "`binary_packages_in_repositories`.`package`," . + "MIN(`binary_packages_in_repositories`.`last_moved`) AS `first_last_moved`" . + " FROM `binary_packages_in_repositories`" . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_repository_stabilities() . + " WHERE `repository_stabilities`.`name`=\"testing\"" . + " GROUP BY `binary_packages_in_repositories`.`package`" . + ") AS `binary_packages_in_repositories`" . + " ON `binary_packages_in_repositories`.`package`=`binary_packages`.`id`" + ) +); + +foreach ($age_queries as $age_query) { + $result = mysql_run_query( + "SELECT " . + "AVG(UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(" . $age_query["column"] . ")) AS `avg`," . + "STDDEV(UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(" . $age_query["column"] . ")) AS `stddev`" . + " FROM " . $age_query["table"] + ); + if ($result -> num_rows > 0) { + $result = $result->fetch_assoc(); + foreach ($result as $key => $val) + $ages[$age_query["label"]][$key] = format_time_duration($val); + }; +}; + +print_header("Build Master Status"); + +if (isset($last_commit)) + print " latest package source is from " . $last_commit . ".<br>\n"; + +if (isset($last_return)) + print " latest built package is from " . $last_return . ".<br>\n"; + +if (isset($last_moved)) + print " latest package move was on " . $last_moved . ".<br>\n"; + +foreach ($ages as $label => $value) + print " " . $label . ": " . + $value["avg"] . " ± " . + $value["stddev"] . ".<br>\n"; + +print_footer(); diff --git a/buildmaster/to-delete.php b/buildmaster/to-delete.php new file mode 100644 index 0000000..df11750 --- /dev/null +++ b/buildmaster/to-delete.php @@ -0,0 +1,77 @@ +<?php +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + + $result = mysql_run_query( + "SELECT " . + "`repositories`.`name` AS `repo`," . + "`binary_packages`.`pkgname`," . + "`binary_packages`.`epoch`," . + "`binary_packages`.`pkgver`," . + "`binary_packages`.`pkgrel`," . + "`binary_packages`.`sub_pkgrel`," . + "`architectures`.`name` AS `arch`" . + " FROM `binary_packages`" . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + "WHERE `binary_packages_in_repositories`.`is_to_be_deleted` " . + "AND `repositories`.`is_on_master_mirror`" + ); + + $available = explode( + "\n", + shell_exec("find /var/lib/pacman/ -name '*.db' -exec tar -tzf {} \; | sed -n 's,-[^-]\+-[^-]\+/$,,;T;p'") + ); + $available = array_combine( $available, $available); +?> +<html> +<head> +<title>List of packages to be deleted</title> +<link rel="stylesheet" type="text/css" href="/static/style.css"> +</head> +<body> +<?php + +show_warning_on_offline_slave(); + +if ($result -> num_rows > 0) { + + $count = 0; + + while ($row = $result->fetch_assoc()) { + + if (isset($available[$row["pkgname"]])) + $color = "#FF0000"; + else + $color = "#00FF00"; + + $rows[$count] = + "<font color=\"" . $color . "\">" . + $row["repo"] . "/" . + $row["pkgname"] . "-"; + if ($row["epoch"] != "0") + $rows[$count] = + $rows[$count] . + $row["epoch"] . ":"; + $rows[$count] = + $rows[$count] . + $row["pkgver"] . "-" . + $row["pkgrel"] . "." . + $row["sub_pkgrel"] . "-" . + $row["arch"] . ".pkg.tar.xz</font>"; + $count++; + } + + sort($rows); + + foreach ($rows as $row) { + print $row."<br>\n"; + } +} else { + print "No packages are to be deleted.\n"; +} + +?> +</body> +</html> diff --git a/buildmaster/todos.php b/buildmaster/todos.php new file mode 100644 index 0000000..bf77f08 --- /dev/null +++ b/buildmaster/todos.php @@ -0,0 +1,97 @@ +<?php +require_once "../init.php"; + +include BASE . "/lib/helper.php"; +include BASE . "/lib/mysql.php"; + +$result = mysql_run_query( + "SELECT DISTINCT " . + "`todos`.`id`," . + "`todos`.`file`," . + "`todos`.`line`," . + "`todos`.`description` " . + "FROM `todos`;" +); + +if (isset($_GET["graph"])) { + + if ($result -> num_rows > 0) { + + while ($row = $result->fetch_assoc()) + $knot_rows[$row["id"]] = + $row["file"]. " (line ".$row["line"].") #".$row["id"].":\\n". + str_replace("\"","\\\"",$row["description"]); + + $knots=""; + foreach ($knot_rows as $knot) + $knots=$knots . "\"" . $knot . "\";\n"; + + } + + $result = mysql_run_query( + "SELECT DISTINCT " . + "`todo_links`.`dependent`," . + "`todo_links`.`depending_on` " . + "FROM `todo_links`;" + ); + + if ($result -> num_rows > 0) { + $count = 0; + while ($row = $result->fetch_assoc()) { + $link_rows[$count]["dependent"] = + $knot_rows[$row["dependent"]]; + $link_rows[$count]["depending_on"] = + $knot_rows[$row["depending_on"]]; + $count++; + } + + $edges=""; + foreach ($link_rows as $link) + $edges=$edges . "\"" . $link["depending_on"] . "\" -> \"" . $link["dependent"] . "\";\n"; + } + + header ("Content-type: image/png"); + passthru( + "echo \"" . base64_encode( + "digraph dependencies {\n" . + "rankdir=LR;\n" . + "fontname=dejavu;\n" . + $knots . + $edges . + "}\n" + ) . "\" | " . + "base64 -d | " . + "timeout 30 dot -Tpng -o/dev/stdout /dev/stdin" + ); + +} else { // isset($_GET["graph"]) + + if ($result -> num_rows > 0) { + + print "<html>\n"; + print "<head>\n"; + print "<title>Todos in the build scripts</title>\n"; + print "</head>\n"; + print "<body>\n"; + show_warning_on_offline_slave(); + + while ($row = $result->fetch_assoc()) { + print "<a href=\"#TODO" . $row["id"] . "\" name=\"TODO" . $row["id"] ."\">TODO #" . $row["id"] . "</a>"; + print " - "; + print "<a href=\""; + print git_url("builder","tree","master",$row["file"],$row["line"]); + print "\">" . $row["file"] . "(line " . $row["line"] . ")</a>"; + print ":<br>\n"; + print str_replace("\\n","<br>\n",$row["description"]); + print "<br>\n"; + print "<br>\n"; + } + + print "</body>\n"; + print "</html>\n"; + + } + +} + +?> diff --git a/init.php b/init.php new file mode 100644 index 0000000..6c8a8f4 --- /dev/null +++ b/init.php @@ -0,0 +1,2 @@ +<?php +define("BASE", __DIR__); diff --git a/lib/.htaccess b/lib/.htaccess new file mode 100644 index 0000000..3a42882 --- /dev/null +++ b/lib/.htaccess @@ -0,0 +1 @@ +Deny from all diff --git a/lib/format.php b/lib/format.php new file mode 100644 index 0000000..00e8296 --- /dev/null +++ b/lib/format.php @@ -0,0 +1,58 @@ +<?php + +# do not include twice +if (function_exists("export_as_requested")) + return; + +require_once "../init.php"; +include_once BASE . "/lib/http.php"; + +function export_as_requested($content) { + if (isset($content["All"])) { + $content["json"]=$content["All"]; + $content["tsv"]=$content["All"]; + unset($content["All"]); + } + if (isset($content["json"]) && isset($_GET["json"])) { + header ("Content-type: application/json"); + print json_encode( + $content["json"], + JSON_UNESCAPED_SLASHES + ); + } elseif (isset($content["tsv"]) && isset($_GET["tsv"])) { + header ("Content-type: text/tab-separated-values"); + if (! isset($_GET["no-headers"])) + print implode("\t",array_keys($content["tsv"][0])) . "\n"; + print implode( + "", + array_map( + function($row){ + return implode("\t",$row) . "\n"; + }, + $content["tsv"] + ) + ); + } else { + throw_http_error( + 406, + "Not Acceptable", + implode( + "<br>\n", + array_merge( + array( + "Unknown output format.", + "Accepted:" + ), + array_map( + function($type){ + return "<a href=\"?" . $type . "\">" . $type . "</a>"; + }, + array_keys( + $content + ) + ) + ) + ) + ); + } +} diff --git a/lib/helper.php b/lib/helper.php new file mode 100644 index 0000000..8296cd9 --- /dev/null +++ b/lib/helper.php @@ -0,0 +1,195 @@ +<?php + +# do not include twice +if (function_exists("format_time_duration")) + return; + +require_once "../init.php"; + +function format_time_duration($val) { + $val = floor($val); + $result = ""; + $result = + sprintf( + "%02d", + $val % 60 + ); + $val = floor($val / 60); + if ($val == 0) + return $result; + $result = + sprintf( + "%02d:%s", + $val % 60, + $result + ); + $val = floor($val / 60); + if ($val == 0) + return $result; + $result = + sprintf( + "%d:%s", + $val % 24, + $result + ); + $val = floor($val / 24); + if ($val == 0) + return $result; + $tmp = $val % 7; + $printed_conjunction = true; + if ($tmp > 1) + $result = + sprintf( + "%d days and %s", + $tmp, + $result + ); + elseif ($tmp == 1) + $result = + sprintf( + "%d day and %s", + $tmp, + $result + ); + else + $printed_conjunction = false; + $val = floor($val / 7); + if ($val == 0) + return $result; + if ($printed_conjunction) + $result = + sprintf( + ", %s", + $result + ); + else + $result = + sprintf( + " and %s", + $result + ); + if ($val>1) + $result = + sprintf( + "%d weeks%s", + $val, + $result + ); + else + $result = + sprintf( + "%d week%s", + $val, + $result + ); + return $result; +}; + +function git_url($repository,$type,$commit,$path,$line = null,$commit_is_hash = null) { + global $git_available; + if (!isset($git_available)) { + $memcache = new Memcache; + $memcache->connect('localhost', 11211) or die ('Memcached Connection Error'); + $git_available = $memcache->get('git_available'); + if ($git_available === false) { + $git_available = + preg_match( + "/ 200 OK$/", + get_headers("https://git.archlinux32.org/archlinux32/packages")[0] + ); + $memcache->set('git_available',$git_available,0,120); + }; + $git_available = $git_available == 1; + } + if (!isset($commit_is_hash)) + $commit_is_hash = preg_match("/^[0-9a-f]{40}$/",$commit)==1; + if ($git_available) { + if (isset($line)) + $line = "#L" . $line; + else + $line = ""; + if ($commit_is_hash) + $commit = "commit/" . $commit; + else + $commit = "branch/" . $commit; + switch ($type) { + case "tree": + return + "https://git.archlinux32.org/archlinux32/" . + $repository . + "/src/" . + $commit . + "/" . + $path . + $line; + case "log": + return + "https://git.archlinux32.org/archlinux32/" . + $repository . + "/commits/" . + $commit . + "/" . + $path . + $line; + } + + } else { + if (isset($line)) + $line = "#n" . $line; + else + $line = ""; + if ($commit_is_hash) + $commit = "?id=" . $commit; + else + $commit = "?h=" . $commit; + switch ($type) { + case "tree": + return + "https://git2.archlinux32.org/Archlinux32/" . + $repository . + "/tree/" . + $path . + $commit . + $line; + case "log": + return + "https://git2.archlinux32.org/Archlinux32/" . + $repository . + "/log/" . + $path . + $commit . + $line; + } + }; +}; + +function if_unset($array, $index, $default) { + if (isset($array[$index])) + return $array[$index]; + else + return $default; +}; + +function site_is_reachable($url) { + $scd = stream_context_get_default(); + stream_context_set_default(array('timeout' => 10)); + $headers = get_headers($url); + stream_context_set_default($scd); + if (is_array($headers)) + foreach ($headers as $header) { + if (!(strpos($header, 'HTTP/') === 0)) + continue; + if (explode(' ', $header)[1] == '200') + return true; + return false; + } + return false; +} + +function add_fancy_unit($value, $unit) { + $suffixes = array("z", "y", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "Y", "Z"); + if ($value==0) + return $value . " " . $unit; + $exponent = max(0,min(count($suffixes)-1,round(log(abs($value))/log(1024)-1))); + return sprintf("%.2f %s%s", $value / pow(1024,$exponent), $suffixes[8 + $exponent], $unit); +} diff --git a/lib/http.php b/lib/http.php new file mode 100644 index 0000000..9b63337 --- /dev/null +++ b/lib/http.php @@ -0,0 +1,17 @@ +<?php + +# do not include twice +if (function_exists("throw_http_error")) + return; + +function throw_http_error($error_number, $error_message, $extra_message = "") { + header("Status: " . $error_number . " " . $error_message); + print "Error " . $error_number . ": " . $error_message . "\n"; + if ($extra_message != "") + print "<br>\n" . $extra_message; + die(); +}; + +function die_500($message) { + throw_http_error(500, "Internal Server Error", $message); +}; diff --git a/lib/mysql-joins.php b/lib/mysql-joins.php new file mode 100644 index 0000000..751f1a0 --- /dev/null +++ b/lib/mysql-joins.php @@ -0,0 +1,1438 @@ +<?php + +/** + * generate below content with + * php mysql-joins.php + * executed from the builder directory + **/ + +if (!isset($_SERVER["SERVER_ADDR"])) { + foreach (array('.', '../builder', '../../builder') as $base_dir) + if (file_exists($base_dir . '/lib/mysql-functions')) { + putenv('base_dir=' . $base_dir); + break; + } + $new_output = + "\n" . + trim( + shell_exec( + '. ${base_dir}/lib/mysql-functions;' . + 'declare -f $(' . + 'declare -F | cut -d" " -f3 | grep "^mysql_join_[a-z]" | grep -v "with_version"' . + ')' + ) + ); + $output = ""; + $i = 5; + while ((strcmp($new_output,$output)!=0) && ($i > 0)) { + $output = $new_output; + $new_output = + preg_replace( + array( + '/ \[ -n "([^"]+)" \]; then/', + '/(\n\s*printf '."'[^'%]*)%s([^']*'".') "(\$[0-9]+)"/', + '/(\n\s*if [^\n]*)(\n([^\n]*;\n)+\s*)(else)(\n([^\n]*;\n)+\s*)fi;?\n/', + '/(\n\s*if [^\n]*)(\n([^\n]*;\n)+\s*)fi;?\n/' + ), + array( + ' (!empty(\1))', + '\1'."'".'.\3.'."'".'\2', + '\1 {\2} \4 {\5}'."\n", + '\1 {\2}'."\n" + ), + $output + ); + $i--; + } + $output = + preg_replace( + array( + '/\$1/', + '/\$2/', + '/(\n)(\S+) \(\)\s*\n{/', + '/(\n})/', + '/(\s)printf(\s)/' + ), + array( + '$table_left', + '$table_right', + '\1function \2 ($table_left="", $table_right="") {'."\n".' $result = "";', + "\n".' return $result;\1', + '\1$result .=\2' + ), + $output + ); + print $output . "\n"; + die(); +} + +// auto-generated content below + +function mysql_join_allowed_email_actions_email_actions ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `email_actions`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`action`='; + } else { + $result .= ' ON `allowed_email_actions`.`action`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`email_actions`.`id`'; + } + return $result; +} +function mysql_join_allowed_email_actions_gpg_keys ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `gpg_keys`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`gpg_key`='; + } else { + $result .= ' ON `allowed_email_actions`.`gpg_key`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`gpg_keys`.`id`'; + } + return $result; +} +function mysql_join_architectures_binary_packages ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `architectures`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`architecture`'; + } else { + $result .= '`binary_packages`.`architecture`'; + } + return $result; +} +function mysql_join_architectures_build_assignments ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_assignments`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `architectures`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`architecture`'; + } else { + $result .= '`build_assignments`.`architecture`'; + } + return $result; +} +function mysql_join_architectures_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `architectures`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`architecture`'; + } else { + $result .= '`repositories`.`architecture`'; + } + return $result; +} +function mysql_join_binary_packages_architectures ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `architectures`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`architecture`='; + } else { + $result .= ' ON `binary_packages`.`architecture`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`architectures`.`id`'; + } + return $result; +} +function mysql_join_binary_packages_binary_packages_in_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages_in_repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `binary_packages`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`package`'; + } else { + $result .= '`binary_packages_in_repositories`.`package`'; + } + return $result; +} +function mysql_join_binary_packages_build_assignments ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_assignments`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`build_assignment`='; + } else { + $result .= ' ON `binary_packages`.`build_assignment`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`build_assignments`.`id`'; + } + return $result; +} +function mysql_join_binary_packages_build_dependency_loops ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_dependency_loops`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`build_assignment`='; + } else { + $result .= ' ON `binary_packages`.`build_assignment`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`build_assignment`'; + } else { + $result .= '`build_dependency_loops`.`build_assignment`'; + } + return $result; +} +function mysql_join_binary_packages_build_slaves ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_slaves`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`build_assignment`='; + } else { + $result .= ' ON `binary_packages`.`build_assignment`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`currently_building`'; + } else { + $result .= '`build_slaves`.`currently_building`'; + } + return $result; +} +function mysql_join_binary_packages_dependencies ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `dependencies`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `binary_packages`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`dependent`'; + } else { + $result .= '`dependencies`.`dependent`'; + } + return $result; +} +function mysql_join_binary_packages_in_repositories_binary_packages ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`package`='; + } else { + $result .= ' ON `binary_packages_in_repositories`.`package`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`binary_packages`.`id`'; + } + return $result; +} +function mysql_join_binary_packages_in_repositories_dependencies ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `dependencies`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`package`='; + } else { + $result .= ' ON `binary_packages_in_repositories`.`package`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`dependent`'; + } else { + $result .= '`dependencies`.`dependent`'; + } + return $result; +} +function mysql_join_binary_packages_in_repositories_install_target_providers ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `install_target_providers`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`package`='; + } else { + $result .= ' ON `binary_packages_in_repositories`.`package`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`package`'; + } else { + $result .= '`install_target_providers`.`package`'; + } + return $result; +} +function mysql_join_binary_packages_in_repositories_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`repository`='; + } else { + $result .= ' ON `binary_packages_in_repositories`.`repository`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`repositories`.`id`'; + } + return $result; +} +function mysql_join_binary_packages_install_target_providers ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `install_target_providers`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `binary_packages`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`package`'; + } else { + $result .= '`install_target_providers`.`package`'; + } + return $result; +} +function mysql_join_build_assignments_architectures ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `architectures`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`architecture`='; + } else { + $result .= ' ON `build_assignments`.`architecture`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`architectures`.`id`'; + } + return $result; +} +function mysql_join_build_assignments_binary_packages ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `build_assignments`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`build_assignment`'; + } else { + $result .= '`binary_packages`.`build_assignment`'; + } + return $result; +} +function mysql_join_build_assignments_build_dependency_loops ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_dependency_loops`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `build_assignments`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`build_assignment`'; + } else { + $result .= '`build_dependency_loops`.`build_assignment`'; + } + return $result; +} +function mysql_join_build_assignments_build_slaves ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_slaves`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `build_assignments`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`currently_building`'; + } else { + $result .= '`build_slaves`.`currently_building`'; + } + return $result; +} +function mysql_join_build_assignments_failed_builds ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `failed_builds`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `build_assignments`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`build_assignment`'; + } else { + $result .= '`failed_builds`.`build_assignment`'; + } + return $result; +} +function mysql_join_build_assignments_package_sources ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `package_sources`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`package_source`='; + } else { + $result .= ' ON `build_assignments`.`package_source`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`package_sources`.`id`'; + } + return $result; +} +function mysql_join_build_dependency_loops_binary_packages ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`build_assignment`='; + } else { + $result .= ' ON `build_dependency_loops`.`build_assignment`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`build_assignment`'; + } else { + $result .= '`binary_packages`.`build_assignment`'; + } + return $result; +} +function mysql_join_build_dependency_loops_build_assignments ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_assignments`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`build_assignment`='; + } else { + $result .= ' ON `build_dependency_loops`.`build_assignment`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`build_assignments`.`id`'; + } + return $result; +} +function mysql_join_build_slaves_binary_packages ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`currently_building`='; + } else { + $result .= ' ON `build_slaves`.`currently_building`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`build_assignment`'; + } else { + $result .= '`binary_packages`.`build_assignment`'; + } + return $result; +} +function mysql_join_build_slaves_build_assignments ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_assignments`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`currently_building`='; + } else { + $result .= ' ON `build_slaves`.`currently_building`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`build_assignments`.`id`'; + } + return $result; +} +function mysql_join_build_slaves_failed_builds ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `failed_builds`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `build_slaves`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`build_slave`'; + } else { + $result .= '`failed_builds`.`build_slave`'; + } + return $result; +} +function mysql_join_build_slaves_ssh_keys ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `ssh_keys`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`ssh_key`='; + } else { + $result .= ' ON `build_slaves`.`ssh_key`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`ssh_keys`.`id`'; + } + return $result; +} +function mysql_join_build_slaves_ssh_log ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `ssh_log`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `build_slaves`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`build_slave`'; + } else { + $result .= '`ssh_log`.`build_slave`'; + } + return $result; +} +function mysql_join_dependencies_binary_packages ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`dependent`='; + } else { + $result .= ' ON `dependencies`.`dependent`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`binary_packages`.`id`'; + } + return $result; +} +function mysql_join_dependencies_binary_packages_in_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages_in_repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`dependent`='; + } else { + $result .= ' ON `dependencies`.`dependent`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`package`'; + } else { + $result .= '`binary_packages_in_repositories`.`package`'; + } + return $result; +} +function mysql_join_dependencies_dependency_types ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `dependency_types`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`dependency_type`='; + } else { + $result .= ' ON `dependencies`.`dependency_type`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`dependency_types`.`id`'; + } + return $result; +} +function mysql_join_dependencies_install_target_providers ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `install_target_providers`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`depending_on`='; + } else { + $result .= ' ON `dependencies`.`depending_on`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`install_target`'; + } else { + $result .= '`install_target_providers`.`install_target`'; + } + return $result; +} +function mysql_join_dependencies_install_targets ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `install_targets`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`depending_on`='; + } else { + $result .= ' ON `dependencies`.`depending_on`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`install_targets`.`id`'; + } + return $result; +} +function mysql_join_dependencies_versions ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `versions`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`version`='; + } else { + $result .= ' ON `dependencies`.`version`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`versions`.`id`'; + } + return $result; +} +function mysql_join_dependency_types_dependencies ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `dependencies`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `dependency_types`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`dependency_type`'; + } else { + $result .= '`dependencies`.`dependency_type`'; + } + return $result; +} +function mysql_join_email_actions_allowed_email_actions ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `allowed_email_actions`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `email_actions`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`action`'; + } else { + $result .= '`allowed_email_actions`.`action`'; + } + return $result; +} +function mysql_join_email_actions_email_log ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `email_log`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `email_actions`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`action`'; + } else { + $result .= '`email_log`.`action`'; + } + return $result; +} +function mysql_join_email_log_email_actions ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `email_actions`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`action`='; + } else { + $result .= ' ON `email_log`.`action`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`email_actions`.`id`'; + } + return $result; +} +function mysql_join_email_log_gpg_keys ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `gpg_keys`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`gpg_key`='; + } else { + $result .= ' ON `email_log`.`gpg_key`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`gpg_keys`.`id`'; + } + return $result; +} +function mysql_join_fail_reasons_failed_builds ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `failed_builds`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `fail_reasons`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`reason`'; + } else { + $result .= '`failed_builds`.`reason`'; + } + return $result; +} +function mysql_join_failed_builds_build_assignments ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_assignments`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`build_assignment`='; + } else { + $result .= ' ON `failed_builds`.`build_assignment`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`build_assignments`.`id`'; + } + return $result; +} +function mysql_join_failed_builds_build_slaves ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_slaves`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`build_slave`='; + } else { + $result .= ' ON `failed_builds`.`build_slave`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`build_slaves`.`id`'; + } + return $result; +} +function mysql_join_failed_builds_fail_reasons ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `fail_reasons`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`reason`='; + } else { + $result .= ' ON `failed_builds`.`reason`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`fail_reasons`.`id`'; + } + return $result; +} +function mysql_join_git_repositories_upstream_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `upstream_repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `git_repositories`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`git_repository`'; + } else { + $result .= '`upstream_repositories`.`git_repository`'; + } + return $result; +} +function mysql_join_gpg_keys_allowed_email_actions ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `allowed_email_actions`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `gpg_keys`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`gpg_key`'; + } else { + $result .= '`allowed_email_actions`.`gpg_key`'; + } + return $result; +} +function mysql_join_gpg_keys_email_log ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `email_log`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `gpg_keys`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`gpg_key`'; + } else { + $result .= '`email_log`.`gpg_key`'; + } + return $result; +} +function mysql_join_gpg_keys_persons ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `persons`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`owner`='; + } else { + $result .= ' ON `gpg_keys`.`owner`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`persons`.`id`'; + } + return $result; +} +function mysql_join_install_target_providers_binary_packages ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`package`='; + } else { + $result .= ' ON `install_target_providers`.`package`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`binary_packages`.`id`'; + } + return $result; +} +function mysql_join_install_target_providers_binary_packages_in_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages_in_repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`package`='; + } else { + $result .= ' ON `install_target_providers`.`package`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`package`'; + } else { + $result .= '`binary_packages_in_repositories`.`package`'; + } + return $result; +} +function mysql_join_install_target_providers_dependencies ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `dependencies`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`install_target`='; + } else { + $result .= ' ON `install_target_providers`.`install_target`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`depending_on`'; + } else { + $result .= '`dependencies`.`depending_on`'; + } + return $result; +} +function mysql_join_install_target_providers_install_targets ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `install_targets`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`install_target`='; + } else { + $result .= ' ON `install_target_providers`.`install_target`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`install_targets`.`id`'; + } + return $result; +} +function mysql_join_install_target_providers_versions ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `versions`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`version`='; + } else { + $result .= ' ON `install_target_providers`.`version`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`versions`.`id`'; + } + return $result; +} +function mysql_join_install_targets_dependencies ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `dependencies`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `install_targets`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`depending_on`'; + } else { + $result .= '`dependencies`.`depending_on`'; + } + return $result; +} +function mysql_join_install_targets_install_target_providers ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `install_target_providers`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `install_targets`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`install_target`'; + } else { + $result .= '`install_target_providers`.`install_target`'; + } + return $result; +} +function mysql_join_package_sources_build_assignments ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_assignments`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `package_sources`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`package_source`'; + } else { + $result .= '`build_assignments`.`package_source`'; + } + return $result; +} +function mysql_join_package_sources_repository_moves ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `repository_moves`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`upstream_package_repository`='; + } else { + $result .= ' ON `package_sources`.`upstream_package_repository`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`upstream_package_repository`'; + } else { + $result .= '`repository_moves`.`upstream_package_repository`'; + } + return $result; +} +function mysql_join_package_sources_toolchain_order ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `toolchain_order`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`pkgbase`='; + } else { + $result .= ' ON `package_sources`.`pkgbase`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`pkgbase`'; + } else { + $result .= '`toolchain_order`.`pkgbase`'; + } + return $result; +} +function mysql_join_package_sources_upstream_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `upstream_repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`upstream_package_repository`='; + } else { + $result .= ' ON `package_sources`.`upstream_package_repository`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`upstream_repositories`.`id`'; + } + return $result; +} +function mysql_join_persons_gpg_keys ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `gpg_keys`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `persons`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`owner`'; + } else { + $result .= '`gpg_keys`.`owner`'; + } + return $result; +} +function mysql_join_persons_ssh_keys ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `ssh_keys`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `persons`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`owner`'; + } else { + $result .= '`ssh_keys`.`owner`'; + } + return $result; +} +function mysql_join_repositories_architectures ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `architectures`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`architecture`='; + } else { + $result .= ' ON `repositories`.`architecture`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`architectures`.`id`'; + } + return $result; +} +function mysql_join_repositories_binary_packages_in_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `binary_packages_in_repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `repositories`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`repository`'; + } else { + $result .= '`binary_packages_in_repositories`.`repository`'; + } + return $result; +} +function mysql_join_repositories_repository_stabilities ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `repository_stabilities`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`stability`='; + } else { + $result .= ' ON `repositories`.`stability`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`repository_stabilities`.`id`'; + } + return $result; +} +function mysql_join_repository_moves_package_sources ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `package_sources`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`upstream_package_repository`='; + } else { + $result .= ' ON `repository_moves`.`upstream_package_repository`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`upstream_package_repository`'; + } else { + $result .= '`package_sources`.`upstream_package_repository`'; + } + return $result; +} +function mysql_join_repository_moves_upstream_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `upstream_repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`upstream_package_repository`='; + } else { + $result .= ' ON `repository_moves`.`upstream_package_repository`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`upstream_repositories`.`id`'; + } + return $result; +} +function mysql_join_repository_stabilities_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `repository_stabilities`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`stability`'; + } else { + $result .= '`repositories`.`stability`'; + } + return $result; +} +function mysql_join_ssh_keys_build_slaves ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_slaves`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `ssh_keys`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`ssh_key`'; + } else { + $result .= '`build_slaves`.`ssh_key`'; + } + return $result; +} +function mysql_join_ssh_keys_persons ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `persons`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`owner`='; + } else { + $result .= ' ON `ssh_keys`.`owner`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`persons`.`id`'; + } + return $result; +} +function mysql_join_ssh_log_build_slaves ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `build_slaves`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`build_slave`='; + } else { + $result .= ' ON `ssh_log`.`build_slave`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`build_slaves`.`id`'; + } + return $result; +} +function mysql_join_toolchain_order_package_sources ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `package_sources`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`pkgbase`='; + } else { + $result .= ' ON `toolchain_order`.`pkgbase`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`pkgbase`'; + } else { + $result .= '`package_sources`.`pkgbase`'; + } + return $result; +} +function mysql_join_upstream_repositories_git_repositories ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `git_repositories`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`git_repository`='; + } else { + $result .= ' ON `upstream_repositories`.`git_repository`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`id`'; + } else { + $result .= '`git_repositories`.`id`'; + } + return $result; +} +function mysql_join_upstream_repositories_package_sources ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `package_sources`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `upstream_repositories`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`upstream_package_repository`'; + } else { + $result .= '`package_sources`.`upstream_package_repository`'; + } + return $result; +} +function mysql_join_upstream_repositories_repository_moves ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `repository_moves`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `upstream_repositories`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`upstream_package_repository`'; + } else { + $result .= '`repository_moves`.`upstream_package_repository`'; + } + return $result; +} +function mysql_join_versions_dependencies ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `dependencies`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `versions`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`version`'; + } else { + $result .= '`dependencies`.`version`'; + } + return $result; +} +function mysql_join_versions_install_target_providers ($table_left="", $table_right="") { + $result = ""; + $result .= ' JOIN `install_target_providers`'; + if (!empty($table_right)) { + $result .= ' AS `'.$table_right.'`'; + } + if (!empty($table_left)) { + $result .= ' ON `'.$table_left.'`.`id`='; + } else { + $result .= ' ON `versions`.`id`='; + } + if (!empty($table_right)) { + $result .= '`'.$table_right.'`.`version`'; + } else { + $result .= '`install_target_providers`.`version`'; + } + return $result; +} diff --git a/lib/mysql.php b/lib/mysql.php new file mode 100644 index 0000000..19d0dae --- /dev/null +++ b/lib/mysql.php @@ -0,0 +1,90 @@ +<?php + +# do not include twice +if (isset($mysql)) + return; + +require_once "../init.php"; +include_once BASE . "/lib/http.php"; +include_once BASE . "/lib/mysql-joins.php"; + +$mysql = new mysqli("localhost", "webserver", "empty", "buildmaster"); +if ( $mysql -> connect_error ) { + die_500( "Connection failed: " . $mysql -> connect_error ); +} + +function print_important_trace_components($call) { + return substr($call['file'], strlen(BASE)+1) . '(' . $call['line'] . ')'; +} + +function mysql_log_duration_and_trace($start) { + $start = round((microtime(true) - $start) * 1000000); + $trace = debug_backtrace(); + array_shift($trace); + // silently fail if logfile is unavailable + if (($fp = fopen(BASE . '/log', 'a')) !== false) { + flock($fp, LOCK_EX); + fwrite($fp, + date('Y-m-d H:i:s') . " " . + $start . " " . + implode(' ', array_map('print_important_trace_components', $trace)) . " - " . + $trace[0]['args'][0] . "\n" + ); + flock($fp, LOCK_UN); + fclose($fp); + } +} + +function mysql_run_query($query) { + global $mysql; + $start = microtime(true); + if ( ! $result = $mysql -> query($query) ) + die_500( "Query failed: " . $mysql -> error ); + mysql_log_duration_and_trace($start); + return $result; +} + +function mysql_prepare_query($query) { + global $mysql; + $start = microtime(true); + if ( ! $result = $mysql -> prepare($query) ) + die_500( "Prepare failed: " . $mysql -> error ); + mysql_log_duration_and_trace($start); + return $result; +} + +function show_warning_on_offline_slave() { + $result = mysql_run_query("SHOW STATUS LIKE \"Slave_running\""); + if (($result -> num_rows == 0) || + ($result -> fetch_assoc() ["Value"] != "ON")) { + print "<div><font color=\"ff0000\">The replication slave is currently not running. The database might be outdated.</font></div>\n"; + } +} + +function mysql_url_encode($input) { + return + "REPLACE(" . $input . ",\"+\",\"%2B\")"; +} + +function mysql_query_package_version($table) { + return + "CONCAT(" . + "IF(" . + "`" .$table . "`.`epoch`=\"0\"," . + "\"\"," . + "CONCAT(" . + "`" . $table . "`.`epoch`," . + "\":\"" . + ")" . + ")," . + "`" . $table . "`.`pkgver`,\"-\"," . + "`" . $table . "`.`pkgrel`," . + "IF(`" . $table . "`.`sub_pkgrel_omitted`," . + "\"\"," . + "CONCAT(" . + "\".\"," . + "`" . $table . "`.`sub_pkgrel`" . + ")" . + ")" . + ")"; +} diff --git a/lib/style.php b/lib/style.php new file mode 100644 index 0000000..29659f6 --- /dev/null +++ b/lib/style.php @@ -0,0 +1,74 @@ +<?php + +if (function_exists("print_header")) + return; + +require_once "../init.php"; +require_once BASE . "/lib/mysql.php"; + +function print_header($title) { +?> +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <title>Arch Linux 32 - <?php print $title; ?></title> + <link rel="stylesheet" type="text/css" href="/static/archweb.css" media="screen, projection" /> + <link rel="icon" type="image/x-icon" href="/static/favicon.ico" /> + <link rel="shortcut icon" type="image/x-icon" href="/static/favicon.ico" /> + <link rel="stylesheet" type="text/css" href="/static/flags/fam.47411010d402.css" media="screen, projection" /> + </head> + <body class=""> + <div id="archnavbar" class="anb-packages"> + <div id="archnavbarlogo"> + <h1><a href="/" title="Return to the main page">Arch Linux</a></h1> + </div> + <div id="archnavbarmenu"> + <ul id="archnavbarlist"> + <li id="anb-home"><a href="https://www.archlinux32.org/">Home</a></li> + <li id="anb-news"><a href="https://news.archlinux32.org/">News</a></li> + <li id="anb-packages"><a href="https://packages.archlinux32.org/">Packages</a></li> + <li id="anb-forums"><a href="https://bbs.archlinux32.org/">Forums</a></li> + <li id="anb-bugs"><a href="https://bugs.archlinux32.org/" title="Report and track bugs">Bugs</a></li> + <li id="anb-mailing-list"><a href="https://lists.archlinux.org/listinfo/arch-ports">Mailing List</a></li> + <li id="anb-download"><a href="https://www.archlinux32.org/download/" title="Get Arch Linux">Download</a></li> + <li id="anb-arch-linux-official"><a href="https://www.archlinux.org/">Arch Linux Official</a></li> + </ul> + </div> + </div> + <div id="content"> +<?php + show_warning_on_offline_slave(); +} + +function print_footer() { +?> + <div id="footer"> + <p> + Copyright © 2002-2018 <a href="mailto:jvinet@zeroflux.org" title="Contact Judd Vinet">Judd Vinet</a> and <a href="mailto:aaron@archlinux.org" title="Contact Aaron Griffin">Aaron Griffin</a>. + Copyright © 2018 <a href="mailto:arch@eckner.net" title="Contact Erich Eckner">Erich Eckner</a>. + </p> + <p> + The Arch Linux name and logo are recognized <a href="https://wiki.archlinux.org/index.php/DeveloperWiki:TrademarkPolicy" title="Arch Linux Trademark Policy">trademarks</a>. Some rights reserved. + </p> + <p> + The registered trademark Linux® is used pursuant to a sublicense from LMI, the exclusive licensee of Linus Torvalds, owner of the mark on a world-wide basis. + </p> + </div> + </div> + <script type="application/ld+json"> + { + "@context": "http://schema.org", + "@type": "WebSite", + "url": "/", + "potentialAction": { + "@type": "SearchAction", + "target": "/?q={search_term}", + "query-input": "required name=search_term" + } + } + </script> + </body> +</html> +<?php +} diff --git a/mirrors/index.php b/mirrors/index.php new file mode 100644 index 0000000..b74b25c --- /dev/null +++ b/mirrors/index.php @@ -0,0 +1,135 @@ +<?php +require_once "../init.php"; + +require_once BASE . "/lib/mysql.php"; +require_once BASE . "/lib/style.php"; + +$cutoff = 3600; + +$sorts = array( + "server" => array( + "title" => "server", + "label" => "Server", + "mysql" => "`url`" + ), + "country" => array( + "title" => "country", + "label" => "Country", + "mysql" => "`l_ms`.`country_code`" + ), + "isos" => array( + "title" => "wether isos are available", + "label" => "ISOs", + "mysql" => "`l_ms`.`isos`" + ), + "protocols" => array( + "title" => "available protocols", + "label" => "Protocols", + "mysql" => "`protocols`" + ) +); + +$query = + "SELECT " . + "GROUP_CONCAT(`l_ms`.`protocol`) AS `protocols`," . + "SUBSTRING(`l_ms`.`url`,LENGTH(`l_ms`.`protocol`)+4) AS `url`," . + "`l_ms`.`country`," . + "`l_ms`.`country_code`," . + "`l_ms`.`isos`," . + "`l_ms`.`ipv4`," . + "`l_ms`.`ipv6`" . + " FROM (" . + "SELECT " . + "`mirror_statuses`.`url`," . + "MAX(`mirror_statuses`.`start`) AS `start`" . + " FROM `mirror_statuses`" . + " WHERE `mirror_statuses`.`start` > UNIX_TIMESTAMP(NOW())-" . $cutoff . + " GROUP BY `mirror_statuses`.`url`" . + ") AS `ls`" . + " JOIN `mirror_statuses` AS `l_ms`" . + " ON `ls`.`url`=`l_ms`.`url`" . + " AND `ls`.`start`=`l_ms`.`start`" . + " GROUP BY `url`" . + " ORDER BY "; + +if (isset($_GET["sort"])) { + if (isset($sorts[$_GET["sort"]]["mysql"])) + $query .= $sorts[$_GET["sort"]]["mysql"] . ","; + elseif (isset($sorts[substr($_GET["sort"],1)]["mysql"])) + $query .= $sorts[substr($_GET["sort"],1)]["mysql"] . " DESC,"; +} + +$query .= "`url`"; + +$result = mysql_run_query( + $query +); + +$last_check = 0; +$max_count = 0; + +while($row = $result->fetch_assoc()) + $rows[] = $row; + +print_header("Mirror Overview"); + +?> + <div id="dev-mirrorlist" class="box"> + <h2>Mirror Overview</h2> + <table class="results"> + <thead> + <tr> +<?php + foreach ($sorts as $get => $sort) { + print " <th>\n"; + print " <a href=\"/mirrors/?"; + print substr(str_replace( + "&sort=".$_GET["sort"]."&", + "&", + "&".$_SERVER["QUERY_STRING"]."&" + ),1)."sort="; + if ($_GET["sort"] == $get) + print "-"; + print $get."\" title=\"Sort package by ".$sort["title"]."\">".$sort["label"]."</a>\n"; + print " </th>\n"; + } +?> + </tr> + </thead> + <tbody> +<?php + +$oddity = "odd"; +foreach ($rows as $row) { + print " <tr class=\"" . $oddity ."\">\n"; + print " <td>\n"; + print " " . $row["url"] . "\n"; + print " </td>\n"; + print " <td class=\"country\">\n"; + print " <span class=\"fam-flag fam-flag-" . $row["country_code"] . "\" title=\"" . $row["country"] . "\">\n"; + print " </span>\n"; + print " " . $row["country"] . "\n"; + print " </td>\n"; + print " <td>\n"; + if ($row["isos"]) + print " Yes\n"; + else + print " No\n"; + print " </td>\n"; + print " <td class=\"wrap\">\n"; + print " " . $row["protocols"] . "\n"; + print " </td>\n"; + print " </tr>\n"; + if ($oddity == "odd") + $oddity = "even"; + else + $oddity = "odd"; +} + +?> + </tbody> + </table> + </div> +<?php + + print_footer(); diff --git a/mirrors/status.php b/mirrors/status.php new file mode 100644 index 0000000..ddf922f --- /dev/null +++ b/mirrors/status.php @@ -0,0 +1,84 @@ +<?php +require_once "../init.php"; + +require_once BASE . "/lib/mysql.php"; +require_once BASE . "/lib/format.php"; + +$cutoff = 86400; + +$result = mysql_run_query( + "SELECT " . + "`l_ms`.`protocol`," . + "`l_ms`.`url`," . + "`l_ms`.`country`," . + "`l_ms`.`country_code`," . + "`l_ms`.`last_sync`," . + "`l_ms`.`start`," . + "AVG(IF(`a_ms`.`active`,(`a_ms`.`start`-`a_ms`.`last_sync`)/3600,NULL)) AS `delay`," . + "AVG(IF(`a_ms`.`active`,(`a_ms`.`stop`-`a_ms`.`start`)/3600,NULL)) AS `duration_avg`," . + "STD(IF(`a_ms`.`active`,(`a_ms`.`stop`-`a_ms`.`start`)/3600,NULL)) AS `duration_stddev`," . + "`l_ms`.`isos`," . + "`l_ms`.`ipv4`," . + "`l_ms`.`ipv6`," . + "`l_ms`.`active`," . + "(`l_ms`.`active` AND (`l_ms`.`start` > UNIX_TIMESTAMP(NOW()) - 3600)) AS `recently_active`," . + "AVG(IF(`a_ms`.`active`,1,0)) AS `completion_pct`," . + "COUNT(1) AS `count`" . + " FROM (" . + "SELECT " . + "`mirror_statuses`.`url`," . + "MAX(`mirror_statuses`.`start`) AS `start`" . + " FROM `mirror_statuses`" . + " WHERE `mirror_statuses`.`start` > UNIX_TIMESTAMP(NOW())-" . $cutoff . + " GROUP BY `mirror_statuses`.`url`" . + ") AS `ls`" . + " JOIN `mirror_statuses` AS `l_ms`" . + " ON `ls`.`url`=`l_ms`.`url`" . + " AND `ls`.`start`=`l_ms`.`start`" . + " JOIN `mirror_statuses` AS `a_ms`" . + " ON `a_ms`.`url`=`l_ms`.`url`" . + " AND `a_ms`.`start` > UNIX_TIMESTAMP(NOW())-" . $cutoff . + " GROUP BY `l_ms`.`id`" +); + +$last_check = 0; +$max_count = 0; + +while($row = $result->fetch_assoc()) { + foreach (array( + "start", + "delay", + "duration_avg", + "duration_stddev", + "completion_pct", + "count", + "isos", + "ipv4", + "ipv6", + "active", + "recently_active" + ) as $key) + $row[$key] = floatval($row[$key]); + $row["last_sync"] = gmdate("Y-m-d\TH:i:s\Z", $row["last_sync"]); + $row["score"] = + ($row["delay"] + $row["duration_avg"] + $row["duration_stddev"]) / $row["completion_pct"]; + $urls[] = $row; + $last_check = max ($row["start"], $last_check); + $max_count = max ($row["count"], $max_count); +} + +$content = array( + "cutoff" => $cutoff, + "check_frequency" => $cutoff/$max_count, + "num_checks" => $max_count, + "last_check" => gmdate("Y-m-d\TH:i:s.v\Z",$last_check), //"2018-06-15T07:25:06.741Z", +// "version" => 3, + "urls" => $urls +); + +export_as_requested( + array( + "json" => $content, + "tsv" => $urls + ) +); diff --git a/packages/favicon.ico b/packages/favicon.ico Binary files differnew file mode 100644 index 0000000..8ef6f13 --- /dev/null +++ b/packages/favicon.ico diff --git a/packages/index.php b/packages/index.php new file mode 100644 index 0000000..1d3acca --- /dev/null +++ b/packages/index.php @@ -0,0 +1,532 @@ +<?php +require_once "../init.php"; + +require_once BASE . "/lib/mysql.php"; +require_once BASE . "/lib/style.php"; +require_once BASE . "/lib/format.php"; + + + foreach (array("bugs","sort","del","uses_upstream","uses_modification") as $expected_param) + if (! isset($_GET[$expected_param])) + $_GET[$expected_param] = ""; + + $multi_select_search_criteria = array( + "arch" => array( + "name" => "arch", + "title" => "CPU architecture", + "label" => "Arch", + "table" => "architectures", + "column" => "`architectures`.`name`", + "extra_condition" => "", + "values" => array() + ), + "repo" => array( + "name" => "repo", + "title" => "respository", + "label" => "Repository", + "table" => "repositories", + "column" => "CONCAT(`architectures`.`name`,\"/\",`repositories`.`name`)", + "extra_condition" => mysql_join_repositories_architectures() . " WHERE `repositories`.`is_on_master_mirror`", + "values" => array() + ) + ); + + foreach ( $multi_select_search_criteria as $criterium => $content ) { + $result = mysql_run_query( + "SELECT " . $content["column"] . " AS `name` FROM `" . $content["table"] . "`" . $content["extra_condition"] . " ORDER BY `name`" + ); + while ($row = $result -> fetch_assoc()) + $multi_select_search_criteria[$criterium]["values"][] = $row["name"]; + } + + $float_columns = array( + "has_issues", + "is_to_be_deleted" + ); + + $filter = " WHERE 1"; + foreach ($multi_select_search_criteria as $criterium) + if (isset($_GET[$criterium["name"]])) { + $filter .= " AND " . $criterium["column"] . " IN ("; + foreach ($criterium["values"] as $value) + if (strpos("&" . urldecode($_SERVER["QUERY_STRING"]) . "&", "&" . $criterium["name"] . "=" . $value . "&") !== false) + $filter .= "\"" . $value . "\","; + $filter .= "\"\")"; + } + + $single_select_search_criteria = array( + "bugs" => array( + "name" => "bugs", + "label" => "Bugs", + "title" => "bug-tracker status", + "options" => array( + "All" => "1", + "Bugs" => "`binary_packages`.`has_issues`", + "No Bugs" => "NOT `binary_packages`.`has_issues`" + ) + ), + "del" => array( + "name" => "del", + "label" => "To Be Deleted", + "title" => "to-be-deleted status", + "options" => array( + "All" => "1", + "To Be Deleted" => "`binary_packages_in_repositories`.`is_to_be_deleted`", + "Not To Be Deleted" => "NOT `binary_packages_in_repositories`.`is_to_be_deleted`" + ) + ), + "uses_upstream" => array( + "name" => "uses_upstream", + "label" => "Upstream", + "title" => "wether upstream source exists", + "options" => array( + "All" => "1", + "Uses Upstream" => "`package_sources`.`uses_upstream`", + "Does Not Use Upstream" => "NOT `package_sources`.`uses_upstream`" + ) + ), + "uses_modification" => array( + "name" => "uses_modification", + "label" => "Modification", + "title" => "wether modification exists", + "options" => array( + "All" => "1", + "Uses Modification" => "`package_sources`.`uses_modification`", + "Does Not Use Modification" => "NOT `package_sources`.`uses_modification`" + ) + ) + ); + + foreach ($single_select_search_criteria as $criterium) + if (isset($_GET[$criterium["name"]]) && + isset($criterium["options"][$_GET[$criterium["name"]]])) + $filter .= " AND " . $criterium["options"][$_GET[$criterium["name"]]]; + + if (isset($_GET["q"])) { + $exact_filter = " AND `binary_packages`.`pkgname` = from_base64(\"".base64_encode($_GET["q"])."\")"; + $fuzzy_filter = " AND `binary_packages`.`pkgname` LIKE from_base64(\"".base64_encode("%".$_GET["q"]."%")."\")"; + } else { + $exact_filter = " AND 0"; + $fuzzy_filter = ""; + } + + $query = " FROM `binary_packages`" . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + " AND `repositories`.`is_on_master_mirror`" . + mysql_join_repositories_architectures("","r_a") . + mysql_join_binary_packages_build_assignments() . + mysql_join_build_assignments_package_sources() . + $filter . $exact_filter . + " ORDER BY "; + + $query .= "`binary_packages`.`pkgname`,`repositories`.`stability`,`repositories`.`name`,`architectures`.`name`"; + + $result = mysql_run_query( + "SELECT " . + "`binary_packages`.`pkgname`," . + "`package_sources`.`pkgbase`," . + "CONCAT(`r_a`.`name`,\"/\",`repositories`.`name`) AS `repo`," . + "`architectures`.`name` AS `arch`," . + mysql_query_package_version("binary_packages") . + " AS `version`," . + "IF(`binary_packages`.`has_issues`,1,0) AS `has_issues`," . + "`build_assignments`.`return_date` AS `build_date`," . + "`binary_packages_in_repositories`.`last_moved` AS `move_date`," . + "IF(`binary_packages_in_repositories`.`is_to_be_deleted`,1,0) AS `is_to_be_deleted`" . + $query + ); + $exact_matches = array(); + while ($row = $result -> fetch_assoc()) { + foreach ($float_columns as $float_column) + $row[$float_column] = floatval($row[$float_column]); + $exact_matches[] = $row; + } + + $sorts = array( + "arch" => array( + "title" => "architecture", + "label" => "Arch", + "mysql" => "`architectures`.`name`" + ), + "repo" => array( + "title" => "repository", + "label" => "Repo", + "mysql" => "CONCAT(`r_a`.`name`,\"/\",`repositories`.`name`)" + ), + "pkgname" => array( + "title" => "package name", + "label" => "Name", + "mysql" => "`binary_packages`.`pkgname`" + ), + "pkgver" => array( + "title" => "package version", + "label" => "Version", + "mysql" => mysql_query_package_version("binary_packages") + ), + "bugs" => array( + "title" => "bug status", + "label" => "Bugs", + "mysql" => "NOT `binary_packages`.`has_issues`" + ), + "build_date" => array( + "title" => "build date", + "label" => "Build Date", + "mysql" => "IFNULL(`build_assignments`.`return_date`,\"00-00-0000 00:00:00\")" + ), + "move_date" => array( + "title" => "last update", + "label" => "Last Updated", + "mysql" => "IFNULL(`binary_packages_in_repositories`.`last_moved`,\"00-00-0000 00:00:00\")" + ), + "del" => array( + "title" => "to be deleted", + "label" => "Delete", + "mysql" => "`binary_packages_in_repositories`.`is_to_be_deleted`" + ) + ); + + $query = " FROM `binary_packages`" . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + " AND `repositories`.`is_on_master_mirror`" . + mysql_join_repositories_architectures("","r_a") . + mysql_join_binary_packages_build_assignments() . + mysql_join_build_assignments_package_sources() . + $filter . $fuzzy_filter . + " ORDER BY "; + + if (isset($_GET["sort"])) { + if (isset($sorts[$_GET["sort"]]["mysql"])) + $query .= $sorts[$_GET["sort"]]["mysql"] . ","; + elseif (isset($sorts[substr($_GET["sort"],1)]["mysql"])) + $query .= $sorts[substr($_GET["sort"],1)]["mysql"] . " DESC,"; + } + + $query .= "`binary_packages`.`pkgname`,`repositories`.`stability`,`repositories`.`name`,`architectures`.`name`"; + + $result = mysql_run_query( + "SELECT COUNT(1)" . $query + ); + $num_results = implode($result -> fetch_assoc()); + + $pages = max(ceil($num_results / 100), 1); + if (isset($_GET["page"])) + $page = max(min($_GET["page"]+0, $pages),1); + else + $page = 1; + + $result = mysql_run_query( + "SELECT " . + "`binary_packages`.`pkgname`," . + "`package_sources`.`pkgbase`," . + "CONCAT(`r_a`.`name`,\"/\",`repositories`.`name`) AS `repo`," . + "`architectures`.`name` AS `arch`," . + mysql_query_package_version("binary_packages") . + " AS `version`," . + "IF(`binary_packages`.`has_issues`,1,0) AS `has_issues`," . + "`build_assignments`.`return_date` AS `build_date`," . + "`binary_packages_in_repositories`.`last_moved` AS `move_date`," . + "IF(`binary_packages_in_repositories`.`is_to_be_deleted`,1,0) AS `is_to_be_deleted`" . + $query . + " LIMIT " . (($page-1)*100) . ", 100" + ); + $fuzzy_matches = array(); + while ($row = $result -> fetch_assoc()) { + foreach ($float_columns as $float_column) + $row[$float_column] = floatval($row[$float_column]); + $fuzzy_matches[] = $row; + } + + function print_results($results) { + $oddity="odd"; + foreach ($results as $row) { + print " <tr class=\"" . $oddity . "\">\n"; + print " <td>\n"; + print " " . $row["arch"] . "\n"; + print " </td>\n"; + print " <td>\n"; + print " " . $row["repo"] . "\n"; + print " </td>\n"; + print " <td>\n"; + print " <a href=\"/" . $row["repo"] . "/" . $row["pkgname"] ."/\" "; + print "title=\"View package details for " . $row["pkgname"] . "\">" . $row["pkgname"] . "</a>\n"; + print " </td>\n"; + print " <td>\n"; + print " " . $row["version"] . "\n"; + print " </td>\n"; + print " <td>\n"; + print " "; + if ($row["has_issues"]) + print "has open bug reports"; + else + print " "; + print "\n"; + print " </td>\n"; + print " <td>\n"; + print " "; + if (isset($row["build_date"])) + print $row["build_date"]; + else + print " "; + print "\n"; + print " </td>\n"; + print " <td>\n"; + print " "; + if (isset($row["move_date"])) + print $row["move_date"]; + else + print " "; + print "\n"; + print " </td>\n"; + print " <td>\n"; + print " "; + if ($row["is_to_be_deleted"]) + print "to be deleted"; + else + print " "; + print "\n"; + print " </td>\n"; + print " </tr>\n"; + if ($oddity == "odd" ) + $oddity = "even"; + else + $oddity = "odd"; + } + } + + function header_and_footer() { + + global $page, $pages, $num_results; + + print " <div class=\"pkglist-stats\">\n"; + print " <p>\n"; + print " " . $num_results . " matching package"; + if ($num_results != 1) + print "s"; + print " found.\n"; + + if ($pages != 1) + print " Page " . $page . " of " . $pages . ".\n"; + + print " </p>\n"; + + if ($pages != 1) { + print " <div class=\"pkglist-nav\">\n"; + print " <span class=\"prev\">\n"; + + print " "; + if ($page > 1) { + print "<a href=\"?"; + print substr(str_replace( + "&page=".$page."&", + "&", + "&".$_SERVER["QUERY_STRING"]."&" + ),1)."page=".($page-1); + print "\" title=\"Go to previous page\">"; + }; + print "< Prev"; + if ($page > 1) + print "</a>"; + print "\n"; + print " </span>\n"; + print " <span class=\"next\">\n"; + + print " "; + if ($page < $pages) { + print "<a href=\"?"; + print substr(str_replace( + "&page=".$page."&", + "&", + "&".$_SERVER["QUERY_STRING"]."&" + ),1)."page=".($page+1); + print "\" title=\"Go to next page\">"; + }; + print "Next >"; + if ($page < $pages) + print "</a>"; + print "\n"; + print " </span>\n"; + print " </div>\n"; + }; + print " </div>\n"; + + }; + + if (isset($_GET["exact"])) { + export_as_requested( + array( + "All" => $exact_matches + ) + ); + die(); + }; + + if (isset($_GET["fuzzy"])) { + export_as_requested( + array( + "All" => $fuzzy_matches + ) + ); + die(); + }; + + print_header("Package Search"); + +?> + <div id="pkglist-search" class="box filter-criteria"> + <h2>Package Search</h2> + <form id="pkg-search" method="get" action="/"> + <p><input id="id_sort" name="sort" type="hidden" /></p> + <fieldset> + <legend>Enter search criteria</legend> +<?php + foreach ($multi_select_search_criteria as $criterium) { + print " <div>\n"; + print " <label for=\"id_" . $criterium["name"] . "\" title=\"Limit results to a specific " . $criterium["title"] . "\">"; + print $criterium["label"]; + print "</label>\n"; + print " <select multiple=\"multiple\" id=\"id_" . $criterium["name"] . "\" name=\"" . $criterium["name"] . "\">\n"; + foreach ($criterium["values"] as $value) { + print " <option value=\"" . $value . "\""; + if (strpos( "&" . urldecode($_SERVER["QUERY_STRING"]) . "&", "&" . $criterium["name"] . "=" . $value . "&") !== false) + print " selected=\"selected\""; + print ">" . $value . "</option>\n"; + } + print " </select>\n"; + print " </div>\n"; + } +?> + <div> + <label for="id_q" title="Enter keywords as desired">Keywords</label> + <input id="id_q" name="q" size="30" type="text" <?php +if (isset($_GET["q"])) + print "value=\"".$_GET["q"]."\""; +?>/> + </div> +<?php + foreach ($single_select_search_criteria as $criterium) { + + print " <div>\n"; + print " <label for=\"id_"; + print $criterium["name"]; + print "\" title=\"Limit results based on "; + print $criterium["title"]; + print "\">"; + print $criterium["label"]; + print "</label><select id=\"id_"; + print $criterium["name"]; + print "\" name=\""; + print $criterium["name"]; + print "\">\n"; + + foreach ($criterium["options"] as $label => $option) { + print " <option value=\""; + if ($label != "All") + print $label; + print "\""; + if ($_GET[$criterium["name"]]==$label) + print " selected=\"selected\""; + print ">" . $label . "</option>\n"; + } + print " </select>\n"; + print " </div>\n"; + } +?> + <div> + <label> </label> + <input title="Search for packages using this criteria" type="submit" value="Search"> + </div> + </fieldset> + </form> + </div> +<?php + +if (count($exact_matches) > 0) { +?> + <div id="exact-matches" class="box"> + <div class="pkglist-stats"> + <p><?php print count($exact_matches); ?> exact match<?php if (count($exact_matches) != 1) print "es"; ?> found.</p> + </div> + <table class="results"> + <thead> + <tr> +<?php + + foreach ($sorts as $get => $sort) { + print " <th>\n"; + print " ".$sort["label"]."\n"; + print " </th>\n"; + } +?> + </tr> + </thead> + <tbody> +<?php + print_results($exact_matches); +?> + </tbody> + </table> + </div> +<?php +} + +?> + <div id="pkglist-results" class="box"> +<?php + + header_and_footer(); + +?> + <table class="results"> + <thead> + <tr> +<?php + + foreach ($sorts as $get => $sort) { + print " <th>\n"; + print " <a href=\"/?"; + print substr(str_replace( + "&sort=".$_GET["sort"]."&", + "&", + "&".$_SERVER["QUERY_STRING"]."&" + ),1)."sort="; + if ($_GET["sort"] == $get) + print "-"; + print $get."\" title=\"Sort package by ".$sort["title"]."\">".$sort["label"]."</a>\n"; + print " </th>\n"; + } +?> + </tr> + </thead> + <tbody> +<?php + + print_results($fuzzy_matches); + +?> + </tbody> + </table> +<?php + + header_and_footer(); + +?> + </div> + <div id="pkglist-about" class="box"> + <p> + Can't find what you are looking for? Try searching again + using different criteria, or try + searching the <a href="https://aur.archlinux.org/">AUR</a> + to see if the package can be found there. + </p> + <p> + You are browsing the Arch Linux 32 package database. From here you can find + detailed information about packages located in the 32 bit repositories. + </p> + </div> +<?php + + print_footer(); diff --git a/packages/pkginfo.php b/packages/pkginfo.php new file mode 100644 index 0000000..0717aa1 --- /dev/null +++ b/packages/pkginfo.php @@ -0,0 +1,701 @@ +<?php +require_once "../init.php"; + +if (($_GET['repo']=='i686') || ($_GET['repo']=='i486') || ($_GET['repo']=='any')) { + header('Location: /' . $_GET['repo'] . '/' . $_GET['repo_arch'] . '/' . $_GET['pkgname'] . '/'); + error_log('needed redirect URL: ' . $_SERVER['REQUEST_URI'] . ', HTTP_USER_AGENT: ' . $_SERVER['HTTP_USER_AGENT'] . ', HTTP_REFERER: ' . $_SERVER['HTTP_REFERER']); + die(); +} + +require_once BASE . "/lib/helper.php"; +require_once BASE . "/lib/mysql.php"; +require_once BASE . "/lib/style.php"; + + $memcache = new Memcache; + $memcache -> connect('localhost', 11211) or die ('Memcached Connection Error'); + $pkgapi_reachable = $memcache -> get('pkgapi_reachable'); + $tld = explode('.', $_SERVER['HTTP_HOST']); + end($tld); + $tld = current($tld); + if ((array_key_exists('HTTPS', $_SERVER) && + ($_SERVER['HTTPS'] == 'on')) || + (array_key_exists('HTTP_X_FORWARDED_PROTO', $_SERVER) && + ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))) + $protocol = 'https'; + else + $protocol = 'http'; + if ($pkgapi_reachable === false) { + if (site_is_reachable($protocol . '://pkgapi.archlinux32.' . $tld . '/')) + $pkgapi_reachable = 'YES'; + else + $pkgapi_reachable = 'NO'; + $memcache -> set('pkgapi_reachable', $pkgapi_reachable, 0, 300); + } + if ($pkgapi_reachable == 'YES') + $skip_json_checks = false; + else + $skip_json_checks = true; + + if (!array_key_exists("repo_arch",$_GET)) { + $_GET["repo_arch"] = $_GET["arch"]; + unset($_GET["arch"]); + } + + if (!$skip_json_checks) { + $json_content = json_decode( + file_get_contents( + $protocol . '://pkgapi.archlinux32.' . $tld . '/' . + urlencode($_GET["repo_arch"]) . '/' . + urlencode($_GET["repo"]) . '/' . + urlencode($_GET["pkgname"]) + ), + true + ); + + if (!isset($json_content) || !array_key_exists('Name', $json_content)) { + //throw_http_error(404, "Package Not Found In Sync Database"); + unset($json_content); + $skip_json_checks = true; + }; + } + + $mysql_result = mysql_run_query( + "SELECT " . + "`binary_packages`.`id`," . + "`binary_packages`.`pkgname`," . + "`sp_q`.`split_packages`," . + "`package_sources`.`pkgbase`," . + mysql_query_package_version("binary_packages") . + " AS `version`," . + "`repositories`.`stability` AS `repo_stability`," . + "`repository_stabilities`.`name` AS `repo_stability_name`," . + "`repositories`.`name` AS `repo`," . + "`r_a`.`name` AS `repo_arch`," . + "`architectures`.`name` AS `arch`," . + "`git_repositories`.`name` AS `git_repo`," . + "`package_sources`.`uses_upstream`," . + "`package_sources`.`uses_modification`," . + "MAX(`binary_packages_in_repositories`.`last_moved`) AS `last_moved`," . + "`sr`.`name` AS `stable_repo`" . + " FROM `binary_packages`" . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_repository_stabilities() . + mysql_join_repositories_architectures("","r_a") . + mysql_join_binary_packages_build_assignments() . + mysql_join_build_assignments_package_sources() . + mysql_join_package_sources_upstream_repositories() . + mysql_join_upstream_repositories_git_repositories() . + mysql_join_upstream_repositories_repository_moves() . + " JOIN `repositories` AS `sr` ON `sr`.`id`=`repository_moves`.`to_repository`" . + " JOIN (" . + "SELECT DISTINCT `binary_packages`.`build_assignment`," . + "GROUP_CONCAT(" . + "CONCAT(" . + "\"\\\"\",`binary_packages`.`id`,\"\\\": {" . + "\\\"pkgname\\\":" . + " \\\"\",`binary_packages`.`pkgname`,\"\\\"," . + "\\\"repository\\\":" . + " \\\"\",`repositories`.`name`,\"\\\"," . + "\\\"repo_arch\\\":" . + " \\\"\",`architectures`.`name`,\"\\\"" . + "}\"" . + ")" . + ") AS `split_packages`" . + " FROM `binary_packages`" . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_architectures() . + " GROUP BY `binary_packages`.`build_assignment`" . + ") AS `sp_q`" . + " ON `sp_q`.`build_assignment`=`build_assignments`.`id`" . + " WHERE `binary_packages`.`pkgname`=from_base64(\"" . base64_encode($_GET["pkgname"]) . "\")" . + " AND `r_a`.`name`=from_base64(\"" . base64_encode($_GET["repo_arch"]) . "\")" . + " AND `repositories`.`name`=from_base64(\"" . base64_encode($_GET["repo"]) . "\")" . + " AND NOT EXISTS (" . + "SELECT 1" . + " FROM `repository_moves` AS `rm`" . + " WHERE `rm`.`from_repository`=`sr`.`id`" . + ")" . + " GROUP BY `binary_packages`.`id`" + ); + + if ($mysql_result -> num_rows != 1) + throw_http_error(404, "Package Not Found In Buildmaster's Database"); + + $mysql_content = $mysql_result -> fetch_assoc(); + $mysql_content["split_packages"] = array_map("unserialize", array_unique(array_map("serialize", json_decode("{".$mysql_content["split_packages"]."}",true)))); + + if (!$skip_json_checks) { + $same_keys = array ( + array("mysql" => "pkgname", "json" => "Name"), + array("mysql" => "version", "json" => "Version", "suffix_diff" => ".0"), + array("mysql" => "repo", "json" => "Repository"), + array("mysql" => "arch", "json" => "Architecture") + ); + + foreach ($same_keys as $same_key) + if (($mysql_content[$same_key["mysql"]] != $json_content[$same_key["json"]]) && + ((!array_key_exists('suffix_diff', $same_key)) || + ($mysql_content[$same_key["mysql"]] != $json_content[$same_key["json"]].$same_key["suffix_diff"]))) + die_500("Inconsistency in Database found:<br>\n" . + "buildmaster[" . $same_key["mysql"] . "] != repositories[" . $same_key["json"] . "]:<br>\n" . + "\"" . $mysql_content[$same_key["mysql"]] . "\" != \"" . $json_content[$same_key["json"]] . "\""); + } + + // query _all_ dependencies + + $mysql_result = mysql_run_query( + "SELECT DISTINCT " . + "`dependency_types`.`name` AS `dependency_type`," . + "GROUP_CONCAT(" . + "CONCAT(\"\\\"\",`install_target_providers`.`id`,\"\\\": \",\"{\\n\"," . + "\" \\\"repo\\\": \\\"\",`repositories`.`name`,\"\\\",\\n\"," . + "\" \\\"repo_arch\\\": \\\"\",`r_a`.`name`,\"\\\",\\n\"," . + "\" \\\"arch\\\": \\\"\",`architectures`.`name`,\"\\\",\\n\"," . + "\" \\\"pkgname\\\": \\\"\",`binary_packages`.`pkgname`,\"\\\",\\n\"," . + "\" \\\"is_to_be_deleted\\\": \\\"\",IF(`binary_packages_in_repositories`.`is_to_be_deleted`,\"1\",\"0\"),\"\\\"\\n\"," . + "\"}\"" . + ")) AS `deps`," . + "IF(" . + "(" . + "`versions`.`order`=1 AND `dependencies`.`version_relation`=\">=\"" . + ") OR (" . + "`versions`.`epoch`=8388607 AND `dependencies`.`version_relation`=\"<\"" . + ")," . + "\"\"," . + "CONCAT(" . + "`dependencies`.`version_relation`," . + "IF(" . + "`versions`.`epoch`=0," . + "\"\"," . + "CONCAT(" . + "`versions`.`epoch`," . + "\":\"" . + ")" . + ")," . + "`versions`.`version`" . + ")" . + ") AS `version`," . + "`install_targets`.`name` AS `install_target`" . + " FROM `dependencies`" . + " LEFT JOIN (". + "`binary_packages_in_repositories` AS `bpir`" . + mysql_join_binary_packages_in_repositories_repositories('bpir','r') . + mysql_join_repositories_architectures('r','r_a') . + ") ON `bpir`.`package`=`dependencies`.`dependent`" . + mysql_join_dependencies_dependency_types() . + mysql_join_dependencies_install_targets() . + " AND `install_targets`.`name` NOT IN (\"base\",\"base-devel\")" . + mysql_join_dependencies_versions() . + " LEFT JOIN (" . + "`install_target_providers`" . + mysql_join_install_target_providers_binary_packages() . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + " JOIN `repository_stability_relations` ON `repository_stability_relations`.`more_stable`=`repositories`.`stability`" . + " AND `repository_stability_relations`.`less_stable`=" . $mysql_content["repo_stability"] . + ") ON `install_target_providers`.`install_target`=`dependencies`.`depending_on`" . + " AND `repositories`.`architecture`=`r`.`architecture`" . + " WHERE `dependencies`.`dependent`=" . $mysql_content["id"] . + " AND NOT EXISTS (" . + "SELECT 1 FROM `binary_packages` AS `subst_bp`" . + mysql_join_binary_packages_binary_packages_in_repositories('subst_bp','subst_bpir') . + mysql_join_binary_packages_in_repositories_repositories('subst_bpir','subst_r') . + // the substitue must be truly less stable than the dependency + " JOIN `repository_stability_relations` AS `subst_rsr` ON `subst_rsr`.`less_stable`=`subst_r`.`stability`" . + " AND `subst_rsr`.`less_stable`!=`subst_rsr`.`more_stable`" . + // and more (or equally) stable than us + " JOIN `repository_stability_relations` AS `subst_rsr2` ON `subst_rsr2`.`more_stable`=`subst_r`.`stability`" . + " WHERE `subst_bp`.`pkgname`=`binary_packages`.`pkgname`" . + " AND `subst_rsr`.`more_stable`=`repositories`.`stability`" . + " AND `subst_rsr2`.`less_stable`=" . $mysql_content["repo_stability"] . + ")" . + " GROUP BY CONCAT(`install_targets`.`id`,\"-\",`versions`.`id`),`dependency_types`.`id`" . + " ORDER BY FIELD (`dependency_types`.`name`,\"run\",\"make\",\"check\",\"link\"), `install_targets`.`name`" + ); + + $dependencies = array(); + while ($row = $mysql_result -> fetch_assoc()) { + $row["deps"] = array_map("unserialize", array_unique(array_map("serialize", json_decode("{".$row["deps"]."}",true)))); + $dependencies[] = $row; + } + + if (!$skip_json_checks) { + function dependency_is_runtime($dep) { + return $dep["dependency_type"]=="run"; + }; + + function dependency_extract_name($dep) { + return $dep["install_target"]; + }; + + $dep_it = array_filter( $dependencies, "dependency_is_runtime"); + $dep_it = array_map("dependency_extract_name", $dep_it); + $dep_it = preg_replace("/[<=>].*$/","",$dep_it); + if (array_key_exists("Depends On",$json_content)) + $js_dep = preg_replace("/[<=>].*$/","",$json_content["Depends On"]); + elseif (array_key_exists("Requires",$json_content)) + $js_dep = preg_replace("/[<=>].*$/","",$json_content["Requires"]); + else + $js_dep = array(); + if (!is_array($js_dep)) + $js_dep = array(); + if (!isset($dep_it)) + $dep_it = array(); + $dep_errors = implode( + ", ", + array_diff( + array_merge($dep_it,$js_dep), + $dep_it + ) + ); + + if ($dep_errors != "") + die_500( + "Dependencies differ: " . $dep_errors. "<br>\n" . + "mysql: " . implode(", ",$dep_it) . "<br>\n" . + "json: " . implode(", ",$js_dep) + ); + + foreach ($dependencies as $key => $dep) { + if ($dep["dependency_type"]!="run") { + $dependencies[$key]["json"]="not required"; + continue; + } + foreach ($js_dep as $js) + if ($js == preg_replace("/[<=>].*$/","",$dep["install_target"])) + $dependencies[$key]["json"]=$js; + } + } + + // query dependent packages + + $mysql_result = mysql_run_query( + "SELECT DISTINCT " . + "`dependency_types`.`name` AS `dependency_type`," . + "`install_targets`.`name` AS `install_target`," . + "`repositories`.`name` AS `repo`," . + "`repositories`.`is_on_master_mirror`," . + "`r_a`.`name` AS `repo_arch`," . + "`architectures`.`name` AS `arch`," . + "`binary_packages`.`pkgname`," . + "IF(`binary_packages_in_repositories`.`is_to_be_deleted`,1,0) AS `is_to_be_deleted`" . + " FROM `install_target_providers`" . + " LEFT JOIN (". + "`binary_packages_in_repositories` AS `bpir`" . + mysql_join_binary_packages_in_repositories_repositories('bpir','r') . + ") ON `bpir`.`package`=`install_target_providers`.`package`" . + mysql_join_install_target_providers_install_targets() . + " AND `install_targets`.`name` NOT IN (\"base\",\"base-devel\")" . + mysql_join_install_target_providers_dependencies() . + mysql_join_dependencies_dependency_types() . + mysql_join_dependencies_binary_packages() . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + " AND `repositories`.`architecture`=`r`.`architecture`" . + mysql_join_repositories_architectures("","r_a") . + " JOIN `repository_stability_relations` ON `repository_stability_relations`.`less_stable`=`repositories`.`stability`" . + " AND `repository_stability_relations`.`more_stable`=" . $mysql_content["repo_stability"] . + " WHERE `install_target_providers`.`package`=" . $mysql_content["id"] . + " AND NOT EXISTS (" . + "SELECT 1 FROM `binary_packages` AS `subst_bp`" . + mysql_join_binary_packages_binary_packages_in_repositories('subst_bp','subst_bpir') . + mysql_join_binary_packages_in_repositories_repositories('subst_bpir','subst_r') . + // the substitue must be truly less stable than we + " JOIN `repository_stability_relations` AS `subst_rsr` ON `subst_rsr`.`less_stable`=`subst_r`.`stability`" . + " AND `subst_rsr`.`less_stable`!=`subst_rsr`.`more_stable`" . + // and more (or equally) stable than the required-by + " JOIN `repository_stability_relations` AS `subst_rsr2` ON `subst_rsr2`.`more_stable`=`subst_r`.`stability`" . + " WHERE `subst_bp`.`pkgname`=from_base64(\"" . base64_encode($mysql_content["pkgname"]) . "\")" . + " AND `subst_rsr2`.`less_stable`=`repositories`.`stability`" . + " AND `subst_rsr`.`more_stable`=" . $mysql_content["repo_stability"] . + ")" . + " GROUP BY `binary_packages`.`id`,`dependency_types`.`id`" . + " ORDER BY" . + " FIELD (`dependency_types`.`name`,\"run\",\"make\",\"check\",\"link\")," . + " `install_targets`.`name`!=`binary_packages`.`pkgname`," . + " `install_targets`.`name`," . + " `binary_packages`.`pkgname`," . + " `repositories`.`stability`," . + " `repositories`.`name`" + ); + + $dependent = array(); + while ($row = $mysql_result -> fetch_assoc()) + $dependent[] = $row; + + if ($skip_json_checks) + $content = $mysql_content; + else + $content = array_merge($mysql_content,$json_content); + + foreach (array("Download Size", "Installed Size") as $key) { + $content["Print " . $key] = + add_fancy_unit($content[$key], "B"); + } + + // query substitutes + + $mysql_result = mysql_run_query( + "SELECT " . + "`binary_packages`.`pkgname` AS `pkgname`," . + "IF(`binary_packages_in_repositories`.`is_to_be_deleted`,1,0) AS `is_to_be_deleted`," . + "`repositories`.`name` AS `repo`," . + "`repositories`.`is_on_master_mirror`," . + "`architectures`.`name` AS `arch`," . + "`r_a`.`name` AS `repo_arch`," . + mysql_query_package_version("binary_packages") . + " AS `version`" . + " FROM `binary_packages` " . + mysql_join_binary_packages_architectures() . + mysql_join_binary_packages_binary_packages_in_repositories() . + mysql_join_binary_packages_in_repositories_repositories() . + mysql_join_repositories_architectures("","r_a") . + " JOIN `binary_packages` AS `original`" . + " ON `binary_packages`.`pkgname`=`original`.`pkgname`" . + " AND `binary_packages`.`id`!=`original`.`id`" . + " WHERE `original`.`id`=" . $mysql_content["id"] + ); + + $elsewhere = array(); + while ($row = $mysql_result -> fetch_assoc()) + $elsewhere[] = $row; + + print_header($content["pkgname"] . " " . $content["version"] . " (" . $content["arch"] . ")"); + +?> + <div id="archdev-navbar"> + </div> + <div id="pkgdetails" class="box"> + <h2><?php print $content["pkgname"]." ".$content["version"]; ?></h2> + <div id="detailslinks" class="listing"> + <div id="actionlist"> + <h4>Package Actions</h4> + <ul class="small"> +<?php + if ($content["uses_upstream"]) { + print " <li>\n"; + print " <a href=\"https://projects.archlinux.org/svntogit/"; + print $content["git_repo"]; + print ".git/tree/trunk?h=packages/"; + print $content["pkgbase"]; + print "\" title=\"View upstream's source files for "; + print $content["pkgname"]; + print "\">Upstream's Source Files</a> /\n"; + print " <a href=\"https://projects.archlinux.org/svntogit/"; + print $content["git_repo"]; + print ".git/log/trunk?h=packages/"; + print $content["pkgbase"]; + print "\" title=\"View upstream's changes for "; + print $content["pkgname"]; + print "\">Upstream's Changes</a>\n"; + print " </li>\n"; + } + if ($content["uses_modification"]) { + print " <li>\n"; + print " <a href=\""; + print git_url("packages","tree","master",$content["stable_repo"]."/".$content["pkgbase"]); + print "\" title=\"View archlinux32's source files for "; + print $content["pkgname"]; + print "\">Archlinux32's Source Files</a> /\n"; + print " <a href=\""; + print git_url("packages","log","master",$content["stable_repo"]."/".$content["pkgbase"]); + print "\" title=\"View upstream's changes for "; + print $content["pkgname"]; + print "\">Archlinux32's Changes</a>\n"; + print " </li>\n"; + } +?> + <li> +<?php + print " <a href=\"https://www.archlinux.org/packages/?sort=&q="; + print $content["pkgname"]; + print "&maintainer=&flagged=\">"; + print "Search for ".$content["pkgname"]." upstream"; + print "</a>\n"; +?> + </li> + <li> +<?php + print " <a href=\"https://bugs.archlinux32.org/index.php?string="; + print $content["pkgname"]; + print "\" title=\"View existing bug tickets for "; + print $content["pkgname"]; + print "\">Bug Reports</a> / \n"; + print " <a href=\"https://bugs.archlinux32.org/index.php?do=newtask&project=1&product_category="; + if ($content["repo_stability_name"]=="stable") + print "8"; // stable + elseif ($content["repo_stability_name"]=="testing") + print "6"; // testing + elseif ($content["repo_stability_name"]=="unbuilt") + print "7"; // build-list + else + print "1"; // packages + print "&item_summary=%5B"; + print $content["pkgname"]; + print "%5D+PLEASE+ENTER+SUMMARY\" title=\"Report new bug for "; + print $content["pkgname"]; + print "\">Add New Bug</a>\n"; +?> + </li> + <li> + <a href="http://pool.mirror.archlinux32.org/<?php + print $content["repo_arch"]."/".$content["repo"]."/".$content["pkgname"]."-".$content["version"]."-".$content["arch"]; +?>.pkg.tar.xz" rel="nofollow" title="Download <?php print $content["pkgname"]; ?> from mirror">Download From Mirror</a> + </li> + </ul> + </div> +<?php + +if (count($elsewhere)>0) { + print " <div id=\"elsewhere\" class=\"widget\">\n"; + print " <h4>Versions Elsewhere</h4>\n"; + foreach ($elsewhere as $subst) { + print " <ul>\n"; + print " <li>\n"; + if ($subst["is_on_master_mirror"]) { + print " <a href=\"/" . $subst["repo_arch"] . "/" . $subst["repo"] . "/" . $subst["pkgname"] ."/\""; + print " title=\"Package details for " . $subst["pkgname"] ."\">"; + } + if ($subst["is_to_be_deleted"]) + print "<s>"; + print $subst["pkgname"] . "-" . $subst["version"] . " [" . $subst["repo"] . "] (" . $subst["arch"] . ")"; + if ($subst["is_to_be_deleted"]) + print "</s>"; + if ($subst["is_on_master_mirror"]) + print "</a>\n"; + print " </li>\n"; + print " </ul>\n"; + } + print " </div>\n"; +} + +?> + </div> + <div itemscope itemtype="http://schema.org/SoftwareApplication"> + <meta itemprop="name" content="<?php print $content["pkgname"]; ?>"/> + <meta itemprop="version" content="<?php print $content["version"]; ?>"/> + <meta itemprop="softwareVersion" content="<?php print $content["version"]; ?>"/> + <meta itemprop="fileSize" content="<?php print if_unset($content, "Download Size", "0"); ?>"/> + <meta itemprop="dateCreated" content="<?php print if_unset($content,"Build Date","0"); ?>"/> + <meta itemprop="datePublished" content="<?php print $content["last_moved"]; ?>"/> + <meta itemprop="operatingSystem" content="Arch Linux 32"/> + <table id="pkginfo"> + <tr> + <th> + Architecture: + </th> + <td> + <a href="/?arch=<?php + print $content["arch"]; + ?>" title="Browse packages for <?php + print $content["arch"]; + ?> architecture"><?php + print $content["arch"]; + ?></a> + </td> + </tr> + <tr> + <th> + Repository: + </th> + <td> + <a href="/?repo=<?php + print urlencode($content["repo_arch"] . "/" . $content["repo"]); + ?>" title="Browse the <?php + print $content["repo_arch"] . "/" . $content["repo"]; + ?> repository"><?php + print $content["repo_arch"] . "/" . $content["repo"]; + ?></a> + </td> + </tr> +<?php +$count = count($content["split_packages"]); +if ($count > 1 || $content["pkgname"] != $content["pkgbase"]) { + print " <tr>\n"; + print " <th>\n"; + print " Split Packages:\n"; + print " </th>\n"; + print " <td>\n"; + foreach ($content["split_packages"] as $split_package) { + print " "; + if ($split_package["pkgname"] != $content["pkgname"]) { + print "<a href=\"/" . $split_package["repo_arch"]; + print "/" . $split_package["repository"]; + print "/" . $split_package["pkgname"]; + print "/\">"; + } + print $split_package["pkgname"]; + $count --; + if ($split_package["pkgname"] != $content["pkgname"]) + print "</a>"; + if ($count > 0) + print ", "; + } + if ($content["pkgname"] != $content["pkgbase"]) + print " (" . $content["pkgbase"] . ")"; + print "\n"; + print " </td>\n"; + print " </tr>\n"; +} +?> + <tr> + <th> + Description: + </th> + <td class="wrap" itemprop="description"> + <?php print if_unset($content, "Description", "<font color=\"#ff0000\">not found in pkg-api</font>")."\n"; ?> + </td> + </tr> + <tr> + <th> + Upstream URL: + </th> + <td> + <a itemprop="url" href="<?php print if_unset($content, "URL", ""); ?>" title="Visit the website for <?php print $content["pkgname"]; ?>"><?php print if_unset($content, "URL", "<font color=\"#ff0000\">not found in pkg-api</font>"); ?></a> + </td> + </tr> + <tr> + <th> + License(s): + </th> + <td class="wrap"> + <?php + $licenses = if_unset($content, "Licenses", "<font color=\"#ff0000\">not found in pkg-api</font>"); + if (is_array($licenses)) + print implode(", ",$licenses); + else + print $licenses; + print "\n"; +?> + </td> + </tr> + <tr> + <th> + Package Size: + </th> + <td> + <?php print if_unset($content, "Print Download Size", "<font color=\"#ff0000\">not found in pkg-api</font>")."\n"; ?> + </td> + </tr> + <tr> + <th> + Installed Size: + </th> + <td> + <?php print if_unset($content, "Print Installed Size", "<font color=\"#ff0000\">not found in pkg-api</font>")."\n"; ?> + </td> + </tr> + <tr> + <th> + Build Date: + </th> + <td> + <?php print if_unset($content, "Build Date", "<font color=\"#ff0000\">not found in pkg-api</font>")."\n"; ?> + </td> + </tr> + <tr> + <th> + Last Updated: + </th> + <td> + <?php print $content["last_moved"]."\n"; ?> + </td> + </tr> + </table> + </div> + <div id="metadata"> + <div id="pkgdeps" class="listing"> + <h3 title="<?php print $content["pkgname"]; ?> has the following dependencies"> + Dependencies (<?php print count($dependencies); ?>) + </h3> + <ul id="pkgdepslist"> +<?php + foreach ($dependencies as $dep) { + print " <li>\n"; + if (!$skip_json_checks && !array_key_exists ('json', $dep)) + print " (in database only)\n"; + if (count($dep["deps"]) == 0) { + print " <font color=\"#ff0000\">not satisfiable dependency: \"" . $dep["install_target"] . $dep["version"] . "\"</font>\n"; + } else { + $virtual_dep = ( + (count($dep["deps"]) > 1) || + (array_values($dep["deps"])[0]["pkgname"] != $dep["install_target"]) + ); + print " "; + if ($virtual_dep) { + print $dep["install_target"] . $dep["version"]; + print " <span class=\"virtual-dep\">("; + }; + $first = true; + foreach ($dep["deps"] as $d_p) { + if (!$first) + print ", "; + $first = false; + print "<a href=\"/".$d_p["repo_arch"]."/".$d_p["repo"]."/".$d_p["pkgname"]."/\" "; + print "title=\"View package details for ".$d_p["pkgname"]."\">"; + if ($d_p["is_to_be_deleted"]) + print "<s>"; + print $d_p["pkgname"]; + if ($d_p["is_to_be_deleted"]) + print "</s>"; + print "</a>"; + if (!$virtual_dep) + print $dep["version"]; + } + if ($virtual_dep) + print ")</span>"; + print "\n"; + }; + if ($dep["dependency_type"]!="run") + print " <span class=\"" . $dep["dependency_type"] . "-dep\">(" . $dep["dependency_type"] . ")</span>\n"; + print " </li>\n"; + } +?> + </ul> + </div> + <div id="pkgreqs" class="listing"> + <h3 title="Packages that require <?php print $content["pkgname"]; ?>"> + Required By (<?php print count($dependent); ?>) + </h3> + <ul id="pkgreqslist"> +<?php + foreach ($dependent as $dep) { + print " <li>\n"; + print " "; + if ($dep["install_target"] != $content["pkgname"]) + print $dep["install_target"] . " ("; + if ($dep["is_on_master_mirror"]=="1") { + print "<a href=\"/".$dep["repo_arch"]."/".$dep["repo"]."/".$dep["pkgname"]."/\" "; + print "title=\"View package details for ".$dep["pkgname"]."\">"; + } + if ($dep["is_to_be_deleted"]) + print "<s>"; + print $dep["pkgname"]; + if ($dep["is_to_be_deleted"]) + print "</s>"; + if ($dep["repo"] != $content["repo"]) + print " [" . $dep["repo"] . "]"; + if ($dep["is_on_master_mirror"]=="1") + print "</a>"; + if ($dep["install_target"] != $content["pkgname"]) + print ")\n"; + if ($dep["dependency_type"] != "run") + print " <span class=\"" . $dep["dependency_type"] . "-dep\">(" . $dep["dependency_type"] . ")</span>"; + print "\n"; + print " </li>\n"; + } +?> + </ul> + </div> + <div id="pkgfiles"> + </div> + </div> + </div> +<?php + + print_footer(); diff --git a/pkgapi/index.html b/pkgapi/index.html new file mode 100644 index 0000000..aca92a7 --- /dev/null +++ b/pkgapi/index.html @@ -0,0 +1,5 @@ +<html> + <body> + This is the pkgapi for archlinux32 - query it <a href="/i486/core/gcc">like so.</a> + </bod> +</html> diff --git a/pkgapi/pacman-i486.conf b/pkgapi/pacman-i486.conf new file mode 100644 index 0000000..3dee4f9 --- /dev/null +++ b/pkgapi/pacman-i486.conf @@ -0,0 +1,64 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +DBPath = /var/lib/pacman-i486/ +CacheDir = /var/cache/pacman-i486/pkg/ +LogFile = /dev/null +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +#UseDelta = 0.7 +Architecture = i486 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#TotalDownload +CheckSpace +#VerbosePkgLists + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +[staging] +Include = /etc/pacman.d/mirrorlist32 + +[community-staging] +Include = /etc/pacman.d/mirrorlist32 + +[testing] +Include = /etc/pacman.d/mirrorlist32 + +[community-testing] +Include = /etc/pacman.d/mirrorlist32 + +[core] +Include = /etc/pacman.d/mirrorlist32 + +[extra] +Include = /etc/pacman.d/mirrorlist32 + +[community] +Include = /etc/pacman.d/mirrorlist32 diff --git a/pkgapi/pacman-i686.conf b/pkgapi/pacman-i686.conf new file mode 100644 index 0000000..442b10e --- /dev/null +++ b/pkgapi/pacman-i686.conf @@ -0,0 +1,64 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +DBPath = /var/lib/pacman-i686/ +CacheDir = /var/cache/pacman-i686/pkg/ +LogFile = /dev/null +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +#UseDelta = 0.7 +Architecture = i686 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#TotalDownload +CheckSpace +#VerbosePkgLists + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +[staging] +Include = /etc/pacman.d/mirrorlist32 + +[community-staging] +Include = /etc/pacman.d/mirrorlist32 + +[testing] +Include = /etc/pacman.d/mirrorlist32 + +[community-testing] +Include = /etc/pacman.d/mirrorlist32 + +[core] +Include = /etc/pacman.d/mirrorlist32 + +[extra] +Include = /etc/pacman.d/mirrorlist32 + +[community] +Include = /etc/pacman.d/mirrorlist32 diff --git a/pkgapi/pkginfo.php b/pkgapi/pkginfo.php new file mode 100644 index 0000000..d9301ed --- /dev/null +++ b/pkgapi/pkginfo.php @@ -0,0 +1,53 @@ +<?php +require_once "../init.php"; + +include BASE . "/lib/http.php"; + +foreach (array('arch', 'repo', 'pkgname') as $must_have_key) { + if (!array_key_exists($must_have_key, $_GET)) + throw_http_error(400, 'Malformed request', 'Key ' . $must_have_key . ' was not given.'); + if (!preg_match('/^[-+_.a-zA-Z0-9]+$/', $_GET[$must_have_key])) + throw_http_error(400, 'Malformed request', 'Value for ' . $must_have_key . ' is invalid.'); +} + +if (($_GET['arch'] != 'i486') && ($_GET['arch'] != 'i686')) + throw_http_error(400, 'Malformed request', 'Architecture ' . $_GET['arch'] . ' is unkown.'); + +$infos = trim( + shell_exec( + 'pacinfo' . + ' --config=' . BASE . '/pkgapi/pacman-' . $_GET['arch'] . '.conf ' . + $_GET['repo'] . '/' . + $_GET['pkgname'] . + ' | grep "^Build Date:"; ' . + 'pacinfo' . + ' --raw' . + ' --config=' . BASE . '/pkgapi/pacman-' . $_GET['arch'] . '.conf ' . + $_GET['repo'] . '/' . + $_GET['pkgname'] . + ' | grep -v "^Build Date:"' + ) +); + +if (!isset($infos)) + throw_http_error(404, 'Package not found.'); + +function parse_pacinfo_line($line) { + return preg_split('/: +/', $line, 2); +} + +function extract_first($array) { + return $array[0]; +} + +$infos = explode("\n", $infos); +$infos = array_map('parse_pacinfo_line', $infos); +$merged_infos = array(); +foreach ($infos as $info) + $merged_infos = array_merge_recursive($merged_infos, array($info[0] => $info[1])); + +header ("Content-type: application/json"); +print json_encode( + $merged_infos, + JSON_UNESCAPED_SLASHES +); diff --git a/static/archnav32.png b/static/archnav32.png Binary files differnew file mode 100644 index 0000000..a7fd0d8 --- /dev/null +++ b/static/archnav32.png diff --git a/static/archweb.css b/static/archweb.css new file mode 100644 index 0000000..29b7172 --- /dev/null +++ b/static/archweb.css @@ -0,0 +1,703 @@ +#archnavbar{ +height:40px!important; +padding:10px 15px!important; +background:#333!important; +border-bottom:5px #08c solid!important} +#archnavbarlogo{ +float:left!important; +margin:0!important; +padding:0!important; +height:40px!important; +width:230px!important; +background:url(archnav32.png) no-repeat!important} +#archnavbarlogo h1{ +margin:0!important; +padding:0!important; +text-indent:-9999px!important} +#archnavbarlogo a{ +display:block!important; +height:40px!important; +width:230px!important} +#archnavbarlist{ +display:inline!important; +float:right!important; +list-style:none!important; +margin:0!important; +padding:0!important} +#archnavbarlist li{ +float:left!important; +font-size:14px!important; +font-family:sans-serif!important; +line-height:45px!important; +padding-right:15px!important; +padding-left:15px!important} +#archnavbarlist li a{ +color:#999; +font-weight:bold!important; +text-decoration:none!important} +#archnavbarlist li a:hover{ +color:white!important; +text-decoration:underline!important} +*{ +margin:0; +padding:0; +line-height:1.4} +body{ +min-width:650px; +background:#f6f9fc; +color:#222; +font:normal 100% sans-serif; +text-align:center} +p{ +margin:.33em 0 1em} +ol, +ul{ +margin-bottom:1em; +padding-left:2em} +ul{ +list-style:square} +code{ +font:1.2em monospace; +background:#ffd; +padding:.15em .25em} +pre{ +font:1.2em monospace; +border:1px solid #bdb; +background:#dfd; +padding:.5em; +margin:1em} +pre code{ +display:block; +background:none; +overflow:auto} +blockquote{ +margin:1.5em 2em} +input{ +vertical-align:middle} +select[multiple]{ +padding:1px 0} +select[multiple] option{ +padding:0 .5em 0 .3em} +input[type=submit]{ +padding:0 .6em} +.clear{ +clear:both} +.hide{ +display:none} +hr{ +border:none; +border-top:1px solid #888} +img{ +border:0} +#content{ +font-size:.812em} +a{ +text-decoration:none} +a:link, +th a:visited{ +color:#07b} +a:visited{ +color:#666} +a:hover{ +text-decoration:underline; +color:#666} +a:active{ +color:#e90} +a.headerlink{ +visibility:hidden; +padding-left:.5em} +h3:hover>a.headerlink{ +visibility:visible} +h2{ +font-size:1.5em; +margin-bottom:.5em; +border-bottom:1px solid #888} +h3{ +font-size:1.25em; +margin-top:.5em} +h4{ +font-size:1.15em; +margin-top:1em} +h5{ +font-size:1em; +margin-top:1em} +#content{ +width:95%; +margin:0 auto; +text-align:left} +#content-left-wrapper{ +float:left; +width:100%} +#content-left{ +margin:0 340px 0 0} +#content-right{ +float:left; +width:300px; +margin-left:-300px} +div.box{ +margin-bottom:1.5em; +padding:.65em; +background:#ecf2f5; +border:1px solid #bcd} +#footer{ +clear:both; +margin:2em 0 1em} +#footer p{ +margin:0; +text-align:center; +font-size:.85em} +div.center, +table.center, +img.center{ +width:auto; +margin-left:auto; +margin-right:auto} +p.center, +td.center, +th.center{ +text-align:center} +table{ +width:100%; +border-collapse:collapse} +table .wrap{ +white-space:normal} +th, +td{ +white-space:nowrap; +text-align:left} +th{ +vertical-align:middle; +font-weight:bold} +td{ +vertical-align:top} +table.pretty1{ +width:auto; +margin-top:.25em; +margin-bottom:.5em; +border-collapse:collapse; +border:1px solid #bcd} +.pretty1 th{ +padding:.35em; +background:#e4eeff; +border:1px solid #bcd} +.pretty1 td{ +padding:.35em; +border:1px dotted #bcd} +table.pretty2{ +width:auto; +margin-top:.25em; +margin-bottom:.5em; +border-collapse:collapse; +border:1px solid #bbb} +.pretty2 th{ +padding:.35em; +background:#eee; +border:1px solid #bbb} +.pretty2 td{ +padding:.35em; +border:1px dotted #bbb} +table.compact{ +width:auto} +.compact td{ +padding:.25em 0 .25em 1.5em} +dl{ +clear:both} +dl dt, +dl dd{ +margin-bottom:4px; +padding:8px 0 4px; +font-weight:bold; +border-top:1px dotted #bbb} +dl dt{ +color:#333; +float:left; +padding-right:15px} +form p{ +margin:.5em 0} +fieldset{ +border:0} +label{ +width:12em; +vertical-align:top; +display:inline-block; +font-weight:bold} +input[type=text], +input[type=password], +textarea{ +padding:.10em} +form.general-form label, +form.general-form .form-help{ +width:10em; +vertical-align:top; +display:inline-block} +form.general-form input[type=text], +form.general-form textarea{ +width:45%} +#archdev-navbar{ +margin:1.5em 0} +#archdev-navbar ul{ +list-style:none; +margin:-0.5em 0; +padding:0} +#archdev-navbar li{ +display:inline; +margin:0; +padding:0; +font-size:.9em} +#archdev-navbar li a{ +padding:0 .5em; +color:#07b} +#sys-message{ +width:35em; +text-align:center; +margin:1em auto; +padding:.5em; +background:#fff; +border:1px solid #f00} +#sys-message p{ +margin:0} +ul.errorlist{ +color:red} +form ul.errorlist{ +margin:.5em 0} +table th.tablesorter-header{ +padding-right:20px; +background-image:url(data:image/gif; +base64, +R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); +background-repeat:no-repeat; +background-position:center right; +cursor:pointer} +table thead th.tablesorter-headerAsc{ +background-color:#e4eeff; +background-image:url(data:image/gif; +base64, +R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7)} +table thead th.tablesorter-headerDesc{ +background-color:#e4eeff; +background-image:url(data:image/gif; +base64, +R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7)} +table thead th.sorter-false{ +background-image:none; +cursor:default} +#intro p.readmore{ +margin:-0.5em 0 0 0; +font-size:.9em; +text-align:right} +#news{ +margin-top:1.5em} +#news h3{ +float:left; +padding-bottom:.5em} +#news div{ +margin-bottom:1em} +#news div p{ +margin-bottom:.5em} +#news .more{ +font-weight:normal} +#news .rss-icon{ +float:right; +margin-top:1em} +#news h4{ +clear:both; +font-size:1em; +margin-top:1.5em; +border-bottom:1px dotted #bbb} +#news .timestamp{ +float:right; +font-size:.85em; +margin:-1.8em .5em 0 0} +#news h3 a{ +display:block; +background:#1794D1; +font-size:15px; +padding:2px 10px; +color:white} +#news a:active{ +color:white} +h3 span.arrow{ +display:block; +width:0; +height:0; +border-left:6px solid transparent; +border-right:6px solid transparent; +border-top:6px solid #1794D1; +margin:0 auto; +font-size:0; +line-height:0} +#pkgsearch{ +padding:1em .75em; +background:#3ad; +color:#fff; +border:1px solid #08b} +#pkgsearch label{ +width:auto; +padding:.1em 0} +#pkgsearch input{ +width:10em; +float:right; +font-size:1em; +color:#000; +background:#fff; +border:1px solid #09c} +.pkgsearch-typeahead{ +position:absolute; +top:100%; +left:0; +z-index:1000; +display:none; +float:left; +padding:.15em .1em; +margin:0; +min-width:10em; +font-size:.812em; +text-align:left; +list-style:none; +background-color:#f6f9fc; +border:1px solid #09c} +.pkgsearch-typeahead li a{ +color:#000} +.pkgsearch-typeahead li.active a{ +color:#07b} +#pkg-updates h3{ +margin:0 0 .3em} +#pkg-updates .more{ +font-weight:normal} +#pkg-updates .rss-icon{ +float:right; +margin:-2em 0 0 0} +#pkg-updates table{ +margin:0} +#pkg-updates td.pkg-name{ +white-space:normal} +#pkg-updates td.pkg-arch{ +text-align:right} +#pkg-updates span.testing{ +font-style:italic} +#pkg-updates span.staging{ +font-style:italic; +color:#ff8040} +#nav-sidebar ul{ +list-style:none; +margin:.5em 0 .5em 1em; +padding:0} +#arch-sponsors img{ +padding:.3em 0} +div.widget{ +margin-bottom:1.5em} +#konami{ +position:fixed; +top:0; +left:0; +width:100%; +height:100%; +text-align:center; +opacity:.6} +#rss-feeds .rss{ +padding-right:20px; +background:url(rss.c5ebdc5318d6.png) top right no-repeat} +#artwork img.inverted{ +background:#333; +padding:0} +#artwork div.imagelist img{ +display:inline; +margin:.75em} +.news-nav{ +float:right; +margin-top:-2.2em} +.news-nav .prev, +.news-nav .next{ +margin:0 1em} +div.news-article .article-info{ +margin:0; +color:#999} +#newsform{ +width:60em} +#newsform input[type=text], +#newsform textarea{ +width:75%} +.todolist-nav{ +float:right; +margin-top:-2.2em} +.todolist-nav .prev, +.todolist-nav .next{ +margin:0 1em} +#donor-list ul{ +width:100%} +#donor-list li{ +float:left; +width:25%; +min-width:20em} +#arch-downloads h3{ +border-bottom:1px dotted #bbb} +table.results{ +font-size:.846em; +border-top:1px dotted #999; +border-bottom:1px dotted #999} +.results th{ +padding:.5em 1em .25em .25em; +border-bottom:1px solid #999; +white-space:nowrap; +background-color:#fff} +.results td{ +padding:.3em 1em .3em 3px} +.results tr.odd{ +background:#fff} +.results tr.even{ +background:#e4eeff} +.results .flagged{ +color:red} +.results tr.empty td{ +text-align:center} +#pkglist-about{ +margin-top:1.5em} +.pkglist-stats{ +font-size:.85em} +#pkglist-results .pkglist-nav{ +float:right; +margin-top:-2.2em} +.pkglist-nav .prev{ +margin-right:1em} +.pkglist-nav .next{ +margin-right:1em} +.filter-criteria{ +margin-bottom:1em} +.filter-criteria h3{ +font-size:1em; +margin-top:0} +.filter-criteria div{ +float:left; +margin-right:1.65em; +font-size:.85em} +.filter-criteria legend{ +display:none} +.filter-criteria label{ +width:auto; +display:block; +font-weight:normal} +#pkgdetails #detailslinks{ +float:right} +#pkgdetails #detailslinks h4{ +margin-top:0; +margin-bottom:.25em} +#pkgdetails #detailslinks ul{ +list-style:none; +padding:0; +margin-bottom:0; +font-size:.846em} +#pkgdetails #detailslinks>div{ +padding:.5em; +margin-bottom:1em; +background:#eee; +border:1px solid #bbb} +#pkgdetails #actionlist .flagged{ +color:red; +font-size:.9em; +font-style:italic} +#pkgdetails #pkginfo{ +width:auto} +#pkgdetails #pkginfo td{ +padding:.25em 0 .25em 1.5em} +#pkgdetails #pkginfo .userdata{ +font-size:.85em; +padding:.5em} +#flag-pkg-form label{ +width:10em} +#flag-pkg-form textarea, +#flag-pkg-form input[type=text]{ +width:45%} +#pkgdetails #metadata{ +clear:both} +#pkgdetails #metadata h3{ +background:#555; +color:#fff; +font-size:1em; +margin-bottom:.5em; +padding:.2em .35em} +#pkgdetails #metadata ul{ +list-style:none; +margin:0; +padding:0} +#pkgdetails #metadata li{ +padding-left:.5em} +#pkgdetails #metadata p{ +padding-left:.5em} +#pkgdetails #metadata .message{ +font-style:italic} +#pkgdetails #metadata br{ +clear:both} +#pkgdetails #pkgdeps{ +float:left; +width:48%; +margin-right:2%} +#pkgdetails #metadata .virtual-dep, +#pkgdetails #metadata .testing-dep, +#pkgdetails #metadata .staging-dep, +#pkgdetails #metadata .opt-dep, +#pkgdetails #metadata .make-dep, +#pkgdetails #metadata .link-dep, +#pkgdetails #metadata .check-dep, +#pkgdetails #metadata .dep-desc{ +font-style:italic} +#pkgdetails #pkgreqs{ +float:left; +width:50%} +#pkgdetails #pkgfiles{ +clear:left; +padding-top:1em} +#pkgfilelist li.d{ +color:#666} +#pkgfilelist li.f{ +} +table td.country{ +white-space:normal} +#list-generator div ul{ +list-style:none; +display:inline; +padding-left:0} +#list-generator div ul li{ +display:inline} +.visualize-mirror .axis path, +.visualize-mirror .axis line{ +fill:none; +stroke:#000; +stroke-width:3px; +shape-rendering:crispEdges} +.visualize-mirror .url-dot{ +stroke:#000} +.visualize-mirror .url-line{ +fill:none; +stroke-width:1.5px} +#arch-bio-toc{ +width:75%; +margin:0 auto; +text-align:center} +#arch-bio-toc a{ +white-space:nowrap} +.arch-bio-entry{ +width:75%; +min-width:640px; +margin:0 auto} +.arch-bio-entry td.pic{ +vertical-align:top; +padding-right:15px; +padding-top:2.25em} +.arch-bio-entry td.pic img{ +padding:4px; +border:1px solid #ccc} +.arch-bio-entry td h3{ +border-bottom:1px dotted #ccc; +margin-bottom:.5em} +.arch-bio-entry table.bio{ +margin-bottom:2em} +.arch-bio-entry table.bio th{ +color:#666; +font-weight:normal; +text-align:right; +padding-right:.5em; +vertical-align:top; +white-space:nowrap} +.arch-bio-entry table.bio td{ +width:100%; +padding-bottom:.25em; +white-space:normal} +#dev-login{ +width:auto} +#dash-pkg-notify{ +text-align:right; +padding:1em 0 0; +margin-top:1em; +font-size:.85em; +border-top:1px dotted #bbb} +#dash-pkg-notify label{ +width:auto; +font-weight:normal} +#dash-pkg-notify input{ +vertical-align:middle; +margin:0 .25em} +#dash-pkg-notify input[type=submit]{ +margin-top:-0.25em} +#dash-pkg-notify p{ +margin:0} +table.dash-stats .key{ +width:50%} +ul.admin-actions{ +float:right; +list-style:none; +margin-top:-2.5em} +ul.admin-actions li{ +display:inline; +padding-left:1.5em} +.todo-table .complete, +.signoff-yes, +#key-status .signed-yes, +#releng-result .success-yes, +#release-list .available-yes{ +color:green} +.todo-table .incomplete, +.signoff-no, +#key-status .signed-no, +#releng-result .success-no, +#release-list .available-no{ +color:red} +.todo-table .inprogress, +.signoff-bad{ +color:darkorange} +.todo-info{ +color:#999; +border-bottom:1px dotted #bbb} +.todo-description{ +margin-top:1em; +padding-left:2em; +max-width:900px} +.todo-pkgbases{ +border-top:1px dotted #bbb} +.todo-list h4{ +margin-top:0; +margin-bottom:.4em} +#dev-signoffs tr:hover{ +background:#ffd} +ul.signoff-list{ +list-style:none; +margin:0; +padding:0} +.signoff-yes{ +font-weight:bold} +.signoff-disabled{ +color:gray} +#releng-feedback label{ +width:auto; +display:inline; +font-weight:normal} +#releng-feedback ul{ +padding-left:1em} +#releng-feedback li{ +list-style:none} +#releng-feedback ul+.helptext{ +position:relative; +top:-0.9em} +#archnavbar.anb-home ul li#anb-home a, +#archnavbar.anb-packages ul li#anb-packages a, +#archnavbar.anb-download ul li#anb-download a{ +color:white!important} +.visualize-buttons{ +margin:.5em .33em} +.visualize-buttons button.active{ +depressed:true} +.visualize-chart{ +position:relative; +height:500px; +margin:.33em} +#visualize-archrepo .treemap-cell{ +border:solid 1px white; +overflow:hidden; +position:absolute} +#visualize-archrepo .treemap-cell span{ +padding:3px; +font-size:.85em; +line-height:1em} +#visualize-keys svg{ +width:100%; +height:100%} + diff --git a/static/favicon.ico b/static/favicon.ico Binary files differnew file mode 100644 index 0000000..8ef6f13 --- /dev/null +++ b/static/favicon.ico diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..90432d2 --- /dev/null +++ b/static/style.css @@ -0,0 +1 @@ +tr:nth-child(even) { background-color: #f2f2f2} |