From cf80b4f24e96e7d6e40845ac1fe206fc67a20b12 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Isma=C3=ABl=20Bouya?= Date: Thu, 3 Jan 2019 15:01:52 +0100 Subject: [PATCH] Add gitweb service --- virtual/eldiron.nix | 19 + virtual/packages.nix | 2 + virtual/packages/gitweb.conf | 24 + virtual/packages/gitweb.nix | 72 +++ virtual/packages/gitweb/git-favicon.png | Bin 0 -> 1125 bytes virtual/packages/gitweb/git-logo.png | Bin 0 -> 2412 bytes virtual/packages/gitweb/gitweb.css | 783 ++++++++++++++++++++++++ virtual/packages/gitweb/gitweb.js | 27 + 8 files changed, 927 insertions(+) create mode 100644 virtual/packages/gitweb.conf create mode 100644 virtual/packages/gitweb.nix create mode 100644 virtual/packages/gitweb/git-favicon.png create mode 100644 virtual/packages/gitweb/git-logo.png create mode 100644 virtual/packages/gitweb/gitweb.css create mode 100644 virtual/packages/gitweb/gitweb.js diff --git a/virtual/eldiron.nix b/virtual/eldiron.nix index 292b31a..c8536c6 100644 --- a/virtual/eldiron.nix +++ b/virtual/eldiron.nix @@ -91,6 +91,8 @@ AuthorizedKeysCommandUser nobody ''; + users.users.wwwrun.extraGroups = [ "gitolite" ]; + # FIXME: after initial install, need to # (1) copy rc file (adjust gitolite_ldap_groups.sh) # (2) (mark old readonly and) sync repos except gitolite-admin @@ -154,6 +156,10 @@ text = '' if [ -d /var/lib/gitolite ]; then ln -sf ${gitolite_ldap_groups} /var/lib/gitolite/gitolite_ldap_groups.sh + chmod g+rx /var/lib/gitolite + fi + if [ -f /var/lib/gitolite/projects.list ]; then + chmod g+r /var/lib/gitolite/projects.list fi ''; }; @@ -245,6 +251,7 @@ mypkgs.connexionswing_dev.apache.modules ++ mypkgs.connexionswing_prod.apache.modules ++ mypkgs.ympd.apache.modules ++ + mypkgs.git.web.apache.modules ++ pkgs.lib.lists.flatten (pkgs.lib.attrsets.mapAttrsToList (n: v: v.modules) apacheConfig) ++ [ "macro" ]); extraConfig = builtins.concatStringsSep "\n" @@ -292,6 +299,18 @@ mypkgs.nextcloud.apache.vhostConf ]; }) + (withSSL "eldiron" // { + listen = [ { ip = "*"; port = 443; } ]; + hostName = "git.immae.eu"; + documentRoot = mypkgs.git.web.webRoot; + extraConfig = builtins.concatStringsSep "\n" [ + mypkgs.git.web.apache.vhostConf + ] + '' + RewriteEngine on + RewriteCond %{REQUEST_URI} ^/releases + RewriteRule /releases(.*) https://release.immae.eu$1 [P,L] + ''; + }) { # Should go last, default fallback listen = [ { ip = "*"; port = 80; } ]; hostName = "redirectSSL"; diff --git a/virtual/packages.nix b/virtual/packages.nix index 3cfa9b6..d9656f7 100644 --- a/virtual/packages.nix +++ b/virtual/packages.nix @@ -5,6 +5,7 @@ let nextcloud = import ./packages/nextcloud.nix; adminer = import ./packages/adminer.nix; ympd = import ./packages/ympd.nix; + gitweb = import ./packages/gitweb.nix; in { inherit adminer; @@ -12,4 +13,5 @@ in connexionswing_dev = connexionswing { environment = "dev"; }; connexionswing_prod = connexionswing { environment = "prod"; }; inherit nextcloud; + git = { web = gitweb; }; } diff --git a/virtual/packages/gitweb.conf b/virtual/packages/gitweb.conf new file mode 100644 index 0000000..0d5f50d --- /dev/null +++ b/virtual/packages/gitweb.conf @@ -0,0 +1,24 @@ +$git_temp = "/tmp"; + +# The directories where your projects are. Must not end with a slash. +$projectroot = "/srv/git/repositories"; + +$projects_list = "/srv/git/projects.list"; +$strict_export = "true"; + +# Base URLs for links displayed in the web interface. +our @git_base_url_list = qw(ssh://gitolite@git.immae.eu https://git.immae.eu); + +$feature{'blame'}{'default'} = [1]; +$feature{'avatar'}{'default'} = ['gravatar']; +$feature{'highlight'}{'default'} = [1]; + +@stylesheets = ("gitweb-theme/gitweb.css"); +$logo = "gitweb-theme/git-logo.png"; +$favicon = "gitweb-theme/git-favicon.png"; + +$javascript = "gitweb-theme/gitweb.js"; +$logo_url = "https://git.immae.eu/"; +$projects_list_group_categories = "true"; +$projects_list_description_width = 60; +$project_list_default_category = "__Others__"; diff --git a/virtual/packages/gitweb.nix b/virtual/packages/gitweb.nix new file mode 100644 index 0000000..437a11a --- /dev/null +++ b/virtual/packages/gitweb.nix @@ -0,0 +1,72 @@ +with import ../../libs.nix; +with nixpkgs_unstable; +let + gitweb = rec { + varDir = "/var/lib/gitolite"; + webRoot = pkgs.gitweb.overrideAttrs(old: { + installPhase = old.installPhase + '' + cp -r ${./gitweb} $out/gitweb-theme; + ''; + }); + config = pkgs.writeText "gitweb.conf" '' + $git_temp = "/tmp"; + + # The directories where your projects are. Must not end with a + # slash. + $projectroot = "${varDir}/repositories"; + + $projects_list = "${varDir}/projects.list"; + $strict_export = "true"; + + # Base URLs for links displayed in the web interface. + our @git_base_url_list = qw(ssh://gitolite@git.immae.eu https://git.immae.eu); + + $feature{'blame'}{'default'} = [1]; + $feature{'avatar'}{'default'} = ['gravatar']; + $feature{'highlight'}{'default'} = [1]; + + @stylesheets = ("gitweb-theme/gitweb.css"); + $logo = "gitweb-theme/git-logo.png"; + $favicon = "gitweb-theme/git-favicon.png"; + $javascript = "gitweb-theme/gitweb.js"; + $logo_url = "https://git.immae.eu/"; + $projects_list_group_categories = "true"; + $projects_list_description_width = 60; + $project_list_default_category = "__Others__"; + ''; + apache = { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "cgid" ]; + vhostConf = '' + SetEnv GIT_PROJECT_ROOT ${varDir}/repositories/ + ScriptAliasMatch \ + "(?x)^/(.*/(HEAD | \ + info/refs | \ + objects/(info/[^/]+ | \ + [0-9a-f]{2}/[0-9a-f]{38} | \ + pack/pack-[0-9a-f]{40}\.(pack|idx)) | \ + git-(upload|receive)-pack))$" \ + ${pkgs.git}/libexec/git-core/git-http-backend/$1 + + + Require all granted + + + Require all granted + + + DirectoryIndex gitweb.cgi + Require all granted + AllowOverride None + Options ExecCGI FollowSymLinks + + SetHandler cgi-script + SetEnv GITWEB_CONFIG "${config}" + + + ''; + }; +}; +in + gitweb diff --git a/virtual/packages/gitweb/git-favicon.png b/virtual/packages/gitweb/git-favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..4fa44bb051e6ed0726911f095d6991e430805242 GIT binary patch literal 1125 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 .list_head { + width: 98.5%; +} + +.page_body > .diff_tree { + width: 99.5%; +} + +.patch > .header { + width: 99%; +} + +.author .avatar, +.author_date .avatar { + position: relative; + top: 3px; +} + +.object_header .avatar { + border: 1px solid #D8D8D8; + float: right; +} + +.object_header td, +.object_header th { + vertical-align: top; +} + +/* Refs +---------------------------------------------------------------------------- */ + +span.refs span { + color: #707070; + display: inline-block; + margin: 0; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 3px; + height: 18px; + padding: 0 6px; + text-overflow: ellipsis; +} + +span.refs span.ref { + color: #707070; + display: inline-block; + margin: 0; + background-color: #c4c4ff; + border: 1px solid #7878ff; + border-radius: 3px; + height: 18px; + padding: 0 6px; + text-overflow: ellipsis; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSUnpolg7AAAAHJQTFRFAAAAVVWqZmbMVVXVYGDgbW3td3fuc3PzdHT0cHD1d3f6dHT6dnb7dHT7dnb8dnb8dnb9d3f9dnb+eHj+d3f+eHj+d3f+d3f+d3f+eHj+d3f+eHj+d3f+eHj+d3f+d3f+eHj+d3f+d3f+d3f+eHj/////V9oQhQAAACR0Uk5TAAIEBQcNDhMVGCotNTZAT217i5CgobvExtjZ4eLr7vP09ff7uqQ6cgAAAAFiS0dEJcMByQ8AAABUSURBVBjTpc43AoAwDENRh95bgNBM1f3PyOpslD++RSJ61YgH5M2IbIkn4GocSR1MZVBL4t2n4FgkbaxI8Sqph041WknZCWAIrcmEUbpf3lNe0N9u59YFYHnZ78gAAAAASUVORK5CYII=); + background-repeat: no-repeat; + padding-left: 18px; +} + +span.refs span.tag { + color: #707070; + display: inline-block; + margin: 0; + background-color: #ffffab; + border: 1px solid #d9d93b; + border-radius: 3px; + height: 18px; + padding: 0 6px; + text-overflow: ellipsis; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAMAAABhEH5lAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSUZZ+h9RwAAAGZQTFRFAAAAtrYkwMBAwMBAx8c4yso11NQ71NQ51dU52Ng71tY519c719c719c62Ng719c719c62Ng72dk62Ng62Ng72Ng72dk62Ng72Ng62dk62dk72dk62Ng62dk72Ng72Ng72dk7////ou/AnQAAACB0Uk5TAAYHCxESLjRCWWlqa4uNkpissbrO19jc3ufs8vf6/f7atAU2AAAAAWJLR0QhxGwNFgAAAF1JREFUGFeNy0cOgCAABVGw94rY5d//lC7omhhn+ZIh5Gf1xPk0Zi5dAABROIQjSU/fsAXhDkCUljAv8jW2wlQpaixpo4Nj+dtatVpjkSJjLNaizRVpvhBCu/4h391jzw1lU12Z7wAAAABJRU5ErkJggg==); + background-repeat: no-repeat; + padding-left: 18px; +} + +span.refs span.head { + color: #707070; + display: inline-block; + margin: 0; + background-color: #c4ffc4; + border: 1px solid #78ff78; + border-radius: 3px; + height: 18px; + padding: 0 6px; + text-overflow: ellipsis; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKFSYDsafX/gAAAUpJREFUOMvVkjFLA0EQhd/s7l06MSCihbV/wC5/QBDEIFYWprRIIQQJFqKFQi4kUbBQsFSwtrUQLQULUTBFLCzVIgimCXe7z0q5yIWcqfRVwzDzMTNvgL8mSUqWw3JOtFQJdsIwLDYyjdYgkEmkazl2oVtQWk36nn8AYBYASmFpxmizGtnoqO7Vb+M9KglEkASdpWU872nvVCiPRpuTnz2JIHGyqX3d0kZfR1G0Ht+g/do+FIhOBbLW3n/FNb/28D0puZ+dyL44ur1UoH5yzt2JyIj6UGdDgwrPhYzSagNEszJaeU/lWlylbmnaeGZZICsAppxzi6nt73HK85oQCMknOuarpno+FIjglVjZDXaCS2yDv3rIHlCb88FY0BlUl3hs7ektkhckb5DFWhoz+n12zr7ZPLpYUqLm0oBMn8NUzLhpAgjpWMS/1CcSJ3ykD7Rk1QAAAABJRU5ErkJggg==); + background-repeat: no-repeat; + padding-left: 18px; +} + +span.refs a { + color: #4e4e4e; + font: 11px "Bitstream Vera Sans Mono", "DejaVu Sans Mono", Monaco, monospace; + line-height: 18px; +} + +/* Diffs +---------------------------------------------------------------------------- */ + +div.diff.to_file a.path, +div.diff.to_file { + color: #007000; +} + +div.diff.from_file a.path, +div.diff.from_file { + color: #aa0000; +} + +.patch .header { + margin: 0; +} + +.patchset { + overflow-x: auto; + overflow-y: hidden; +} + +.chunk_header { + background: #eaf2f5; + color: #999; +} + +.rem { + background: #ffdddd; +} +.rem .marked { + background: #ffaaaa; +} +.add { + background: #ddffdd; +} +.add .marked { + background: #7dff7d; +} + +.extended_header { + width: 99.5%; +} + +div.chunk_block { + overflow: hidden; +} + +div.chunk_block div.old { + float: left; + width: 50%; + overflow: hidden; + border-right: 5px solid #EAF2F5; +} + +div.chunk_block.rem, +div.chunk_block.add { + background: transparent; +} + +div.chunk_block div.old .add, +div.chunk_block div.old .rem { + padding-right: 3px; +} + +div.chunk_block div.new .add, +div.chunk_block div.new .rem { + padding-left: 3px; +} + +div.chunk_block div.new { + margin-left: 50%; + width: 50%; + border-left: 5px solid #EAF2F5; +} + +/* Category +---------------------------------------------------------------------------- */ + +td.category { + background: #E6F1F6; /* old browsers */ + background: -moz-linear-gradient(top, #C8D8E7 0%, #E6F1F3 100%); /* firefox */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#C8D8E7), color-stop(100%,#E6F1F3)); /* webkit */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#C8D8E7', endColorstr='#E6F1F3',GradientType=0 ); /* ie */ + background: -o-linear-gradient(top, #C8D8E7 0%, #E6F1F3 100%); + font-weight: bold; + border-bottom: 1px solid #D1D1D1; + border-top: 1px solid #D1D1D1; +} + +/* Age +---------------------------------------------------------------------------- */ + +/* noage: "No commits" */ +.project_list td.noage { + color: #cdcdcd; +} + +/* age2: 60*60*24*2 <= age */ +.project_list td.age2, .blame td.age2 { + color: #545454; +} + +/* age1: 60*60*2 <= age < 60*60*24*2 */ +.project_list td.age1 { + color: #009900; +} + +/* age0: age < 60*60*2 */ +.project_list td.age0 { + color: #009900; + font-weight: bold; +} + +/* File status +---------------------------------------------------------------------------- */ + +.diff_tree span.file_status.new { + color: #008000; +} + +table.diff_tree span.file_status.deleted { + color: #c00000; +} + +table.diff_tree span.file_status.moved, +table.diff_tree span.file_status.mode_chnge { + color: #545454; +} + +table.diff_tree span.file_status.copied { + color: #70a070; +} + +span.cntrl { + border: dashed #aaaaaa; + border-width: 1px; + padding: 0px 2px 0px 2px; + margin: 0px 2px 0px 2px; +} + +span.match { + background: #aaffaa; + color: #000; +} + +td.error { + color: red; + background: yellow; +} + +/* blob view */ + +td.pre, div.pre, div.diff { + white-space: pre-wrap; +} + +/* JavaScript-based timezone manipulation */ + +.popup { /* timezone selection UI */ + position: absolute; + /* "top: 0; right: 0;" would be better, if not for bugs in browsers */ + top: 0; left: 0; + border: 1px solid #d8d8d8; + padding: 2px; + background-color: #f0f0f0; + font-style: normal; + color: #545454; + cursor: auto; +} + +.close-button { /* close timezone selection UI without selecting */ + /* float doesn't work within absolutely positioned container, + * if width of container is not set explicitly */ + /* float: right; */ + position: absolute; + top: 0px; right: 0px; + border: 1px solid #ffaaaa; + margin: 1px 1px 1px 1px; + padding-bottom: 2px; + width: 12px; + height: 10px; + font-size: 9px; + font-weight: bold; + text-align: center; + background-color: #ffdddd; + cursor: pointer; +} + +/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */ + +/* Highlighting theme definition: */ + +.num { color:#6ecf36; } +.esc { color:#ff00ff; } +.str { color:#ff00d3; background-color: #edc9ec } +.dstr { color:#818100; } +.slc { color:#838183; font-style:italic; } +.com { color:#838183; font-style:italic; } +.dir { color:#008200; } +.sym { color:#000000; } +.line { color:#555555; } +.kwa { color:#666666; font-weight:bold; } +.kwb { color:#6b3099; } +.kwc { color:#d4663d; } +.kwd { color:#2928ff; } + +/**** Styles supplémentaires *****/ + +.readme div.toc { + float: right; + border: 1px solid black; + background-color: white; +} +.readme div.toc span.toctitle { + display: inline-block; + width: 100%; + text-align: center; + font-weight: bold; +} + +.readme table { + background-color: white; +} + +.readme table thead tr { + background-color: #ccc; +} + +.readme table tbody tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.readme table td, .readme table th { + border: 1px solid black; +} diff --git a/virtual/packages/gitweb/gitweb.js b/virtual/packages/gitweb/gitweb.js new file mode 100644 index 0000000..72f3cfa --- /dev/null +++ b/virtual/packages/gitweb/gitweb.js @@ -0,0 +1,27 @@ +function include(filename, onload) { + var head = document.getElementsByTagName('head')[0]; + var script = document.createElement('script'); + script.src = filename; + script.type = 'text/javascript'; + script.onload = script.onreadystatechange = function() { + if (script.readyState) { + if (script.readyState === 'complete' || script.readyState === 'loaded') { + script.onreadystatechange = null; + onload(); + } + } + else { + onload(); + } + } + head.appendChild(script); +} + +include('static/gitweb.js', function() {}); +include('//code.jquery.com/jquery-3.1.0.min.js', function() { + $("div.title").each(function(index, element) { + if ($(element).text() === "readme" || $(element).text() === " ") { + $(element).hide(); + } + }); +}); -- 2.41.0