From 7786ce2a332b0eba4b3ca7c57f906a32e8715da3 Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Fri, 29 Oct 2010 19:46:24 -0500 Subject: Starting repo cleanup to make this not so awful --- architecture.mdwn | 1 - architecture/data.mdwn | 19 - architecture/features.mdwn | 7 - architecture/mail.mdwn | 6 - architecture/needed_admin_infrastructure.mdwn | 7 - .../needed_user_facing_infrastructure.mdwn | 37 -- architecture/setup_file_overrides.mdwn | 24 - docs.mdwn | 1 + docs/architecture.mdwn | 1 + docs/architecture/data.mdwn | 19 + docs/architecture/features.mdwn | 7 + docs/architecture/mail.mdwn | 6 + docs/architecture/needed_admin_infrastructure.mdwn | 7 + .../needed_user_facing_infrastructure.mdwn | 37 ++ docs/architecture/setup_file_overrides.mdwn | 24 + libpiny/Build.PL | 30 + libpiny/debian/changelog | 89 +++ libpiny/debian/compat | 1 + libpiny/debian/control | 13 + libpiny/debian/copyright | 2 + libpiny/debian/rules | 4 + libpiny/debian/source/format | 1 + libpiny/lib/IkiWiki/FakeSetup.pm | 88 +++ libpiny/lib/Piny.pm | 16 + libpiny/lib/Piny/Config.pm | 218 +++++++ libpiny/lib/Piny/Email.pm | 49 ++ libpiny/lib/Piny/Environment.pm | 45 ++ libpiny/lib/Piny/Group.pm | 136 +++++ libpiny/lib/Piny/Repo.pm | 637 +++++++++++++++++++++ libpiny/lib/Piny/User.pm | 216 +++++++ libpiny/lib/Piny/User/IkiWiki.pm | 37 ++ libpiny/share/ikiwiki.setup | 76 +++ libpiny/test | 12 + pinyadmin/Makefile | 12 + pinyadmin/bin/addaccess | 2 + pinyadmin/bin/appendkeys | 5 + pinyadmin/bin/createuser | 1 + pinyadmin/bin/lsaccess | 30 + pinyadmin/bin/lsrepo | 10 + pinyadmin/bin/newrepo | 2 + pinyadmin/bin/newuser | 2 + pinyadmin/bin/pinyconfig | 2 + pinyadmin/bin/pinyshell | 5 + pinyadmin/bin/readkeys | 3 + pinyadmin/bin/rmaccess | 2 + pinyadmin/bin/rmrepo | 2 + pinyadmin/bin/writekeys | 5 + pinyadmin/debian/changelog | 48 ++ pinyadmin/debian/compat | 1 + pinyadmin/debian/control | 13 + pinyadmin/debian/copyright | 3 + pinyadmin/debian/pinyadmin.manpages | 1 + pinyadmin/debian/rules | 4 + pinyadmin/debian/source/format | 1 + pinyadmin/doc/addaccess.latex | 17 + pinyadmin/doc/newrepo.latex | 15 + pinyadmin/doc/newuser.latex | 16 + pinyadmin/doc/pinyconfig.latex | 17 + pinyadmin/doc/pinyshell.latex | 19 + pinyadmin/doc/rebuildrepo.latex | 16 + pinyadmin/doc/rmaccess.latex | 22 + pinyadmin/doc/rmrepo.latex | 14 + pinyadmin/sbin/addaccess | 19 + pinyadmin/sbin/newrepo | 40 ++ pinyadmin/sbin/newuser | 129 +++++ pinyadmin/sbin/pinyconfig | 38 ++ pinyadmin/sbin/rebuildrepo | 14 + pinyadmin/sbin/rmaccess | 19 + pinyadmin/sbin/rmrepo | 21 + usr/src/libpiny/Build.PL | 30 - usr/src/libpiny/debian/changelog | 89 --- usr/src/libpiny/debian/compat | 1 - usr/src/libpiny/debian/control | 13 - usr/src/libpiny/debian/copyright | 2 - usr/src/libpiny/debian/rules | 4 - usr/src/libpiny/debian/source/format | 1 - usr/src/libpiny/lib/IkiWiki/FakeSetup.pm | 88 --- usr/src/libpiny/lib/Piny.pm | 16 - usr/src/libpiny/lib/Piny/Config.pm | 218 ------- usr/src/libpiny/lib/Piny/Email.pm | 49 -- usr/src/libpiny/lib/Piny/Environment.pm | 45 -- usr/src/libpiny/lib/Piny/Group.pm | 136 ----- usr/src/libpiny/lib/Piny/Repo.pm | 637 --------------------- usr/src/libpiny/lib/Piny/User.pm | 216 ------- usr/src/libpiny/lib/Piny/User/IkiWiki.pm | 37 -- usr/src/libpiny/share/ikiwiki.setup | 76 --- usr/src/libpiny/test | 12 - usr/src/pinyadmin/Makefile | 12 - usr/src/pinyadmin/bin/addaccess | 2 - usr/src/pinyadmin/bin/appendkeys | 5 - usr/src/pinyadmin/bin/createuser | 1 - usr/src/pinyadmin/bin/lsaccess | 30 - usr/src/pinyadmin/bin/lsrepo | 10 - usr/src/pinyadmin/bin/newrepo | 2 - usr/src/pinyadmin/bin/newuser | 2 - usr/src/pinyadmin/bin/pinyconfig | 2 - usr/src/pinyadmin/bin/pinyshell | 5 - usr/src/pinyadmin/bin/readkeys | 3 - usr/src/pinyadmin/bin/rmaccess | 2 - usr/src/pinyadmin/bin/rmrepo | 2 - usr/src/pinyadmin/bin/writekeys | 5 - usr/src/pinyadmin/debian/changelog | 48 -- usr/src/pinyadmin/debian/compat | 1 - usr/src/pinyadmin/debian/control | 13 - usr/src/pinyadmin/debian/copyright | 3 - usr/src/pinyadmin/debian/pinyadmin.manpages | 1 - usr/src/pinyadmin/debian/rules | 4 - usr/src/pinyadmin/debian/source/format | 1 - usr/src/pinyadmin/doc/addaccess.latex | 17 - usr/src/pinyadmin/doc/newrepo.latex | 15 - usr/src/pinyadmin/doc/newuser.latex | 16 - usr/src/pinyadmin/doc/pinyconfig.latex | 17 - usr/src/pinyadmin/doc/pinyshell.latex | 19 - usr/src/pinyadmin/doc/rebuildrepo.latex | 16 - usr/src/pinyadmin/doc/rmaccess.latex | 22 - usr/src/pinyadmin/doc/rmrepo.latex | 14 - usr/src/pinyadmin/sbin/addaccess | 19 - usr/src/pinyadmin/sbin/newrepo | 40 -- usr/src/pinyadmin/sbin/newuser | 129 ----- usr/src/pinyadmin/sbin/pinyconfig | 38 -- usr/src/pinyadmin/sbin/rebuildrepo | 14 - usr/src/pinyadmin/sbin/rmaccess | 19 - usr/src/pinyadmin/sbin/rmrepo | 21 - 123 files changed, 2342 insertions(+), 2341 deletions(-) delete mode 100644 architecture.mdwn delete mode 100644 architecture/data.mdwn delete mode 100644 architecture/features.mdwn delete mode 100644 architecture/mail.mdwn delete mode 100644 architecture/needed_admin_infrastructure.mdwn delete mode 100644 architecture/needed_user_facing_infrastructure.mdwn delete mode 100644 architecture/setup_file_overrides.mdwn create mode 100644 docs.mdwn create mode 100644 docs/architecture.mdwn create mode 100644 docs/architecture/data.mdwn create mode 100644 docs/architecture/features.mdwn create mode 100644 docs/architecture/mail.mdwn create mode 100644 docs/architecture/needed_admin_infrastructure.mdwn create mode 100644 docs/architecture/needed_user_facing_infrastructure.mdwn create mode 100644 docs/architecture/setup_file_overrides.mdwn create mode 100644 libpiny/Build.PL create mode 100644 libpiny/debian/changelog create mode 100644 libpiny/debian/compat create mode 100644 libpiny/debian/control create mode 100644 libpiny/debian/copyright create mode 100755 libpiny/debian/rules create mode 100644 libpiny/debian/source/format create mode 100644 libpiny/lib/IkiWiki/FakeSetup.pm create mode 100644 libpiny/lib/Piny.pm create mode 100644 libpiny/lib/Piny/Config.pm create mode 100644 libpiny/lib/Piny/Email.pm create mode 100644 libpiny/lib/Piny/Environment.pm create mode 100644 libpiny/lib/Piny/Group.pm create mode 100644 libpiny/lib/Piny/Repo.pm create mode 100644 libpiny/lib/Piny/User.pm create mode 100644 libpiny/lib/Piny/User/IkiWiki.pm create mode 100644 libpiny/share/ikiwiki.setup create mode 100755 libpiny/test create mode 100644 pinyadmin/Makefile create mode 100755 pinyadmin/bin/addaccess create mode 100755 pinyadmin/bin/appendkeys create mode 120000 pinyadmin/bin/createuser create mode 100755 pinyadmin/bin/lsaccess create mode 100755 pinyadmin/bin/lsrepo create mode 100755 pinyadmin/bin/newrepo create mode 100755 pinyadmin/bin/newuser create mode 100755 pinyadmin/bin/pinyconfig create mode 100755 pinyadmin/bin/pinyshell create mode 100755 pinyadmin/bin/readkeys create mode 100755 pinyadmin/bin/rmaccess create mode 100755 pinyadmin/bin/rmrepo create mode 100755 pinyadmin/bin/writekeys create mode 100644 pinyadmin/debian/changelog create mode 100644 pinyadmin/debian/compat create mode 100644 pinyadmin/debian/control create mode 100644 pinyadmin/debian/copyright create mode 100644 pinyadmin/debian/pinyadmin.manpages create mode 100755 pinyadmin/debian/rules create mode 100644 pinyadmin/debian/source/format create mode 100644 pinyadmin/doc/addaccess.latex create mode 100644 pinyadmin/doc/newrepo.latex create mode 100644 pinyadmin/doc/newuser.latex create mode 100644 pinyadmin/doc/pinyconfig.latex create mode 100644 pinyadmin/doc/pinyshell.latex create mode 100644 pinyadmin/doc/rebuildrepo.latex create mode 100644 pinyadmin/doc/rmaccess.latex create mode 100644 pinyadmin/doc/rmrepo.latex create mode 100755 pinyadmin/sbin/addaccess create mode 100755 pinyadmin/sbin/newrepo create mode 100755 pinyadmin/sbin/newuser create mode 100755 pinyadmin/sbin/pinyconfig create mode 100755 pinyadmin/sbin/rebuildrepo create mode 100755 pinyadmin/sbin/rmaccess create mode 100755 pinyadmin/sbin/rmrepo delete mode 100644 usr/src/libpiny/Build.PL delete mode 100644 usr/src/libpiny/debian/changelog delete mode 100644 usr/src/libpiny/debian/compat delete mode 100644 usr/src/libpiny/debian/control delete mode 100644 usr/src/libpiny/debian/copyright delete mode 100755 usr/src/libpiny/debian/rules delete mode 100644 usr/src/libpiny/debian/source/format delete mode 100644 usr/src/libpiny/lib/IkiWiki/FakeSetup.pm delete mode 100644 usr/src/libpiny/lib/Piny.pm delete mode 100644 usr/src/libpiny/lib/Piny/Config.pm delete mode 100644 usr/src/libpiny/lib/Piny/Email.pm delete mode 100644 usr/src/libpiny/lib/Piny/Environment.pm delete mode 100644 usr/src/libpiny/lib/Piny/Group.pm delete mode 100644 usr/src/libpiny/lib/Piny/Repo.pm delete mode 100644 usr/src/libpiny/lib/Piny/User.pm delete mode 100644 usr/src/libpiny/lib/Piny/User/IkiWiki.pm delete mode 100644 usr/src/libpiny/share/ikiwiki.setup delete mode 100755 usr/src/libpiny/test delete mode 100644 usr/src/pinyadmin/Makefile delete mode 100755 usr/src/pinyadmin/bin/addaccess delete mode 100755 usr/src/pinyadmin/bin/appendkeys delete mode 120000 usr/src/pinyadmin/bin/createuser delete mode 100755 usr/src/pinyadmin/bin/lsaccess delete mode 100755 usr/src/pinyadmin/bin/lsrepo delete mode 100755 usr/src/pinyadmin/bin/newrepo delete mode 100755 usr/src/pinyadmin/bin/newuser delete mode 100755 usr/src/pinyadmin/bin/pinyconfig delete mode 100755 usr/src/pinyadmin/bin/pinyshell delete mode 100755 usr/src/pinyadmin/bin/readkeys delete mode 100755 usr/src/pinyadmin/bin/rmaccess delete mode 100755 usr/src/pinyadmin/bin/rmrepo delete mode 100755 usr/src/pinyadmin/bin/writekeys delete mode 100644 usr/src/pinyadmin/debian/changelog delete mode 100644 usr/src/pinyadmin/debian/compat delete mode 100644 usr/src/pinyadmin/debian/control delete mode 100644 usr/src/pinyadmin/debian/copyright delete mode 100644 usr/src/pinyadmin/debian/pinyadmin.manpages delete mode 100755 usr/src/pinyadmin/debian/rules delete mode 100644 usr/src/pinyadmin/debian/source/format delete mode 100644 usr/src/pinyadmin/doc/addaccess.latex delete mode 100644 usr/src/pinyadmin/doc/newrepo.latex delete mode 100644 usr/src/pinyadmin/doc/newuser.latex delete mode 100644 usr/src/pinyadmin/doc/pinyconfig.latex delete mode 100644 usr/src/pinyadmin/doc/pinyshell.latex delete mode 100644 usr/src/pinyadmin/doc/rebuildrepo.latex delete mode 100644 usr/src/pinyadmin/doc/rmaccess.latex delete mode 100644 usr/src/pinyadmin/doc/rmrepo.latex delete mode 100755 usr/src/pinyadmin/sbin/addaccess delete mode 100755 usr/src/pinyadmin/sbin/newrepo delete mode 100755 usr/src/pinyadmin/sbin/newuser delete mode 100755 usr/src/pinyadmin/sbin/pinyconfig delete mode 100755 usr/src/pinyadmin/sbin/rebuildrepo delete mode 100755 usr/src/pinyadmin/sbin/rmaccess delete mode 100755 usr/src/pinyadmin/sbin/rmrepo diff --git a/architecture.mdwn b/architecture.mdwn deleted file mode 100644 index 581ceb7..0000000 --- a/architecture.mdwn +++ /dev/null @@ -1 +0,0 @@ -[[!map pages="architecture/* and ! architecture/*/*"]] diff --git a/architecture/data.mdwn b/architecture/data.mdwn deleted file mode 100644 index a81a268..0000000 --- a/architecture/data.mdwn +++ /dev/null @@ -1,19 +0,0 @@ -Data model! - -Dynamic data lookup should opportunisticly cache any associated cheap data. For instance, there are three data from stat(/srv/git/$reponame.git), so looking up one should grab the others. Jules points out that everything here is inherently cached, and I should be using getpw*() for passwd parsing. - -[[!table format=dsv delimiter=# data=""" -datum #stored location #constraint -username #usually $ENV{SUDO_USER} # !~ /^git-|^ikiwiki-/ and =~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ -uid #/etc/passwd # None -email #/etc/passwd GECOS #Email::Valid::Loose->new("-fqdn" => 1, "-fudge" => 0, "-local_rules" => 0, "-mxcheck" => 1, "-tldcheck" => 0 ); -repoaccess #/etc/group git-$reponame entry # None -reponame #/srv/git/$reponame.git # =~ /^[a-z0-9][a-z0-9.-]+$/ -repodescription #/srv/git/$reponame.git/description # =~ /^[\x{0020}-\x{FDCF}\x{FDF0}-\x{FFFD}]{1,80}$/ -repoowner #stat /srv/git/$reponame.git/objects uid; might be better as first non-ikiwiki user in /etc/group git-$reponame entry # None -repoglobalwritable #stat /srv/git/$reponame.git/objects o+w bit # None -repoglobalreadable #stat /srv/git/$reponame.git/objects o+r bit # None -repoikiwikidisable #probably in /srv/git/$reponame.git/config # None -repointernaltemplates #probably in /srv/git/$reponame.git/config # None -repospecialdomain #probably in /srv/git/$reponame.git/config # None -"""]] diff --git a/architecture/features.mdwn b/architecture/features.mdwn deleted file mode 100644 index fbdedb2..0000000 --- a/architecture/features.mdwn +++ /dev/null @@ -1,7 +0,0 @@ -An in-distributed-repo model for - -- code -- blogs -- bugs -- web pages -- [[mail]] diff --git a/architecture/mail.mdwn b/architecture/mail.mdwn deleted file mode 100644 index 61bbfcd..0000000 --- a/architecture/mail.mdwn +++ /dev/null @@ -1,6 +0,0 @@ -I can presumably get mailing lists into ikiwiki using one of the following: - -- MLM+Ikiwiki [comment-by-mail plugin](http://ikiwiki.info/todo/comment_by_mail/) -- MLM+Ikiwiki [mailbox plugin](http://pivot.cs.unb.ca/git/?p=ikimailbox.git;a=summary) - -But how would we get it into git? Might we have to do that externally? diff --git a/architecture/needed_admin_infrastructure.mdwn b/architecture/needed_admin_infrastructure.mdwn deleted file mode 100644 index 59365c2..0000000 --- a/architecture/needed_admin_infrastructure.mdwn +++ /dev/null @@ -1,7 +0,0 @@ -- DONE: HTTP AUTH from PAM through the magic of mod-auth-pam -- DONE: HTTP access from /etc/group through the magic of mod-auth-sys-group -- DONE: Shell security through rbash and privilege escalation security (for mkwiki, mkuser, etc) through sudo -- DONE: Guaranteed namespace coherence with the vhosting of cgi, secure, and normal with the aid of a wildcard SSL certificate -- TODO: Work out how to pass mailing list emails around. Probably either ssh or vserver namespace magic. -- DONE: manual [[setup file overrides]], /etc/ikiwiki/piny/$reponame.setup.pl, included directly with 'do' before dumping state. -- DONE: rebuildrepo diff --git a/architecture/needed_user_facing_infrastructure.mdwn b/architecture/needed_user_facing_infrastructure.mdwn deleted file mode 100644 index 1e7284a..0000000 --- a/architecture/needed_user_facing_infrastructure.mdwn +++ /dev/null @@ -1,37 +0,0 @@ -TODO: user-facing documentation on piny-web -TODO: help system on pinyshell (display on login) - -It'd be nice to maintain feature parity between command line access and web access. - -[[!table data=""" -feature |command line |web -anonymous account creation |DONE: ssh createuser@piny.be |TODO: CGI frontend to adduser -password modification |DONE: /srv/rbin/passwd |TODO: Authen::PAM chauthtok CGI jblake: the pam interface was *really* not designed with http in mind though if you hard-code the interaction script it's not hard at all -repo creation, deletion |DONE: /srv/rbin/newrepo, rmrepo, lsrepo |TODO: CGI frontend -repo user management |DONE: /srv/rbin/addaccess, rmaccess, lsaccess |TODO: CGI frontend -[[mailing list addition|mail]] |TODO: /srv/rbin/addlist, dependent on getting sympa up |TODO: CGI frontend -authorized_keys modification |DONE: /srv/rbin/readkeys, writekeys, appendkeys |TODO: CGI frontend, though i am not convinced anyone would care -disable password auth if ssh key|TODO |Ha ha NEVER -commit access |DONE: git+ssh://piny.be/srv/git/whatever.git |DONE: Ikiwiki+mod-auth-sys-group/mod-auth-pam, though I am told there is a magic hook to allow public editing through git:// -wysiwyg editing tool |Ha ha no |TODO: wmd a good option, though needs UI tweaks -fork |TODO: /srv/rbin/fork |TODO: CGI frontend -upload and commit container contents |no |TODO: CGI frontend -user or repo activity data aggregation |TODO: /srv/rbin/activity |TODO: rss generation, possibly install a dynamic rss reader -help system |lock down 'man', print introduction on login |command documentation should be rendered online, perhaps -config tweaking |PARTIAL: pinyconfig |TODO: CGI frontend -"""]] - -Needed config tweakables - -- TODO: ikiwiki-editable vs. git-only -- TODO: toggle ikiwiki autoindexing -- TODO: optional use of repository subdirectory as srcdir -- TODO: globally readable repos vs. group readable repos -- TODO: globally writable repos vs. group writable repos -- TODO: editable ikiwiki templates vs. default layout -- TODO: user-configured domain vs. default piny domain - -Other - -- TODO: overall site layout/theme/css -- TODO: front page to piny server editable by sysadmin ("here's what's on this server; readme; faq; about;") diff --git a/architecture/setup_file_overrides.mdwn b/architecture/setup_file_overrides.mdwn deleted file mode 100644 index 6133a22..0000000 --- a/architecture/setup_file_overrides.mdwn +++ /dev/null @@ -1,24 +0,0 @@ -Use cases: - -### Adding post-update hooks, which requires diverting Ikiwiki's hook. - - mv /srv/git/poop.git/hooks/post-update /srv/git/poop.git/hooks/post-update-ikiwiki - cat > /srv/git/poop.git/hooks/post-update - #!/bin/sh - /srv/git/poop.git/hooks/post-update-ikiwiki & - echo This is a hook that does things! - cat > /srv/ikiwiki/piny/poop.setup.pl - foreach(@{$conf->{wrappers}}) { $_->{wrapper} =~ s/post-update/post-update-ikiwiki/; }; - rebuildrepo poop - -### Adding or removing plugins, or plugin confuration variables. - - cat > /srv/ikiwiki/piny/poop.setup.pl - push(@{$conf->{add_plugins}}, 'txt'); - rebuildrepo poop - -### Any other special confuration requests from hosted projects. - - cat > /srv/ikiwiki/piny/poop.setup.pl - $conf->{teximg_prefix} .= "\n\\newcommand{\\unit}[1]{\\ensuremath{\\, \\mathrm{#1}}}" - rebuildrepo poop diff --git a/docs.mdwn b/docs.mdwn new file mode 100644 index 0000000..5a6f22b --- /dev/null +++ b/docs.mdwn @@ -0,0 +1 @@ +[[!map pages="docs/* and ! docs/*/*"]] diff --git a/docs/architecture.mdwn b/docs/architecture.mdwn new file mode 100644 index 0000000..581ceb7 --- /dev/null +++ b/docs/architecture.mdwn @@ -0,0 +1 @@ +[[!map pages="architecture/* and ! architecture/*/*"]] diff --git a/docs/architecture/data.mdwn b/docs/architecture/data.mdwn new file mode 100644 index 0000000..a81a268 --- /dev/null +++ b/docs/architecture/data.mdwn @@ -0,0 +1,19 @@ +Data model! + +Dynamic data lookup should opportunisticly cache any associated cheap data. For instance, there are three data from stat(/srv/git/$reponame.git), so looking up one should grab the others. Jules points out that everything here is inherently cached, and I should be using getpw*() for passwd parsing. + +[[!table format=dsv delimiter=# data=""" +datum #stored location #constraint +username #usually $ENV{SUDO_USER} # !~ /^git-|^ikiwiki-/ and =~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ +uid #/etc/passwd # None +email #/etc/passwd GECOS #Email::Valid::Loose->new("-fqdn" => 1, "-fudge" => 0, "-local_rules" => 0, "-mxcheck" => 1, "-tldcheck" => 0 ); +repoaccess #/etc/group git-$reponame entry # None +reponame #/srv/git/$reponame.git # =~ /^[a-z0-9][a-z0-9.-]+$/ +repodescription #/srv/git/$reponame.git/description # =~ /^[\x{0020}-\x{FDCF}\x{FDF0}-\x{FFFD}]{1,80}$/ +repoowner #stat /srv/git/$reponame.git/objects uid; might be better as first non-ikiwiki user in /etc/group git-$reponame entry # None +repoglobalwritable #stat /srv/git/$reponame.git/objects o+w bit # None +repoglobalreadable #stat /srv/git/$reponame.git/objects o+r bit # None +repoikiwikidisable #probably in /srv/git/$reponame.git/config # None +repointernaltemplates #probably in /srv/git/$reponame.git/config # None +repospecialdomain #probably in /srv/git/$reponame.git/config # None +"""]] diff --git a/docs/architecture/features.mdwn b/docs/architecture/features.mdwn new file mode 100644 index 0000000..fbdedb2 --- /dev/null +++ b/docs/architecture/features.mdwn @@ -0,0 +1,7 @@ +An in-distributed-repo model for + +- code +- blogs +- bugs +- web pages +- [[mail]] diff --git a/docs/architecture/mail.mdwn b/docs/architecture/mail.mdwn new file mode 100644 index 0000000..61bbfcd --- /dev/null +++ b/docs/architecture/mail.mdwn @@ -0,0 +1,6 @@ +I can presumably get mailing lists into ikiwiki using one of the following: + +- MLM+Ikiwiki [comment-by-mail plugin](http://ikiwiki.info/todo/comment_by_mail/) +- MLM+Ikiwiki [mailbox plugin](http://pivot.cs.unb.ca/git/?p=ikimailbox.git;a=summary) + +But how would we get it into git? Might we have to do that externally? diff --git a/docs/architecture/needed_admin_infrastructure.mdwn b/docs/architecture/needed_admin_infrastructure.mdwn new file mode 100644 index 0000000..59365c2 --- /dev/null +++ b/docs/architecture/needed_admin_infrastructure.mdwn @@ -0,0 +1,7 @@ +- DONE: HTTP AUTH from PAM through the magic of mod-auth-pam +- DONE: HTTP access from /etc/group through the magic of mod-auth-sys-group +- DONE: Shell security through rbash and privilege escalation security (for mkwiki, mkuser, etc) through sudo +- DONE: Guaranteed namespace coherence with the vhosting of cgi, secure, and normal with the aid of a wildcard SSL certificate +- TODO: Work out how to pass mailing list emails around. Probably either ssh or vserver namespace magic. +- DONE: manual [[setup file overrides]], /etc/ikiwiki/piny/$reponame.setup.pl, included directly with 'do' before dumping state. +- DONE: rebuildrepo diff --git a/docs/architecture/needed_user_facing_infrastructure.mdwn b/docs/architecture/needed_user_facing_infrastructure.mdwn new file mode 100644 index 0000000..1e7284a --- /dev/null +++ b/docs/architecture/needed_user_facing_infrastructure.mdwn @@ -0,0 +1,37 @@ +TODO: user-facing documentation on piny-web +TODO: help system on pinyshell (display on login) + +It'd be nice to maintain feature parity between command line access and web access. + +[[!table data=""" +feature |command line |web +anonymous account creation |DONE: ssh createuser@piny.be |TODO: CGI frontend to adduser +password modification |DONE: /srv/rbin/passwd |TODO: Authen::PAM chauthtok CGI jblake: the pam interface was *really* not designed with http in mind though if you hard-code the interaction script it's not hard at all +repo creation, deletion |DONE: /srv/rbin/newrepo, rmrepo, lsrepo |TODO: CGI frontend +repo user management |DONE: /srv/rbin/addaccess, rmaccess, lsaccess |TODO: CGI frontend +[[mailing list addition|mail]] |TODO: /srv/rbin/addlist, dependent on getting sympa up |TODO: CGI frontend +authorized_keys modification |DONE: /srv/rbin/readkeys, writekeys, appendkeys |TODO: CGI frontend, though i am not convinced anyone would care +disable password auth if ssh key|TODO |Ha ha NEVER +commit access |DONE: git+ssh://piny.be/srv/git/whatever.git |DONE: Ikiwiki+mod-auth-sys-group/mod-auth-pam, though I am told there is a magic hook to allow public editing through git:// +wysiwyg editing tool |Ha ha no |TODO: wmd a good option, though needs UI tweaks +fork |TODO: /srv/rbin/fork |TODO: CGI frontend +upload and commit container contents |no |TODO: CGI frontend +user or repo activity data aggregation |TODO: /srv/rbin/activity |TODO: rss generation, possibly install a dynamic rss reader +help system |lock down 'man', print introduction on login |command documentation should be rendered online, perhaps +config tweaking |PARTIAL: pinyconfig |TODO: CGI frontend +"""]] + +Needed config tweakables + +- TODO: ikiwiki-editable vs. git-only +- TODO: toggle ikiwiki autoindexing +- TODO: optional use of repository subdirectory as srcdir +- TODO: globally readable repos vs. group readable repos +- TODO: globally writable repos vs. group writable repos +- TODO: editable ikiwiki templates vs. default layout +- TODO: user-configured domain vs. default piny domain + +Other + +- TODO: overall site layout/theme/css +- TODO: front page to piny server editable by sysadmin ("here's what's on this server; readme; faq; about;") diff --git a/docs/architecture/setup_file_overrides.mdwn b/docs/architecture/setup_file_overrides.mdwn new file mode 100644 index 0000000..6133a22 --- /dev/null +++ b/docs/architecture/setup_file_overrides.mdwn @@ -0,0 +1,24 @@ +Use cases: + +### Adding post-update hooks, which requires diverting Ikiwiki's hook. + + mv /srv/git/poop.git/hooks/post-update /srv/git/poop.git/hooks/post-update-ikiwiki + cat > /srv/git/poop.git/hooks/post-update + #!/bin/sh + /srv/git/poop.git/hooks/post-update-ikiwiki & + echo This is a hook that does things! + cat > /srv/ikiwiki/piny/poop.setup.pl + foreach(@{$conf->{wrappers}}) { $_->{wrapper} =~ s/post-update/post-update-ikiwiki/; }; + rebuildrepo poop + +### Adding or removing plugins, or plugin confuration variables. + + cat > /srv/ikiwiki/piny/poop.setup.pl + push(@{$conf->{add_plugins}}, 'txt'); + rebuildrepo poop + +### Any other special confuration requests from hosted projects. + + cat > /srv/ikiwiki/piny/poop.setup.pl + $conf->{teximg_prefix} .= "\n\\newcommand{\\unit}[1]{\\ensuremath{\\, \\mathrm{#1}}}" + rebuildrepo poop diff --git a/libpiny/Build.PL b/libpiny/Build.PL new file mode 100644 index 0000000..bfb5fd7 --- /dev/null +++ b/libpiny/Build.PL @@ -0,0 +1,30 @@ +use Module::Build; + +open( DCH, "<", "debian/changelog" ) or die "changelog: $!"; + +my $version = "0"; +while ( defined ( my $line = ) ) { + if ( $line =~ /\(([0-9.]+)\)/ ) { + $version = $1; + last; + }; +}; + +close( DCH ); + +my $build = Module::Build->new + ( 'module_name' => 'Piny' + , 'dist_version' => $version + , 'license' => 'BSD-3' + , 'setup_files' => { 'share/ikiwiki.setup' => 'share/ikiwiki.setup' } + , 'install_path' => + { 'share' => '/usr/share/libpiny' + } + , 'requires' => + { 'Moose' => 0 + , 'Email::Valid::Loose' => 0 + } + ); + +$build->add_build_element( "setup" ); +$build->create_build_script( ); diff --git a/libpiny/debian/changelog b/libpiny/debian/changelog new file mode 100644 index 0000000..e97c2fe --- /dev/null +++ b/libpiny/debian/changelog @@ -0,0 +1,89 @@ +libpiny-perl (0.14) unstable; urgency=low + + * Support rebuilding a repo's config. + + -- Julian Blake Kongslie Wed, 13 Oct 2010 20:38:15 -0700 + +libpiny-perl (0.13) unstable; urgency=low + + * Vastly overhauled the config stuff. + + -- Julian Blake Kongslie Mon, 11 Oct 2010 21:55:40 -0700 + +libpiny-perl (0.12) unstable; urgency=low + + * Support for per-repo configuration in the git config, section piny. + * Support for per-repo custom http/https base URLs. + + -- Julian Blake Kongslie Sun, 01 Aug 2010 20:07:44 -0700 + +libpiny-perl (0.11) unstable; urgency=low + + * Destroying dead repos. + + -- Julian Blake Kongslie Mon, 19 Jul 2010 02:30:01 -0700 + +libpiny-perl (0.10) unstable; urgency=low + + * Support for the global /etc/piny.conf stuff. + + -- Julian Blake Kongslie Sun, 18 Jul 2010 21:23:28 -0700 + +libpiny-perl (0.9) unstable; urgency=low + + * Creating new repos. + + -- Julian Blake Kongslie Wed, 07 Jul 2010 15:34:37 -0700 + +libpiny-perl (0.8) unstable; urgency=low + + * Added apache config stuff. + + -- Julian Blake Kongslie Wed, 07 Jul 2010 14:26:38 -0700 + +libpiny-perl (0.7) unstable; urgency=low + + * Lots more ikiwiki integration. + + -- Julian Blake Kongslie Wed, 07 Jul 2010 13:45:42 -0700 + +libpiny-perl (0.6) unstable; urgency=low + + * Added IkiWiki::FakeSetup for manipulating IkiWiki setup scripts. + + -- Julian Blake Kongslie Wed, 07 Jul 2010 12:12:37 -0700 + +libpiny-perl (0.5) unstable; urgency=low + + * Allow listing repos and querying access rights. + + -- Julian Blake Kongslie Tue, 29 Jun 2010 22:28:59 -0700 + +libpiny-perl (0.4) unstable; urgency=low + + * Switch to native packaging. + + -- Julian Blake Kongslie Sun, 18 Apr 2010 12:33:19 -0700 + +libpiny-perl (0.3-1) unstable; urgency=low + + * Fix some build-depends stuff. + * Add group membership manipulation. + * Add some more type constraints. + * Fix a bug in the username detection. + * Forbid purely-numeric usernames. + * Use fixed paths to reach adduser and deluser. + + -- Julian Blake Kongslie Thu, 18 Mar 2010 16:56:24 -0700 + +libpiny-perl (0.2-1) unstable; urgency=low + + * Switched to Module::Build because it seems marginally sane. + + -- Julian Blake Kongslie Thu, 18 Mar 2010 00:08:05 -0700 + +libpiny-perl (0.1-1) unstable; urgency=low + + * Initial release. + + -- Julian Blake Kongslie Wed, 17 Mar 2010 23:44:25 -0700 diff --git a/libpiny/debian/compat b/libpiny/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/libpiny/debian/compat @@ -0,0 +1 @@ +7 diff --git a/libpiny/debian/control b/libpiny/debian/control new file mode 100644 index 0000000..b64d8fa --- /dev/null +++ b/libpiny/debian/control @@ -0,0 +1,13 @@ +Source: libpiny-perl +Maintainer: Julian Blake Kongslie +Section: perl +Build-depends: debhelper (>= 7) +Priority: extra +Standards-version: 3.8.4 + +Package: libpiny-perl +Architecture: all +Depends: ${perl:Depends}, ${misc:Depends}, libconfig-simple-perl, libemail-valid-loose-perl, libmoose-perl, libmoosex-singleton-perl, libmoosex-strictconstructor-perl +Description: Perl interface for the piny infrastructure + This is a set of modules for accomplishing administrative tasks in the piny.be + infrastructure. diff --git a/libpiny/debian/copyright b/libpiny/debian/copyright new file mode 100644 index 0000000..db049e1 --- /dev/null +++ b/libpiny/debian/copyright @@ -0,0 +1,2 @@ +Copyright © 2010 Julian Blake Kongslie +Licensed under the BSD 3-clause license. diff --git a/libpiny/debian/rules b/libpiny/debian/rules new file mode 100755 index 0000000..2d33f6a --- /dev/null +++ b/libpiny/debian/rules @@ -0,0 +1,4 @@ +#!/usr/bin/make -f + +%: + dh $@ diff --git a/libpiny/debian/source/format b/libpiny/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/libpiny/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/libpiny/lib/IkiWiki/FakeSetup.pm b/libpiny/lib/IkiWiki/FakeSetup.pm new file mode 100644 index 0000000..c9c823b --- /dev/null +++ b/libpiny/lib/IkiWiki/FakeSetup.pm @@ -0,0 +1,88 @@ +package IkiWiki::FakeSetup; + +use strict; +use warnings; + +use Data::Dumper qw( ); +use Exporter qw( import ); + +our @EXPORT_OK = qw( readSetup writeSetup ); + +sub readSetup { + my ( $setupfile ) = @_; + + # Sorry about the use of globals but it's hard to share lexicals with dynamically generated source. + $IkiWiki::FakeSetup::package = undef; + @IkiWiki::FakeSetup::args = (); + + sub inc { + my ( $self, $file ) = @_; + + my $package = $file; + $package =~ s/\//::/g; + $package =~ s/\.pm//; + + my @src = + ( "package $package;\n" + , "sub import {\n" + , " my ( \$class, \@args ) = \@_;\n" + , " \$IkiWiki::FakeSetup::package = \$class;\n" + , " \@IkiWiki::FakeSetup::args = \@args;\n" + , "}\n" + , "1;\n" + ); + + return sub { if ( scalar @src ) { $_ = shift @src; return 1; } else { return 0; } }; + + }; + + eval { + my @oldINC = @INC; + @INC = ( ".", \&inc ); + + my %oldINC = %INC; + %INC = ( ); + + do $setupfile; + + @INC = @oldINC; + %INC = %oldINC; + }; + + return ( $IkiWiki::FakeSetup::package, @IkiWiki::FakeSetup::args ); + +} + +sub writeSetup { + my ( $package, @args ) = @_; + + my $d = Data::Dumper->new( \@args ); + $d->Terse( 1 ); + + return "#!/usr/bin/perl\n\nuse $package " . $d->Dump( ) . ";\n"; +} + +1; + +__END__ + +Because it may not be completely obvious, here's how you would use this: + +#!/usr/bin/perl + +use strict; +use warnings; + +use IkiWiki::FakeSetup qw( readSetup writeSetup ); + +# This reads the setup file, returning the package it uses and any configuration it passed to that package. +my ( $package, $config ) = readSetup( "almighty_ikiwiki_template.setup" ); + +# Make changes to the configuration. +$config->{"srcdir"} = "/some/dir"; +$config->{"adminemail"} = "somejerk\@jerkville.com"; + +# Open a new file, and write the changed configuration to it. +open( SETUP, ">", "almighty_ikiwiki_template_changed.setup" ); +print SETUP writeSetup( $package, $config ); +close( SETUP ); diff --git a/libpiny/lib/Piny.pm b/libpiny/lib/Piny.pm new file mode 100644 index 0000000..54a5b00 --- /dev/null +++ b/libpiny/lib/Piny.pm @@ -0,0 +1,16 @@ +# Copyright © 2010 Julian Blake Kongslie +# Licensed under the BSD 3-clause license. + +# This very pointedly does not have a package line. +# That way, you can "use Piny" and import all the Piny packages into your namespace in one fell swoop. +# Of course, you don't get to pass arguments to their import functions anymore. + +use Piny::Config; +use Piny::Email; +use Piny::Environment; +use Piny::Group; +use Piny::Repo; +use Piny::User; +use Piny::User::IkiWiki; + +1; diff --git a/libpiny/lib/Piny/Config.pm b/libpiny/lib/Piny/Config.pm new file mode 100644 index 0000000..76405ee --- /dev/null +++ b/libpiny/lib/Piny/Config.pm @@ -0,0 +1,218 @@ +# Copyright © 2010 Julian Blake Kongslie +# Licensed under the BSD 3-clause license. + +use strict; +use warnings; + +package Piny::Config; + +use Moose; +use Moose::Util::TypeConstraints; +use MooseX::StrictConstructor; + +use Carp; +use Config::Simple qw( -lc ); + +# Types + +subtype 'GitBool' + => as 'Str' + => where { $_ =~ /^(1|0|true|false)$/i } + => message { 'Not correct format for a git-compatible boolean.' } + ; + +subtype 'Path' + => as 'Str' + => where { $_ =~ /^\// and -e $_ } + => message { 'Not an absolute path, or does not exist.' } + ; + +subtype 'PathDir' + => as 'Path' + => where { -d $_ } + => message { 'Not an absolute path, or not a directory.' } + ; + +subtype 'HttpUrl' + => as 'Str' + => where { $_ =~ /^http:\/\//i } + => message { 'Not a http:// URL.' } + ; + +subtype 'HttpsUrl' + => as 'Str' + => where { $_ =~ /^https:\/\//i } + => message { 'Not a https:// URL.' } + ; + +# Attributes + +has 'confpath' => + ( is => 'ro' + , isa => 'Str' + , predicate => 'has_confpath' + ); + +has '_conf' => + ( is => 'ro' + , isa => 'HashRef[Str]' + , lazy_build => 1 + , clearer => 'clear_conf' + , init_arg => undef + ); + +# Builder methods + +# If constructed with just one argument, then treat it as a config path. +around BUILDARGS => sub { + my ( $orig, $class ) = ( shift, shift ); + + if ( @_ == 1 && ! ref $_[0] ) { + return $class->$orig( confpath => $_[0] ); + } else { + return $class->$orig( @_ ); + }; +}; + +sub _build__conf { + my ( $s ) = @_; + + my $conf; + + if ( $s->has_confpath and -e $s->confpath ) { + $conf = Config::Simple->new( $s->confpath )->vars; + } else { + $conf = { }; + }; + + if ( -e "/etc/piny-default.conf" ) { + + my $default = Config::Simple->new( "/etc/piny-default.conf" )->vars; + + foreach my $key ( keys %$default ) { + if ( not exists $conf->{$key} ) { + $conf->{$key} = $default->{$key}; + }; + }; + + }; + + if ( -e "/etc/piny-override.conf" ) { + + my $override = Config::Simple->new( "/etc/piny-override.conf" )->vars; + + foreach my $key ( keys %$override ) { + $conf->{$key} = $override->{$key}; + }; + + }; + + return $conf; +}; + +# Save the config + +sub save { + my ( $s ) = @_; + + if ( not $s->has_confpath ) { + croak "Can't save a Piny::Config if the confpath is not set!"; + }; + + if ( -e "/etc/piny-override.conf" ) { + + my $override = Config::Simple->new( "/etc/piny-override.conf" )->vars; + + foreach my $key ( keys %$override ) { + if ( exists $s->_conf->{$key} and $s->_conf->{$key} eq $override->{$key} ) { + delete $s->_conf->{$key}; + }; + }; + + }; + + if ( -e "/etc/piny-default.conf" ) { + + my $default = Config::Simple->new( "/etc/piny-default.conf" )->vars; + + foreach my $key ( keys %$default ) { + if ( exists $s->_conf->{$key} and $s->_conf->{$key} eq $default->{$key} ) { + delete $s->_conf->{$key}; + }; + }; + + }; + + my $cs = Config::Simple->new( syntax => "ini" ); + + foreach my $key ( keys %{$s->_conf} ) { + $cs->param( $key, $s->_conf->{$key} ); + }; + + $cs->write( $s->confpath ); +}; + +# Tweakable helper + +sub tweakable { + my ( $attr, $default, $isa ) = @_; + + $attr = lc $attr; + + my $attrname = $attr; + $attrname =~ s/_/./; + + if ( $attrname =~ /_/ ) { croak "Illegal attribute name $attrname! (use only one underbar)"; }; + + has $attr => + ( is => 'rw' + , isa => $isa + , lazy_build => 1 + , trigger => sub { + my ( $s, $new, $old ) = @_; + + $s->_conf->{$attrname} = $new; + + if ( $s->has_confpath ) { + $s->save; + } else { + carp "Attribute $attrname modification ignored!"; + }; + + $s->clear_conf; + my $clearer = "clear_$attr"; + $s->$clearer; + } + ); + + my $builder = sub { + my ( $s ) = @_; + + if ( exists $s->_conf->{$attrname} ) { + return $s->_conf->{$attrname}; + } else { + return $default; + }; + }; + + { + no strict "refs"; + + *{"_build_" . $attr} = $builder; + }; +}; + +# The tweakables + +tweakable "piny_ikiwikidestdir" => "/srv/www/piny.be/", 'PathDir'; +tweakable "piny_ikiwikisrcdir" => "/srv/ikiwiki/", 'PathDir'; +tweakable "piny_ikiwikiurl" => "http://piny.be/", 'HttpUrl'; +tweakable "piny_ikiwikisecureurl" => "https://secure.piny.be/", 'HttpsUrl'; +tweakable "piny_ikiwikisecurepath" => "/srv/www/secure.piny.be/", 'PathDir'; +tweakable "receive_denynonfastforwards" => "true", 'GitBool'; + +# Moose boilerplate + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/libpiny/lib/Piny/Email.pm b/libpiny/lib/Piny/Email.pm new file mode 100644 index 0000000..baa56f0 --- /dev/null +++ b/libpiny/lib/Piny/Email.pm @@ -0,0 +1,49 @@ +# Copyright © 2010 Julian Blake Kongslie +# Licensed under the BSD 3-clause license. + +use strict; +use warnings; + +package Piny::Email; + +use Moose; +use Moose::Util::TypeConstraints; +use MooseX::StrictConstructor; + +use Email::Valid::Loose; + +# Types + +my $checker = Email::Valid::Loose->new("-fqdn" => 1, "-fudge" => 0, "-local_rules" => 0, "-mxcheck" => 1, "-tldcheck" => 0 ); + +subtype 'EmailAddress' + => as 'Str' + => where { $checker->address( $_ ) } + => message { 'That does not appear to be a valid email address.' } + ; + +# Attributes + +has 'address' => + ( is => 'ro' + , isa => 'EmailAddress' + ); + +# Builder methods + +# If constructed with just one argument, then treat it as an address. +around BUILDARGS => sub { + my ( $orig, $class ) = ( shift, shift ); + + if ( @_ == 1 && ! ref $_[0] ) { + return $class->$orig( address => $_[0] ); + } else { + return $class->$orig( @_ ); + }; +}; + +# Moose boilerplate + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/libpiny/lib/Piny/Environment.pm b/libpiny/lib/Piny/Environment.pm new file mode 100644 index 0000000..06416b8 --- /dev/null +++ b/libpiny/lib/Piny/Environment.pm @@ -0,0 +1,45 @@ +# Copyright © 2010 Julian Blake Kongslie +# Licensed under the BSD 3-clause license. + +use strict; +use warnings; + +package Piny::Environment; + +use MooseX::Singleton; +use MooseX::StrictConstructor; + +use Piny::User; + +# Attributes + +has 'user' => + ( is => 'ro' + , isa => 'Piny::User' + , lazy_build => 1 + , init_arg => undef + ); + +# Builder methods + +sub _build_user { + my ( $s ) = @_; + + if ( defined $ENV{"SUDO_UID"} ) { + return Piny::User->new( uid => $ENV{"SUDO_UID"} ); + } elsif ( defined $ENV{"SUDO_USER"} ) { + return Piny::User->new( name => $ENV{"SUDO_USER"} ); + } elsif ( defined $ENV{"UID"} ) { + return Piny::User->new( uid => $ENV{"UID"} ); + } elsif ( defined $ENV{"USER"} ) { + return Piny::User->new( name => $ENV{"USER"} ); + } else { + return Piny::User->new( uid => $< ); + }; +}; + +# Moose boilerplate + +__PACKAGE__->meta->make_immutable( inline_constructor => 0 ); + +1; diff --git a/libpiny/lib/Piny/Group.pm b/libpiny/lib/Piny/Group.pm new file mode 100644 index 0000000..86a6d95 --- /dev/null +++ b/libpiny/lib/Piny/Group.pm @@ -0,0 +1,136 @@ +# Copyright © 2010 Julian Blake Kongslie +# Licensed under the BSD 3-clause license. + +use strict; +use warnings; + +package Piny::Group; + +use Moose; +use MooseX::StrictConstructor; + +use Piny::User; + +# Attributes + +has 'gid' => + ( is => 'ro' + , isa => 'Int' + , lazy_build => 1 + ); + +has 'name' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + ); + +has 'grent' => + ( is => 'ro' + , isa => 'ArrayRef' + , lazy_build => 1 + , init_arg => undef + ); + +has 'members' => + ( is => 'ro' + , isa => 'ArrayRef[Piny::User]' + , lazy_build => 1 + , init_arg => undef + ); + +# Public methods + +sub add_member { + my ( $s, @users ) = @_; + + foreach my $user ( @users ) { + system( "/usr/sbin/adduser", $user->name( ), $s->name( ) ); + $user->clear_groups( ); + }; + + $s->clear_members( ); +}; + +sub remove_member { + my ( $s, @users ) = @_; + + foreach my $user ( @users ) { + system( "/usr/sbin/deluser", $user->name( ), $s->name( ) ); + $user->clear_groups( ); + }; + + $s->clear_members( ); +}; + +# Builder methods + +# If constructed with just one argument, then +# * If that argument is numeric, treat it as a GID. +# * Otherwise, treat it as a name. +around BUILDARGS => sub { + my ( $orig, $class ) = ( shift, shift ); + + if ( @_ == 1 && ! ref $_[0] ) { + if ( $_[0] =~ m/^\d+$/ ) { + return $class->$orig( gid => $_[0] ); + } else { + return $class->$orig( name => $_[0] ); + }; + } else { + return $class->$orig( @_ ); + }; +}; + +sub BUILD { + my ( $s ) = @_; + + if ( not ( $s->has_gid( ) or $s->has_name( ) ) ) { + die "You must provide either GID or name!"; + }; + + if ( $s->has_gid( ) and $s->has_name( ) ) { + die "You must not provide both GID and name!"; + }; +}; + +sub _build_gid { + my ( $s ) = @_; + + return $s->grent( )->[2]; +}; + +sub _build_name { + my ( $s ) = @_; + + return $s->grent( )->[0]; +}; + +sub _build_grent { + my ( $s ) = @_; + + if ( $s->has_gid( ) ) { + my @res = getgrgid( $s->gid( ) ); + die "getgrgid( " . $s->gid( ) . " ) failed: $!" unless @res; + return \@res; + } elsif ( $s->has_name( ) ) { + my @res = getgrnam( $s->name( ) ); + die "getgrnam( " . $s->name( ) . " ) failed: $!" unless @res; + return \@res; + } else { + die "Not enough information provided to lookup group!"; + }; +}; + +sub _build_members { + my ( $s ) = @_; + + return [ ] if ( $s->grent( )->[3] eq "" ); + return [ map { Piny::User->new( name => $_ ) } split( /:/, $s->grent( )->[3] ) ]; +}; + +# Moose boilerplate + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/libpiny/lib/Piny/Repo.pm b/libpiny/lib/Piny/Repo.pm new file mode 100644 index 0000000..8ebb0f4 --- /dev/null +++ b/libpiny/lib/Piny/Repo.pm @@ -0,0 +1,637 @@ +# Copyright © 2010 Julian Blake Kongslie +# Licensed under the BSD 3-clause license. + +use strict; +use warnings; + +package Piny::Repo; + +use Moose; +use Moose::Util::TypeConstraints; +use MooseX::StrictConstructor; + +use File::Find qw( find ); +use File::Temp qw( ); +use IO::Dir qw( ); + +use IkiWiki::FakeSetup qw( readSetup writeSetup ); + +use Piny::Config; +use Piny::Environment; +use Piny::Group; +use Piny::User; +use Piny::User::IkiWiki; + +# Types + +subtype 'Reponame' + => as 'Str' + => where { $_ =~ /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/ } + => message { 'That name is not in the correct format for a piny repo.' } + ; + +subtype 'SimpleText' + => as 'Str' + => where { $_ =~ /^[\x{0020}-\x{FDCF}\x{FDF0}-\x{FFFD}]{1,80}$/ } + => message { 'That description is not in the correct format for a piny repo.' } + ; + +# Attributes + +has 'name' => + ( is => 'rw' + , isa => 'Reponame' + , trigger => \&_rename_repo + , required => 1 + ); + +has 'group' => + ( is => 'ro' + , isa => 'Piny::Group' + , lazy_build => 1 + , init_arg => undef + ); + +has 'path' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'description' => + ( is => 'rw' + , isa => 'SimpleText' + , trigger => \&_set_description + , lazy_build => 1 + , init_arg => undef + ); + +has 'repostat' => + ( is => 'ro' + , isa => 'ArrayRef' + , lazy_build => 1 + , init_arg => undef + ); + +has 'owner' => + ( is => 'rw' + , isa => 'Piny::User' + , trigger => \&_change_owner + , lazy_build => 1 + , init_arg => undef + ); + +has 'globally_readable' => + ( is => 'ro' + , isa => 'Bool' + , lazy_build => 1 + , init_arg => undef + ); + +has 'globally_writable' => + ( is => 'ro' + , isa => 'Bool' + , lazy_build => 1 + , init_arg => undef + ); + +has 'ikiwiki_setup' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'ikiwiki_destdir' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'ikiwiki_srcdir' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'ikiwiki_url' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'ikiwiki_cgiurl' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'ikiwiki_historyurl' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'ikiwiki_diffurl' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'ikiwiki_cgipath' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'secure_path' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'apache_config' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'config' => + ( is => 'ro' + , isa => 'Piny::Config' + , lazy_build => 1 + , init_arg => undef + ); + +# Public methods + +sub add_access { + my ( $s, @users ) = @_; + + $s->group->add_member( @users ); +}; + +sub remove_access { + my ( $s, @users ) = @_; + + $s->group->remove_member( @users ); +}; + +sub has_access { + my ( $s, $user ) = @_; + + return $s->owner->uid == $user->uid || $user->has_group( $s->group ); +}; + +sub rebuild { + my ( $s ) = @_; + + my $ikiuser = Piny::User::IkiWiki->new( "name" => "ikiwiki-" . $s->name ); + + foreach( "git-daemon-export-ok", "packed-refs" ) { + open( TOUCH, ">", $s->path . "/" . $_ ) or die "Could not touch $_ for repo: $!"; + close( TOUCH ); + }; + + foreach( "info", "logs" ) { + (-e $s->path . "/" . $_) or mkdir( $s->path . "/" . $_ ) or die "Could not mkdir $_ for repo: $!"; + }; + + chown( 0, 0, $s->path, $s->path . "/config" ) or die "Could not change ownership of git dir!"; + + foreach( "branches", "description", "HEAD", "info", "logs", "objects", "packed-refs", "refs" ) { + system( "/bin/chown", "-R", $s->owner->name . "." . $s->group->name, $s->path . "/" . $_ ) and die "Could not change ownership of $_ for repo: $!"; + }; + + system( "/bin/chown", "-R", $ikiuser->name . "." . $ikiuser->name, $s->path . "/hooks" ) and die "Could not change ownership of git hooks!"; + + open( SETUP, ">", "/etc/ikiwiki/piny/" . $s->name . ".setup" ) or die "Could not open new ikiwiki setup file: $!"; + print SETUP $s->ikiwiki_setup; + close( SETUP ) or die "Could not close new ikiwiki setup file: $!"; + + system( "/bin/chown", "-R", $ikiuser->name . "." . $ikiuser->name, $s->ikiwiki_srcdir, $s->ikiwiki_destdir, $s->secure_path ) and die "Could not change ownership of ikiwiki directories!"; + + open( WIKILIST, ">", "/etc/ikiwiki/wikilist.d/" . $s->name ) or die "Could not create wikilist.d file: $!"; + print WIKILIST $ikiuser->name . " /etc/ikiwiki/piny/" . $s->name . ".setup\n"; + close( WIKILIST ) or die "Could not close wikilist.d file: $!"; + + my $temp = File::Temp->new( ) or die "Could not create temporary file: $!"; + $temp->unlink_on_destroy( 0 ); + + my $dh = IO::Dir->new( "/etc/ikiwiki/wikilist.d" ) or die "Could not open wikilist.d directory: $!"; + while ( defined ( my $entry = $dh->read ) ) { + next if ( $entry =~ /^\./ ); + open( FILE, "<", "/etc/ikiwiki/wikilist.d/" . $entry ) or die "Could not open wikilist.d entry $entry: $!"; + print $temp ; + close( FILE ) or die "Could not close wikilist.d entry $entry: $!"; + }; + + $temp->close or die "Could not close new wikilist: $!"; + + chmod( 00644, $temp->filename ) or die "Could not fix mode of new wikilist: $!"; + + rename( $temp->filename, "/etc/ikiwiki/wikilist" ) or die "Could not rename over old wikilist: $!"; + + $ENV{"GIT_DIR"} = $s->path; + system( "/usr/bin/git", "config", "gitweb.owner", $s->owner->email->address ) and die "Could not git config gitweb.owner!"; + delete $ENV{"GIT_DIR"}; + + system( "/usr/bin/sudo", "-u", $ikiuser->name, "/usr/bin/ikiwiki", "--setup", "/etc/ikiwiki/piny/" . $s->name . ".setup" ) and die "Could not do initial compile of ikiwiki!"; + + open( APACHE, ">", "/etc/apache2/piny-available/" . $s->name ) or die "Could not open new apache config: $!"; + print APACHE $s->apache_config; + close( APACHE ) or die "Could not close new apache config: $!"; + + unlink( "/etc/apache2/piny-enabled/" . $s->name ); + symlink( "/etc/apache2/piny-available/" . $s->name, "/etc/apache2/piny-enabled/" . $s->name ) or die "Could not symlink apache config: $!"; + + system( "/etc/init.d/apache2", "reload" ) and die "Could not reload apache config!"; +}; + +sub destroy { + my ( $s ) = @_; + + my $user = Piny::Environment->instance->user; + + unlink( "/etc/apache2/piny-enabled/" . $s->name ); + unlink( "/etc/apache2/piny-available/" . $s->name ); + + system( "/etc/init.d/apache2", "reload" ) and die "Could not reload apache config!"; + + unlink( "/etc/ikiwiki/wikilist.d/" . $s->name ); + + my $temp = File::Temp->new( ) or die "Could not create temporary file: $!"; + $temp->unlink_on_destroy( 0 ); + + my $dh = IO::Dir->new( "/etc/ikiwiki/wikilist.d" ) or die "Could not open wikilist.d directory: $!"; + while ( defined ( my $entry = $dh->read ) ) { + next if ( $entry =~ /^\./ ); + open( FILE, "<", "/etc/ikiwiki/wikilist.d/" . $entry ) or die "Could not open wikilist.d entry $entry: $!"; + print $temp ; + close( FILE ) or die "Could not close wikilist.d entry $entry: $!"; + }; + + $temp->close or die "Could not close new wikilist: $!"; + + chmod( 00644, $temp->filename ) or die "Could not fix mode of new wikilist: $!"; + + rename( $temp->filename, "/etc/ikiwiki/wikilist" ) or die "Could not rename over old wikilist: $!"; + + system( "rm", "-rf", $s->secure_path, $s->ikiwiki_destdir, $s->ikiwiki_srcdir, "/etc/ikiwiki/piny/" . $s->name . ".setup", $s->path ); + + my $ikiuser = Piny::User::IkiWiki->new( "name" => "ikiwiki-" . $s->name ); + + system( "deluser", "--remove-home", $ikiuser->name ); + system( "delgroup", $ikiuser->name ); + system( "delgroup", "git-" . $s->name ); + +}; + +# Triggers + +sub _rename_repo { + my ( $s, $new_name, $old_name ) = @_; + + return unless defined $old_name; + + my $olddir = "/srv/git/$old_name.git"; + my $newdir = "/srv/git/$new_name.git"; + + rename( $olddir, $newdir ) or die "Couldn't rename $olddir to $newdir: $!"; + + warn "XXX Not renaming all the ikiwiki stuff!"; + + $s->clear_path; + $s->clear_ikiwiki_setup; + $s->clear_ikiwiki_destdir; + $s->clear_ikiwiki_srcdir; + $s->clear_ikiwiki_url; + $s->clear_ikiwiki_cgiurl; + $s->clear_ikiwiki_historyurl; + $s->clear_ikiwiki_cgipath; + $s->clear_secure_path; + $s->clear_apache_config; +}; + +sub _set_description { + my ( $s, $new_description, $old_description ) = @_; + + return unless defined $old_description; + + open( my $fd, ">", $s->path . "/description" ) or die "Unable to open " . $s->path . "/description for writing: $!"; + print $fd $new_description; + close( $fd ) or die "Error when closing " . $s->path . "/description: $!"; +}; + +sub _change_owner { + my ( $s, $new_owner, $old_owner ) = @_; + + return unless defined $old_owner; + + find( { wanted => sub { chown( $new_owner->uid, -1, $_ ) or die "Couldn't chown $_: $!"; }, no_chdir => 1 }, $s->path . "/objects" ); + + $s->clear_ikiwiki_setup; +}; + +# Class methods + +sub all_repos { + my ( $class, $dir ) = @_; + + $dir = "/srv/git" unless defined $dir; + + my @ret; + + find( { wanted => sub { if ( /^[^.].*\.git$/ ) { $File::Find::prune = 1; push( @ret, $File::Find::name ); }; } }, $dir ); + + @ret = map { s/^\Q$dir\E\/?//; s/\.git$//; $class->new( name => $_ ); } @ret; + + return @ret; +}; + +sub create { + my ( $class, $name, $description ) = @_; + + my $user = Piny::Environment->instance->user; + + find_type_constraint( "Reponame" )->assert_valid( $name ); + find_type_constraint( "SimpleText" )->assert_valid( $description ); + + my $repo = $class->new( "name" => $name ); + + mkdir( $repo->path ) or die "The repo $name appears to already exist! ($!)"; + + system( "/usr/sbin/adduser", "--quiet", "--system", "--group", "--gecos", $name, "ikiwiki-$name" ) and die "Could not create ikiwiki user!"; + + my $ikiuser = Piny::User::IkiWiki->new( "name" => "ikiwiki-$name" ); + + system( "/usr/sbin/addgroup", "--quiet", "git-$name" ) and die "Could not create repo group!"; + + my $group = Piny::Group->new( "name" => "git-$name" ); + + system( "/usr/sbin/adduser", "--quiet", $user->name, $group->name ) and die "Could not add you to the repo group!"; + system( "/usr/sbin/adduser", "--quiet", $ikiuser->name, $group->name ) and die "Could not add ikiwiki user to the repo group!"; + + $ENV{"GIT_DIR"} = $repo->path; + system( "/usr/bin/git", "init", "--template=/srv/git-template.git", "--quiet", "--shared" ) and die "Could not initialize git repo!"; + + foreach( "git-daemon-export-ok", "packed-refs" ) { + open( TOUCH, ">", $repo->path . "/" . $_ ) or die "Could not touch $_ for repo: $!"; + close( TOUCH ); + }; + + foreach( "info", "logs" ) { + ( -e $repo->path . "/" . $_ ) or mkdir( $repo->path . "/" . $_ ) or die "Could not mkdir $_ for repo: $!"; + }; + + foreach( "branches", "description", "HEAD", "info", "logs", "objects", "packed-refs", "refs" ) { + system( "/bin/chown", "-R", $user->name . "." . $group->name, $repo->path . "/" . $_ ) and die "Could not change ownership of $_ for repo: $!"; + }; + + chown( 0, 0, $repo->path, $repo->path . "/config" ) or die "Could not change ownership of git dir!"; + + system( "/bin/chown", "-R", $ikiuser->name . "." . $ikiuser->name, $repo->path . "/hooks" ) and die "Could not change ownership of git hooks!"; + + system( "/usr/bin/git", "config", "gitweb.owner", $repo->owner->email->address ) and die "Could not git config gitweb.owner!"; + delete $ENV{"GIT_DIR"}; + + $repo->description( $description ); + + open( SETUP, ">", "/etc/ikiwiki/piny/" . $repo->name . ".setup" ) or die "Could not open new ikiwiki setup file: $!"; + print SETUP $repo->ikiwiki_setup; + close( SETUP ) or die "Could not close new ikiwiki setup file: $!"; + + system( "/usr/bin/git", "clone", "--quiet", $repo->path, $repo->ikiwiki_srcdir ) and die "Could not clone repo to ikiwiki srcdir!"; + + mkdir( $repo->ikiwiki_destdir ) or die "Could not create ikiwiki destdir: $!"; + mkdir( $repo->secure_path ) or die "Could not create secure dir: $!"; + + system( "/bin/chown", "-R", $ikiuser->name . "." . $ikiuser->name, $repo->ikiwiki_srcdir, $repo->ikiwiki_destdir, $repo->secure_path ) and die "Could not change ownership of ikiwiki directories!"; + + open( WIKILIST, ">", "/etc/ikiwiki/wikilist.d/" . $repo->name ) or die "Could not create wikilist.d file: $!"; + print WIKILIST $ikiuser->name . " /etc/ikiwiki/piny/" . $repo->name . ".setup\n"; + close( WIKILIST ) or die "Could not close wikilist.d file: $!"; + + my $temp = File::Temp->new( ) or die "Could not create temporary file: $!"; + $temp->unlink_on_destroy( 0 ); + + my $dh = IO::Dir->new( "/etc/ikiwiki/wikilist.d" ) or die "Could not open wikilist.d directory: $!"; + while ( defined ( my $entry = $dh->read ) ) { + next if ( $entry =~ /^\./ ); + open( FILE, "<", "/etc/ikiwiki/wikilist.d/" . $entry ) or die "Could not open wikilist.d entry $entry: $!"; + print $temp ; + close( FILE ) or die "Could not close wikilist.d entry $entry: $!"; + }; + + $temp->close or die "Could not close new wikilist: $!"; + + chmod( 00644, $temp->filename ) or die "Could not fix mode of new wikilist: $!"; + + rename( $temp->filename, "/etc/ikiwiki/wikilist" ) or die "Could not rename over old wikilist: $!"; + + system( "/usr/bin/sudo", "-u", $ikiuser->name, "/usr/bin/ikiwiki", "--setup", "/etc/ikiwiki/piny/" . $repo->name . ".setup" ) and die "Could not do initial compile of ikiwiki!"; + + open( APACHE, ">", "/etc/apache2/piny-available/" . $repo->name ) or die "Could not open new apache config: $!"; + print APACHE $repo->apache_config; + close( APACHE ) or die "Could not close new apache config: $!"; + + symlink( "/etc/apache2/piny-available/" . $repo->name, "/etc/apache2/piny-enabled/" . $repo->name ) or die "Could not symlink apache config: $!"; + + system( "/etc/init.d/apache2", "reload" ) and die "Could not reload apache config!"; + + return $repo; +}; + +# Builder methods + +# If constructed with just one argument, then treat it as a repo name. +around BUILDARGS => sub { + my ( $orig, $class ) = ( shift, shift ); + + if ( @_ == 1 && ! ref $_[0] ) { + return $class->$orig( name => $_[0] ); + } else { + return $class->$orig( @_ ); + }; +}; + +sub _build_group { + my ( $s ) = @_; + + return Piny::Group->new( name => "git-" . $s->name ); +}; + +sub _build_path { + my ( $s ) = @_; + + return "/srv/git/" . $s->name . ".git"; +}; + +sub _build_description { + my ( $s ) = @_; + + open( my $d, "<", $s->path . "/description" ) or die "Unable to open " . $s->path . "/description: $!"; + my $desc; + { + local $/ = undef; + $desc = <$d>; + }; + close( $d ); + + return $desc; +}; + +sub _build_repostat { + my ( $s ) = @_; + + my @res = stat( $s->path . "/objects" ); + die "stat( " . $s->path . "/objects ) failed: $!" unless @res; + return \@res; +}; + +sub _build_owner { + my ( $s ) = @_; + + my ( $uid ) = $s->repostat->[4]; + + return Piny::User->new( uid => $uid ); +}; + +sub _build_globally_readable { + my ( $s ) = @_; + + return ( $s->repostat->[2] & 0444 ) == 0444; +}; + +sub _build_globally_writable { + my ( $s ) = @_; + + return ( $s->repostat->[2] & 0111 ) == 0111; +}; + +sub _build_ikiwiki_setup { + my ( $s ) = @_; + + my ( $package, $config ) = readSetup( "/usr/share/libpiny/ikiwiki.setup" ); + + $config->{"wikiname"} = $s->name; + $config->{"adminemail"} = $s->owner->email->address; + $config->{"srcdir"} = $s->ikiwiki_srcdir; + $config->{"destdir"} = $s->ikiwiki_destdir; + $config->{"url"} = $s->ikiwiki_url; + $config->{"cgiurl"} = $s->ikiwiki_cgiurl; + $config->{"historyurl"} = $s->ikiwiki_historyurl; + $config->{"diffurl"} = $s->ikiwiki_diffurl; + + $config->{"wrappers"} = + [ { "wrapper" => $s->ikiwiki_cgipath + , "wrappergroup" => $s->group->name + , "wrappermode" => "06755" + , "cgi" => 1 + } + , { "wrapper" => $s->path . "/hooks/post-update" + , "wrappergroup" => $s->group->name + , "wrappermode" => "06755" + , "notify" => 0 + } + ]; + + if ( -e "/etc/ikiwiki/piny/" . $s->name . ".setup.pl" ) { + undef $@; + eval { + package TEMP; + use Piny; + $TEMP::repo = $s; + $TEMP::conf = $config; + no strict 'vars'; + do "/etc/ikiwiki/piny/" . $s->name . ".setup.pl"; + }; + if ( not $@ ) { $config = $TEMP::conf; }; + }; + + return writeSetup( $package, $config ); +}; + +sub _build_ikiwiki_destdir { + my ( $s ) = @_; + + return $s->config->piny_ikiwikidestdir . $s->name; +}; + +sub _build_ikiwiki_srcdir { + my ( $s ) = @_; + + return $s->config->piny_ikiwikisrcdir . $s->name; +}; + +sub _build_ikiwiki_url { + my ( $s ) = @_; + + return $s->config->piny_ikiwikiurl . $s->name; +}; + +sub _build_ikiwiki_cgiurl { + my ( $s ) = @_; + + return $s->config->piny_ikiwikisecureurl . "repos/" . $s->name . "/ikiwiki.cgi"; +}; + +sub _build_secure_path { + my ( $s ) = @_; + + return $s->config->piny_ikiwikisecurepath . "repos/" . $s->name; +}; + +sub _build_ikiwiki_cgipath { + my ( $s ) = @_; + + return $s->secure_path . "/ikiwiki.cgi"; +}; + +sub _build_ikiwiki_historyurl { + my ( $s ) = @_; + + if ( defined $s->config->{"https_url"} ) { + return $s->config->{"https_url"} . "cgit/" . $s->name . "/log/[[file]]"; + } else { + return $s->config->piny_ikiwikisecureurl . "cgit/" . $s->name . "/log/[[file]]"; + }; +}; + +sub _build_ikiwiki_diffurl { + my ( $s ) = @_; + + if ( defined $s->config->{"https_url"} ) { + return $s->config->{"https_url"} . "cgit/" . $s->name . "/diff/?id=[[sha1_commit]]"; + } else { + return $s->config->piny_ikiwikisecureurl . "cgit/" . $s->name . "/diff/?id=[[sha1_commit]]"; + }; +}; + +sub _build_apache_config { + my ( $s ) = @_; + + return "secure_path . ">\n AuthPAM_Enabled on\n AuthGROUP_Enabled on\n AuthPAM_FallThrough off\n AuthBasicAuthoritative off\n AuthType Basic\n AuthName \"User access to " . $s->name . " repository needed.\"\n Require group " . $s->group->name . "\n\n"; +}; + +sub _build_config { + my ( $s ) = @_; + + return Piny::Config->new( confpath => $s->path . "/config" ); +}; + +# Moose boilerplate + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/libpiny/lib/Piny/User.pm b/libpiny/lib/Piny/User.pm new file mode 100644 index 0000000..20ef4f1 --- /dev/null +++ b/libpiny/lib/Piny/User.pm @@ -0,0 +1,216 @@ +# Copyright © 2010 Julian Blake Kongslie +# Licensed under the BSD 3-clause license. + +use strict; +use warnings; + +package Piny::User; + +use Moose; +use Moose::Util::TypeConstraints; +use MooseX::StrictConstructor; + +use Piny::Email; +use Piny::Group; + +# Types + +subtype 'Username' + => as 'Str' + => where { $_ =~ /^(?!(git|ikiwiki)-)[a-zA-Z][a-zA-Z0-9_.-]*$/ } + => message { 'That username is not in the correct format for a piny user.' } + ; + +# Attributes + +has 'uid' => + ( is => 'ro' + , isa => 'Int' + , lazy_build => 1 + ); + +has 'name' => + ( is => 'ro' + , isa => 'Username' + , lazy_build => 1 + ); + +has 'pwent' => + ( is => 'ro' + , isa => 'ArrayRef' + , lazy_build => 1 + , init_arg => undef + ); + +has 'password_hash' => + ( is => 'ro' + , isa => 'Str' + , lazy_build => 1 + , init_arg => undef + ); + +has 'email' => + ( is => 'ro' + , isa => 'Piny::Email' + , lazy_build => 1 + , init_arg => undef + ); + +has 'groups' => + ( is => 'ro' + , isa => 'ArrayRef[Piny::Group]' + , lazy_build => 1 + , init_arg => undef + ); + +# Public methods + +sub add_group { + my ( $s, @groups ) = @_; + + foreach my $group ( @groups ) { + $group->add_member( $s ); + }; +}; + +sub remove_group { + my ( $s, @groups ) = @_; + + foreach my $group ( @groups ) { + $group->remove_member( $s ); + }; +}; + +sub has_group { + my ( $s, $group ) = @_; + + foreach my $owngroup ( @{$s->groups( )} ) { + return 1 if $owngroup->gid( ) == $group->gid( ); + }; + + return; +}; + +# Class methods + +sub all_users { + my ( $class ) = @_; + + my @ret; + + endpwent( ); + + while ( my @info = getpwent( ) ) { + eval { + my $user = $class->new( uid => $info[2] ); + # Some forced early evaluation, so error checking happens now. + $user->name( ); + $user->email( ); + push( @ret, $user ); + }; + }; + + endpwent( ); + + return @ret; +}; + +# Builder methods + +# If constructed with just one argument, then +# * If that argument is numeric, treat it as a UID. +# * Otherwise, treat it as a username. +around BUILDARGS => sub { + my ( $orig, $class ) = ( shift, shift ); + + if ( @_ == 1 && ! ref $_[0] ) { + if ( $_[0] =~ m/^\d+$/ ) { + return $class->$orig( uid => $_[0] ); + } else { + return $class->$orig( name => $_[0] ); + }; + } else { + return $class->$orig( @_ ); + }; +}; + +sub BUILD { + my ( $s ) = @_; + + if ( not ( $s->has_uid( ) or $s->has_name( ) ) ) { + die "You must provide either UID or name!"; + }; + + if ( $s->has_uid( ) and $s->has_name( ) ) { + die "You must not provide both UID and name!"; + }; +}; + +sub _build_uid { + my ( $s ) = @_; + + return $s->pwent( )->[2]; +}; + +sub _build_name { + my ( $s ) = @_; + + return $s->pwent( )->[0]; +}; + +sub _build_pwent { + my ( $s ) = @_; + + if ( $s->has_uid( ) ) { + my @res = getpwuid( $s->uid( ) ); + die "getpwuid( " . $s->uid( ) . " ) failed: $!" unless @res; + return \@res; + } elsif ( $s->has_name( ) ) { + my @res = getpwnam( $s->name( ) ); + die "getpwnam( " . $s->name( ) . " ) failed: $!" unless @res; + return \@res; + } else { + die "Not enough information provided to lookup user!"; + }; +}; + +sub _build_password_hash { + my ( $s ) = @_; + + return $s->pwent( )->[1]; +}; + +sub _build_email { + my ( $s ) = @_; + + return Piny::Email->new( address => $s->pwent( )->[6] ); +}; + +sub _build_groups { + my ( $s ) = @_; + + my @res; + my @ent; + + endgrent( ); + + while ( @ent = getgrent( ) ) { + next if ( $ent[3] eq "" ); + foreach my $member ( split( / /, $ent[3] ) ) { + if ( $member eq $s->name( ) ) { + push @res, Piny::Group->new( gid => $ent[2] ); + last; + }; + }; + }; + + endgrent( ); + + return \@res; +}; + +# Moose boilerplate + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/libpiny/lib/Piny/User/IkiWiki.pm b/libpiny/lib/Piny/User/IkiWiki.pm new file mode 100644 index 0000000..8585e90 --- /dev/null +++ b/libpiny/lib/Piny/User/IkiWiki.pm @@ -0,0 +1,37 @@ +# Copyright © 2010 Julian Blake Kongslie +# Licensed under the BSD 3-clause license. + +use strict; +use warnings; + +package Piny::User::IkiWiki; + +use Moose; +use Moose::Util::TypeConstraints; +use MooseX::StrictConstructor; + +use Piny::User; + +extends "Piny::User"; + +# Types + +subtype 'IkiWikiUsername' + => as 'Str' + => where { $_ =~ /^ikiwiki-[a-zA-Z][a-zA-Z0-9_.-]*$/ } + => message { 'That username is not in the correct format for an ikiwiki user.' } + ; + +# Attributes + +has 'name' => + ( is => 'ro' + , isa => 'IkiWikiUsername' + , lazy_build => 1 + ); + +# Moose boilerplate + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/libpiny/share/ikiwiki.setup b/libpiny/share/ikiwiki.setup new file mode 100644 index 0000000..18f8418 --- /dev/null +++ b/libpiny/share/ikiwiki.setup @@ -0,0 +1,76 @@ +#!/usr/bin/perl +# Configuration file for ikiwiki. +# Passing this to ikiwiki --setup will make ikiwiki generate wrappers and +# build the wiki. +# +# Remember to re-run ikiwiki --setup any time you edit this file. + +use IkiWiki::Setup::Standard { + # wikiname => "', # LATER MODIFIED BY LATER MODIFIED BY PINY + # adminemail => "', # LATER MODIFIED BY LATER MODIFIED BY PINY + # srcdir => "', # LATER MODIFIED BY PINY + # destdir => "', # LATER MODIFIED BY PINY + # url => "', # LATER MODIFIED BY PINY + # cgiurl => "', # LATER MODIFIED BY PINY + # historyurl => "', # LATER MODIFIED BY PINY + # diffurl => "', # LATER MODIFIED BY PINY + + templatedir => "/srv/templates", # TODO: user-customizable templates + underlaydir => "/usr/share/ikiwiki/basewiki", + + rcs => "git", + gitorigin_branch => "origin", + gitmaster_branch => "master", + + # wrappers => [ ], controlled by piny + + # Generate rss feeds for blogs? + rss => 1, + # Generate atom feeds for blogs? + atom => 0, + # Include discussion links on all pages? + discussion => 0, + # To exclude files matching a regexp from processing. This adds to + # the default exclude list. + #exclude => qr/*\.wav/, + # To change the extension used for generated html files. + #htmlext => "htm", + # Time format (for strftime) + #timeformat => "%c", + # Locale to use. Must be a UTF-8 locale. + #locale => "en_US.UTF-8", + # Only send cookies over SSL connections. + sslcookie => 1, + # Logging settings: + verbose => 0, + syslog => 1, + # To link to user pages in a subdirectory of the wiki. + #userdir => "users", + # To create output files named page.html rather than page/index.html. + usedirs => 1, + # Simple spam prevention: require an account-creation password. + #account_creation_password => "example", + # Use new "!"-prefixed preprocessor directive syntax + prefix_directives => 1, + httpauth => 1, + # To add plugins, list them here. + add_plugins => [qw{sidebar toc meta table tag graphviz httpauth img attachment rename remove map teximg version edittemplate}], + disable_plugins => [qw{openid passwordauth}], + teximg_prefix => "\\documentclass{scrartcl} +\\usepackage[version=3]{mhchem} +\\usepackage{amsmath} +\\usepackage{amsfonts} +\\usepackage{amssymb} +\\pagestyle{empty} +\\begin{document}", + + teximg_dvipng => 1, + + # For use with the tag plugin, make all tags be located under a + # base page. + tagbase => "tag", + + # For use with the search plugin if your estseek.cgi is located + # somewhere else. + #estseek => "/usr/lib/estraier/estseek.cgi", +}; diff --git a/libpiny/test b/libpiny/test new file mode 100755 index 0000000..fc1eb55 --- /dev/null +++ b/libpiny/test @@ -0,0 +1,12 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Devel::REPL; + +use lib "lib"; + +use Piny; + +Devel::REPL->new->run; diff --git a/pinyadmin/Makefile b/pinyadmin/Makefile new file mode 100644 index 0000000..64ac713 --- /dev/null +++ b/pinyadmin/Makefile @@ -0,0 +1,12 @@ +build: + mkdir -p man + for f in doc/*.latex; do latex2man $$f man/$$(basename $$f .latex).man; done + ln -s newuser.man man/createuser.man + +install: + install -o root -g root -m 755 -d $(DESTDIR)/usr/bin $(DESTDIR)/usr/sbin + install -o root -g root -m 755 bin/* $(DESTDIR)/usr/bin + install -o root -g root -m 755 sbin/* $(DESTDIR)/usr/sbin + +clean: + rm -rf man diff --git a/pinyadmin/bin/addaccess b/pinyadmin/bin/addaccess new file mode 100755 index 0000000..849119d --- /dev/null +++ b/pinyadmin/bin/addaccess @@ -0,0 +1,2 @@ +#!/bin/sh +exec /usr/bin/sudo /usr/sbin/addaccess "$@" diff --git a/pinyadmin/bin/appendkeys b/pinyadmin/bin/appendkeys new file mode 100755 index 0000000..a4b7d98 --- /dev/null +++ b/pinyadmin/bin/appendkeys @@ -0,0 +1,5 @@ +#!/bin/sh + +/bin/mkdir -p ~/.ssh +/bin/echo Please input authorized keys to be appended. ctrl-d to finish, ctrl-c to abort current line. +/bin/cat >> ~/.ssh/authorized_keys diff --git a/pinyadmin/bin/createuser b/pinyadmin/bin/createuser new file mode 120000 index 0000000..e9d7937 --- /dev/null +++ b/pinyadmin/bin/createuser @@ -0,0 +1 @@ +newuser \ No newline at end of file diff --git a/pinyadmin/bin/lsaccess b/pinyadmin/bin/lsaccess new file mode 100755 index 0000000..ce41fc4 --- /dev/null +++ b/pinyadmin/bin/lsaccess @@ -0,0 +1,30 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Piny; + +my $env = Piny::Environment->instance( ); + +my ( $reponame ) = @ARGV; + +if ( defined $reponame ) { + + my $repo = Piny::Repo->new( $reponame ); + + foreach my $user ( Piny::User->all_users( ) ) { + if ( $repo->has_access( $user ) ) { + print $user->name . "\n"; + }; + }; + +} else { + + foreach my $repo ( Piny::Repo->all_repos( ) ) { + if ( $repo->has_access( $env->user ) ) { + print $repo->name . "\n"; + }; + }; + +}; diff --git a/pinyadmin/bin/lsrepo b/pinyadmin/bin/lsrepo new file mode 100755 index 0000000..2d88eb5 --- /dev/null +++ b/pinyadmin/bin/lsrepo @@ -0,0 +1,10 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Piny; + +foreach my $repo ( Piny::Repo->all_repos( ) ) { + print $repo->name . "\n"; +}; diff --git a/pinyadmin/bin/newrepo b/pinyadmin/bin/newrepo new file mode 100755 index 0000000..025e0cf --- /dev/null +++ b/pinyadmin/bin/newrepo @@ -0,0 +1,2 @@ +#!/bin/sh +exec /usr/bin/sudo /usr/sbin/newrepo "$@" diff --git a/pinyadmin/bin/newuser b/pinyadmin/bin/newuser new file mode 100755 index 0000000..1f73ed6 --- /dev/null +++ b/pinyadmin/bin/newuser @@ -0,0 +1,2 @@ +#!/bin/sh +exec /usr/bin/sudo /usr/sbin/newuser diff --git a/pinyadmin/bin/pinyconfig b/pinyadmin/bin/pinyconfig new file mode 100755 index 0000000..4e54f76 --- /dev/null +++ b/pinyadmin/bin/pinyconfig @@ -0,0 +1,2 @@ +#!/bin/sh +exec /usr/bin/sudo /usr/sbin/pinyconfig "$@" diff --git a/pinyadmin/bin/pinyshell b/pinyadmin/bin/pinyshell new file mode 100755 index 0000000..0db88a8 --- /dev/null +++ b/pinyadmin/bin/pinyshell @@ -0,0 +1,5 @@ +#!/bin/sh +cd /srv/rbin +export PATH=/srv/rbin + +exec /bin/rbash "$@" diff --git a/pinyadmin/bin/readkeys b/pinyadmin/bin/readkeys new file mode 100755 index 0000000..745bd8d --- /dev/null +++ b/pinyadmin/bin/readkeys @@ -0,0 +1,3 @@ +#!/bin/sh + +/bin/cat ~/.ssh/authorized_keys diff --git a/pinyadmin/bin/rmaccess b/pinyadmin/bin/rmaccess new file mode 100755 index 0000000..665052c --- /dev/null +++ b/pinyadmin/bin/rmaccess @@ -0,0 +1,2 @@ +#!/bin/sh +exec /usr/bin/sudo /usr/sbin/rmaccess "$@" diff --git a/pinyadmin/bin/rmrepo b/pinyadmin/bin/rmrepo new file mode 100755 index 0000000..e0e8085 --- /dev/null +++ b/pinyadmin/bin/rmrepo @@ -0,0 +1,2 @@ +#!/bin/sh +exec /usr/bin/sudo /usr/sbin/rmrepo "$@" diff --git a/pinyadmin/bin/writekeys b/pinyadmin/bin/writekeys new file mode 100755 index 0000000..61a7760 --- /dev/null +++ b/pinyadmin/bin/writekeys @@ -0,0 +1,5 @@ +#!/bin/sh + +/bin/mkdir -p ~/.ssh +/bin/echo Please input all authorized keys. ctrl-d to finish, ctrl-c to abort. +/usr/bin/sponge ~/.ssh/authorized_keys diff --git a/pinyadmin/debian/changelog b/pinyadmin/debian/changelog new file mode 100644 index 0000000..e11d900 --- /dev/null +++ b/pinyadmin/debian/changelog @@ -0,0 +1,48 @@ +pinyadmin (0.8) unstable; urgency=low + + * New config tweakable stuff. + + -- Julian Blake Kongslie Mon, 11 Oct 2010 21:56:04 -0700 + +pinyadmin (0.7) unstable; urgency=low + + * Creating ssh key management utilities. + + -- Joe Rayhawk Fri, 03 Sep 2010 01:40:01 -0700 + +pinyadmin (0.6) unstable; urgency=low + + * Revised newrepo to use libpiny. + + -- Julian Blake Kongslie Wed, 07 Jul 2010 15:44:31 -0700 + +pinyadmin (0.5) unstable; urgency=low + + * Listing repos and repo access rights. + + -- Julian Blake Kongslie Tue, 29 Jun 2010 22:32:30 -0700 + +pinyadmin (0.4) unstable; urgency=low + + * Minor typo in manpage. + + -- Julian Blake Kongslie Sun, 18 Apr 2010 13:51:13 -0700 + +pinyadmin (0.3) unstable; urgency=low + + * A few more manpages. + + -- Julian Blake Kongslie Sun, 18 Apr 2010 13:19:34 -0700 + +pinyadmin (0.2) unstable; urgency=low + + * Switch to native packaging. + * Add manpages. + + -- Julian Blake Kongslie Sun, 18 Apr 2010 13:01:32 -0700 + +pinyadmin (0.1-1) unstable; urgency=low + + * Initial release. + + -- Julian Blake Kongslie Thu, 18 Mar 2010 13:55:40 -0700 diff --git a/pinyadmin/debian/compat b/pinyadmin/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/pinyadmin/debian/compat @@ -0,0 +1 @@ +7 diff --git a/pinyadmin/debian/control b/pinyadmin/debian/control new file mode 100644 index 0000000..e8c2d70 --- /dev/null +++ b/pinyadmin/debian/control @@ -0,0 +1,13 @@ +Source: pinyadmin +Maintainer: Julian Blake Kongslie +Section: admin +Build-depends: debhelper (>= 7), texlive-extra-utils +Priority: extra +Standards-version: 3.8.4 + +Package: pinyadmin +Architecture: all +Depends: ${perl:Depends}, ${misc:Depends}, libpiny-perl (>= 0.14), moreutils +Description: Administrative programs for piny + The command-line programs for day-to-day administrative tasks in the Piny + infrastructure. diff --git a/pinyadmin/debian/copyright b/pinyadmin/debian/copyright new file mode 100644 index 0000000..9d12aab --- /dev/null +++ b/pinyadmin/debian/copyright @@ -0,0 +1,3 @@ +Copyright © 2010 Joe Rayhawk +Copyright © 2010 Julian Blake Kongslie +Licensed under the BSD 3-clause license. diff --git a/pinyadmin/debian/pinyadmin.manpages b/pinyadmin/debian/pinyadmin.manpages new file mode 100644 index 0000000..85c5e00 --- /dev/null +++ b/pinyadmin/debian/pinyadmin.manpages @@ -0,0 +1 @@ +man/* diff --git a/pinyadmin/debian/rules b/pinyadmin/debian/rules new file mode 100755 index 0000000..2d33f6a --- /dev/null +++ b/pinyadmin/debian/rules @@ -0,0 +1,4 @@ +#!/usr/bin/make -f + +%: + dh $@ diff --git a/pinyadmin/debian/source/format b/pinyadmin/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/pinyadmin/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/pinyadmin/doc/addaccess.latex b/pinyadmin/doc/addaccess.latex new file mode 100644 index 0000000..a8c29f9 --- /dev/null +++ b/pinyadmin/doc/addaccess.latex @@ -0,0 +1,17 @@ +\usepackage{latex2man} + +\begin{Name}{1piny}{addaccess}{Piny Team}{Piny}{addaccess} + +\Prog{addaccess} - allow access to a repository + +\section{Synopsis} + +\Prog{addaccess} \Arg{reponame} \Arg{username} \Dots + +\section{Description} + +The \Prog{addaccess} command grants users write access to a repository. +It may only be run by the owner of the repository. + +For each \Arg{username} passed on the command line, \Prog{addaccess} will grant write permission to the repository. +Other users are not affected. diff --git a/pinyadmin/doc/newrepo.latex b/pinyadmin/doc/newrepo.latex new file mode 100644 index 0000000..a708b6c --- /dev/null +++ b/pinyadmin/doc/newrepo.latex @@ -0,0 +1,15 @@ +\usepackage{latex2man} + +\begin{Name}{1piny}{newrepo}{Piny Team}{Piny}{newrepo} + +\Prog{newrepo} - create a new repository + +\section{Synopsis} + +\Prog{newrepo} \Arg{reponame} + +\section{Description} + +The \Prog{newrepo} command creates a new repository with the given name. +The current user is set as the owner of the new repository. +No other users are given access to the new repository. diff --git a/pinyadmin/doc/newuser.latex b/pinyadmin/doc/newuser.latex new file mode 100644 index 0000000..721d468 --- /dev/null +++ b/pinyadmin/doc/newuser.latex @@ -0,0 +1,16 @@ +\usepackage{latex2man} + +\begin{Name}{8piny}{newuser}{Piny Team}{Piny}{createuser} + +\Prog{newuser} - add a piny user + +\section{Synopsis} + +\Prog{newuser} + +\Prog{createuser} + +\section{Description} + +The \Prog{newuser} program is an interactive script which walks the user through the process of creating a new Piny account. +Normally it is set as the shell of a passwordless user such as "newuser" or "createuser", so that users can create accounts without any assistance from a sysadmin. diff --git a/pinyadmin/doc/pinyconfig.latex b/pinyadmin/doc/pinyconfig.latex new file mode 100644 index 0000000..4908dbb --- /dev/null +++ b/pinyadmin/doc/pinyconfig.latex @@ -0,0 +1,17 @@ +\usepackage{latex2man} + +\begin{Name}{1piny}{pinyconfig}{Piny Team}{Piny}{pinyconfig} + +\Prog{pinyconfig} - change tweakables on a repo + +\section{Synopsis} + +\Prog{pinyconfig} \Arg{reponame} \Arg{tweakable} \oArg{value} + +\section{Description} + +The \Prog{pinyconfig} command reads and writes tweakables for a repo. + +When run, it prints the value of the tweakable for the repo named. +If a value was passed, it sets the value of the tweakable to that value +before printing it. diff --git a/pinyadmin/doc/pinyshell.latex b/pinyadmin/doc/pinyshell.latex new file mode 100644 index 0000000..481ddf3 --- /dev/null +++ b/pinyadmin/doc/pinyshell.latex @@ -0,0 +1,19 @@ +\usepackage{latex2man} + +\begin{Name}{8piny}{pinyshell}{Piny Team}{Piny}{pinyshell} + +\Prog{pinyshell} - a restricted shell + +\section{Synopsis} + +\Prog{pinyshell} + +\section{Description} + +\Prog{pinyshell} is just another way to invoke \Cmd{1}{rbash}; the separate name is used for accounting purposes within the piny infrastructure. + +Users which should be managed by the Piny infrastructure should have \Prog{pinyshell} as their shell. + +\section{See Also} + +\Cmd{1}{rbash} diff --git a/pinyadmin/doc/rebuildrepo.latex b/pinyadmin/doc/rebuildrepo.latex new file mode 100644 index 0000000..a2e0935 --- /dev/null +++ b/pinyadmin/doc/rebuildrepo.latex @@ -0,0 +1,16 @@ +\usepackage{latex2man} + +\begin{Name}{8piny}{rebuildrepo}{Piny Team}{Piny}{rebuildrepo} + +\Prog{rebuildrepo} - rebuild a repo configuration + +\section{Synopsis} + +\Prog{rebuildrepo} \Arg{reponame} \Dots + +\section{Description} + +The \Prog{rebuildrepo} command rewrites all of the configuration files for +the given repo and adjusts ownership and group membership of its files to a +normalized state. It is needed to propagate certain kinds of changes; +normally only the system administrator should run it. diff --git a/pinyadmin/doc/rmaccess.latex b/pinyadmin/doc/rmaccess.latex new file mode 100644 index 0000000..41f7af4 --- /dev/null +++ b/pinyadmin/doc/rmaccess.latex @@ -0,0 +1,22 @@ +\usepackage{latex2man} + +\begin{Name}{1piny}{rmaccess}{Piny Team}{Piny}{rmaccess} + +\Prog{rmaccess} - remove access to a repository + +\section{Synopsis} + +\Prog{rmaccess} \Arg{reponame} \Arg{username} \Dots + +\section{Description} + +The \Prog{rmaccess} command denies users write access to a repository. +It may only be run by the owner of the repository. + +For each \Arg{username} passed on the command line, \Prog{addaccess} will deny write permission to the repository. +Other users are not affected. + +\section{Bugs} + +You cannot deny write permission to the owner of the repository. +If you try, the program will appear to succeed, but the owner will still be able to make changes. diff --git a/pinyadmin/doc/rmrepo.latex b/pinyadmin/doc/rmrepo.latex new file mode 100644 index 0000000..12b58df --- /dev/null +++ b/pinyadmin/doc/rmrepo.latex @@ -0,0 +1,14 @@ +\usepackage{latex2man} + +\begin{Name}{1piny}{rmrepo}{Piny Team}{Piny}{rmrepo} + +\Prog{rmrepo} - delete a repository + +\section{Synopsis} + +\Prog{rmrepo} \Arg{reponame} \Dots + +\section{Description} + +The \Prog{rmrepo} command permanently destroys the repository with the given name. +The current user must be the owner of the repository. diff --git a/pinyadmin/sbin/addaccess b/pinyadmin/sbin/addaccess new file mode 100755 index 0000000..e351114 --- /dev/null +++ b/pinyadmin/sbin/addaccess @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Piny; + +my $env = Piny::Environment->instance( ); + +my ( $reponame, @users ) = @ARGV; + +my $repo = Piny::Repo->new( $reponame ); + +if ( $repo->owner->uid != $env->user->uid ) { + print "You are not the owner of that repo!\n"; + exit( 3 ); +}; + +$repo->add_access( map { Piny::User->new( $_ ) } @users ); diff --git a/pinyadmin/sbin/newrepo b/pinyadmin/sbin/newrepo new file mode 100755 index 0000000..a178ecb --- /dev/null +++ b/pinyadmin/sbin/newrepo @@ -0,0 +1,40 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Moose::Util::TypeConstraints qw( find_type_constraint ); + +use Piny; + +my ( $name ) = @ARGV; + +if ( not defined $name ) { + print "Usage: newrepo REPONAME\n"; + exit 1; +}; + +if ( not find_type_constraint( "Reponame" )->check( $name ) ) { + print "That is not a valid repo name; must be at least 1 character long, begin with a lowercase alphanumeric character, and contain only alphanumeric characters and dashes.\n"; + exit 1; +}; + +my $description; +while( 1 ) { + + print "Provide a one-line description to be used in repo listings, the shorter the better:\n"; + chomp( $description = ); + + if ( not find_type_constraint( "SimpleText" )->check( $description ) ) { + print "Must be 1-80 characters long; control characters (including tab) not allowed.\n"; + next; + }; + + print "Okay! Working, please wait...\n"; + last; + +}; + +my $repo = Piny::Repo->create( $name, $description ); + +print "Repo URL: " . $repo->ikiwiki_url . "\n"; diff --git a/pinyadmin/sbin/newuser b/pinyadmin/sbin/newuser new file mode 100755 index 0000000..e064f06 --- /dev/null +++ b/pinyadmin/sbin/newuser @@ -0,0 +1,129 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Email::Valid::Loose qw( ); + +# If they passed any arguments, complain and exit. +if ( scalar @ARGV ) { + print "You can't pass any arguments to this script!\n"; + exit 2; +}; + +# If they didn't provide a terminal definition, then assume xterm. +# Everybody emulates xterm to at least a basic extent. +if ( not exists $ENV{"TERM"} ) { + $ENV{"TERM"} = "xterm"; + print "I don't know what terminal you're using; guessing xterm...\n"; +}; + +# Disable buffering. +$|++; + +# Configure the strictness of our email checks. +my $checker = Email::Valid::Loose->new + ( "-fqdn" => 1 + , "-fudge" => 0 + , "-local_rules" => 0 + , "-mxcheck" => 1 + , "-tldcheck" => 0 + ); + +my ( $email, $username, $password1, $password2 ); + +while ( 1 ) { + + print "Email address to associate with new user: "; + chomp ( $email = ); + + if ( $email eq "" ) { + print "You must provide an email address!\n"; + next; + }; + + $email = $checker->address( $email ); + if ( not defined $email ) { + print "Please, at least pretend to provide a valid email address.\n"; + next; + }; + + last; + +}; + +while ( 1 ) { + + print "Desired username: "; + chomp ( $username = ); + + if ( $username eq "" ) { + print "You have to enter a username!\n"; + next; + }; + + if ( $username =~ /^git-|^ikiwiki-/ ) { + print "Your username cannot start with git- or ikiwiki-!\n"; + next + }; + + if ( $username !~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ ) { + print( "Usernames must consist only of letters, digits, underscores, periods, and dashes, and not start with a dash. Usernames are case sensitive.\n" ); + next + }; + + last; + +}; + +while ( 1 ) { + + system( "stty", "-echo" ); + print "Desired password: "; + chomp ( $password1 = ); + print "\nRetype password: "; + chomp ( $password2 = ); + print "\n"; + system( "stty", "echo" ); + + if ( $password1 ne $password2 ) { + print "Provided passwords do not match; try again.\n"; + next; + }; + + if ( $password1 eq "" ) { + print "You have to enter a password!\n"; + next; + }; + + last; + +}; + +my @saltchars = + ( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' + , 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' + , '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' + , '.', '/' + ); + +my $salt = "\$6\$"; + +foreach my $n ( 1 .. 16 ) { + $salt .= $saltchars[int ( rand ( scalar @saltchars ) )]; +}; + +$salt .= "\$"; + +my $crypt = crypt( $password1, $salt ); + +my $ret = system( "/usr/sbin/useradd", "-c", "$email", "-k", "/var/empty", "-g", "users", "-m", "-p", $crypt, "-s", "/usr/bin/pinyshell", $username ); + +if ( $ret ) { + print "An error occured creating the user; most likely, that username is already taken.\n"; + exit 1; +}; + +print "Your user has been created. Try logging in!\n"; + +exit 0; diff --git a/pinyadmin/sbin/pinyconfig b/pinyadmin/sbin/pinyconfig new file mode 100755 index 0000000..f6752db --- /dev/null +++ b/pinyadmin/sbin/pinyconfig @@ -0,0 +1,38 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Piny; + +my ( $reponame, $attr, $value ) = @ARGV; + +if ( not defined $reponame or not defined $attr ) { + die "Usage: $0 reponame tweakable [value]\n"; +}; + +$attr = lc $attr; +$attr =~ s/\./_/g; + +my $repo = Piny::Repo->new( $reponame ); + +if ( defined $value ) { + undef $@; + eval { + $repo->config->$attr( $value ); + }; + if ( $@ ) { + print STDERR "$attr is not a legal tweakable, or $value is not a legal value for that tweakable.\n$@\n"; + }; + if ( $value ne $repo->config->$attr ) { + print STDERR "Failed to set $attr (perhaps an override is in place)\n"; + }; +}; + +undef $@; +eval { + print "$attr = " . $repo->config->$attr . "\n"; +}; +if ( $@ ) { + print STDERR "$attr is not a legal tweakable, or its current value is illegal.\n$@\n"; +}; diff --git a/pinyadmin/sbin/rebuildrepo b/pinyadmin/sbin/rebuildrepo new file mode 100755 index 0000000..9d4e359 --- /dev/null +++ b/pinyadmin/sbin/rebuildrepo @@ -0,0 +1,14 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Piny; + +foreach my $reponame ( @ARGV ) { + + my $repo = Piny::Repo->new( $reponame ); + + $repo->rebuild; + +}; diff --git a/pinyadmin/sbin/rmaccess b/pinyadmin/sbin/rmaccess new file mode 100755 index 0000000..d6c22a9 --- /dev/null +++ b/pinyadmin/sbin/rmaccess @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Piny; + +my $env = Piny::Environment->instance( ); + +my ( $reponame, @users ) = @ARGV; + +my $repo = Piny::Repo->new( $reponame ); + +if ( $repo->owner->uid != $env->user->uid ) { + print "You are not the owner of that repo!\n"; + exit( 3 ); +}; + +$repo->remove_access( map { Piny::User->new( $_ ) } @users ); diff --git a/pinyadmin/sbin/rmrepo b/pinyadmin/sbin/rmrepo new file mode 100755 index 0000000..dff8fe5 --- /dev/null +++ b/pinyadmin/sbin/rmrepo @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Piny; + +my $env = Piny::Environment->instance( ); + +foreach my $reponame ( @ARGV ) { + + my $repo = Piny::Repo->new( $reponame ); + + if ( $env->user->uid != 0 and $repo->owner->uid != $env->user->uid ) { + print STDERR "You are not the owner of $reponame!\n"; + exit 1; + }; + + $repo->destroy; + +}; diff --git a/usr/src/libpiny/Build.PL b/usr/src/libpiny/Build.PL deleted file mode 100644 index bfb5fd7..0000000 --- a/usr/src/libpiny/Build.PL +++ /dev/null @@ -1,30 +0,0 @@ -use Module::Build; - -open( DCH, "<", "debian/changelog" ) or die "changelog: $!"; - -my $version = "0"; -while ( defined ( my $line = ) ) { - if ( $line =~ /\(([0-9.]+)\)/ ) { - $version = $1; - last; - }; -}; - -close( DCH ); - -my $build = Module::Build->new - ( 'module_name' => 'Piny' - , 'dist_version' => $version - , 'license' => 'BSD-3' - , 'setup_files' => { 'share/ikiwiki.setup' => 'share/ikiwiki.setup' } - , 'install_path' => - { 'share' => '/usr/share/libpiny' - } - , 'requires' => - { 'Moose' => 0 - , 'Email::Valid::Loose' => 0 - } - ); - -$build->add_build_element( "setup" ); -$build->create_build_script( ); diff --git a/usr/src/libpiny/debian/changelog b/usr/src/libpiny/debian/changelog deleted file mode 100644 index e97c2fe..0000000 --- a/usr/src/libpiny/debian/changelog +++ /dev/null @@ -1,89 +0,0 @@ -libpiny-perl (0.14) unstable; urgency=low - - * Support rebuilding a repo's config. - - -- Julian Blake Kongslie Wed, 13 Oct 2010 20:38:15 -0700 - -libpiny-perl (0.13) unstable; urgency=low - - * Vastly overhauled the config stuff. - - -- Julian Blake Kongslie Mon, 11 Oct 2010 21:55:40 -0700 - -libpiny-perl (0.12) unstable; urgency=low - - * Support for per-repo configuration in the git config, section piny. - * Support for per-repo custom http/https base URLs. - - -- Julian Blake Kongslie Sun, 01 Aug 2010 20:07:44 -0700 - -libpiny-perl (0.11) unstable; urgency=low - - * Destroying dead repos. - - -- Julian Blake Kongslie Mon, 19 Jul 2010 02:30:01 -0700 - -libpiny-perl (0.10) unstable; urgency=low - - * Support for the global /etc/piny.conf stuff. - - -- Julian Blake Kongslie Sun, 18 Jul 2010 21:23:28 -0700 - -libpiny-perl (0.9) unstable; urgency=low - - * Creating new repos. - - -- Julian Blake Kongslie Wed, 07 Jul 2010 15:34:37 -0700 - -libpiny-perl (0.8) unstable; urgency=low - - * Added apache config stuff. - - -- Julian Blake Kongslie Wed, 07 Jul 2010 14:26:38 -0700 - -libpiny-perl (0.7) unstable; urgency=low - - * Lots more ikiwiki integration. - - -- Julian Blake Kongslie Wed, 07 Jul 2010 13:45:42 -0700 - -libpiny-perl (0.6) unstable; urgency=low - - * Added IkiWiki::FakeSetup for manipulating IkiWiki setup scripts. - - -- Julian Blake Kongslie Wed, 07 Jul 2010 12:12:37 -0700 - -libpiny-perl (0.5) unstable; urgency=low - - * Allow listing repos and querying access rights. - - -- Julian Blake Kongslie Tue, 29 Jun 2010 22:28:59 -0700 - -libpiny-perl (0.4) unstable; urgency=low - - * Switch to native packaging. - - -- Julian Blake Kongslie Sun, 18 Apr 2010 12:33:19 -0700 - -libpiny-perl (0.3-1) unstable; urgency=low - - * Fix some build-depends stuff. - * Add group membership manipulation. - * Add some more type constraints. - * Fix a bug in the username detection. - * Forbid purely-numeric usernames. - * Use fixed paths to reach adduser and deluser. - - -- Julian Blake Kongslie Thu, 18 Mar 2010 16:56:24 -0700 - -libpiny-perl (0.2-1) unstable; urgency=low - - * Switched to Module::Build because it seems marginally sane. - - -- Julian Blake Kongslie Thu, 18 Mar 2010 00:08:05 -0700 - -libpiny-perl (0.1-1) unstable; urgency=low - - * Initial release. - - -- Julian Blake Kongslie Wed, 17 Mar 2010 23:44:25 -0700 diff --git a/usr/src/libpiny/debian/compat b/usr/src/libpiny/debian/compat deleted file mode 100644 index 7f8f011..0000000 --- a/usr/src/libpiny/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/usr/src/libpiny/debian/control b/usr/src/libpiny/debian/control deleted file mode 100644 index b64d8fa..0000000 --- a/usr/src/libpiny/debian/control +++ /dev/null @@ -1,13 +0,0 @@ -Source: libpiny-perl -Maintainer: Julian Blake Kongslie -Section: perl -Build-depends: debhelper (>= 7) -Priority: extra -Standards-version: 3.8.4 - -Package: libpiny-perl -Architecture: all -Depends: ${perl:Depends}, ${misc:Depends}, libconfig-simple-perl, libemail-valid-loose-perl, libmoose-perl, libmoosex-singleton-perl, libmoosex-strictconstructor-perl -Description: Perl interface for the piny infrastructure - This is a set of modules for accomplishing administrative tasks in the piny.be - infrastructure. diff --git a/usr/src/libpiny/debian/copyright b/usr/src/libpiny/debian/copyright deleted file mode 100644 index db049e1..0000000 --- a/usr/src/libpiny/debian/copyright +++ /dev/null @@ -1,2 +0,0 @@ -Copyright © 2010 Julian Blake Kongslie -Licensed under the BSD 3-clause license. diff --git a/usr/src/libpiny/debian/rules b/usr/src/libpiny/debian/rules deleted file mode 100755 index 2d33f6a..0000000 --- a/usr/src/libpiny/debian/rules +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/make -f - -%: - dh $@ diff --git a/usr/src/libpiny/debian/source/format b/usr/src/libpiny/debian/source/format deleted file mode 100644 index 89ae9db..0000000 --- a/usr/src/libpiny/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (native) diff --git a/usr/src/libpiny/lib/IkiWiki/FakeSetup.pm b/usr/src/libpiny/lib/IkiWiki/FakeSetup.pm deleted file mode 100644 index c9c823b..0000000 --- a/usr/src/libpiny/lib/IkiWiki/FakeSetup.pm +++ /dev/null @@ -1,88 +0,0 @@ -package IkiWiki::FakeSetup; - -use strict; -use warnings; - -use Data::Dumper qw( ); -use Exporter qw( import ); - -our @EXPORT_OK = qw( readSetup writeSetup ); - -sub readSetup { - my ( $setupfile ) = @_; - - # Sorry about the use of globals but it's hard to share lexicals with dynamically generated source. - $IkiWiki::FakeSetup::package = undef; - @IkiWiki::FakeSetup::args = (); - - sub inc { - my ( $self, $file ) = @_; - - my $package = $file; - $package =~ s/\//::/g; - $package =~ s/\.pm//; - - my @src = - ( "package $package;\n" - , "sub import {\n" - , " my ( \$class, \@args ) = \@_;\n" - , " \$IkiWiki::FakeSetup::package = \$class;\n" - , " \@IkiWiki::FakeSetup::args = \@args;\n" - , "}\n" - , "1;\n" - ); - - return sub { if ( scalar @src ) { $_ = shift @src; return 1; } else { return 0; } }; - - }; - - eval { - my @oldINC = @INC; - @INC = ( ".", \&inc ); - - my %oldINC = %INC; - %INC = ( ); - - do $setupfile; - - @INC = @oldINC; - %INC = %oldINC; - }; - - return ( $IkiWiki::FakeSetup::package, @IkiWiki::FakeSetup::args ); - -} - -sub writeSetup { - my ( $package, @args ) = @_; - - my $d = Data::Dumper->new( \@args ); - $d->Terse( 1 ); - - return "#!/usr/bin/perl\n\nuse $package " . $d->Dump( ) . ";\n"; -} - -1; - -__END__ - -Because it may not be completely obvious, here's how you would use this: - -#!/usr/bin/perl - -use strict; -use warnings; - -use IkiWiki::FakeSetup qw( readSetup writeSetup ); - -# This reads the setup file, returning the package it uses and any configuration it passed to that package. -my ( $package, $config ) = readSetup( "almighty_ikiwiki_template.setup" ); - -# Make changes to the configuration. -$config->{"srcdir"} = "/some/dir"; -$config->{"adminemail"} = "somejerk\@jerkville.com"; - -# Open a new file, and write the changed configuration to it. -open( SETUP, ">", "almighty_ikiwiki_template_changed.setup" ); -print SETUP writeSetup( $package, $config ); -close( SETUP ); diff --git a/usr/src/libpiny/lib/Piny.pm b/usr/src/libpiny/lib/Piny.pm deleted file mode 100644 index 54a5b00..0000000 --- a/usr/src/libpiny/lib/Piny.pm +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright © 2010 Julian Blake Kongslie -# Licensed under the BSD 3-clause license. - -# This very pointedly does not have a package line. -# That way, you can "use Piny" and import all the Piny packages into your namespace in one fell swoop. -# Of course, you don't get to pass arguments to their import functions anymore. - -use Piny::Config; -use Piny::Email; -use Piny::Environment; -use Piny::Group; -use Piny::Repo; -use Piny::User; -use Piny::User::IkiWiki; - -1; diff --git a/usr/src/libpiny/lib/Piny/Config.pm b/usr/src/libpiny/lib/Piny/Config.pm deleted file mode 100644 index 76405ee..0000000 --- a/usr/src/libpiny/lib/Piny/Config.pm +++ /dev/null @@ -1,218 +0,0 @@ -# Copyright © 2010 Julian Blake Kongslie -# Licensed under the BSD 3-clause license. - -use strict; -use warnings; - -package Piny::Config; - -use Moose; -use Moose::Util::TypeConstraints; -use MooseX::StrictConstructor; - -use Carp; -use Config::Simple qw( -lc ); - -# Types - -subtype 'GitBool' - => as 'Str' - => where { $_ =~ /^(1|0|true|false)$/i } - => message { 'Not correct format for a git-compatible boolean.' } - ; - -subtype 'Path' - => as 'Str' - => where { $_ =~ /^\// and -e $_ } - => message { 'Not an absolute path, or does not exist.' } - ; - -subtype 'PathDir' - => as 'Path' - => where { -d $_ } - => message { 'Not an absolute path, or not a directory.' } - ; - -subtype 'HttpUrl' - => as 'Str' - => where { $_ =~ /^http:\/\//i } - => message { 'Not a http:// URL.' } - ; - -subtype 'HttpsUrl' - => as 'Str' - => where { $_ =~ /^https:\/\//i } - => message { 'Not a https:// URL.' } - ; - -# Attributes - -has 'confpath' => - ( is => 'ro' - , isa => 'Str' - , predicate => 'has_confpath' - ); - -has '_conf' => - ( is => 'ro' - , isa => 'HashRef[Str]' - , lazy_build => 1 - , clearer => 'clear_conf' - , init_arg => undef - ); - -# Builder methods - -# If constructed with just one argument, then treat it as a config path. -around BUILDARGS => sub { - my ( $orig, $class ) = ( shift, shift ); - - if ( @_ == 1 && ! ref $_[0] ) { - return $class->$orig( confpath => $_[0] ); - } else { - return $class->$orig( @_ ); - }; -}; - -sub _build__conf { - my ( $s ) = @_; - - my $conf; - - if ( $s->has_confpath and -e $s->confpath ) { - $conf = Config::Simple->new( $s->confpath )->vars; - } else { - $conf = { }; - }; - - if ( -e "/etc/piny-default.conf" ) { - - my $default = Config::Simple->new( "/etc/piny-default.conf" )->vars; - - foreach my $key ( keys %$default ) { - if ( not exists $conf->{$key} ) { - $conf->{$key} = $default->{$key}; - }; - }; - - }; - - if ( -e "/etc/piny-override.conf" ) { - - my $override = Config::Simple->new( "/etc/piny-override.conf" )->vars; - - foreach my $key ( keys %$override ) { - $conf->{$key} = $override->{$key}; - }; - - }; - - return $conf; -}; - -# Save the config - -sub save { - my ( $s ) = @_; - - if ( not $s->has_confpath ) { - croak "Can't save a Piny::Config if the confpath is not set!"; - }; - - if ( -e "/etc/piny-override.conf" ) { - - my $override = Config::Simple->new( "/etc/piny-override.conf" )->vars; - - foreach my $key ( keys %$override ) { - if ( exists $s->_conf->{$key} and $s->_conf->{$key} eq $override->{$key} ) { - delete $s->_conf->{$key}; - }; - }; - - }; - - if ( -e "/etc/piny-default.conf" ) { - - my $default = Config::Simple->new( "/etc/piny-default.conf" )->vars; - - foreach my $key ( keys %$default ) { - if ( exists $s->_conf->{$key} and $s->_conf->{$key} eq $default->{$key} ) { - delete $s->_conf->{$key}; - }; - }; - - }; - - my $cs = Config::Simple->new( syntax => "ini" ); - - foreach my $key ( keys %{$s->_conf} ) { - $cs->param( $key, $s->_conf->{$key} ); - }; - - $cs->write( $s->confpath ); -}; - -# Tweakable helper - -sub tweakable { - my ( $attr, $default, $isa ) = @_; - - $attr = lc $attr; - - my $attrname = $attr; - $attrname =~ s/_/./; - - if ( $attrname =~ /_/ ) { croak "Illegal attribute name $attrname! (use only one underbar)"; }; - - has $attr => - ( is => 'rw' - , isa => $isa - , lazy_build => 1 - , trigger => sub { - my ( $s, $new, $old ) = @_; - - $s->_conf->{$attrname} = $new; - - if ( $s->has_confpath ) { - $s->save; - } else { - carp "Attribute $attrname modification ignored!"; - }; - - $s->clear_conf; - my $clearer = "clear_$attr"; - $s->$clearer; - } - ); - - my $builder = sub { - my ( $s ) = @_; - - if ( exists $s->_conf->{$attrname} ) { - return $s->_conf->{$attrname}; - } else { - return $default; - }; - }; - - { - no strict "refs"; - - *{"_build_" . $attr} = $builder; - }; -}; - -# The tweakables - -tweakable "piny_ikiwikidestdir" => "/srv/www/piny.be/", 'PathDir'; -tweakable "piny_ikiwikisrcdir" => "/srv/ikiwiki/", 'PathDir'; -tweakable "piny_ikiwikiurl" => "http://piny.be/", 'HttpUrl'; -tweakable "piny_ikiwikisecureurl" => "https://secure.piny.be/", 'HttpsUrl'; -tweakable "piny_ikiwikisecurepath" => "/srv/www/secure.piny.be/", 'PathDir'; -tweakable "receive_denynonfastforwards" => "true", 'GitBool'; - -# Moose boilerplate - -__PACKAGE__->meta->make_immutable; - -1; diff --git a/usr/src/libpiny/lib/Piny/Email.pm b/usr/src/libpiny/lib/Piny/Email.pm deleted file mode 100644 index baa56f0..0000000 --- a/usr/src/libpiny/lib/Piny/Email.pm +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright © 2010 Julian Blake Kongslie -# Licensed under the BSD 3-clause license. - -use strict; -use warnings; - -package Piny::Email; - -use Moose; -use Moose::Util::TypeConstraints; -use MooseX::StrictConstructor; - -use Email::Valid::Loose; - -# Types - -my $checker = Email::Valid::Loose->new("-fqdn" => 1, "-fudge" => 0, "-local_rules" => 0, "-mxcheck" => 1, "-tldcheck" => 0 ); - -subtype 'EmailAddress' - => as 'Str' - => where { $checker->address( $_ ) } - => message { 'That does not appear to be a valid email address.' } - ; - -# Attributes - -has 'address' => - ( is => 'ro' - , isa => 'EmailAddress' - ); - -# Builder methods - -# If constructed with just one argument, then treat it as an address. -around BUILDARGS => sub { - my ( $orig, $class ) = ( shift, shift ); - - if ( @_ == 1 && ! ref $_[0] ) { - return $class->$orig( address => $_[0] ); - } else { - return $class->$orig( @_ ); - }; -}; - -# Moose boilerplate - -__PACKAGE__->meta->make_immutable; - -1; diff --git a/usr/src/libpiny/lib/Piny/Environment.pm b/usr/src/libpiny/lib/Piny/Environment.pm deleted file mode 100644 index 06416b8..0000000 --- a/usr/src/libpiny/lib/Piny/Environment.pm +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright © 2010 Julian Blake Kongslie -# Licensed under the BSD 3-clause license. - -use strict; -use warnings; - -package Piny::Environment; - -use MooseX::Singleton; -use MooseX::StrictConstructor; - -use Piny::User; - -# Attributes - -has 'user' => - ( is => 'ro' - , isa => 'Piny::User' - , lazy_build => 1 - , init_arg => undef - ); - -# Builder methods - -sub _build_user { - my ( $s ) = @_; - - if ( defined $ENV{"SUDO_UID"} ) { - return Piny::User->new( uid => $ENV{"SUDO_UID"} ); - } elsif ( defined $ENV{"SUDO_USER"} ) { - return Piny::User->new( name => $ENV{"SUDO_USER"} ); - } elsif ( defined $ENV{"UID"} ) { - return Piny::User->new( uid => $ENV{"UID"} ); - } elsif ( defined $ENV{"USER"} ) { - return Piny::User->new( name => $ENV{"USER"} ); - } else { - return Piny::User->new( uid => $< ); - }; -}; - -# Moose boilerplate - -__PACKAGE__->meta->make_immutable( inline_constructor => 0 ); - -1; diff --git a/usr/src/libpiny/lib/Piny/Group.pm b/usr/src/libpiny/lib/Piny/Group.pm deleted file mode 100644 index 86a6d95..0000000 --- a/usr/src/libpiny/lib/Piny/Group.pm +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright © 2010 Julian Blake Kongslie -# Licensed under the BSD 3-clause license. - -use strict; -use warnings; - -package Piny::Group; - -use Moose; -use MooseX::StrictConstructor; - -use Piny::User; - -# Attributes - -has 'gid' => - ( is => 'ro' - , isa => 'Int' - , lazy_build => 1 - ); - -has 'name' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - ); - -has 'grent' => - ( is => 'ro' - , isa => 'ArrayRef' - , lazy_build => 1 - , init_arg => undef - ); - -has 'members' => - ( is => 'ro' - , isa => 'ArrayRef[Piny::User]' - , lazy_build => 1 - , init_arg => undef - ); - -# Public methods - -sub add_member { - my ( $s, @users ) = @_; - - foreach my $user ( @users ) { - system( "/usr/sbin/adduser", $user->name( ), $s->name( ) ); - $user->clear_groups( ); - }; - - $s->clear_members( ); -}; - -sub remove_member { - my ( $s, @users ) = @_; - - foreach my $user ( @users ) { - system( "/usr/sbin/deluser", $user->name( ), $s->name( ) ); - $user->clear_groups( ); - }; - - $s->clear_members( ); -}; - -# Builder methods - -# If constructed with just one argument, then -# * If that argument is numeric, treat it as a GID. -# * Otherwise, treat it as a name. -around BUILDARGS => sub { - my ( $orig, $class ) = ( shift, shift ); - - if ( @_ == 1 && ! ref $_[0] ) { - if ( $_[0] =~ m/^\d+$/ ) { - return $class->$orig( gid => $_[0] ); - } else { - return $class->$orig( name => $_[0] ); - }; - } else { - return $class->$orig( @_ ); - }; -}; - -sub BUILD { - my ( $s ) = @_; - - if ( not ( $s->has_gid( ) or $s->has_name( ) ) ) { - die "You must provide either GID or name!"; - }; - - if ( $s->has_gid( ) and $s->has_name( ) ) { - die "You must not provide both GID and name!"; - }; -}; - -sub _build_gid { - my ( $s ) = @_; - - return $s->grent( )->[2]; -}; - -sub _build_name { - my ( $s ) = @_; - - return $s->grent( )->[0]; -}; - -sub _build_grent { - my ( $s ) = @_; - - if ( $s->has_gid( ) ) { - my @res = getgrgid( $s->gid( ) ); - die "getgrgid( " . $s->gid( ) . " ) failed: $!" unless @res; - return \@res; - } elsif ( $s->has_name( ) ) { - my @res = getgrnam( $s->name( ) ); - die "getgrnam( " . $s->name( ) . " ) failed: $!" unless @res; - return \@res; - } else { - die "Not enough information provided to lookup group!"; - }; -}; - -sub _build_members { - my ( $s ) = @_; - - return [ ] if ( $s->grent( )->[3] eq "" ); - return [ map { Piny::User->new( name => $_ ) } split( /:/, $s->grent( )->[3] ) ]; -}; - -# Moose boilerplate - -__PACKAGE__->meta->make_immutable; - -1; diff --git a/usr/src/libpiny/lib/Piny/Repo.pm b/usr/src/libpiny/lib/Piny/Repo.pm deleted file mode 100644 index 8ebb0f4..0000000 --- a/usr/src/libpiny/lib/Piny/Repo.pm +++ /dev/null @@ -1,637 +0,0 @@ -# Copyright © 2010 Julian Blake Kongslie -# Licensed under the BSD 3-clause license. - -use strict; -use warnings; - -package Piny::Repo; - -use Moose; -use Moose::Util::TypeConstraints; -use MooseX::StrictConstructor; - -use File::Find qw( find ); -use File::Temp qw( ); -use IO::Dir qw( ); - -use IkiWiki::FakeSetup qw( readSetup writeSetup ); - -use Piny::Config; -use Piny::Environment; -use Piny::Group; -use Piny::User; -use Piny::User::IkiWiki; - -# Types - -subtype 'Reponame' - => as 'Str' - => where { $_ =~ /^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/ } - => message { 'That name is not in the correct format for a piny repo.' } - ; - -subtype 'SimpleText' - => as 'Str' - => where { $_ =~ /^[\x{0020}-\x{FDCF}\x{FDF0}-\x{FFFD}]{1,80}$/ } - => message { 'That description is not in the correct format for a piny repo.' } - ; - -# Attributes - -has 'name' => - ( is => 'rw' - , isa => 'Reponame' - , trigger => \&_rename_repo - , required => 1 - ); - -has 'group' => - ( is => 'ro' - , isa => 'Piny::Group' - , lazy_build => 1 - , init_arg => undef - ); - -has 'path' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'description' => - ( is => 'rw' - , isa => 'SimpleText' - , trigger => \&_set_description - , lazy_build => 1 - , init_arg => undef - ); - -has 'repostat' => - ( is => 'ro' - , isa => 'ArrayRef' - , lazy_build => 1 - , init_arg => undef - ); - -has 'owner' => - ( is => 'rw' - , isa => 'Piny::User' - , trigger => \&_change_owner - , lazy_build => 1 - , init_arg => undef - ); - -has 'globally_readable' => - ( is => 'ro' - , isa => 'Bool' - , lazy_build => 1 - , init_arg => undef - ); - -has 'globally_writable' => - ( is => 'ro' - , isa => 'Bool' - , lazy_build => 1 - , init_arg => undef - ); - -has 'ikiwiki_setup' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'ikiwiki_destdir' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'ikiwiki_srcdir' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'ikiwiki_url' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'ikiwiki_cgiurl' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'ikiwiki_historyurl' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'ikiwiki_diffurl' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'ikiwiki_cgipath' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'secure_path' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'apache_config' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'config' => - ( is => 'ro' - , isa => 'Piny::Config' - , lazy_build => 1 - , init_arg => undef - ); - -# Public methods - -sub add_access { - my ( $s, @users ) = @_; - - $s->group->add_member( @users ); -}; - -sub remove_access { - my ( $s, @users ) = @_; - - $s->group->remove_member( @users ); -}; - -sub has_access { - my ( $s, $user ) = @_; - - return $s->owner->uid == $user->uid || $user->has_group( $s->group ); -}; - -sub rebuild { - my ( $s ) = @_; - - my $ikiuser = Piny::User::IkiWiki->new( "name" => "ikiwiki-" . $s->name ); - - foreach( "git-daemon-export-ok", "packed-refs" ) { - open( TOUCH, ">", $s->path . "/" . $_ ) or die "Could not touch $_ for repo: $!"; - close( TOUCH ); - }; - - foreach( "info", "logs" ) { - (-e $s->path . "/" . $_) or mkdir( $s->path . "/" . $_ ) or die "Could not mkdir $_ for repo: $!"; - }; - - chown( 0, 0, $s->path, $s->path . "/config" ) or die "Could not change ownership of git dir!"; - - foreach( "branches", "description", "HEAD", "info", "logs", "objects", "packed-refs", "refs" ) { - system( "/bin/chown", "-R", $s->owner->name . "." . $s->group->name, $s->path . "/" . $_ ) and die "Could not change ownership of $_ for repo: $!"; - }; - - system( "/bin/chown", "-R", $ikiuser->name . "." . $ikiuser->name, $s->path . "/hooks" ) and die "Could not change ownership of git hooks!"; - - open( SETUP, ">", "/etc/ikiwiki/piny/" . $s->name . ".setup" ) or die "Could not open new ikiwiki setup file: $!"; - print SETUP $s->ikiwiki_setup; - close( SETUP ) or die "Could not close new ikiwiki setup file: $!"; - - system( "/bin/chown", "-R", $ikiuser->name . "." . $ikiuser->name, $s->ikiwiki_srcdir, $s->ikiwiki_destdir, $s->secure_path ) and die "Could not change ownership of ikiwiki directories!"; - - open( WIKILIST, ">", "/etc/ikiwiki/wikilist.d/" . $s->name ) or die "Could not create wikilist.d file: $!"; - print WIKILIST $ikiuser->name . " /etc/ikiwiki/piny/" . $s->name . ".setup\n"; - close( WIKILIST ) or die "Could not close wikilist.d file: $!"; - - my $temp = File::Temp->new( ) or die "Could not create temporary file: $!"; - $temp->unlink_on_destroy( 0 ); - - my $dh = IO::Dir->new( "/etc/ikiwiki/wikilist.d" ) or die "Could not open wikilist.d directory: $!"; - while ( defined ( my $entry = $dh->read ) ) { - next if ( $entry =~ /^\./ ); - open( FILE, "<", "/etc/ikiwiki/wikilist.d/" . $entry ) or die "Could not open wikilist.d entry $entry: $!"; - print $temp ; - close( FILE ) or die "Could not close wikilist.d entry $entry: $!"; - }; - - $temp->close or die "Could not close new wikilist: $!"; - - chmod( 00644, $temp->filename ) or die "Could not fix mode of new wikilist: $!"; - - rename( $temp->filename, "/etc/ikiwiki/wikilist" ) or die "Could not rename over old wikilist: $!"; - - $ENV{"GIT_DIR"} = $s->path; - system( "/usr/bin/git", "config", "gitweb.owner", $s->owner->email->address ) and die "Could not git config gitweb.owner!"; - delete $ENV{"GIT_DIR"}; - - system( "/usr/bin/sudo", "-u", $ikiuser->name, "/usr/bin/ikiwiki", "--setup", "/etc/ikiwiki/piny/" . $s->name . ".setup" ) and die "Could not do initial compile of ikiwiki!"; - - open( APACHE, ">", "/etc/apache2/piny-available/" . $s->name ) or die "Could not open new apache config: $!"; - print APACHE $s->apache_config; - close( APACHE ) or die "Could not close new apache config: $!"; - - unlink( "/etc/apache2/piny-enabled/" . $s->name ); - symlink( "/etc/apache2/piny-available/" . $s->name, "/etc/apache2/piny-enabled/" . $s->name ) or die "Could not symlink apache config: $!"; - - system( "/etc/init.d/apache2", "reload" ) and die "Could not reload apache config!"; -}; - -sub destroy { - my ( $s ) = @_; - - my $user = Piny::Environment->instance->user; - - unlink( "/etc/apache2/piny-enabled/" . $s->name ); - unlink( "/etc/apache2/piny-available/" . $s->name ); - - system( "/etc/init.d/apache2", "reload" ) and die "Could not reload apache config!"; - - unlink( "/etc/ikiwiki/wikilist.d/" . $s->name ); - - my $temp = File::Temp->new( ) or die "Could not create temporary file: $!"; - $temp->unlink_on_destroy( 0 ); - - my $dh = IO::Dir->new( "/etc/ikiwiki/wikilist.d" ) or die "Could not open wikilist.d directory: $!"; - while ( defined ( my $entry = $dh->read ) ) { - next if ( $entry =~ /^\./ ); - open( FILE, "<", "/etc/ikiwiki/wikilist.d/" . $entry ) or die "Could not open wikilist.d entry $entry: $!"; - print $temp ; - close( FILE ) or die "Could not close wikilist.d entry $entry: $!"; - }; - - $temp->close or die "Could not close new wikilist: $!"; - - chmod( 00644, $temp->filename ) or die "Could not fix mode of new wikilist: $!"; - - rename( $temp->filename, "/etc/ikiwiki/wikilist" ) or die "Could not rename over old wikilist: $!"; - - system( "rm", "-rf", $s->secure_path, $s->ikiwiki_destdir, $s->ikiwiki_srcdir, "/etc/ikiwiki/piny/" . $s->name . ".setup", $s->path ); - - my $ikiuser = Piny::User::IkiWiki->new( "name" => "ikiwiki-" . $s->name ); - - system( "deluser", "--remove-home", $ikiuser->name ); - system( "delgroup", $ikiuser->name ); - system( "delgroup", "git-" . $s->name ); - -}; - -# Triggers - -sub _rename_repo { - my ( $s, $new_name, $old_name ) = @_; - - return unless defined $old_name; - - my $olddir = "/srv/git/$old_name.git"; - my $newdir = "/srv/git/$new_name.git"; - - rename( $olddir, $newdir ) or die "Couldn't rename $olddir to $newdir: $!"; - - warn "XXX Not renaming all the ikiwiki stuff!"; - - $s->clear_path; - $s->clear_ikiwiki_setup; - $s->clear_ikiwiki_destdir; - $s->clear_ikiwiki_srcdir; - $s->clear_ikiwiki_url; - $s->clear_ikiwiki_cgiurl; - $s->clear_ikiwiki_historyurl; - $s->clear_ikiwiki_cgipath; - $s->clear_secure_path; - $s->clear_apache_config; -}; - -sub _set_description { - my ( $s, $new_description, $old_description ) = @_; - - return unless defined $old_description; - - open( my $fd, ">", $s->path . "/description" ) or die "Unable to open " . $s->path . "/description for writing: $!"; - print $fd $new_description; - close( $fd ) or die "Error when closing " . $s->path . "/description: $!"; -}; - -sub _change_owner { - my ( $s, $new_owner, $old_owner ) = @_; - - return unless defined $old_owner; - - find( { wanted => sub { chown( $new_owner->uid, -1, $_ ) or die "Couldn't chown $_: $!"; }, no_chdir => 1 }, $s->path . "/objects" ); - - $s->clear_ikiwiki_setup; -}; - -# Class methods - -sub all_repos { - my ( $class, $dir ) = @_; - - $dir = "/srv/git" unless defined $dir; - - my @ret; - - find( { wanted => sub { if ( /^[^.].*\.git$/ ) { $File::Find::prune = 1; push( @ret, $File::Find::name ); }; } }, $dir ); - - @ret = map { s/^\Q$dir\E\/?//; s/\.git$//; $class->new( name => $_ ); } @ret; - - return @ret; -}; - -sub create { - my ( $class, $name, $description ) = @_; - - my $user = Piny::Environment->instance->user; - - find_type_constraint( "Reponame" )->assert_valid( $name ); - find_type_constraint( "SimpleText" )->assert_valid( $description ); - - my $repo = $class->new( "name" => $name ); - - mkdir( $repo->path ) or die "The repo $name appears to already exist! ($!)"; - - system( "/usr/sbin/adduser", "--quiet", "--system", "--group", "--gecos", $name, "ikiwiki-$name" ) and die "Could not create ikiwiki user!"; - - my $ikiuser = Piny::User::IkiWiki->new( "name" => "ikiwiki-$name" ); - - system( "/usr/sbin/addgroup", "--quiet", "git-$name" ) and die "Could not create repo group!"; - - my $group = Piny::Group->new( "name" => "git-$name" ); - - system( "/usr/sbin/adduser", "--quiet", $user->name, $group->name ) and die "Could not add you to the repo group!"; - system( "/usr/sbin/adduser", "--quiet", $ikiuser->name, $group->name ) and die "Could not add ikiwiki user to the repo group!"; - - $ENV{"GIT_DIR"} = $repo->path; - system( "/usr/bin/git", "init", "--template=/srv/git-template.git", "--quiet", "--shared" ) and die "Could not initialize git repo!"; - - foreach( "git-daemon-export-ok", "packed-refs" ) { - open( TOUCH, ">", $repo->path . "/" . $_ ) or die "Could not touch $_ for repo: $!"; - close( TOUCH ); - }; - - foreach( "info", "logs" ) { - ( -e $repo->path . "/" . $_ ) or mkdir( $repo->path . "/" . $_ ) or die "Could not mkdir $_ for repo: $!"; - }; - - foreach( "branches", "description", "HEAD", "info", "logs", "objects", "packed-refs", "refs" ) { - system( "/bin/chown", "-R", $user->name . "." . $group->name, $repo->path . "/" . $_ ) and die "Could not change ownership of $_ for repo: $!"; - }; - - chown( 0, 0, $repo->path, $repo->path . "/config" ) or die "Could not change ownership of git dir!"; - - system( "/bin/chown", "-R", $ikiuser->name . "." . $ikiuser->name, $repo->path . "/hooks" ) and die "Could not change ownership of git hooks!"; - - system( "/usr/bin/git", "config", "gitweb.owner", $repo->owner->email->address ) and die "Could not git config gitweb.owner!"; - delete $ENV{"GIT_DIR"}; - - $repo->description( $description ); - - open( SETUP, ">", "/etc/ikiwiki/piny/" . $repo->name . ".setup" ) or die "Could not open new ikiwiki setup file: $!"; - print SETUP $repo->ikiwiki_setup; - close( SETUP ) or die "Could not close new ikiwiki setup file: $!"; - - system( "/usr/bin/git", "clone", "--quiet", $repo->path, $repo->ikiwiki_srcdir ) and die "Could not clone repo to ikiwiki srcdir!"; - - mkdir( $repo->ikiwiki_destdir ) or die "Could not create ikiwiki destdir: $!"; - mkdir( $repo->secure_path ) or die "Could not create secure dir: $!"; - - system( "/bin/chown", "-R", $ikiuser->name . "." . $ikiuser->name, $repo->ikiwiki_srcdir, $repo->ikiwiki_destdir, $repo->secure_path ) and die "Could not change ownership of ikiwiki directories!"; - - open( WIKILIST, ">", "/etc/ikiwiki/wikilist.d/" . $repo->name ) or die "Could not create wikilist.d file: $!"; - print WIKILIST $ikiuser->name . " /etc/ikiwiki/piny/" . $repo->name . ".setup\n"; - close( WIKILIST ) or die "Could not close wikilist.d file: $!"; - - my $temp = File::Temp->new( ) or die "Could not create temporary file: $!"; - $temp->unlink_on_destroy( 0 ); - - my $dh = IO::Dir->new( "/etc/ikiwiki/wikilist.d" ) or die "Could not open wikilist.d directory: $!"; - while ( defined ( my $entry = $dh->read ) ) { - next if ( $entry =~ /^\./ ); - open( FILE, "<", "/etc/ikiwiki/wikilist.d/" . $entry ) or die "Could not open wikilist.d entry $entry: $!"; - print $temp ; - close( FILE ) or die "Could not close wikilist.d entry $entry: $!"; - }; - - $temp->close or die "Could not close new wikilist: $!"; - - chmod( 00644, $temp->filename ) or die "Could not fix mode of new wikilist: $!"; - - rename( $temp->filename, "/etc/ikiwiki/wikilist" ) or die "Could not rename over old wikilist: $!"; - - system( "/usr/bin/sudo", "-u", $ikiuser->name, "/usr/bin/ikiwiki", "--setup", "/etc/ikiwiki/piny/" . $repo->name . ".setup" ) and die "Could not do initial compile of ikiwiki!"; - - open( APACHE, ">", "/etc/apache2/piny-available/" . $repo->name ) or die "Could not open new apache config: $!"; - print APACHE $repo->apache_config; - close( APACHE ) or die "Could not close new apache config: $!"; - - symlink( "/etc/apache2/piny-available/" . $repo->name, "/etc/apache2/piny-enabled/" . $repo->name ) or die "Could not symlink apache config: $!"; - - system( "/etc/init.d/apache2", "reload" ) and die "Could not reload apache config!"; - - return $repo; -}; - -# Builder methods - -# If constructed with just one argument, then treat it as a repo name. -around BUILDARGS => sub { - my ( $orig, $class ) = ( shift, shift ); - - if ( @_ == 1 && ! ref $_[0] ) { - return $class->$orig( name => $_[0] ); - } else { - return $class->$orig( @_ ); - }; -}; - -sub _build_group { - my ( $s ) = @_; - - return Piny::Group->new( name => "git-" . $s->name ); -}; - -sub _build_path { - my ( $s ) = @_; - - return "/srv/git/" . $s->name . ".git"; -}; - -sub _build_description { - my ( $s ) = @_; - - open( my $d, "<", $s->path . "/description" ) or die "Unable to open " . $s->path . "/description: $!"; - my $desc; - { - local $/ = undef; - $desc = <$d>; - }; - close( $d ); - - return $desc; -}; - -sub _build_repostat { - my ( $s ) = @_; - - my @res = stat( $s->path . "/objects" ); - die "stat( " . $s->path . "/objects ) failed: $!" unless @res; - return \@res; -}; - -sub _build_owner { - my ( $s ) = @_; - - my ( $uid ) = $s->repostat->[4]; - - return Piny::User->new( uid => $uid ); -}; - -sub _build_globally_readable { - my ( $s ) = @_; - - return ( $s->repostat->[2] & 0444 ) == 0444; -}; - -sub _build_globally_writable { - my ( $s ) = @_; - - return ( $s->repostat->[2] & 0111 ) == 0111; -}; - -sub _build_ikiwiki_setup { - my ( $s ) = @_; - - my ( $package, $config ) = readSetup( "/usr/share/libpiny/ikiwiki.setup" ); - - $config->{"wikiname"} = $s->name; - $config->{"adminemail"} = $s->owner->email->address; - $config->{"srcdir"} = $s->ikiwiki_srcdir; - $config->{"destdir"} = $s->ikiwiki_destdir; - $config->{"url"} = $s->ikiwiki_url; - $config->{"cgiurl"} = $s->ikiwiki_cgiurl; - $config->{"historyurl"} = $s->ikiwiki_historyurl; - $config->{"diffurl"} = $s->ikiwiki_diffurl; - - $config->{"wrappers"} = - [ { "wrapper" => $s->ikiwiki_cgipath - , "wrappergroup" => $s->group->name - , "wrappermode" => "06755" - , "cgi" => 1 - } - , { "wrapper" => $s->path . "/hooks/post-update" - , "wrappergroup" => $s->group->name - , "wrappermode" => "06755" - , "notify" => 0 - } - ]; - - if ( -e "/etc/ikiwiki/piny/" . $s->name . ".setup.pl" ) { - undef $@; - eval { - package TEMP; - use Piny; - $TEMP::repo = $s; - $TEMP::conf = $config; - no strict 'vars'; - do "/etc/ikiwiki/piny/" . $s->name . ".setup.pl"; - }; - if ( not $@ ) { $config = $TEMP::conf; }; - }; - - return writeSetup( $package, $config ); -}; - -sub _build_ikiwiki_destdir { - my ( $s ) = @_; - - return $s->config->piny_ikiwikidestdir . $s->name; -}; - -sub _build_ikiwiki_srcdir { - my ( $s ) = @_; - - return $s->config->piny_ikiwikisrcdir . $s->name; -}; - -sub _build_ikiwiki_url { - my ( $s ) = @_; - - return $s->config->piny_ikiwikiurl . $s->name; -}; - -sub _build_ikiwiki_cgiurl { - my ( $s ) = @_; - - return $s->config->piny_ikiwikisecureurl . "repos/" . $s->name . "/ikiwiki.cgi"; -}; - -sub _build_secure_path { - my ( $s ) = @_; - - return $s->config->piny_ikiwikisecurepath . "repos/" . $s->name; -}; - -sub _build_ikiwiki_cgipath { - my ( $s ) = @_; - - return $s->secure_path . "/ikiwiki.cgi"; -}; - -sub _build_ikiwiki_historyurl { - my ( $s ) = @_; - - if ( defined $s->config->{"https_url"} ) { - return $s->config->{"https_url"} . "cgit/" . $s->name . "/log/[[file]]"; - } else { - return $s->config->piny_ikiwikisecureurl . "cgit/" . $s->name . "/log/[[file]]"; - }; -}; - -sub _build_ikiwiki_diffurl { - my ( $s ) = @_; - - if ( defined $s->config->{"https_url"} ) { - return $s->config->{"https_url"} . "cgit/" . $s->name . "/diff/?id=[[sha1_commit]]"; - } else { - return $s->config->piny_ikiwikisecureurl . "cgit/" . $s->name . "/diff/?id=[[sha1_commit]]"; - }; -}; - -sub _build_apache_config { - my ( $s ) = @_; - - return "secure_path . ">\n AuthPAM_Enabled on\n AuthGROUP_Enabled on\n AuthPAM_FallThrough off\n AuthBasicAuthoritative off\n AuthType Basic\n AuthName \"User access to " . $s->name . " repository needed.\"\n Require group " . $s->group->name . "\n\n"; -}; - -sub _build_config { - my ( $s ) = @_; - - return Piny::Config->new( confpath => $s->path . "/config" ); -}; - -# Moose boilerplate - -__PACKAGE__->meta->make_immutable; - -1; diff --git a/usr/src/libpiny/lib/Piny/User.pm b/usr/src/libpiny/lib/Piny/User.pm deleted file mode 100644 index 20ef4f1..0000000 --- a/usr/src/libpiny/lib/Piny/User.pm +++ /dev/null @@ -1,216 +0,0 @@ -# Copyright © 2010 Julian Blake Kongslie -# Licensed under the BSD 3-clause license. - -use strict; -use warnings; - -package Piny::User; - -use Moose; -use Moose::Util::TypeConstraints; -use MooseX::StrictConstructor; - -use Piny::Email; -use Piny::Group; - -# Types - -subtype 'Username' - => as 'Str' - => where { $_ =~ /^(?!(git|ikiwiki)-)[a-zA-Z][a-zA-Z0-9_.-]*$/ } - => message { 'That username is not in the correct format for a piny user.' } - ; - -# Attributes - -has 'uid' => - ( is => 'ro' - , isa => 'Int' - , lazy_build => 1 - ); - -has 'name' => - ( is => 'ro' - , isa => 'Username' - , lazy_build => 1 - ); - -has 'pwent' => - ( is => 'ro' - , isa => 'ArrayRef' - , lazy_build => 1 - , init_arg => undef - ); - -has 'password_hash' => - ( is => 'ro' - , isa => 'Str' - , lazy_build => 1 - , init_arg => undef - ); - -has 'email' => - ( is => 'ro' - , isa => 'Piny::Email' - , lazy_build => 1 - , init_arg => undef - ); - -has 'groups' => - ( is => 'ro' - , isa => 'ArrayRef[Piny::Group]' - , lazy_build => 1 - , init_arg => undef - ); - -# Public methods - -sub add_group { - my ( $s, @groups ) = @_; - - foreach my $group ( @groups ) { - $group->add_member( $s ); - }; -}; - -sub remove_group { - my ( $s, @groups ) = @_; - - foreach my $group ( @groups ) { - $group->remove_member( $s ); - }; -}; - -sub has_group { - my ( $s, $group ) = @_; - - foreach my $owngroup ( @{$s->groups( )} ) { - return 1 if $owngroup->gid( ) == $group->gid( ); - }; - - return; -}; - -# Class methods - -sub all_users { - my ( $class ) = @_; - - my @ret; - - endpwent( ); - - while ( my @info = getpwent( ) ) { - eval { - my $user = $class->new( uid => $info[2] ); - # Some forced early evaluation, so error checking happens now. - $user->name( ); - $user->email( ); - push( @ret, $user ); - }; - }; - - endpwent( ); - - return @ret; -}; - -# Builder methods - -# If constructed with just one argument, then -# * If that argument is numeric, treat it as a UID. -# * Otherwise, treat it as a username. -around BUILDARGS => sub { - my ( $orig, $class ) = ( shift, shift ); - - if ( @_ == 1 && ! ref $_[0] ) { - if ( $_[0] =~ m/^\d+$/ ) { - return $class->$orig( uid => $_[0] ); - } else { - return $class->$orig( name => $_[0] ); - }; - } else { - return $class->$orig( @_ ); - }; -}; - -sub BUILD { - my ( $s ) = @_; - - if ( not ( $s->has_uid( ) or $s->has_name( ) ) ) { - die "You must provide either UID or name!"; - }; - - if ( $s->has_uid( ) and $s->has_name( ) ) { - die "You must not provide both UID and name!"; - }; -}; - -sub _build_uid { - my ( $s ) = @_; - - return $s->pwent( )->[2]; -}; - -sub _build_name { - my ( $s ) = @_; - - return $s->pwent( )->[0]; -}; - -sub _build_pwent { - my ( $s ) = @_; - - if ( $s->has_uid( ) ) { - my @res = getpwuid( $s->uid( ) ); - die "getpwuid( " . $s->uid( ) . " ) failed: $!" unless @res; - return \@res; - } elsif ( $s->has_name( ) ) { - my @res = getpwnam( $s->name( ) ); - die "getpwnam( " . $s->name( ) . " ) failed: $!" unless @res; - return \@res; - } else { - die "Not enough information provided to lookup user!"; - }; -}; - -sub _build_password_hash { - my ( $s ) = @_; - - return $s->pwent( )->[1]; -}; - -sub _build_email { - my ( $s ) = @_; - - return Piny::Email->new( address => $s->pwent( )->[6] ); -}; - -sub _build_groups { - my ( $s ) = @_; - - my @res; - my @ent; - - endgrent( ); - - while ( @ent = getgrent( ) ) { - next if ( $ent[3] eq "" ); - foreach my $member ( split( / /, $ent[3] ) ) { - if ( $member eq $s->name( ) ) { - push @res, Piny::Group->new( gid => $ent[2] ); - last; - }; - }; - }; - - endgrent( ); - - return \@res; -}; - -# Moose boilerplate - -__PACKAGE__->meta->make_immutable; - -1; diff --git a/usr/src/libpiny/lib/Piny/User/IkiWiki.pm b/usr/src/libpiny/lib/Piny/User/IkiWiki.pm deleted file mode 100644 index 8585e90..0000000 --- a/usr/src/libpiny/lib/Piny/User/IkiWiki.pm +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright © 2010 Julian Blake Kongslie -# Licensed under the BSD 3-clause license. - -use strict; -use warnings; - -package Piny::User::IkiWiki; - -use Moose; -use Moose::Util::TypeConstraints; -use MooseX::StrictConstructor; - -use Piny::User; - -extends "Piny::User"; - -# Types - -subtype 'IkiWikiUsername' - => as 'Str' - => where { $_ =~ /^ikiwiki-[a-zA-Z][a-zA-Z0-9_.-]*$/ } - => message { 'That username is not in the correct format for an ikiwiki user.' } - ; - -# Attributes - -has 'name' => - ( is => 'ro' - , isa => 'IkiWikiUsername' - , lazy_build => 1 - ); - -# Moose boilerplate - -__PACKAGE__->meta->make_immutable; - -1; diff --git a/usr/src/libpiny/share/ikiwiki.setup b/usr/src/libpiny/share/ikiwiki.setup deleted file mode 100644 index 18f8418..0000000 --- a/usr/src/libpiny/share/ikiwiki.setup +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/perl -# Configuration file for ikiwiki. -# Passing this to ikiwiki --setup will make ikiwiki generate wrappers and -# build the wiki. -# -# Remember to re-run ikiwiki --setup any time you edit this file. - -use IkiWiki::Setup::Standard { - # wikiname => "', # LATER MODIFIED BY LATER MODIFIED BY PINY - # adminemail => "', # LATER MODIFIED BY LATER MODIFIED BY PINY - # srcdir => "', # LATER MODIFIED BY PINY - # destdir => "', # LATER MODIFIED BY PINY - # url => "', # LATER MODIFIED BY PINY - # cgiurl => "', # LATER MODIFIED BY PINY - # historyurl => "', # LATER MODIFIED BY PINY - # diffurl => "', # LATER MODIFIED BY PINY - - templatedir => "/srv/templates", # TODO: user-customizable templates - underlaydir => "/usr/share/ikiwiki/basewiki", - - rcs => "git", - gitorigin_branch => "origin", - gitmaster_branch => "master", - - # wrappers => [ ], controlled by piny - - # Generate rss feeds for blogs? - rss => 1, - # Generate atom feeds for blogs? - atom => 0, - # Include discussion links on all pages? - discussion => 0, - # To exclude files matching a regexp from processing. This adds to - # the default exclude list. - #exclude => qr/*\.wav/, - # To change the extension used for generated html files. - #htmlext => "htm", - # Time format (for strftime) - #timeformat => "%c", - # Locale to use. Must be a UTF-8 locale. - #locale => "en_US.UTF-8", - # Only send cookies over SSL connections. - sslcookie => 1, - # Logging settings: - verbose => 0, - syslog => 1, - # To link to user pages in a subdirectory of the wiki. - #userdir => "users", - # To create output files named page.html rather than page/index.html. - usedirs => 1, - # Simple spam prevention: require an account-creation password. - #account_creation_password => "example", - # Use new "!"-prefixed preprocessor directive syntax - prefix_directives => 1, - httpauth => 1, - # To add plugins, list them here. - add_plugins => [qw{sidebar toc meta table tag graphviz httpauth img attachment rename remove map teximg version edittemplate}], - disable_plugins => [qw{openid passwordauth}], - teximg_prefix => "\\documentclass{scrartcl} -\\usepackage[version=3]{mhchem} -\\usepackage{amsmath} -\\usepackage{amsfonts} -\\usepackage{amssymb} -\\pagestyle{empty} -\\begin{document}", - - teximg_dvipng => 1, - - # For use with the tag plugin, make all tags be located under a - # base page. - tagbase => "tag", - - # For use with the search plugin if your estseek.cgi is located - # somewhere else. - #estseek => "/usr/lib/estraier/estseek.cgi", -}; diff --git a/usr/src/libpiny/test b/usr/src/libpiny/test deleted file mode 100755 index fc1eb55..0000000 --- a/usr/src/libpiny/test +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Devel::REPL; - -use lib "lib"; - -use Piny; - -Devel::REPL->new->run; diff --git a/usr/src/pinyadmin/Makefile b/usr/src/pinyadmin/Makefile deleted file mode 100644 index 64ac713..0000000 --- a/usr/src/pinyadmin/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -build: - mkdir -p man - for f in doc/*.latex; do latex2man $$f man/$$(basename $$f .latex).man; done - ln -s newuser.man man/createuser.man - -install: - install -o root -g root -m 755 -d $(DESTDIR)/usr/bin $(DESTDIR)/usr/sbin - install -o root -g root -m 755 bin/* $(DESTDIR)/usr/bin - install -o root -g root -m 755 sbin/* $(DESTDIR)/usr/sbin - -clean: - rm -rf man diff --git a/usr/src/pinyadmin/bin/addaccess b/usr/src/pinyadmin/bin/addaccess deleted file mode 100755 index 849119d..0000000 --- a/usr/src/pinyadmin/bin/addaccess +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec /usr/bin/sudo /usr/sbin/addaccess "$@" diff --git a/usr/src/pinyadmin/bin/appendkeys b/usr/src/pinyadmin/bin/appendkeys deleted file mode 100755 index a4b7d98..0000000 --- a/usr/src/pinyadmin/bin/appendkeys +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -/bin/mkdir -p ~/.ssh -/bin/echo Please input authorized keys to be appended. ctrl-d to finish, ctrl-c to abort current line. -/bin/cat >> ~/.ssh/authorized_keys diff --git a/usr/src/pinyadmin/bin/createuser b/usr/src/pinyadmin/bin/createuser deleted file mode 120000 index e9d7937..0000000 --- a/usr/src/pinyadmin/bin/createuser +++ /dev/null @@ -1 +0,0 @@ -newuser \ No newline at end of file diff --git a/usr/src/pinyadmin/bin/lsaccess b/usr/src/pinyadmin/bin/lsaccess deleted file mode 100755 index ce41fc4..0000000 --- a/usr/src/pinyadmin/bin/lsaccess +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Piny; - -my $env = Piny::Environment->instance( ); - -my ( $reponame ) = @ARGV; - -if ( defined $reponame ) { - - my $repo = Piny::Repo->new( $reponame ); - - foreach my $user ( Piny::User->all_users( ) ) { - if ( $repo->has_access( $user ) ) { - print $user->name . "\n"; - }; - }; - -} else { - - foreach my $repo ( Piny::Repo->all_repos( ) ) { - if ( $repo->has_access( $env->user ) ) { - print $repo->name . "\n"; - }; - }; - -}; diff --git a/usr/src/pinyadmin/bin/lsrepo b/usr/src/pinyadmin/bin/lsrepo deleted file mode 100755 index 2d88eb5..0000000 --- a/usr/src/pinyadmin/bin/lsrepo +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Piny; - -foreach my $repo ( Piny::Repo->all_repos( ) ) { - print $repo->name . "\n"; -}; diff --git a/usr/src/pinyadmin/bin/newrepo b/usr/src/pinyadmin/bin/newrepo deleted file mode 100755 index 025e0cf..0000000 --- a/usr/src/pinyadmin/bin/newrepo +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec /usr/bin/sudo /usr/sbin/newrepo "$@" diff --git a/usr/src/pinyadmin/bin/newuser b/usr/src/pinyadmin/bin/newuser deleted file mode 100755 index 1f73ed6..0000000 --- a/usr/src/pinyadmin/bin/newuser +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec /usr/bin/sudo /usr/sbin/newuser diff --git a/usr/src/pinyadmin/bin/pinyconfig b/usr/src/pinyadmin/bin/pinyconfig deleted file mode 100755 index 4e54f76..0000000 --- a/usr/src/pinyadmin/bin/pinyconfig +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec /usr/bin/sudo /usr/sbin/pinyconfig "$@" diff --git a/usr/src/pinyadmin/bin/pinyshell b/usr/src/pinyadmin/bin/pinyshell deleted file mode 100755 index 0db88a8..0000000 --- a/usr/src/pinyadmin/bin/pinyshell +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -cd /srv/rbin -export PATH=/srv/rbin - -exec /bin/rbash "$@" diff --git a/usr/src/pinyadmin/bin/readkeys b/usr/src/pinyadmin/bin/readkeys deleted file mode 100755 index 745bd8d..0000000 --- a/usr/src/pinyadmin/bin/readkeys +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -/bin/cat ~/.ssh/authorized_keys diff --git a/usr/src/pinyadmin/bin/rmaccess b/usr/src/pinyadmin/bin/rmaccess deleted file mode 100755 index 665052c..0000000 --- a/usr/src/pinyadmin/bin/rmaccess +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec /usr/bin/sudo /usr/sbin/rmaccess "$@" diff --git a/usr/src/pinyadmin/bin/rmrepo b/usr/src/pinyadmin/bin/rmrepo deleted file mode 100755 index e0e8085..0000000 --- a/usr/src/pinyadmin/bin/rmrepo +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exec /usr/bin/sudo /usr/sbin/rmrepo "$@" diff --git a/usr/src/pinyadmin/bin/writekeys b/usr/src/pinyadmin/bin/writekeys deleted file mode 100755 index 61a7760..0000000 --- a/usr/src/pinyadmin/bin/writekeys +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -/bin/mkdir -p ~/.ssh -/bin/echo Please input all authorized keys. ctrl-d to finish, ctrl-c to abort. -/usr/bin/sponge ~/.ssh/authorized_keys diff --git a/usr/src/pinyadmin/debian/changelog b/usr/src/pinyadmin/debian/changelog deleted file mode 100644 index e11d900..0000000 --- a/usr/src/pinyadmin/debian/changelog +++ /dev/null @@ -1,48 +0,0 @@ -pinyadmin (0.8) unstable; urgency=low - - * New config tweakable stuff. - - -- Julian Blake Kongslie Mon, 11 Oct 2010 21:56:04 -0700 - -pinyadmin (0.7) unstable; urgency=low - - * Creating ssh key management utilities. - - -- Joe Rayhawk Fri, 03 Sep 2010 01:40:01 -0700 - -pinyadmin (0.6) unstable; urgency=low - - * Revised newrepo to use libpiny. - - -- Julian Blake Kongslie Wed, 07 Jul 2010 15:44:31 -0700 - -pinyadmin (0.5) unstable; urgency=low - - * Listing repos and repo access rights. - - -- Julian Blake Kongslie Tue, 29 Jun 2010 22:32:30 -0700 - -pinyadmin (0.4) unstable; urgency=low - - * Minor typo in manpage. - - -- Julian Blake Kongslie Sun, 18 Apr 2010 13:51:13 -0700 - -pinyadmin (0.3) unstable; urgency=low - - * A few more manpages. - - -- Julian Blake Kongslie Sun, 18 Apr 2010 13:19:34 -0700 - -pinyadmin (0.2) unstable; urgency=low - - * Switch to native packaging. - * Add manpages. - - -- Julian Blake Kongslie Sun, 18 Apr 2010 13:01:32 -0700 - -pinyadmin (0.1-1) unstable; urgency=low - - * Initial release. - - -- Julian Blake Kongslie Thu, 18 Mar 2010 13:55:40 -0700 diff --git a/usr/src/pinyadmin/debian/compat b/usr/src/pinyadmin/debian/compat deleted file mode 100644 index 7f8f011..0000000 --- a/usr/src/pinyadmin/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/usr/src/pinyadmin/debian/control b/usr/src/pinyadmin/debian/control deleted file mode 100644 index e8c2d70..0000000 --- a/usr/src/pinyadmin/debian/control +++ /dev/null @@ -1,13 +0,0 @@ -Source: pinyadmin -Maintainer: Julian Blake Kongslie -Section: admin -Build-depends: debhelper (>= 7), texlive-extra-utils -Priority: extra -Standards-version: 3.8.4 - -Package: pinyadmin -Architecture: all -Depends: ${perl:Depends}, ${misc:Depends}, libpiny-perl (>= 0.14), moreutils -Description: Administrative programs for piny - The command-line programs for day-to-day administrative tasks in the Piny - infrastructure. diff --git a/usr/src/pinyadmin/debian/copyright b/usr/src/pinyadmin/debian/copyright deleted file mode 100644 index 9d12aab..0000000 --- a/usr/src/pinyadmin/debian/copyright +++ /dev/null @@ -1,3 +0,0 @@ -Copyright © 2010 Joe Rayhawk -Copyright © 2010 Julian Blake Kongslie -Licensed under the BSD 3-clause license. diff --git a/usr/src/pinyadmin/debian/pinyadmin.manpages b/usr/src/pinyadmin/debian/pinyadmin.manpages deleted file mode 100644 index 85c5e00..0000000 --- a/usr/src/pinyadmin/debian/pinyadmin.manpages +++ /dev/null @@ -1 +0,0 @@ -man/* diff --git a/usr/src/pinyadmin/debian/rules b/usr/src/pinyadmin/debian/rules deleted file mode 100755 index 2d33f6a..0000000 --- a/usr/src/pinyadmin/debian/rules +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/make -f - -%: - dh $@ diff --git a/usr/src/pinyadmin/debian/source/format b/usr/src/pinyadmin/debian/source/format deleted file mode 100644 index 89ae9db..0000000 --- a/usr/src/pinyadmin/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (native) diff --git a/usr/src/pinyadmin/doc/addaccess.latex b/usr/src/pinyadmin/doc/addaccess.latex deleted file mode 100644 index a8c29f9..0000000 --- a/usr/src/pinyadmin/doc/addaccess.latex +++ /dev/null @@ -1,17 +0,0 @@ -\usepackage{latex2man} - -\begin{Name}{1piny}{addaccess}{Piny Team}{Piny}{addaccess} - -\Prog{addaccess} - allow access to a repository - -\section{Synopsis} - -\Prog{addaccess} \Arg{reponame} \Arg{username} \Dots - -\section{Description} - -The \Prog{addaccess} command grants users write access to a repository. -It may only be run by the owner of the repository. - -For each \Arg{username} passed on the command line, \Prog{addaccess} will grant write permission to the repository. -Other users are not affected. diff --git a/usr/src/pinyadmin/doc/newrepo.latex b/usr/src/pinyadmin/doc/newrepo.latex deleted file mode 100644 index a708b6c..0000000 --- a/usr/src/pinyadmin/doc/newrepo.latex +++ /dev/null @@ -1,15 +0,0 @@ -\usepackage{latex2man} - -\begin{Name}{1piny}{newrepo}{Piny Team}{Piny}{newrepo} - -\Prog{newrepo} - create a new repository - -\section{Synopsis} - -\Prog{newrepo} \Arg{reponame} - -\section{Description} - -The \Prog{newrepo} command creates a new repository with the given name. -The current user is set as the owner of the new repository. -No other users are given access to the new repository. diff --git a/usr/src/pinyadmin/doc/newuser.latex b/usr/src/pinyadmin/doc/newuser.latex deleted file mode 100644 index 721d468..0000000 --- a/usr/src/pinyadmin/doc/newuser.latex +++ /dev/null @@ -1,16 +0,0 @@ -\usepackage{latex2man} - -\begin{Name}{8piny}{newuser}{Piny Team}{Piny}{createuser} - -\Prog{newuser} - add a piny user - -\section{Synopsis} - -\Prog{newuser} - -\Prog{createuser} - -\section{Description} - -The \Prog{newuser} program is an interactive script which walks the user through the process of creating a new Piny account. -Normally it is set as the shell of a passwordless user such as "newuser" or "createuser", so that users can create accounts without any assistance from a sysadmin. diff --git a/usr/src/pinyadmin/doc/pinyconfig.latex b/usr/src/pinyadmin/doc/pinyconfig.latex deleted file mode 100644 index 4908dbb..0000000 --- a/usr/src/pinyadmin/doc/pinyconfig.latex +++ /dev/null @@ -1,17 +0,0 @@ -\usepackage{latex2man} - -\begin{Name}{1piny}{pinyconfig}{Piny Team}{Piny}{pinyconfig} - -\Prog{pinyconfig} - change tweakables on a repo - -\section{Synopsis} - -\Prog{pinyconfig} \Arg{reponame} \Arg{tweakable} \oArg{value} - -\section{Description} - -The \Prog{pinyconfig} command reads and writes tweakables for a repo. - -When run, it prints the value of the tweakable for the repo named. -If a value was passed, it sets the value of the tweakable to that value -before printing it. diff --git a/usr/src/pinyadmin/doc/pinyshell.latex b/usr/src/pinyadmin/doc/pinyshell.latex deleted file mode 100644 index 481ddf3..0000000 --- a/usr/src/pinyadmin/doc/pinyshell.latex +++ /dev/null @@ -1,19 +0,0 @@ -\usepackage{latex2man} - -\begin{Name}{8piny}{pinyshell}{Piny Team}{Piny}{pinyshell} - -\Prog{pinyshell} - a restricted shell - -\section{Synopsis} - -\Prog{pinyshell} - -\section{Description} - -\Prog{pinyshell} is just another way to invoke \Cmd{1}{rbash}; the separate name is used for accounting purposes within the piny infrastructure. - -Users which should be managed by the Piny infrastructure should have \Prog{pinyshell} as their shell. - -\section{See Also} - -\Cmd{1}{rbash} diff --git a/usr/src/pinyadmin/doc/rebuildrepo.latex b/usr/src/pinyadmin/doc/rebuildrepo.latex deleted file mode 100644 index a2e0935..0000000 --- a/usr/src/pinyadmin/doc/rebuildrepo.latex +++ /dev/null @@ -1,16 +0,0 @@ -\usepackage{latex2man} - -\begin{Name}{8piny}{rebuildrepo}{Piny Team}{Piny}{rebuildrepo} - -\Prog{rebuildrepo} - rebuild a repo configuration - -\section{Synopsis} - -\Prog{rebuildrepo} \Arg{reponame} \Dots - -\section{Description} - -The \Prog{rebuildrepo} command rewrites all of the configuration files for -the given repo and adjusts ownership and group membership of its files to a -normalized state. It is needed to propagate certain kinds of changes; -normally only the system administrator should run it. diff --git a/usr/src/pinyadmin/doc/rmaccess.latex b/usr/src/pinyadmin/doc/rmaccess.latex deleted file mode 100644 index 41f7af4..0000000 --- a/usr/src/pinyadmin/doc/rmaccess.latex +++ /dev/null @@ -1,22 +0,0 @@ -\usepackage{latex2man} - -\begin{Name}{1piny}{rmaccess}{Piny Team}{Piny}{rmaccess} - -\Prog{rmaccess} - remove access to a repository - -\section{Synopsis} - -\Prog{rmaccess} \Arg{reponame} \Arg{username} \Dots - -\section{Description} - -The \Prog{rmaccess} command denies users write access to a repository. -It may only be run by the owner of the repository. - -For each \Arg{username} passed on the command line, \Prog{addaccess} will deny write permission to the repository. -Other users are not affected. - -\section{Bugs} - -You cannot deny write permission to the owner of the repository. -If you try, the program will appear to succeed, but the owner will still be able to make changes. diff --git a/usr/src/pinyadmin/doc/rmrepo.latex b/usr/src/pinyadmin/doc/rmrepo.latex deleted file mode 100644 index 12b58df..0000000 --- a/usr/src/pinyadmin/doc/rmrepo.latex +++ /dev/null @@ -1,14 +0,0 @@ -\usepackage{latex2man} - -\begin{Name}{1piny}{rmrepo}{Piny Team}{Piny}{rmrepo} - -\Prog{rmrepo} - delete a repository - -\section{Synopsis} - -\Prog{rmrepo} \Arg{reponame} \Dots - -\section{Description} - -The \Prog{rmrepo} command permanently destroys the repository with the given name. -The current user must be the owner of the repository. diff --git a/usr/src/pinyadmin/sbin/addaccess b/usr/src/pinyadmin/sbin/addaccess deleted file mode 100755 index e351114..0000000 --- a/usr/src/pinyadmin/sbin/addaccess +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Piny; - -my $env = Piny::Environment->instance( ); - -my ( $reponame, @users ) = @ARGV; - -my $repo = Piny::Repo->new( $reponame ); - -if ( $repo->owner->uid != $env->user->uid ) { - print "You are not the owner of that repo!\n"; - exit( 3 ); -}; - -$repo->add_access( map { Piny::User->new( $_ ) } @users ); diff --git a/usr/src/pinyadmin/sbin/newrepo b/usr/src/pinyadmin/sbin/newrepo deleted file mode 100755 index a178ecb..0000000 --- a/usr/src/pinyadmin/sbin/newrepo +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Moose::Util::TypeConstraints qw( find_type_constraint ); - -use Piny; - -my ( $name ) = @ARGV; - -if ( not defined $name ) { - print "Usage: newrepo REPONAME\n"; - exit 1; -}; - -if ( not find_type_constraint( "Reponame" )->check( $name ) ) { - print "That is not a valid repo name; must be at least 1 character long, begin with a lowercase alphanumeric character, and contain only alphanumeric characters and dashes.\n"; - exit 1; -}; - -my $description; -while( 1 ) { - - print "Provide a one-line description to be used in repo listings, the shorter the better:\n"; - chomp( $description = ); - - if ( not find_type_constraint( "SimpleText" )->check( $description ) ) { - print "Must be 1-80 characters long; control characters (including tab) not allowed.\n"; - next; - }; - - print "Okay! Working, please wait...\n"; - last; - -}; - -my $repo = Piny::Repo->create( $name, $description ); - -print "Repo URL: " . $repo->ikiwiki_url . "\n"; diff --git a/usr/src/pinyadmin/sbin/newuser b/usr/src/pinyadmin/sbin/newuser deleted file mode 100755 index e064f06..0000000 --- a/usr/src/pinyadmin/sbin/newuser +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Email::Valid::Loose qw( ); - -# If they passed any arguments, complain and exit. -if ( scalar @ARGV ) { - print "You can't pass any arguments to this script!\n"; - exit 2; -}; - -# If they didn't provide a terminal definition, then assume xterm. -# Everybody emulates xterm to at least a basic extent. -if ( not exists $ENV{"TERM"} ) { - $ENV{"TERM"} = "xterm"; - print "I don't know what terminal you're using; guessing xterm...\n"; -}; - -# Disable buffering. -$|++; - -# Configure the strictness of our email checks. -my $checker = Email::Valid::Loose->new - ( "-fqdn" => 1 - , "-fudge" => 0 - , "-local_rules" => 0 - , "-mxcheck" => 1 - , "-tldcheck" => 0 - ); - -my ( $email, $username, $password1, $password2 ); - -while ( 1 ) { - - print "Email address to associate with new user: "; - chomp ( $email = ); - - if ( $email eq "" ) { - print "You must provide an email address!\n"; - next; - }; - - $email = $checker->address( $email ); - if ( not defined $email ) { - print "Please, at least pretend to provide a valid email address.\n"; - next; - }; - - last; - -}; - -while ( 1 ) { - - print "Desired username: "; - chomp ( $username = ); - - if ( $username eq "" ) { - print "You have to enter a username!\n"; - next; - }; - - if ( $username =~ /^git-|^ikiwiki-/ ) { - print "Your username cannot start with git- or ikiwiki-!\n"; - next - }; - - if ( $username !~ /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]+$/ ) { - print( "Usernames must consist only of letters, digits, underscores, periods, and dashes, and not start with a dash. Usernames are case sensitive.\n" ); - next - }; - - last; - -}; - -while ( 1 ) { - - system( "stty", "-echo" ); - print "Desired password: "; - chomp ( $password1 = ); - print "\nRetype password: "; - chomp ( $password2 = ); - print "\n"; - system( "stty", "echo" ); - - if ( $password1 ne $password2 ) { - print "Provided passwords do not match; try again.\n"; - next; - }; - - if ( $password1 eq "" ) { - print "You have to enter a password!\n"; - next; - }; - - last; - -}; - -my @saltchars = - ( 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' - , 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' - , '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - , '.', '/' - ); - -my $salt = "\$6\$"; - -foreach my $n ( 1 .. 16 ) { - $salt .= $saltchars[int ( rand ( scalar @saltchars ) )]; -}; - -$salt .= "\$"; - -my $crypt = crypt( $password1, $salt ); - -my $ret = system( "/usr/sbin/useradd", "-c", "$email", "-k", "/var/empty", "-g", "users", "-m", "-p", $crypt, "-s", "/usr/bin/pinyshell", $username ); - -if ( $ret ) { - print "An error occured creating the user; most likely, that username is already taken.\n"; - exit 1; -}; - -print "Your user has been created. Try logging in!\n"; - -exit 0; diff --git a/usr/src/pinyadmin/sbin/pinyconfig b/usr/src/pinyadmin/sbin/pinyconfig deleted file mode 100755 index f6752db..0000000 --- a/usr/src/pinyadmin/sbin/pinyconfig +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Piny; - -my ( $reponame, $attr, $value ) = @ARGV; - -if ( not defined $reponame or not defined $attr ) { - die "Usage: $0 reponame tweakable [value]\n"; -}; - -$attr = lc $attr; -$attr =~ s/\./_/g; - -my $repo = Piny::Repo->new( $reponame ); - -if ( defined $value ) { - undef $@; - eval { - $repo->config->$attr( $value ); - }; - if ( $@ ) { - print STDERR "$attr is not a legal tweakable, or $value is not a legal value for that tweakable.\n$@\n"; - }; - if ( $value ne $repo->config->$attr ) { - print STDERR "Failed to set $attr (perhaps an override is in place)\n"; - }; -}; - -undef $@; -eval { - print "$attr = " . $repo->config->$attr . "\n"; -}; -if ( $@ ) { - print STDERR "$attr is not a legal tweakable, or its current value is illegal.\n$@\n"; -}; diff --git a/usr/src/pinyadmin/sbin/rebuildrepo b/usr/src/pinyadmin/sbin/rebuildrepo deleted file mode 100755 index 9d4e359..0000000 --- a/usr/src/pinyadmin/sbin/rebuildrepo +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Piny; - -foreach my $reponame ( @ARGV ) { - - my $repo = Piny::Repo->new( $reponame ); - - $repo->rebuild; - -}; diff --git a/usr/src/pinyadmin/sbin/rmaccess b/usr/src/pinyadmin/sbin/rmaccess deleted file mode 100755 index d6c22a9..0000000 --- a/usr/src/pinyadmin/sbin/rmaccess +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Piny; - -my $env = Piny::Environment->instance( ); - -my ( $reponame, @users ) = @ARGV; - -my $repo = Piny::Repo->new( $reponame ); - -if ( $repo->owner->uid != $env->user->uid ) { - print "You are not the owner of that repo!\n"; - exit( 3 ); -}; - -$repo->remove_access( map { Piny::User->new( $_ ) } @users ); diff --git a/usr/src/pinyadmin/sbin/rmrepo b/usr/src/pinyadmin/sbin/rmrepo deleted file mode 100755 index dff8fe5..0000000 --- a/usr/src/pinyadmin/sbin/rmrepo +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; - -use Piny; - -my $env = Piny::Environment->instance( ); - -foreach my $reponame ( @ARGV ) { - - my $repo = Piny::Repo->new( $reponame ); - - if ( $env->user->uid != 0 and $repo->owner->uid != $env->user->uid ) { - print STDERR "You are not the owner of $reponame!\n"; - exit 1; - }; - - $repo->destroy; - -}; -- cgit v1.2.3 From 27a622d8691f16b82b0afae69f9f4fedd15fe6a3 Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Fri, 29 Oct 2010 19:48:20 -0500 Subject: Moved deployment-specific files and configuration to deploy/ until someone fixes the debian packages. --- deploy/etc/apache2/sites-available/001-piny | 63 +++++++++++++ deploy/etc/cgitrc | 100 +++++++++++++++++++++ deploy/etc/cron.daily/piny | 9 ++ deploy/srv/templates/page.tmpl | 132 ++++++++++++++++++++++++++++ etc/apache2/sites-available/001-piny | 63 ------------- etc/cgitrc | 100 --------------------- etc/cron.daily/piny | 9 -- srv/templates/page.tmpl | 132 ---------------------------- 8 files changed, 304 insertions(+), 304 deletions(-) create mode 100644 deploy/etc/apache2/sites-available/001-piny create mode 100644 deploy/etc/cgitrc create mode 100644 deploy/etc/cron.daily/piny create mode 100644 deploy/srv/templates/page.tmpl delete mode 100644 etc/apache2/sites-available/001-piny delete mode 100644 etc/cgitrc delete mode 100644 etc/cron.daily/piny delete mode 100644 srv/templates/page.tmpl diff --git a/deploy/etc/apache2/sites-available/001-piny b/deploy/etc/apache2/sites-available/001-piny new file mode 100644 index 0000000..6e5c3fd --- /dev/null +++ b/deploy/etc/apache2/sites-available/001-piny @@ -0,0 +1,63 @@ + + ServerName piny.be + + DocumentRoot /srv/www/piny.be + + + Options Indexes FollowSymLinks MultiViews + AllowOverride None + + + RedirectMatch 301 ^/$ http://piny.be/piny-web/ + + + + ServerName www.piny.be + RedirectMatch 301 (.*) http://piny.be$1 + + + + ServerName piny.be + DocumentRoot /srv/www/piny.be + + + Options Indexes FollowSymLinks MultiViews + AllowOverride None + + + RedirectMatch 301 ^/$ http://piny.be/piny-web/ + + SSLEngine On + SSLCertificateFile /etc/ssl/private/secure.piny.be.pem + SSLCACertificateFile /etc/ssl/private/GandiStandardSSLCA.pem + + + + ServerName secure.piny.be + RedirectMatch 301 (.*) https://secure.piny.be$1 + + + + ServerName secure.piny.be + DocumentRoot /srv/www/secure.piny.be + + + SSLRequireSSL + SetHandler cgi-script + AllowOverride None + Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch + + + ScriptAlias /cgit /usr/lib/cgi-bin/cgit.cgi + + Include /etc/apache2/piny-enabled + + SSLEngine On + SSLCertificateFile /etc/ssl/private/secure.piny.be.pem + SSLCACertificateFile /etc/ssl/private/GandiStandardSSLCA.pem + + + + ServerName piny.svcs.cs.pdx.edu + RedirectMatch 301 (.*) http://piny.be$1 + diff --git a/deploy/etc/cgitrc b/deploy/etc/cgitrc new file mode 100644 index 0000000..db2a9c4 --- /dev/null +++ b/deploy/etc/cgitrc @@ -0,0 +1,100 @@ +# Enable caching of up to 1000 output entriess +cache-size=1000 + + +# Specify some default clone prefixes +clone-prefix=git://piny.be git+ssh://piny.be/srv/git + +# Specify the css url +css=http://piny.be/piny-shared/cgit/cgit.css + + +# Show extra links for each repository on the index page +enable-index-links=1 + + +# Show number of affected files per commit on the log pages +enable-log-filecount=1 + + +# Show number of added/removed lines per commit on the log pages +enable-log-linecount=1 + + +# Add a cgit favicon +#favicon=/cgit/favicon.ico + + +# Use a custom logo +logo=http://piny.be/piny-shared/cgit/cgit.png + + +# Set the title and heading of the repository index page +root-title=Piny git repositories + + +# Set a subheading for the repository index page +root-desc=For all your informational needs. + + +# Include some more info about foobar.com on the index page +#root-readme=/var/www/htdocs/about.html + + +# Allow download of tar.gz, tar.bz and zip-files +snapshots=tar.gz zip + + +## +## List of repositories. +## PS: Any repositories listed when repo.group is unset will not be +## displayed under a group heading +## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos') +## and included like this: +include=/etc/cgitrepos +## + + +#repo.url=piny-web +#repo.path=/srv/git/piny-web.git +#repo.desc=piny-web +#repo.owner=jrayhawk+piny.be@omgwallhack.org +#repo.readme=info/web/about.html + + +#repo.url=piny-shared +#repo.path=/srv/git/piny-shared.git +#repo.desc=piny-shared +#repo.owner=jrayhawk+piny.be@omgwallhack.org +#repo.readme=info/web/about.html + + +# The next repositories will be displayed under the 'extras' heading + +#repo.url=baz +#repo.path=/pub/git/baz.git +#repo.desc=a set of extensions for bar users + +#repo.url=wiz +#repo.path=/pub/git/wiz.git +#repo.desc=the wizard of foo + + +# Add some mirrored repositories +#repo.group=mirrors + + +#repo.url=git +#repo.path=/pub/git/git.git +#repo.desc=the dscm + + +#repo.url=linux +#repo.path=/pub/git/linux.git +#repo.desc=the kernel + +# Disable adhoc downloads of this repo +repo.snapshots=0 + +# Disable line-counts for this repo +repo.enable-log-linecount=0 diff --git a/deploy/etc/cron.daily/piny b/deploy/etc/cron.daily/piny new file mode 100644 index 0000000..b42a806 --- /dev/null +++ b/deploy/etc/cron.daily/piny @@ -0,0 +1,9 @@ +#!/bin/sh + +export GIT_DIR + +for GIT_DIR in $(find /srv/git/ -maxdepth 1 -mindepth 1 -type d -name '*.git'); do +# echo $GIT_DIR + git gc --aggressive --auto --quiet + git update-server-info +done diff --git a/deploy/srv/templates/page.tmpl b/deploy/srv/templates/page.tmpl new file mode 100644 index 0000000..1a76648 --- /dev/null +++ b/deploy/srv/templates/page.tmpl @@ -0,0 +1,132 @@ + + + + +<TMPL_VAR TITLE> + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ + + + +
Comments on this page are closed.
+
+
+
+ + + + + diff --git a/etc/apache2/sites-available/001-piny b/etc/apache2/sites-available/001-piny deleted file mode 100644 index 6e5c3fd..0000000 --- a/etc/apache2/sites-available/001-piny +++ /dev/null @@ -1,63 +0,0 @@ - - ServerName piny.be - - DocumentRoot /srv/www/piny.be - - - Options Indexes FollowSymLinks MultiViews - AllowOverride None - - - RedirectMatch 301 ^/$ http://piny.be/piny-web/ - - - - ServerName www.piny.be - RedirectMatch 301 (.*) http://piny.be$1 - - - - ServerName piny.be - DocumentRoot /srv/www/piny.be - - - Options Indexes FollowSymLinks MultiViews - AllowOverride None - - - RedirectMatch 301 ^/$ http://piny.be/piny-web/ - - SSLEngine On - SSLCertificateFile /etc/ssl/private/secure.piny.be.pem - SSLCACertificateFile /etc/ssl/private/GandiStandardSSLCA.pem - - - - ServerName secure.piny.be - RedirectMatch 301 (.*) https://secure.piny.be$1 - - - - ServerName secure.piny.be - DocumentRoot /srv/www/secure.piny.be - - - SSLRequireSSL - SetHandler cgi-script - AllowOverride None - Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch - - - ScriptAlias /cgit /usr/lib/cgi-bin/cgit.cgi - - Include /etc/apache2/piny-enabled - - SSLEngine On - SSLCertificateFile /etc/ssl/private/secure.piny.be.pem - SSLCACertificateFile /etc/ssl/private/GandiStandardSSLCA.pem - - - - ServerName piny.svcs.cs.pdx.edu - RedirectMatch 301 (.*) http://piny.be$1 - diff --git a/etc/cgitrc b/etc/cgitrc deleted file mode 100644 index db2a9c4..0000000 --- a/etc/cgitrc +++ /dev/null @@ -1,100 +0,0 @@ -# Enable caching of up to 1000 output entriess -cache-size=1000 - - -# Specify some default clone prefixes -clone-prefix=git://piny.be git+ssh://piny.be/srv/git - -# Specify the css url -css=http://piny.be/piny-shared/cgit/cgit.css - - -# Show extra links for each repository on the index page -enable-index-links=1 - - -# Show number of affected files per commit on the log pages -enable-log-filecount=1 - - -# Show number of added/removed lines per commit on the log pages -enable-log-linecount=1 - - -# Add a cgit favicon -#favicon=/cgit/favicon.ico - - -# Use a custom logo -logo=http://piny.be/piny-shared/cgit/cgit.png - - -# Set the title and heading of the repository index page -root-title=Piny git repositories - - -# Set a subheading for the repository index page -root-desc=For all your informational needs. - - -# Include some more info about foobar.com on the index page -#root-readme=/var/www/htdocs/about.html - - -# Allow download of tar.gz, tar.bz and zip-files -snapshots=tar.gz zip - - -## -## List of repositories. -## PS: Any repositories listed when repo.group is unset will not be -## displayed under a group heading -## PPS: This list could be kept in a different file (e.g. '/etc/cgitrepos') -## and included like this: -include=/etc/cgitrepos -## - - -#repo.url=piny-web -#repo.path=/srv/git/piny-web.git -#repo.desc=piny-web -#repo.owner=jrayhawk+piny.be@omgwallhack.org -#repo.readme=info/web/about.html - - -#repo.url=piny-shared -#repo.path=/srv/git/piny-shared.git -#repo.desc=piny-shared -#repo.owner=jrayhawk+piny.be@omgwallhack.org -#repo.readme=info/web/about.html - - -# The next repositories will be displayed under the 'extras' heading - -#repo.url=baz -#repo.path=/pub/git/baz.git -#repo.desc=a set of extensions for bar users - -#repo.url=wiz -#repo.path=/pub/git/wiz.git -#repo.desc=the wizard of foo - - -# Add some mirrored repositories -#repo.group=mirrors - - -#repo.url=git -#repo.path=/pub/git/git.git -#repo.desc=the dscm - - -#repo.url=linux -#repo.path=/pub/git/linux.git -#repo.desc=the kernel - -# Disable adhoc downloads of this repo -repo.snapshots=0 - -# Disable line-counts for this repo -repo.enable-log-linecount=0 diff --git a/etc/cron.daily/piny b/etc/cron.daily/piny deleted file mode 100644 index b42a806..0000000 --- a/etc/cron.daily/piny +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -export GIT_DIR - -for GIT_DIR in $(find /srv/git/ -maxdepth 1 -mindepth 1 -type d -name '*.git'); do -# echo $GIT_DIR - git gc --aggressive --auto --quiet - git update-server-info -done diff --git a/srv/templates/page.tmpl b/srv/templates/page.tmpl deleted file mode 100644 index 1a76648..0000000 --- a/srv/templates/page.tmpl +++ /dev/null @@ -1,132 +0,0 @@ - - - - -<TMPL_VAR TITLE> - - - - - - - - - - - - - - - - - - - - -
- -
- - -
- - - - -
Comments on this page are closed.
-
-
-
- - - - - -- cgit v1.2.3 From e6738da715d990092fd11258d1f0a1520cb45ff2 Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Fri, 29 Oct 2010 19:50:51 -0500 Subject: Moved issues/ into docs/issues/ --- docs/issues.mdwn | 6 ++++ ...t_now_supports_per_directory_configuration.mdwn | 17 +++++++++ docs/issues/debian_packaging_concerns.mdwn | 42 ++++++++++++++++++++++ docs/issues/not_tracking_templates.mdwn | 9 +++++ .../plain_git_repository_hosting_needed.mdwn | 10 ++++++ docs/issues/shared_underlay.mdwn | 13 +++++++ docs/issues/wmd.mdwn | 12 +++++++ issues.mdwn | 6 ---- ...t_now_supports_per_directory_configuration.mdwn | 17 --------- issues/debian_packaging_concerns.mdwn | 42 ---------------------- issues/not_tracking_templates.mdwn | 9 ----- issues/plain_git_repository_hosting_needed.mdwn | 10 ------ issues/shared_underlay.mdwn | 13 ------- issues/wmd.mdwn | 12 ------- 14 files changed, 109 insertions(+), 109 deletions(-) create mode 100644 docs/issues.mdwn create mode 100644 docs/issues/cgit_now_supports_per_directory_configuration.mdwn create mode 100644 docs/issues/debian_packaging_concerns.mdwn create mode 100644 docs/issues/not_tracking_templates.mdwn create mode 100644 docs/issues/plain_git_repository_hosting_needed.mdwn create mode 100644 docs/issues/shared_underlay.mdwn create mode 100644 docs/issues/wmd.mdwn delete mode 100644 issues.mdwn delete mode 100644 issues/cgit_now_supports_per_directory_configuration.mdwn delete mode 100644 issues/debian_packaging_concerns.mdwn delete mode 100644 issues/not_tracking_templates.mdwn delete mode 100644 issues/plain_git_repository_hosting_needed.mdwn delete mode 100644 issues/shared_underlay.mdwn delete mode 100644 issues/wmd.mdwn diff --git a/docs/issues.mdwn b/docs/issues.mdwn new file mode 100644 index 0000000..8942268 --- /dev/null +++ b/docs/issues.mdwn @@ -0,0 +1,6 @@ +List of open issues; see [[templates/issues]] + +[[!inline pages="issues/* and !issues/*/* and !issues/done and !link(issues/done) and !link(tag/closed)" show=0 rootpage="issues" postformtext="Add a new issue titled:" actions="yes"]] + +For issues, use the following template: [[!edittemplate template="templates/issues" match="issues/*"]] + diff --git a/docs/issues/cgit_now_supports_per_directory_configuration.mdwn b/docs/issues/cgit_now_supports_per_directory_configuration.mdwn new file mode 100644 index 0000000..380981a --- /dev/null +++ b/docs/issues/cgit_now_supports_per_directory_configuration.mdwn @@ -0,0 +1,17 @@ +* Status: [[!taglink closed]] +* Assigned to: [[!taglink jrayhawk]] +* Priority: [[!taglink now]] +* Opened by: jrayhawk + +### Discussion + +On Tue, Oct 06, 2009 at 11:40:11AM +0200, Lars Hjemli wrote: +> If you want auto-discovery of repositories similar to gitweb, the +> 'scan-path' option will automatically include $GITDIR/cgitrc for each +> repository. + +do this instead of the current goofy cgitrc.d thing we got going now. + +### jrayhawk 20101029 + +We've moved over to just inferring paths and using the gitweb.owner variable, now. diff --git a/docs/issues/debian_packaging_concerns.mdwn b/docs/issues/debian_packaging_concerns.mdwn new file mode 100644 index 0000000..aca7000 --- /dev/null +++ b/docs/issues/debian_packaging_concerns.mdwn @@ -0,0 +1,42 @@ +* Status: [[!taglink open]] +* Assigned to: [[!taglink jrayhawk]] +* Priority: [[!taglink now]] +* Opened by: jrayhawk + +### Discussion + +There are a variety of things that wind up needing to be manually handled outside of the package installation in order to get piny working. It would be nice to correct all these. + +* /etc/piny.conf +* /etc/sudoers.d/pinyadmin +* /etc/sv/git-daemon/run + * --base-path=/var/cache /var/cache/git is not a very good place at all; what do we do about that? +* /srv/rbin +* mkdir /srv/git +* mkdir /etc/piny +* mkdir /etc/apache2/piny-available +* mkdir /etc/apache2/piny-enabled +* mkdir /srv/www/$ikiwiki_destdir/repos +* mkdir /etc/ikiwiki/wikilist.d +* lots of /etc/cgitrc changes +* mkdir /srv/www/$ikiwiki_destdir/static +* ln /usr/share/cgit/cgit.css /srv/www/$ikiwiki_destdir/static +* ln /usr/share/cgit/logo.png /srv/www/$ikiwiki_destdir/static +* /srv/git-template.git +* change GROUP to shadow in /etc/apache2/envvars + +* dependencies + * cgit + * libyaml-tiny-perl + * gcc + * libc6-dev + * dvipng + * texlive-science + * graphviz + * perlmagick + * libcgi-formbuilder-perl + * git-daemon-run + * apache2 + * libapache2-mod-auth-sys-group + * libapache2-mod-auth-pam + diff --git a/docs/issues/not_tracking_templates.mdwn b/docs/issues/not_tracking_templates.mdwn new file mode 100644 index 0000000..f745e2f --- /dev/null +++ b/docs/issues/not_tracking_templates.mdwn @@ -0,0 +1,9 @@ +* Status: [[!taglink closed]] +* Assigned to: [[!taglink jrayhawk]] +* Priority: [[!taglink now]] +* Opened by: jrayhawk + +### Discussion + +A bunch of the templates need to be removed; Joey added an 'add_templates' option that allows us to do nested fallback. + diff --git a/docs/issues/plain_git_repository_hosting_needed.mdwn b/docs/issues/plain_git_repository_hosting_needed.mdwn new file mode 100644 index 0000000..8bcb64b --- /dev/null +++ b/docs/issues/plain_git_repository_hosting_needed.mdwn @@ -0,0 +1,10 @@ +* Status: [[!taglink open]] +* Assigned to: [[!taglink jblake]] +* Priority: [[!taglink now]] +* Opened by: jrayhawk + +### Discussion + +We really badly need to be able to host simple non-ikiwiki git repos; it'd probably be best to do so without invoking the ikiwiki engine. + +This should be doable through both newrepo and pinyconfig diff --git a/docs/issues/shared_underlay.mdwn b/docs/issues/shared_underlay.mdwn new file mode 100644 index 0000000..82901c7 --- /dev/null +++ b/docs/issues/shared_underlay.mdwn @@ -0,0 +1,13 @@ +* Status: [[!taglink open]] +* Assigned to: [[!taglink jrayhawk]] +* Priority: [[!taglink now]] +* Opened by: jrayhawk + +### Discussion + +The 'piny-shared' unified underlay repository causes problems with things like the FormattingHelp link in the editpage. These are difficult to correct. + +Solutions: + +* Deunify the underlay repository, then use vserver piny hashify to unify storage. Not sure this is a good idea if I want to migrate to LXC. +* Get Joey or Josh to make provisions for my usage model. diff --git a/docs/issues/wmd.mdwn b/docs/issues/wmd.mdwn new file mode 100644 index 0000000..f126b80 --- /dev/null +++ b/docs/issues/wmd.mdwn @@ -0,0 +1,12 @@ +* Status: [[!taglink open]] +* Assigned to: [[!taglink jrayhawk]] +* Priority: [[!taglink soon]] +* Opened by: jrayhawk + +### Discussion + +Get wmd working + +Also get wmd splitscreen working + +It would be nice if something freely redistributable came along. diff --git a/issues.mdwn b/issues.mdwn deleted file mode 100644 index 8942268..0000000 --- a/issues.mdwn +++ /dev/null @@ -1,6 +0,0 @@ -List of open issues; see [[templates/issues]] - -[[!inline pages="issues/* and !issues/*/* and !issues/done and !link(issues/done) and !link(tag/closed)" show=0 rootpage="issues" postformtext="Add a new issue titled:" actions="yes"]] - -For issues, use the following template: [[!edittemplate template="templates/issues" match="issues/*"]] - diff --git a/issues/cgit_now_supports_per_directory_configuration.mdwn b/issues/cgit_now_supports_per_directory_configuration.mdwn deleted file mode 100644 index 380981a..0000000 --- a/issues/cgit_now_supports_per_directory_configuration.mdwn +++ /dev/null @@ -1,17 +0,0 @@ -* Status: [[!taglink closed]] -* Assigned to: [[!taglink jrayhawk]] -* Priority: [[!taglink now]] -* Opened by: jrayhawk - -### Discussion - -On Tue, Oct 06, 2009 at 11:40:11AM +0200, Lars Hjemli wrote: -> If you want auto-discovery of repositories similar to gitweb, the -> 'scan-path' option will automatically include $GITDIR/cgitrc for each -> repository. - -do this instead of the current goofy cgitrc.d thing we got going now. - -### jrayhawk 20101029 - -We've moved over to just inferring paths and using the gitweb.owner variable, now. diff --git a/issues/debian_packaging_concerns.mdwn b/issues/debian_packaging_concerns.mdwn deleted file mode 100644 index aca7000..0000000 --- a/issues/debian_packaging_concerns.mdwn +++ /dev/null @@ -1,42 +0,0 @@ -* Status: [[!taglink open]] -* Assigned to: [[!taglink jrayhawk]] -* Priority: [[!taglink now]] -* Opened by: jrayhawk - -### Discussion - -There are a variety of things that wind up needing to be manually handled outside of the package installation in order to get piny working. It would be nice to correct all these. - -* /etc/piny.conf -* /etc/sudoers.d/pinyadmin -* /etc/sv/git-daemon/run - * --base-path=/var/cache /var/cache/git is not a very good place at all; what do we do about that? -* /srv/rbin -* mkdir /srv/git -* mkdir /etc/piny -* mkdir /etc/apache2/piny-available -* mkdir /etc/apache2/piny-enabled -* mkdir /srv/www/$ikiwiki_destdir/repos -* mkdir /etc/ikiwiki/wikilist.d -* lots of /etc/cgitrc changes -* mkdir /srv/www/$ikiwiki_destdir/static -* ln /usr/share/cgit/cgit.css /srv/www/$ikiwiki_destdir/static -* ln /usr/share/cgit/logo.png /srv/www/$ikiwiki_destdir/static -* /srv/git-template.git -* change GROUP to shadow in /etc/apache2/envvars - -* dependencies - * cgit - * libyaml-tiny-perl - * gcc - * libc6-dev - * dvipng - * texlive-science - * graphviz - * perlmagick - * libcgi-formbuilder-perl - * git-daemon-run - * apache2 - * libapache2-mod-auth-sys-group - * libapache2-mod-auth-pam - diff --git a/issues/not_tracking_templates.mdwn b/issues/not_tracking_templates.mdwn deleted file mode 100644 index f745e2f..0000000 --- a/issues/not_tracking_templates.mdwn +++ /dev/null @@ -1,9 +0,0 @@ -* Status: [[!taglink closed]] -* Assigned to: [[!taglink jrayhawk]] -* Priority: [[!taglink now]] -* Opened by: jrayhawk - -### Discussion - -A bunch of the templates need to be removed; Joey added an 'add_templates' option that allows us to do nested fallback. - diff --git a/issues/plain_git_repository_hosting_needed.mdwn b/issues/plain_git_repository_hosting_needed.mdwn deleted file mode 100644 index 8bcb64b..0000000 --- a/issues/plain_git_repository_hosting_needed.mdwn +++ /dev/null @@ -1,10 +0,0 @@ -* Status: [[!taglink open]] -* Assigned to: [[!taglink jblake]] -* Priority: [[!taglink now]] -* Opened by: jrayhawk - -### Discussion - -We really badly need to be able to host simple non-ikiwiki git repos; it'd probably be best to do so without invoking the ikiwiki engine. - -This should be doable through both newrepo and pinyconfig diff --git a/issues/shared_underlay.mdwn b/issues/shared_underlay.mdwn deleted file mode 100644 index 82901c7..0000000 --- a/issues/shared_underlay.mdwn +++ /dev/null @@ -1,13 +0,0 @@ -* Status: [[!taglink open]] -* Assigned to: [[!taglink jrayhawk]] -* Priority: [[!taglink now]] -* Opened by: jrayhawk - -### Discussion - -The 'piny-shared' unified underlay repository causes problems with things like the FormattingHelp link in the editpage. These are difficult to correct. - -Solutions: - -* Deunify the underlay repository, then use vserver piny hashify to unify storage. Not sure this is a good idea if I want to migrate to LXC. -* Get Joey or Josh to make provisions for my usage model. diff --git a/issues/wmd.mdwn b/issues/wmd.mdwn deleted file mode 100644 index f126b80..0000000 --- a/issues/wmd.mdwn +++ /dev/null @@ -1,12 +0,0 @@ -* Status: [[!taglink open]] -* Assigned to: [[!taglink jrayhawk]] -* Priority: [[!taglink soon]] -* Opened by: jrayhawk - -### Discussion - -Get wmd working - -Also get wmd splitscreen working - -It would be nice if something freely redistributable came along. -- cgit v1.2.3 From 62f811460f400b73271b43d1d91c5c65f09c1975 Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Fri, 29 Oct 2010 19:51:55 -0500 Subject: fixed the issues.mdwn index display (i think) --- docs/issues.mdwn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/issues.mdwn b/docs/issues.mdwn index 8942268..68be754 100644 --- a/docs/issues.mdwn +++ b/docs/issues.mdwn @@ -1,6 +1,6 @@ List of open issues; see [[templates/issues]] -[[!inline pages="issues/* and !issues/*/* and !issues/done and !link(issues/done) and !link(tag/closed)" show=0 rootpage="issues" postformtext="Add a new issue titled:" actions="yes"]] +[[!inline pages="docs/issues/* and !docs/issues/*/* and !docs/issues/done and !link(docs/issues/done) and !link(tag/closed)" show=0 rootpage="issues" postformtext="Add a new issue titled:" actions="yes"]] -For issues, use the following template: [[!edittemplate template="templates/issues" match="issues/*"]] +For issues, use the following template: [[!edittemplate template="templates/issues" match="docs/issues/*"]] -- cgit v1.2.3 From b22eb9dfad807b799998e271ce52ffc63aa006c9 Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Fri, 29 Oct 2010 19:53:23 -0500 Subject: fixed index.mwdwn links to docs/issues --- index.mdwn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.mdwn b/index.mdwn index 3f9911f..b74a151 100644 --- a/index.mdwn +++ b/index.mdwn @@ -1,8 +1,8 @@ The code behind piny. ### [[Issues]]: -[[!inline pages="issues/* and !issues/*" show=0 rootpage="issues" postformtext="Add a new issue titled:" actions="yes"]] -[[!map pages="issues/* and !issues/*/* and !issues/done and !link(issues/done) and !link(tag/closed)"]] +[[!inline pages="docs/issues/* and !docs/issues/*" show=0 rootpage="docs/issues" postformtext="Add a new issue titled:" actions="yes"]] +[[!map pages="docs/issues/* and !docs/issues/*/* and !docs/issues/done and !link(docs/issues/done) and !link(tag/closed)"]] ### Files: [[!map pages="* and ! */*"]] -- cgit v1.2.3 From 79c284badd015f88d8fd42d941e30bca70dd4eb9 Mon Sep 17 00:00:00 2001 From: Bryan Bishop Date: Fri, 29 Oct 2010 19:54:38 -0500 Subject: ok now for real --- index.mdwn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.mdwn b/index.mdwn index b74a151..320ef0c 100644 --- a/index.mdwn +++ b/index.mdwn @@ -1,6 +1,6 @@ The code behind piny. -### [[Issues]]: +### [[Issues|docs/Issues]]: [[!inline pages="docs/issues/* and !docs/issues/*" show=0 rootpage="docs/issues" postformtext="Add a new issue titled:" actions="yes"]] [[!map pages="docs/issues/* and !docs/issues/*/* and !docs/issues/done and !link(docs/issues/done) and !link(tag/closed)"]] -- cgit v1.2.3