├── .gitconfig ├── .gitignore ├── .licensizer.yml ├── .travis.yml ├── Changes ├── DESIGN ├── MANIFEST ├── MANIFEST.SKIP ├── Makefile.PL ├── README ├── README.pod ├── TODO ├── adm ├── Makefile ├── Template.pm ├── cert-create.sh ├── perltidyrc ├── pogo-tmpl ├── pogotidy ├── readme-upd ├── release └── template ├── bin ├── plack-test ├── pogo-api ├── pogo-client ├── pogo-dispatcher ├── pogo-fg ├── pogo-one ├── pogo-pw ├── pogo-schedule ├── pogo-test-ls-sim ├── pogo-test-ssh-sim ├── pogo-ui └── pogo-worker ├── docs ├── api.pod ├── legacy-zk.pod └── pogo-psgi.jpg ├── inc └── Module │ ├── Install.pm │ └── Install │ ├── Base.pm │ ├── Can.pm │ ├── Fetch.pm │ ├── Makefile.pm │ ├── Metadata.pm │ ├── Win32.pm │ └── WriteAll.pm ├── lib ├── PasswordMonkey │ └── Filler │ │ ├── PogoGPG.pm │ │ ├── PogoPassphrase.pm │ │ └── PogoPassword.pm ├── Pogo.pm └── Pogo │ ├── API.pm │ ├── API │ ├── Status.pm │ └── V1.pm │ ├── AnyEvent │ ├── HTTP.pm │ └── ZooKeeper.pm │ ├── Client.pm │ ├── Client │ ├── Async.pm │ ├── Auth.pm │ ├── Commandline.pm │ └── Util.pm │ ├── Defaults.pm │ ├── Dispatcher.pm │ ├── Dispatcher │ ├── ControlPort.pm │ ├── ControlPort │ │ ├── PSGI.pm │ │ ├── Status.pm │ │ └── V1.pm │ ├── PonyExpress.pm │ └── Wconn │ │ ├── Connection.pm │ │ └── Pool.pm │ ├── Job.pm │ ├── Object │ └── Event.pm │ ├── One.pm │ ├── One │ └── Util.pm │ ├── PasswordMonkey.pm │ ├── Plack │ └── Handler │ │ └── AnyEvent │ │ └── HTTPD.pm │ ├── Plugin.pm │ ├── Plugin │ ├── TagExternal │ │ └── Example.pm │ └── ZooKeeper │ │ └── Default.pm │ ├── Scheduler.pm │ ├── Scheduler │ ├── Classic.pm │ ├── Config.pm │ ├── Config │ │ ├── Tag.pm │ │ └── TagExternal.pm │ ├── Constraint.pm │ ├── Slot.pm │ ├── Task.pm │ └── Thread.pm │ ├── Security.pm │ ├── Util.pm │ ├── Util │ ├── Bucketeer.pm │ ├── Cache.pm │ ├── QP.pm │ ├── SSH.pm │ └── SSH │ │ └── Agent.pm │ ├── Worker.pm │ └── Worker │ ├── Connection.pm │ ├── Task.pm │ └── Task │ ├── Command.pm │ └── Command │ └── Remote.pm ├── t ├── 001Basic.t ├── 002Protocol.t ├── 003QP.t ├── 004WorkerPool.t ├── 005ZooKeeper.t ├── 006API.t ├── 007SSL.t ├── 008Command.t ├── 009API.t ├── 010Plugin.t ├── 011ZKPlugin.t ├── 012Schedule.t ├── 013Config.t ├── 014Sequence.t ├── 015SeqAttr.t ├── 016Bucketeer.t ├── 017Tasks.t ├── 018TasksEvent.t ├── 019Thread.t ├── 020TripleSeq.t ├── 021Constraint.t ├── 022Hangs.t ├── 023NoSeqCon.t ├── 024SlotConstr.t ├── 025MultSeq.t ├── 026APIJobOperations.t ├── 027HostSeq.t ├── 028PogoOne.t ├── 029WorkerRemoteCmd.t ├── 030EndToEnd.t ├── 031Tags.t ├── 032TagExternal.t ├── 033Cache.t ├── 034PonyExpress.pm ├── 035Password.t ├── 036PasswordCrypt.t ├── 037SSH-Agent.t ├── certs │ ├── README │ ├── ca.crt │ ├── dispatcher.crt │ ├── dispatcher.key │ ├── worker.crt │ └── worker.key ├── cfgs │ ├── one.cfg │ └── triple.cfg ├── keys │ ├── nopp │ ├── nopp.pub │ ├── pp │ └── pp.pub ├── lib │ ├── Pogo │ │ └── Plugin │ │ │ ├── Test │ │ │ └── Default.pm │ │ │ └── ZooKeeper │ │ │ └── Test.pm │ ├── PogoFake.pm │ └── PogoTest.pm └── tmpl │ └── index.tmpl ├── tmpl └── index.tmpl └── ui ├── assets ├── oss-tools.css └── pogo.css ├── index.html └── js ├── build ├── pogo-app │ ├── pogo-app-debug.js │ ├── pogo-app-min.js │ └── pogo-app.js ├── pogo-env │ ├── pogo-env-debug.js │ ├── pogo-env-min.js │ └── pogo-env.js ├── pogo-formatters │ ├── pogo-formatters-debug.js │ ├── pogo-formatters-min.js │ └── pogo-formatters.js ├── pogo-loader │ ├── pogo-loader-debug.js │ ├── pogo-loader-min.js │ └── pogo-loader.js ├── pogo-model-host │ ├── pogo-model-host-debug.js │ ├── pogo-model-host-min.js │ └── pogo-model-host.js ├── pogo-model-hostslist │ ├── pogo-model-hostslist-debug.js │ ├── pogo-model-hostslist-min.js │ └── pogo-model-hostslist.js ├── pogo-model-job │ ├── pogo-model-job-debug.js │ ├── pogo-model-job-min.js │ └── pogo-model-job.js ├── pogo-model-jobslist │ ├── pogo-model-jobslist-debug.js │ ├── pogo-model-jobslist-min.js │ └── pogo-model-jobslist.js ├── pogo-view-dashboard │ ├── pogo-view-dashboard-debug.js │ ├── pogo-view-dashboard-min.js │ └── pogo-view-dashboard.js ├── pogo-view-host │ ├── pogo-view-host-debug.js │ ├── pogo-view-host-min.js │ └── pogo-view-host.js ├── pogo-view-hostlog │ ├── pogo-view-hostlog-debug.js │ ├── pogo-view-hostlog-min.js │ └── pogo-view-hostlog.js ├── pogo-view-job │ ├── pogo-view-job-debug.js │ ├── pogo-view-job-min.js │ └── pogo-view-job.js ├── pogo-view-jobhostdata │ ├── pogo-view-jobhostdata-debug.js │ ├── pogo-view-jobhostdata-min.js │ └── pogo-view-jobhostdata.js ├── pogo-view-jobmetadata │ ├── pogo-view-jobmetadata-debug.js │ ├── pogo-view-jobmetadata-min.js │ └── pogo-view-jobmetadata.js ├── pogo-view-multidatatable │ ├── pogo-view-multidatatable-debug.js │ ├── pogo-view-multidatatable-min.js │ └── pogo-view-multidatatable.js └── pogo-view-user │ ├── pogo-view-user-debug.js │ ├── pogo-view-user-min.js │ └── pogo-view-user.js └── src ├── build.xml ├── default.xml ├── pogo-app ├── build.properties ├── build.xml ├── js │ └── pogo-app.js └── tests │ └── pogo-app.html ├── pogo-env ├── build.properties ├── build.xml ├── js │ └── pogo-env.js └── tests │ └── pogo-env.html ├── pogo-formatters ├── build.properties ├── build.xml ├── js │ └── pogo-formatters.js └── tests │ └── pogo-formatters.html ├── pogo-loader ├── build.properties ├── build.xml ├── js │ └── loader.js └── meta_join.ssjs ├── pogo-model-host ├── build.properties ├── build.xml ├── js │ └── pogo-model-host.js └── tests │ └── pogo-model-host.html ├── pogo-model-hostslist ├── build.properties ├── build.xml ├── js │ └── pogo-model-hostslist.js └── tests │ └── pogo-model-hostslist.html ├── pogo-model-job ├── build.properties ├── build.xml ├── js │ └── pogo-model-job.js └── tests │ └── pogo-model-job.html ├── pogo-model-jobslist ├── build.properties ├── build.xml ├── js │ └── pogo-model-jobslist.js └── tests │ └── pogo-model-jobslist.html ├── pogo-view-dashboard ├── build.properties ├── build.xml ├── js │ └── pogo-view-dashboard.js └── tests │ └── pogo-view-dashboard.html ├── pogo-view-host ├── build.properties ├── build.xml ├── js │ └── pogo-view-host.js └── tests │ └── pogo-view-host.html ├── pogo-view-hostlog ├── build.properties ├── build.xml ├── js │ └── pogo-view-hostlog.js └── tests │ └── pogo-view-jobhostdata.html ├── pogo-view-job ├── build.properties ├── build.xml ├── js │ └── pogo-view-job.js └── tests │ └── pogo-view-job.html ├── pogo-view-jobhostdata ├── build.properties ├── build.xml ├── js │ └── pogo-view-jobhostdata.js └── tests │ └── pogo-view-jobhostdata.html ├── pogo-view-jobmetadata ├── build.properties ├── build.xml ├── js │ └── pogo-view-jobmetadata.js └── tests │ └── pogo-view-jobmetadata.html ├── pogo-view-multidatatable ├── build.properties ├── build.xml ├── js │ └── pogo-view-multidatatable.js └── tests │ └── pogo-view-multidatatable.html └── pogo-view-user ├── build.properties ├── build.xml ├── js └── pogo-view-user.js └── tests └── pogo-view-user.html /.gitconfig: -------------------------------------------------------------------------------- 1 | [color] 2 | ui = auto 3 | status = auto 4 | branch = auto 5 | diff = auto 6 | [user] 7 | name = mschilli 8 | email = github@perlmeister.com 9 | [pager] 10 | status = true 11 | diff = true 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | blib 2 | pm_to_blib 3 | Makefile 4 | Makefile.old 5 | META.yml 6 | MYMETA.json 7 | MYMETA.yml 8 | -------------------------------------------------------------------------------- /.licensizer.yml: -------------------------------------------------------------------------------- 1 | # .licensizer.yml 2 | author: | 3 | Mike Schilli 4 | Ian Bettinger 5 | 6 | Many thanks to the following folks for implementing the 7 | original version of Pogo: 8 | 9 | Andrew Sloane , 10 | Michael Fischer , 11 | Nicholas Harteau , 12 | Nick Purvis , 13 | Robert Phan , 14 | Srini Singanallur , 15 | Yogesh Natarajan 16 | 17 | license: | 18 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 19 | 20 | Licensed under the Apache License, Version 2.0 (the "License"); 21 | you may not use this file except in compliance with the License. 22 | You may obtain a copy of the License at 23 | 24 | http://www.apache.org/licenses/LICENSE-2.0 25 | 26 | Unless required by applicable law or agreed to in writing, software 27 | distributed under the License is distributed on an "AS IS" BASIS, 28 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 | See the License for the specific language governing permissions and 30 | imitations under the License. 31 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: perl 2 | install: cpanm --installdeps --notest . || true && cat ~/.cpanm/build.log 3 | perl: 4 | - "5.12" 5 | -------------------------------------------------------------------------------- /Changes: -------------------------------------------------------------------------------- 1 | ###################################################################### 2 | Revision history for Perl extension Pogo 3 | 4 | 5.00 2012/04/13 5 | (ms) Where it all began. 6 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | .licensizer.yml 2 | adm/cert-create.sh 3 | adm/Makefile 4 | adm/pogo-tmpl 5 | adm/template 6 | adm/Template.pm 7 | bin/plack-test 8 | bin/pogo-dispatcher 9 | bin/pogo-fg 10 | bin/pogo-worker 11 | Changes 12 | DESIGN 13 | inc/Module/Install.pm 14 | inc/Module/Install/Base.pm 15 | inc/Module/Install/Can.pm 16 | inc/Module/Install/Fetch.pm 17 | inc/Module/Install/Makefile.pm 18 | inc/Module/Install/Metadata.pm 19 | inc/Module/Install/Win32.pm 20 | inc/Module/Install/WriteAll.pm 21 | lib/Pogo.pm 22 | lib/Pogo/AnyEvent/ZooKeeper.pm 23 | lib/Pogo/API.pm 24 | lib/Pogo/API/Status.pm 25 | lib/Pogo/API/V1.pm 26 | lib/Pogo/Defaults.pm 27 | lib/Pogo/Dispatcher.pm 28 | lib/Pogo/Dispatcher/ControlPort.pm 29 | lib/Pogo/Dispatcher/ControlPort/PSGI.pm 30 | lib/Pogo/Dispatcher/ControlPort/Status.pm 31 | lib/Pogo/Dispatcher/ControlPort/V1.pm 32 | lib/Pogo/Dispatcher/Wconn/Connection.pm 33 | lib/Pogo/Dispatcher/Wconn/Pool.pm 34 | lib/Pogo/Object/Event.pm 35 | lib/Pogo/Security.pm 36 | lib/Pogo/Util.pm 37 | lib/Pogo/Util/QP.pm 38 | lib/Pogo/Worker.pm 39 | lib/Pogo/Worker/Connection.pm 40 | lib/Pogo/Worker/Task.pm 41 | lib/Pogo/Worker/Task/Command.pm 42 | lib/Pogo/Worker/Task/Command/Remote.pm 43 | Makefile.PL 44 | MANIFEST 45 | MANIFEST.SKIP 46 | META.yml 47 | README 48 | t/001Basic.t 49 | t/002Protocol.t 50 | t/003QP.t 51 | t/004WorkerPool.t 52 | t/005ZooKeeper.t 53 | t/006API.t 54 | t/007SSL.t 55 | t/008Command.t 56 | t/certs/ca.crt 57 | t/certs/dispatcher.crt 58 | t/certs/dispatcher.key 59 | t/certs/README 60 | t/certs/worker.crt 61 | t/certs/worker.key 62 | t/lib/PogoOne.pm 63 | t/lib/PogoTest.pm 64 | t/tmpl/index.tmpl 65 | tmpl/index.tmpl 66 | TODO 67 | -------------------------------------------------------------------------------- /MANIFEST.SKIP: -------------------------------------------------------------------------------- 1 | blib 2 | ^Makefile$ 3 | ^Makefile.old$ 4 | .gitignore 5 | docs 6 | MANIFEST.bak 7 | adm/release 8 | .git 9 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | 2 | * reconnect logic disp/worker 3 | * check linebreaks with JSON (duplex protocol) 4 | * resilient to JSON errors (eval) 5 | -------------------------------------------------------------------------------- /adm/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | 4 | clean: 5 | rm -f *.key *.crt *.csr *.tgz ca.conf index.txt* serial* 0*.pem 6 | -------------------------------------------------------------------------------- /adm/Template.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::XXX; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | use Log::Log4perl qw(:easy); 7 | use AnyEvent; 8 | use AnyEvent::Strict; 9 | 10 | ########################################### 11 | sub new { 12 | ########################################### 13 | my($class, %options) = @_; 14 | 15 | my $self = { 16 | %options, 17 | }; 18 | 19 | bless $self, $class; 20 | } 21 | 22 | 1; 23 | 24 | __END__ 25 | 26 | =head1 NAME 27 | 28 | Pogo::XXX - Pogo XXX 29 | 30 | =head1 SYNOPSIS 31 | 32 | use Pogo::XXX; 33 | 34 | my $xxx = Pogo::XXX->new(); 35 | 36 | =head1 DESCRIPTION 37 | 38 | XXX does this and that. 39 | 40 | =head1 METHODS 41 | 42 | =over 4 43 | 44 | =item C 45 | 46 | Constructor. 47 | 48 | =back 49 | 50 | =head1 LICENSE 51 | 52 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 53 | 54 | Licensed under the Apache License, Version 2.0 (the "License"); 55 | you may not use this file except in compliance with the License. 56 | You may obtain a copy of the License at 57 | 58 | http://www.apache.org/licenses/LICENSE-2.0 59 | 60 | Unless required by applicable law or agreed to in writing, software 61 | distributed under the License is distributed on an "AS IS" BASIS, 62 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 63 | See the License for the specific language governing permissions and 64 | imitations under the License. 65 | 66 | =head1 AUTHORS 67 | 68 | Mike Schilli 69 | Ian Bettinger 70 | 71 | Many thanks to the following folks for implementing the 72 | original version of Pogo: 73 | 74 | Andrew Sloane , 75 | Michael Fischer , 76 | Nicholas Harteau , 77 | Nick Purvis , 78 | Robert Phan , 79 | Srini Singanallur , 80 | Yogesh Natarajan 81 | 82 | -------------------------------------------------------------------------------- /adm/perltidyrc: -------------------------------------------------------------------------------- 1 | # perltidy options for Pogo 2 | 3 | -l=80 # line width 4 | -i=4 # 2 cols indent 5 | -ci=4 # 2 cols continuation indent 6 | -ce # cuddled else 7 | -vt=2 # vertical tightness 8 | -nbbc # no blank lines before whole-line comments 9 | -pt=0 # horizontal space around parentheses 10 | -sbt=0 # horizontal space around square brackets 11 | -bt=0 # horizontal space around curly braces 12 | -------------------------------------------------------------------------------- /adm/pogo-tmpl: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use FindBin qw($Bin); 5 | use File::Copy; 6 | use Pod::Usage; 7 | 8 | my($name) = @ARGV; 9 | 10 | if( !defined $name ) { 11 | pod2usage("argument missing"); 12 | } 13 | 14 | my $template = "template"; 15 | 16 | if( $name =~ /\.pm$/ ) { 17 | $template = "Template.pm"; 18 | } 19 | 20 | if( -e $name ) { 21 | pod2usage "$name already exists. Cowardly refusing to move on."; 22 | } 23 | 24 | my($src) = <$Bin/$template>; 25 | 26 | copy $src, $name or die "copy failed: $!"; 27 | 28 | __END__ 29 | 30 | =head1 NAME 31 | 32 | pogo-tmpl - Create new pogo modules/scripts from templates 33 | 34 | =head1 SYNOPSIS 35 | 36 | # creates "pogo-frobnicator" from script template 37 | pogo-tmpl pogo-frobnicator 38 | 39 | # creates "Frobnicate.pm" from module template 40 | pogo-tmpl Frobnicate.pm 41 | 42 | =head1 DESCRIPTION 43 | 44 | Use this script to create new scripts/modules for Pogo development. 45 | 46 | =head1 LICENSE 47 | 48 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 49 | 50 | Licensed under the Apache License, Version 2.0 (the "License"); 51 | you may not use this file except in compliance with the License. 52 | You may obtain a copy of the License at 53 | 54 | http://www.apache.org/licenses/LICENSE-2.0 55 | 56 | Unless required by applicable law or agreed to in writing, software 57 | distributed under the License is distributed on an "AS IS" BASIS, 58 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 59 | See the License for the specific language governing permissions and 60 | imitations under the License. 61 | 62 | =head1 AUTHORS 63 | 64 | Mike Schilli 65 | Ian Bettinger 66 | 67 | Many thanks to the following folks for implementing the 68 | original version of Pogo: 69 | 70 | Andrew Sloane , 71 | Michael Fischer , 72 | Nicholas Harteau , 73 | Nick Purvis , 74 | Robert Phan , 75 | Srini Singanallur , 76 | Yogesh Natarajan 77 | 78 | -------------------------------------------------------------------------------- /adm/pogotidy: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl -w 2 | ########################################### 3 | # pogotidy -- tidy up the entire project 4 | # Mike Schilli, 2012 (m@perlmeister.com) 5 | ########################################### 6 | use strict; 7 | use Sysadm::Install qw(:all); 8 | use Perl::Tidy; 9 | use File::Find; 10 | use File::Compare; 11 | use Log::Log4perl qw(:easy); 12 | 13 | Log::Log4perl->easy_init($DEBUG); 14 | 15 | my $perltidyrc = File::Spec->rel2abs( "adm/perltidyrc" ) ; 16 | my $lib = File::Spec->rel2abs( "lib" ); 17 | 18 | find sub { 19 | 20 | my $source = $_; 21 | my $abs_source = File::Spec->rel2abs( $source ); 22 | my $name = $File::Find::name; 23 | my $destination = $source . ".tdy"; 24 | 25 | return if ! -f $source; 26 | return if $source !~ /\.pm$/; 27 | 28 | DEBUG "pogotidy: $name"; 29 | 30 | # syntax check 31 | my $rc = system "$^X -I$lib -c $abs_source"; 32 | 33 | LOGDIE "Syntax check failed on $source" if $rc != 0; 34 | 35 | Perl::Tidy::perltidy( 36 | source => $source, 37 | destination => $destination, 38 | perltidyrc => $perltidyrc, 39 | ); 40 | 41 | if( compare( $source, $destination ) == 0) { 42 | # no change 43 | unlink $destination; 44 | return; 45 | } 46 | 47 | DEBUG "Fixed up $name"; 48 | mv $destination, $source; 49 | 50 | }, "lib"; 51 | 52 | # perltidy -pro=adm/perltidyrc lib/Pogo/Dispatcher.pm 53 | -------------------------------------------------------------------------------- /adm/readme-upd: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl -w 2 | use strict; 3 | use Sysadm::Install qw(:all); 4 | 5 | my $readme_pod = "README.pod"; 6 | my $readme = "README"; 7 | 8 | my $main_pod = slurp "lib/Pogo.pm"; 9 | my $pogo_one_pod = slurp "bin/pogo-one"; 10 | my $pogo_schedule_pod = slurp "bin/pogo-schedule"; 11 | 12 | $main_pod =~ s/=other.*//s; 13 | $main_pod =~ s/.*?(?==head)//s; 14 | 15 | $pogo_one_pod =~ s/.*?(?==head)//s; 16 | $pogo_one_pod =~ s/=head1 LICENSE.*//sg; 17 | $pogo_schedule_pod =~ s/.*?(?==head)//s; 18 | 19 | my $total_pod = 20 | $main_pod . 21 | $pogo_one_pod . 22 | $pogo_schedule_pod . 23 | "" ; 24 | 25 | blurt $total_pod, $readme_pod; 26 | tap "pod2text", $readme_pod, $readme; 27 | -------------------------------------------------------------------------------- /adm/release: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # Available at http://perlmeister.com/scripts 3 | use ModDevUtils; 4 | use Test::Harness; 5 | 6 | ModDevUtils::release() or exit 0; 7 | -------------------------------------------------------------------------------- /adm/template: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | 5 | use Getopt::Std; 6 | use Pod::Usage; 7 | 8 | getopts("h", \my %opts); 9 | 10 | pod2usage() if $opts{h}; 11 | 12 | __END__ 13 | 14 | =head1 NAME 15 | 16 | pogo-xxx - Pogo XXX script 17 | 18 | =head1 DESCRIPTION 19 | 20 | Does this and that. 21 | 22 | =head1 LICENSE 23 | 24 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 25 | 26 | Licensed under the Apache License, Version 2.0 (the "License"); 27 | you may not use this file except in compliance with the License. 28 | You may obtain a copy of the License at 29 | 30 | http://www.apache.org/licenses/LICENSE-2.0 31 | 32 | Unless required by applicable law or agreed to in writing, software 33 | distributed under the License is distributed on an "AS IS" BASIS, 34 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 35 | See the License for the specific language governing permissions and 36 | imitations under the License. 37 | 38 | =head1 AUTHORS 39 | 40 | Mike Schilli 41 | Ian Bettinger 42 | 43 | Many thanks to the following folks for implementing the 44 | original version of Pogo: 45 | 46 | Andrew Sloane , 47 | Michael Fischer , 48 | Nicholas Harteau , 49 | Nick Purvis , 50 | Robert Phan , 51 | Srini Singanallur , 52 | Yogesh Natarajan 53 | 54 | -------------------------------------------------------------------------------- /bin/plack-test: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl -w 2 | use strict; 3 | use Pogo::Plack::Handler::AnyEvent::HTTPD; 4 | use AnyEvent::HTTP; 5 | 6 | my $port = 9090; 7 | my $server = Plack::Handler::AnyEvent::HTTPD->new( 8 | port => $port, 9 | ); 10 | 11 | $server->register_service( appref() ); 12 | 13 | my $main = AnyEvent->condvar(); 14 | 15 | # main loop 16 | $main->recv(); 17 | 18 | sub appref { 19 | return sub { 20 | my( $env ) = @_; 21 | 22 | my $cv = AnyEvent->condvar(); 23 | 24 | http_get "http://google.com", sub { 25 | my( $body, $hdr ) = @_; 26 | 27 | $cv->send( $body ); 28 | }; 29 | 30 | return ['200', [ content => 'text/html' ], [ $cv->recv() ]]; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /bin/pogo-api: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | 5 | use Getopt::Long; 6 | use Pod::Usage; 7 | use Pogo::API; 8 | use Log::Log4perl qw(:easy); 9 | 10 | my $cmdline_opts = {}; 11 | 12 | GetOptions( $cmdline_opts, 13 | 'verbose|v', 14 | 'host=s', 15 | 'port|p=i', ); 16 | 17 | my @l4p = ( category => "main", level => $INFO ); 18 | 19 | if ( $cmdline_opts->{ verbose } ) { 20 | @l4p = ( level => $DEBUG ); 21 | } 22 | 23 | Log::Log4perl->easy_init({ @l4p, layout => "%F{1}-%L> %m%n" }); 24 | 25 | my $api_server = Pogo::API->new( { host => "0.0.0.0", %$cmdline_opts } ); 26 | $api_server->standalone(); 27 | 28 | INFO "Listening on ", $api_server->host(), ":", $api_server->port(); 29 | 30 | # start event loop 31 | AnyEvent->condvar->recv(); 32 | 33 | __END__ 34 | 35 | =head1 NAME 36 | 37 | pogo-api - Pogo standalone API 38 | 39 | =head1 SYNOPSIS 40 | 41 | pogo-api [options] 42 | 43 | Options: 44 | --host specify address to listen on (defaults to 127.0.0.1) 45 | --port, -p specify port to listen on (defaults to 7657) 46 | --verbose, -v 47 | 48 | =head1 DESCRIPTION 49 | 50 | See Pogo::API and Pogo::API::* version modules. 51 | 52 | =head1 LICENSE 53 | 54 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 55 | 56 | Licensed under the Apache License, Version 2.0 (the "License"); 57 | you may not use this file except in compliance with the License. 58 | You may obtain a copy of the License at 59 | 60 | http://www.apache.org/licenses/LICENSE-2.0 61 | 62 | Unless required by applicable law or agreed to in writing, software 63 | distributed under the License is distributed on an "AS IS" BASIS, 64 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 65 | See the License for the specific language governing permissions and 66 | imitations under the License. 67 | 68 | =head1 AUTHORS 69 | 70 | Mike Schilli 71 | Ian Bettinger 72 | 73 | Many thanks to the following folks for implementing the 74 | original version of Pogo: 75 | 76 | Andrew Sloane , 77 | Michael Fischer , 78 | Nicholas Harteau , 79 | Nick Purvis , 80 | Robert Phan , 81 | Srini Singanallur , 82 | Yogesh Natarajan 83 | 84 | -------------------------------------------------------------------------------- /bin/pogo-client: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | 5 | #use 5.008; 6 | use common::sense; 7 | 8 | use Log::Log4perl qw(:easy); 9 | use Pogo::Client::Commandline; 10 | 11 | Log::Log4perl::init( 12 | { 'log4perl.category.Pogo' => 'INFO, Client', 13 | 'log4perl.appender.Client' => 'Log::Log4perl::Appender::Screen', 14 | 'log4perl.appender.Client.stderr' => 1, 15 | 'log4perl.appender.Client.layout' => 'Log::Log4perl::Layout::PatternLayout', 16 | 'log4perl.appender.Client.layout.ConversionPattern' => '%p %F{1}:%L %M{1}() %m%n', 17 | } 18 | ); 19 | 20 | my $ret; 21 | eval { $ret = Pogo::Client::Commandline->run_from_commandline(); }; 22 | if ($@) 23 | { 24 | chomp( my $err = $@ ); 25 | LOGDIE "ERROR: $err\n"; 26 | } 27 | 28 | exit $ret; 29 | 30 | 1; 31 | 32 | =head1 NAME 33 | 34 | pogo-client - Pogo Commandline Client 35 | 36 | =head1 DESCRIPTION 37 | 38 | Client for interacting with Pogo. Jobs can be submitted, altered, queried, 39 | searched for, etc. 40 | 41 | =head1 USAGE 42 | 43 | pogo-client [--api[=POGO_API]] [-c|--configfile[=ALTERNATE_CONFIG_FILE]] 44 | [--debug] [--help] COMMAND [ARGS] 45 | 46 | =head1 LICENSE 47 | 48 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 49 | 50 | Licensed under the Apache License, Version 2.0 (the "License"); 51 | you may not use this file except in compliance with the License. 52 | You may obtain a copy of the License at 53 | 54 | http://www.apache.org/licenses/LICENSE-2.0 55 | 56 | Unless required by applicable law or agreed to in writing, software 57 | distributed under the License is distributed on an "AS IS" BASIS, 58 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 59 | See the License for the specific language governing permissions and 60 | imitations under the License. 61 | 62 | =head1 AUTHORS 63 | 64 | Mike Schilli 65 | Ian Bettinger 66 | 67 | Many thanks to the following folks for implementing the 68 | original version of Pogo: 69 | 70 | Andrew Sloane , 71 | Michael Fischer , 72 | Nicholas Harteau , 73 | Nick Purvis , 74 | Robert Phan , 75 | Srini Singanallur , 76 | Yogesh Natarajan 77 | -------------------------------------------------------------------------------- /bin/pogo-dispatcher: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | 5 | use Getopt::Std; 6 | use Pod::Usage; 7 | use Pogo::Dispatcher; 8 | use Log::Log4perl qw(:easy); 9 | 10 | getopts("ahvV", \my %opts); 11 | 12 | pod2usage() if $opts{hv}; 13 | 14 | if($opts{V}) { 15 | my $version = $Pogo::Dispatcher::VERSION; 16 | die "$0 $version\n"; 17 | } 18 | 19 | if($opts{v}) { 20 | Log::Log4perl->easy_init({ level => $DEBUG, layout => "%F{1}-%L> %m%n" }); 21 | } 22 | 23 | my $dispatcher = Pogo::Dispatcher->new(); 24 | $dispatcher->start(); 25 | 26 | # API standalone server just for testing 27 | my $api_server; 28 | 29 | if( $opts{ a } ) { 30 | use Pogo::API; 31 | $api_server = Pogo::API->new(); 32 | $api_server->standalone(); 33 | } 34 | 35 | # start event loop 36 | AnyEvent->condvar->recv(); 37 | 38 | __END__ 39 | 40 | =head1 NAME 41 | 42 | pogo-dispatcher - Pogo Dispatcher Daemon 43 | 44 | =head1 DESCRIPTION 45 | 46 | See Pogo::Dispatcher. 47 | 48 | =head1 LICENSE 49 | 50 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 51 | 52 | Licensed under the Apache License, Version 2.0 (the "License"); 53 | you may not use this file except in compliance with the License. 54 | You may obtain a copy of the License at 55 | 56 | http://www.apache.org/licenses/LICENSE-2.0 57 | 58 | Unless required by applicable law or agreed to in writing, software 59 | distributed under the License is distributed on an "AS IS" BASIS, 60 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 61 | See the License for the specific language governing permissions and 62 | imitations under the License. 63 | 64 | =head1 AUTHORS 65 | 66 | Mike Schilli 67 | Ian Bettinger 68 | 69 | Many thanks to the following folks for implementing the 70 | original version of Pogo: 71 | 72 | Andrew Sloane , 73 | Michael Fischer , 74 | Nicholas Harteau , 75 | Nick Purvis , 76 | Robert Phan , 77 | Srini Singanallur , 78 | Yogesh Natarajan 79 | 80 | -------------------------------------------------------------------------------- /bin/pogo-fg: -------------------------------------------------------------------------------- 1 | 2 | perl -Ilib bin/pogo-dispatcher -v 3 | -------------------------------------------------------------------------------- /bin/pogo-pw: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | 5 | # for testing 6 | use FindBin qw( $Bin ); 7 | use lib "$Bin/../lib"; 8 | 9 | use Pogo::PasswordMonkey; 10 | use Getopt::Std; 11 | use Log::Log4perl qw(:easy); 12 | 13 | getopts "v", \my %opts; 14 | 15 | if( $opts{ v } ) { 16 | Log::Log4perl->easy_init({ 17 | level => $DEBUG, layout => "%F{1}:%L %m%n" }); 18 | } 19 | 20 | my $monkey = Pogo::PasswordMonkey->new(); 21 | $monkey->startup(); 22 | $monkey->go( @ARGV ); 23 | 24 | __END__ 25 | 26 | =head1 NAME 27 | 28 | pogo-pw - Run a command and fill in password prompts 29 | 30 | =head1 SYNOPSIS 31 | 32 | $ pogo-pw command args 33 | password=secret0 34 | CTRL-D 35 | 36 | =head1 OPTIONS 37 | 38 | =over 8 39 | 40 | =item B<-v> 41 | 42 | Be verbose. 43 | 44 | =back 45 | 46 | =head1 DESCRIPTION 47 | 48 | C runs pogo commands and fills in password prompts automatically. 49 | It uses the PasswordMonkey CPAN module for the actual work. 50 | 51 | It expects passwords and other parameters on stdin, as C 52 | lines. 53 | 54 | To figure out which PasswordMonkey fillers to use, it dynamically finds 55 | installed PasswordMonkey::Filler plugins at startup in 56 | the C install directory. 57 | 58 | =head1 AUTHOR 59 | 60 | Mike Schilli 61 | Ian Bettinger 62 | 63 | Many thanks to the following folks for implementing the 64 | original version of Pogo: 65 | 66 | Andrew Sloane , 67 | Michael Fischer , 68 | Nicholas Harteau , 69 | Nick Purvis , 70 | Robert Phan , 71 | Srini Singanallur , 72 | Yogesh Natarajan 73 | 74 | =head1 LICENSE 75 | 76 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 77 | 78 | Licensed under the Apache License, Version 2.0 (the "License"); 79 | you may not use this file except in compliance with the License. 80 | You may obtain a copy of the License at 81 | 82 | http://www.apache.org/licenses/LICENSE-2.0 83 | 84 | Unless required by applicable law or agreed to in writing, software 85 | distributed under the License is distributed on an "AS IS" BASIS, 86 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 87 | See the License for the specific language governing permissions and 88 | imitations under the License. 89 | 90 | -------------------------------------------------------------------------------- /bin/pogo-test-ls-sim: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use strict; 3 | use warnings; 4 | 5 | print "foo\nbar\n"; 6 | 7 | __END__ 8 | 9 | =head1 NAME 10 | 11 | pogo-test-ls-sim - Simulate running an 'ls' command (for testing) 12 | 13 | =head1 SYNOPSIS 14 | 15 | $ pogo-test-ls-sim 16 | 17 | =head1 DESCRIPTION 18 | 19 | C is a test tool to simulate a 'ls' command. 20 | 21 | =head1 AUTHOR 22 | 23 | Mike Schilli 24 | Ian Bettinger 25 | 26 | Many thanks to the following folks for implementing the 27 | original version of Pogo: 28 | 29 | Andrew Sloane , 30 | Michael Fischer , 31 | Nicholas Harteau , 32 | Nick Purvis , 33 | Robert Phan , 34 | Srini Singanallur , 35 | Yogesh Natarajan 36 | 37 | =head1 LICENSE 38 | 39 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 40 | 41 | Licensed under the Apache License, Version 2.0 (the "License"); 42 | you may not use this file except in compliance with the License. 43 | You may obtain a copy of the License at 44 | 45 | http://www.apache.org/licenses/LICENSE-2.0 46 | 47 | Unless required by applicable law or agreed to in writing, software 48 | distributed under the License is distributed on an "AS IS" BASIS, 49 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 50 | See the License for the specific language governing permissions and 51 | imitations under the License. 52 | 53 | -------------------------------------------------------------------------------- /bin/pogo-worker: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | 5 | use Getopt::Std; 6 | use Pod::Usage; 7 | use Pogo::Worker; 8 | use Log::Log4perl qw(:easy); 9 | 10 | getopts("hv", \my %opts); 11 | 12 | if($opts{v}) { 13 | Log::Log4perl->easy_init({ level => $DEBUG, layout => "%F{1}-%L %m%n" }); 14 | } 15 | 16 | pod2usage() if $opts{h}; 17 | 18 | my $pw = Pogo::Worker->new(); 19 | $pw->start(); 20 | 21 | # start event loop 22 | AnyEvent->condvar->recv(); 23 | 24 | __END__ 25 | 26 | =head1 NAME 27 | 28 | pogo-worker - Pogo Worker Daemon 29 | 30 | =head1 DESCRIPTION 31 | 32 | See Pogo::Worker. 33 | 34 | =head1 LICENSE 35 | 36 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 37 | 38 | Licensed under the Apache License, Version 2.0 (the "License"); 39 | you may not use this file except in compliance with the License. 40 | You may obtain a copy of the License at 41 | 42 | http://www.apache.org/licenses/LICENSE-2.0 43 | 44 | Unless required by applicable law or agreed to in writing, software 45 | distributed under the License is distributed on an "AS IS" BASIS, 46 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 47 | See the License for the specific language governing permissions and 48 | imitations under the License. 49 | 50 | =head1 AUTHORS 51 | 52 | Mike Schilli 53 | Ian Bettinger 54 | 55 | Many thanks to the following folks for implementing the 56 | original version of Pogo: 57 | 58 | Andrew Sloane , 59 | Michael Fischer , 60 | Nicholas Harteau , 61 | Nick Purvis , 62 | Robert Phan , 63 | Srini Singanallur , 64 | Yogesh Natarajan 65 | 66 | -------------------------------------------------------------------------------- /docs/legacy-zk.pod: -------------------------------------------------------------------------------- 1 | 2 | =head2 ZooKeeper Legacy implementation: 3 | 4 | Namespace-level appgroup and constraints definitions in a yaml configuration 5 | file: 6 | 7 | .yml 8 | 9 | appgroups: 10 | - : 11 | - host1 12 | - host2 13 | sequences: 14 | : 15 | - [ foo, bar, baz ] 16 | constraints: 17 | : 18 | : 15% 19 | 20 | Gets transformed into the following ZooKeeper layout: 21 | 22 | /pogo/ns/ 23 | |- env 24 | |- 25 | |- _ 26 | |- _ 27 | |- 28 | |- _ 29 | |- _ 30 | |- conf/sequences 31 | |- pred 32 | |- : 33 | |- foo: bar 34 | |- bar: baz 35 | |- succ 36 | |- : 37 | |- baz: bar 38 | |- bar: foo 39 | 40 | /pogo/job/: 41 | |- host 42 | |- : 43 | |- _info: () 44 | |- : 45 | |- _info: () 46 | |- : 47 | |- _info: () 48 | |- : 49 | |- _info: () 50 | |- slot 51 | |- 52 | |- 53 | |- 54 | |- 55 | |- 56 | |- 57 | 58 | Where C consists of 59 | C<"EappgroupE_Eenv_name_Eenv_valueE">. 60 | -------------------------------------------------------------------------------- /docs/pogo-psgi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ytoolshed/pogo/edf5f8abfac1bad4044c6f68bcd93efcf477befc/docs/pogo-psgi.jpg -------------------------------------------------------------------------------- /inc/Module/Install/Base.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::Base; 3 | 4 | use strict 'vars'; 5 | use vars qw{$VERSION}; 6 | BEGIN { 7 | $VERSION = '1.00'; 8 | } 9 | 10 | # Suspend handler for "redefined" warnings 11 | BEGIN { 12 | my $w = $SIG{__WARN__}; 13 | $SIG{__WARN__} = sub { $w }; 14 | } 15 | 16 | #line 42 17 | 18 | sub new { 19 | my $class = shift; 20 | unless ( defined &{"${class}::call"} ) { 21 | *{"${class}::call"} = sub { shift->_top->call(@_) }; 22 | } 23 | unless ( defined &{"${class}::load"} ) { 24 | *{"${class}::load"} = sub { shift->_top->load(@_) }; 25 | } 26 | bless { @_ }, $class; 27 | } 28 | 29 | #line 61 30 | 31 | sub AUTOLOAD { 32 | local $@; 33 | my $func = eval { shift->_top->autoload } or return; 34 | goto &$func; 35 | } 36 | 37 | #line 75 38 | 39 | sub _top { 40 | $_[0]->{_top}; 41 | } 42 | 43 | #line 90 44 | 45 | sub admin { 46 | $_[0]->_top->{admin} 47 | or 48 | Module::Install::Base::FakeAdmin->new; 49 | } 50 | 51 | #line 106 52 | 53 | sub is_admin { 54 | ! $_[0]->admin->isa('Module::Install::Base::FakeAdmin'); 55 | } 56 | 57 | sub DESTROY {} 58 | 59 | package Module::Install::Base::FakeAdmin; 60 | 61 | use vars qw{$VERSION}; 62 | BEGIN { 63 | $VERSION = $Module::Install::Base::VERSION; 64 | } 65 | 66 | my $fake; 67 | 68 | sub new { 69 | $fake ||= bless(\@_, $_[0]); 70 | } 71 | 72 | sub AUTOLOAD {} 73 | 74 | sub DESTROY {} 75 | 76 | # Restore warning handler 77 | BEGIN { 78 | $SIG{__WARN__} = $SIG{__WARN__}->(); 79 | } 80 | 81 | 1; 82 | 83 | #line 159 84 | -------------------------------------------------------------------------------- /inc/Module/Install/Can.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::Can; 3 | 4 | use strict; 5 | use Config (); 6 | use File::Spec (); 7 | use ExtUtils::MakeMaker (); 8 | use Module::Install::Base (); 9 | 10 | use vars qw{$VERSION @ISA $ISCORE}; 11 | BEGIN { 12 | $VERSION = '1.00'; 13 | @ISA = 'Module::Install::Base'; 14 | $ISCORE = 1; 15 | } 16 | 17 | # check if we can load some module 18 | ### Upgrade this to not have to load the module if possible 19 | sub can_use { 20 | my ($self, $mod, $ver) = @_; 21 | $mod =~ s{::|\\}{/}g; 22 | $mod .= '.pm' unless $mod =~ /\.pm$/i; 23 | 24 | my $pkg = $mod; 25 | $pkg =~ s{/}{::}g; 26 | $pkg =~ s{\.pm$}{}i; 27 | 28 | local $@; 29 | eval { require $mod; $pkg->VERSION($ver || 0); 1 }; 30 | } 31 | 32 | # check if we can run some command 33 | sub can_run { 34 | my ($self, $cmd) = @_; 35 | 36 | my $_cmd = $cmd; 37 | return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd)); 38 | 39 | for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { 40 | next if $dir eq ''; 41 | my $abs = File::Spec->catfile($dir, $_[1]); 42 | return $abs if (-x $abs or $abs = MM->maybe_command($abs)); 43 | } 44 | 45 | return; 46 | } 47 | 48 | # can we locate a (the) C compiler 49 | sub can_cc { 50 | my $self = shift; 51 | my @chunks = split(/ /, $Config::Config{cc}) or return; 52 | 53 | # $Config{cc} may contain args; try to find out the program part 54 | while (@chunks) { 55 | return $self->can_run("@chunks") || (pop(@chunks), next); 56 | } 57 | 58 | return; 59 | } 60 | 61 | # Fix Cygwin bug on maybe_command(); 62 | if ( $^O eq 'cygwin' ) { 63 | require ExtUtils::MM_Cygwin; 64 | require ExtUtils::MM_Win32; 65 | if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { 66 | *ExtUtils::MM_Cygwin::maybe_command = sub { 67 | my ($self, $file) = @_; 68 | if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { 69 | ExtUtils::MM_Win32->maybe_command($file); 70 | } else { 71 | ExtUtils::MM_Unix->maybe_command($file); 72 | } 73 | } 74 | } 75 | } 76 | 77 | 1; 78 | 79 | __END__ 80 | 81 | #line 156 82 | -------------------------------------------------------------------------------- /inc/Module/Install/Fetch.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::Fetch; 3 | 4 | use strict; 5 | use Module::Install::Base (); 6 | 7 | use vars qw{$VERSION @ISA $ISCORE}; 8 | BEGIN { 9 | $VERSION = '1.00'; 10 | @ISA = 'Module::Install::Base'; 11 | $ISCORE = 1; 12 | } 13 | 14 | sub get_file { 15 | my ($self, %args) = @_; 16 | my ($scheme, $host, $path, $file) = 17 | $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; 18 | 19 | if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) { 20 | $args{url} = $args{ftp_url} 21 | or (warn("LWP support unavailable!\n"), return); 22 | ($scheme, $host, $path, $file) = 23 | $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return; 24 | } 25 | 26 | $|++; 27 | print "Fetching '$file' from $host... "; 28 | 29 | unless (eval { require Socket; Socket::inet_aton($host) }) { 30 | warn "'$host' resolve failed!\n"; 31 | return; 32 | } 33 | 34 | return unless $scheme eq 'ftp' or $scheme eq 'http'; 35 | 36 | require Cwd; 37 | my $dir = Cwd::getcwd(); 38 | chdir $args{local_dir} or return if exists $args{local_dir}; 39 | 40 | if (eval { require LWP::Simple; 1 }) { 41 | LWP::Simple::mirror($args{url}, $file); 42 | } 43 | elsif (eval { require Net::FTP; 1 }) { eval { 44 | # use Net::FTP to get past firewall 45 | my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600); 46 | $ftp->login("anonymous", 'anonymous@example.com'); 47 | $ftp->cwd($path); 48 | $ftp->binary; 49 | $ftp->get($file) or (warn("$!\n"), return); 50 | $ftp->quit; 51 | } } 52 | elsif (my $ftp = $self->can_run('ftp')) { eval { 53 | # no Net::FTP, fallback to ftp.exe 54 | require FileHandle; 55 | my $fh = FileHandle->new; 56 | 57 | local $SIG{CHLD} = 'IGNORE'; 58 | unless ($fh->open("|$ftp -n")) { 59 | warn "Couldn't open ftp: $!\n"; 60 | chdir $dir; return; 61 | } 62 | 63 | my @dialog = split(/\n/, <<"END_FTP"); 64 | open $host 65 | user anonymous anonymous\@example.com 66 | cd $path 67 | binary 68 | get $file $file 69 | quit 70 | END_FTP 71 | foreach (@dialog) { $fh->print("$_\n") } 72 | $fh->close; 73 | } } 74 | else { 75 | warn "No working 'ftp' program available!\n"; 76 | chdir $dir; return; 77 | } 78 | 79 | unless (-f $file) { 80 | warn "Fetching failed: $@\n"; 81 | chdir $dir; return; 82 | } 83 | 84 | return if exists $args{size} and -s $file != $args{size}; 85 | system($args{run}) if exists $args{run}; 86 | unlink($file) if $args{remove}; 87 | 88 | print(((!exists $args{check_for} or -e $args{check_for}) 89 | ? "done!" : "failed! ($!)"), "\n"); 90 | chdir $dir; return !$?; 91 | } 92 | 93 | 1; 94 | -------------------------------------------------------------------------------- /inc/Module/Install/Win32.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::Win32; 3 | 4 | use strict; 5 | use Module::Install::Base (); 6 | 7 | use vars qw{$VERSION @ISA $ISCORE}; 8 | BEGIN { 9 | $VERSION = '1.00'; 10 | @ISA = 'Module::Install::Base'; 11 | $ISCORE = 1; 12 | } 13 | 14 | # determine if the user needs nmake, and download it if needed 15 | sub check_nmake { 16 | my $self = shift; 17 | $self->load('can_run'); 18 | $self->load('get_file'); 19 | 20 | require Config; 21 | return unless ( 22 | $^O eq 'MSWin32' and 23 | $Config::Config{make} and 24 | $Config::Config{make} =~ /^nmake\b/i and 25 | ! $self->can_run('nmake') 26 | ); 27 | 28 | print "The required 'nmake' executable not found, fetching it...\n"; 29 | 30 | require File::Basename; 31 | my $rv = $self->get_file( 32 | url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe', 33 | ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe', 34 | local_dir => File::Basename::dirname($^X), 35 | size => 51928, 36 | run => 'Nmake15.exe /o > nul', 37 | check_for => 'Nmake.exe', 38 | remove => 1, 39 | ); 40 | 41 | die <<'END_MESSAGE' unless $rv; 42 | 43 | ------------------------------------------------------------------------------- 44 | 45 | Since you are using Microsoft Windows, you will need the 'nmake' utility 46 | before installation. It's available at: 47 | 48 | http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe 49 | or 50 | ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe 51 | 52 | Please download the file manually, save it to a directory in %PATH% (e.g. 53 | C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to 54 | that directory, and run "Nmake15.exe" from there; that will create the 55 | 'nmake.exe' file needed by this module. 56 | 57 | You may then resume the installation process described in README. 58 | 59 | ------------------------------------------------------------------------------- 60 | END_MESSAGE 61 | 62 | } 63 | 64 | 1; 65 | -------------------------------------------------------------------------------- /inc/Module/Install/WriteAll.pm: -------------------------------------------------------------------------------- 1 | #line 1 2 | package Module::Install::WriteAll; 3 | 4 | use strict; 5 | use Module::Install::Base (); 6 | 7 | use vars qw{$VERSION @ISA $ISCORE}; 8 | BEGIN { 9 | $VERSION = '1.00'; 10 | @ISA = qw{Module::Install::Base}; 11 | $ISCORE = 1; 12 | } 13 | 14 | sub WriteAll { 15 | my $self = shift; 16 | my %args = ( 17 | meta => 1, 18 | sign => 0, 19 | inline => 0, 20 | check_nmake => 1, 21 | @_, 22 | ); 23 | 24 | $self->sign(1) if $args{sign}; 25 | $self->admin->WriteAll(%args) if $self->is_admin; 26 | 27 | $self->check_nmake if $args{check_nmake}; 28 | unless ( $self->makemaker_args->{PL_FILES} ) { 29 | # XXX: This still may be a bit over-defensive... 30 | unless ($self->makemaker(6.25)) { 31 | $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL'; 32 | } 33 | } 34 | 35 | # Until ExtUtils::MakeMaker support MYMETA.yml, make sure 36 | # we clean it up properly ourself. 37 | $self->realclean_files('MYMETA.yml'); 38 | 39 | if ( $args{inline} ) { 40 | $self->Inline->write; 41 | } else { 42 | $self->Makefile->write; 43 | } 44 | 45 | # The Makefile write process adds a couple of dependencies, 46 | # so write the META.yml files after the Makefile. 47 | if ( $args{meta} ) { 48 | $self->Meta->write; 49 | } 50 | 51 | # Experimental support for MYMETA 52 | if ( $ENV{X_MYMETA} ) { 53 | if ( $ENV{X_MYMETA} eq 'JSON' ) { 54 | $self->Meta->write_mymeta_json; 55 | } else { 56 | $self->Meta->write_mymeta_yaml; 57 | } 58 | } 59 | 60 | return 1; 61 | } 62 | 63 | 1; 64 | -------------------------------------------------------------------------------- /lib/PasswordMonkey/Filler/PogoGPG.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package PasswordMonkey::Filler::PogoGPG; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | 7 | use base qw(PasswordMonkey::Filler); 8 | 9 | ########################################### 10 | sub init { 11 | ########################################### 12 | my($self) = @_; 13 | 14 | $self->{password} = "yes"; 15 | } 16 | 17 | ########################################### 18 | sub pre_filler { 19 | ########################################### 20 | my($self) = @_; 21 | 22 | $self->expect->send_user(" (supplied by pogo-pw)"); 23 | } 24 | 25 | ########################################### 26 | sub prompt { 27 | ########################################### 28 | return qr{key fingerprint is [a-zA-Z0-9:]+\.[\r\n]+Are you sure you want to continue connecting \(yes/no\)\?\s*}; 29 | } 30 | 31 | 1; 32 | 33 | __END__ 34 | 35 | =head1 NAME 36 | 37 | PasswordMonkey::Filler::PogoGPG - PogoGPG 'yes' sayer 38 | 39 | =head1 SYNOPSIS 40 | 41 | use PasswordMonkey::Filler::PogoGPG; 42 | 43 | =head1 DESCRIPTION 44 | 45 | Responds with 'yes' on 46 | 47 | "key fingerprint is ... Are you sure you want to continue 48 | connecting (yes/no)?" 49 | 50 | =head1 AUTHOR 51 | 52 | Mike Schilli 53 | Ian Bettinger 54 | 55 | Many thanks to the following folks for implementing the 56 | original version of Pogo: 57 | 58 | Andrew Sloane , 59 | Michael Fischer , 60 | Nicholas Harteau , 61 | Nick Purvis , 62 | Robert Phan , 63 | Srini Singanallur , 64 | Yogesh Natarajan 65 | 66 | =head1 LICENSE 67 | 68 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 69 | 70 | Licensed under the Apache License, Version 2.0 (the "License"); 71 | you may not use this file except in compliance with the License. 72 | You may obtain a copy of the License at 73 | 74 | http://www.apache.org/licenses/LICENSE-2.0 75 | 76 | Unless required by applicable law or agreed to in writing, software 77 | distributed under the License is distributed on an "AS IS" BASIS, 78 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 79 | See the License for the specific language governing permissions and 80 | imitations under the License. 81 | -------------------------------------------------------------------------------- /lib/PasswordMonkey/Filler/PogoPassphrase.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package PasswordMonkey::Filler::PogoPassphrase; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | our $VERSION = 0.01; 7 | 8 | use base qw(PasswordMonkey::Filler); 9 | 10 | ########################################### 11 | sub init { 12 | ########################################### 13 | my($self) = @_; 14 | 15 | $self->dealbreakers([ 16 | ["Bad passphrase, try again:" => 255], 17 | ]); 18 | } 19 | 20 | ########################################### 21 | sub pre_filler { 22 | ########################################### 23 | my($self) = @_; 24 | 25 | $self->expect->send_user(" (supplied by pogo-pw)"); 26 | } 27 | 28 | ########################################### 29 | sub prompt { 30 | ########################################### 31 | return qr(Enter passphrase for .+:\s*); 32 | } 33 | 34 | 1; 35 | 36 | __END__ 37 | 38 | =head1 NAME 39 | 40 | PassphraseMonkey::Filler::PogoPassphrase - Pogo password provider 41 | 42 | =head1 SYNOPSIS 43 | 44 | use PasswordMonkey::Filler::PogoPassphrase; 45 | 46 | =head1 DESCRIPTION 47 | 48 | Just sends the password when prompted with "Enter passphrase for .+:"; 49 | 50 | This bundle also contains PasswordMonkey::Filler::YinstPkgPassphrase and 51 | PasswordMonkey::Filler::PogoGPG. 52 | 53 | =head1 AUTHOR 54 | 55 | Mike Schilli 56 | Ian Bettinger 57 | 58 | Many thanks to the following folks for implementing the 59 | original version of Pogo: 60 | 61 | Andrew Sloane , 62 | Michael Fischer , 63 | Nicholas Harteau , 64 | Nick Purvis , 65 | Robert Phan , 66 | Srini Singanallur , 67 | Yogesh Natarajan 68 | 69 | =head1 LICENSE 70 | 71 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 72 | 73 | Licensed under the Apache License, Version 2.0 (the "License"); 74 | you may not use this file except in compliance with the License. 75 | You may obtain a copy of the License at 76 | 77 | http://www.apache.org/licenses/LICENSE-2.0 78 | 79 | Unless required by applicable law or agreed to in writing, software 80 | distributed under the License is distributed on an "AS IS" BASIS, 81 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 82 | See the License for the specific language governing permissions and 83 | imitations under the License. 84 | -------------------------------------------------------------------------------- /lib/PasswordMonkey/Filler/PogoPassword.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package PasswordMonkey::Filler::PogoPassword; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | our $VERSION = 0.01; 7 | 8 | use base qw(PasswordMonkey::Filler); 9 | 10 | ########################################### 11 | sub init { 12 | ########################################### 13 | my($self) = @_; 14 | 15 | $self->dealbreakers([ 16 | ["Sorry, try again." => 255], 17 | ["Mismatch; try again, EOF to quit." => 255], 18 | ["New password:" => 255], 19 | ["Retype new password:" => 255], 20 | ["Permission denied, please try again." => 255], 21 | ]); 22 | } 23 | 24 | ########################################### 25 | sub pre_filler { 26 | ########################################### 27 | my($self) = @_; 28 | 29 | $self->expect->send_user(" (supplied by pogo-pw)"); 30 | } 31 | 32 | ########################################### 33 | sub prompt { 34 | ########################################### 35 | return qr((\[sudo\] password for [\w_]+|assword):\s*); 36 | } 37 | 38 | 1; 39 | 40 | __END__ 41 | 42 | =head1 NAME 43 | 44 | PasswordMonkey::Filler::PogoPassword - Pogo password provider 45 | 46 | =head1 SYNOPSIS 47 | 48 | use PasswordMonkey::Filler::PogoPassword; 49 | 50 | =head1 DESCRIPTION 51 | 52 | Just sends the password when prompted with "assword:" or a sudo prompt. 53 | 54 | This bundle also contains PasswordMonkey::Filler::YinstPkgPassphrase and 55 | PasswordMonkey::Filler::PogoGPG. 56 | 57 | =head1 AUTHOR 58 | 59 | Mike Schilli 60 | Ian Bettinger 61 | 62 | Many thanks to the following folks for implementing the 63 | original version of Pogo: 64 | 65 | Andrew Sloane , 66 | Michael Fischer , 67 | Nicholas Harteau , 68 | Nick Purvis , 69 | Robert Phan , 70 | Srini Singanallur , 71 | Yogesh Natarajan 72 | 73 | =head1 LICENSE 74 | 75 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 76 | 77 | Licensed under the Apache License, Version 2.0 (the "License"); 78 | you may not use this file except in compliance with the License. 79 | You may obtain a copy of the License at 80 | 81 | http://www.apache.org/licenses/LICENSE-2.0 82 | 83 | Unless required by applicable law or agreed to in writing, software 84 | distributed under the License is distributed on an "AS IS" BASIS, 85 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 86 | See the License for the specific language governing permissions and 87 | imitations under the License. 88 | -------------------------------------------------------------------------------- /lib/Pogo/API/Status.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::API::Status; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | use Log::Log4perl qw(:easy); 7 | use AnyEvent; 8 | use AnyEvent::Strict; 9 | use JSON qw( to_json ); 10 | use Pogo; 11 | use Pogo::Util qw( http_response_json ); 12 | 13 | ########################################### 14 | sub app { 15 | ########################################### 16 | my ( $class, $dispatcher ) = @_; 17 | 18 | return sub { 19 | my ( $env ) = @_; 20 | 21 | return http_response_json( { pogo_version => $Pogo::VERSION, } ); 22 | }; 23 | } 24 | 25 | 1; 26 | 27 | __END__ 28 | 29 | =head1 NAME 30 | 31 | Pogo::API::Status - Pogo API Status handler 32 | 33 | =head1 SYNOPSIS 34 | 35 | =head1 DESCRIPTION 36 | 37 | Handles /status and reports Pogo version and dispatcher/worker metrics. 38 | 39 | =head1 LICENSE 40 | 41 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 42 | 43 | Licensed under the Apache License, Version 2.0 (the "License"); 44 | you may not use this file except in compliance with the License. 45 | You may obtain a copy of the License at 46 | 47 | http://www.apache.org/licenses/LICENSE-2.0 48 | 49 | Unless required by applicable law or agreed to in writing, software 50 | distributed under the License is distributed on an "AS IS" BASIS, 51 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 52 | See the License for the specific language governing permissions and 53 | imitations under the License. 54 | 55 | =head1 AUTHORS 56 | 57 | Mike Schilli 58 | Ian Bettinger 59 | 60 | Many thanks to the following folks for implementing the 61 | original version of Pogo: 62 | 63 | Andrew Sloane , 64 | Michael Fischer , 65 | Nicholas Harteau , 66 | Nick Purvis , 67 | Robert Phan , 68 | Srini Singanallur , 69 | Yogesh Natarajan 70 | 71 | -------------------------------------------------------------------------------- /lib/Pogo/AnyEvent/HTTP.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::AnyEvent::HTTP; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | 7 | use AnyEvent::HTTP (); 8 | use Sysadm::Install qw( slurp ); 9 | use File::Basename; 10 | 11 | ########################################### 12 | sub http_any { 13 | ########################################### 14 | my ( $method, $url, @args ) = @_; 15 | 16 | my $cb = pop @args; 17 | 18 | if ( my $data = file_url_read( $url ) ) { 19 | my $hdr = { Status => "200" }; 20 | return $cb->( $data, $hdr ); 21 | } 22 | 23 | my $ae_method = "AnyEvent::HTTP::http_$method"; 24 | 25 | no strict 'refs'; 26 | $ae_method->( $url, @args, $cb ); 27 | } 28 | 29 | ########################################### 30 | sub http_get { 31 | ########################################### 32 | my ( @args ) = @_; 33 | 34 | return http_any( "get", @args ); 35 | } 36 | 37 | ########################################### 38 | sub http_post { 39 | ########################################### 40 | my ( @args ) = @_; 41 | 42 | return http_any( "post", @args ); 43 | } 44 | 45 | ########################################### 46 | sub file_url { 47 | ########################################### 48 | my ( $url ) = @_; 49 | 50 | if ( $url =~ m#^file://(.*)# ) { 51 | return $1; 52 | } 53 | 54 | return undef; 55 | } 56 | 57 | ########################################### 58 | sub file_url_read { 59 | ########################################### 60 | my ( $url ) = @_; 61 | 62 | my $file = file_url( $url ); 63 | 64 | if ( !defined $file ) { 65 | return undef; 66 | } 67 | 68 | while ( !-f $file ) { 69 | $file = dirname $file; 70 | } 71 | 72 | if ( -f $file ) { 73 | return slurp $file; 74 | } 75 | 76 | return undef; 77 | } 78 | 79 | 1; 80 | 81 | __END__ 82 | 83 | =head1 NAME 84 | 85 | Pogo::AnyEvent::HTTP 86 | 87 | =head1 SYNOPSIS 88 | 89 | use Pogo::AnyEvent::HTTP; 90 | 91 | Pogo::AnyEvent::http_get( $url, sub { 92 | my( $data, $hdr ) = @_; 93 | } ); 94 | 95 | =head1 DESCRIPTION 96 | 97 | Pogo::AnyEvent::HTTP extends AnyEvent::HTTP to support file:// URLs for 98 | testing. 99 | 100 | =head1 AUTHOR 101 | 102 | 2012, Mike Schilli 103 | -------------------------------------------------------------------------------- /lib/Pogo/Client/Auth.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::Client::Auth; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | use Log::Log4perl qw( :easy ); 7 | use POSIX qw( ttyname ); 8 | use Term::ReadKey qw( ReadMode ReadLine ); 9 | use Exporter; 10 | our @EXPORT_OK = qw( password_get ); 11 | our @ISA = qw( Exporter ); 12 | 13 | ########################################### 14 | sub password_get { 15 | ########################################### 16 | 17 | $| = 1; 18 | print "Password: "; 19 | 20 | ReadMode('noecho'); 21 | my $pw = ReadLine(0); 22 | ReadMode('normal'); 23 | print "\n"; 24 | chomp($pw); 25 | 26 | return $pw; 27 | } 28 | 29 | 1; 30 | 31 | __END__ 32 | 33 | =head1 NAME 34 | 35 | Pogo::Client::Auth - Pogo client password auth utilities 36 | 37 | =head1 SYNOPSIS 38 | 39 | use Pogo::Client::Auth qw( password_get ); 40 | 41 | =head1 DESCRIPTION 42 | 43 | Utilities for getting and checking user-supplied passwords on the 44 | Pogo client. 45 | 46 | =back 47 | 48 | =head1 LICENSE 49 | 50 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 51 | 52 | Licensed under the Apache License, Version 2.0 (the "License"); 53 | you may not use this file except in compliance with the License. 54 | You may obtain a copy of the License at 55 | 56 | http://www.apache.org/licenses/LICENSE-2.0 57 | 58 | Unless required by applicable law or agreed to in writing, software 59 | distributed under the License is distributed on an "AS IS" BASIS, 60 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 61 | See the License for the specific language governing permissions and 62 | imitations under the License. 63 | 64 | =head1 AUTHORS 65 | 66 | Mike Schilli 67 | Ian Bettinger 68 | 69 | Many thanks to the following folks for implementing the 70 | original version of Pogo: 71 | 72 | Andrew Sloane , 73 | Michael Fischer , 74 | Nicholas Harteau , 75 | Nick Purvis , 76 | Robert Phan , 77 | Srini Singanallur , 78 | Yogesh Natarajan 79 | 80 | -------------------------------------------------------------------------------- /lib/Pogo/Dispatcher/ControlPort/PSGI.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::Dispatcher::ControlPort::PSGI; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | use JSON qw(from_json to_json); 7 | use Plack::App::URLMap; 8 | use Log::Log4perl qw(:easy); 9 | 10 | ########################################### 11 | sub app { 12 | ########################################### 13 | my ( $class, $dispatcher ) = @_; 14 | 15 | my $app = Plack::App::URLMap->new; 16 | 17 | # map URLs to modules, like /status => ControlPort/Status.pm etc. 18 | for my $api ( qw( status v1 ) ) { 19 | 20 | my $module = __PACKAGE__; 21 | $module =~ s/::[^:]*$//; 22 | $module .= "::" . ucfirst( $api ); 23 | 24 | eval "require $module"; 25 | if ( $@ ) { 26 | die "Failed to load module $module ($@)"; 27 | } 28 | 29 | DEBUG "Mounting /$api to module $module"; 30 | 31 | $app->mount( "/$api" => $module->app( $dispatcher ) ); 32 | } 33 | 34 | return $app; 35 | } 36 | 37 | __END__ 38 | 39 | =head1 NAME 40 | 41 | Pogo::Dispatcher::ControlPort::PSGI - Pogo Dispatcher Internal ControlPort PSGI interface 42 | 43 | =head1 SYNOPSIS 44 | 45 | use Pogo::Dispatcher::ControlPort::PSGI; 46 | my $app = Pogo::Dispatcher::ControlPort::PSGI->app(); 47 | 48 | =head1 DESCRIPTION 49 | 50 | App handler for the Pogo dispatcher's internal ControlPort. 51 | 52 | =head1 LICENSE 53 | 54 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 55 | 56 | Licensed under the Apache License, Version 2.0 (the "License"); 57 | you may not use this file except in compliance with the License. 58 | You may obtain a copy of the License at 59 | 60 | http://www.apache.org/licenses/LICENSE-2.0 61 | 62 | Unless required by applicable law or agreed to in writing, software 63 | distributed under the License is distributed on an "AS IS" BASIS, 64 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 65 | See the License for the specific language governing permissions and 66 | imitations under the License. 67 | 68 | =head1 AUTHORS 69 | 70 | Mike Schilli 71 | Ian Bettinger 72 | 73 | Many thanks to the following folks for implementing the 74 | original version of Pogo: 75 | 76 | Andrew Sloane , 77 | Michael Fischer , 78 | Nicholas Harteau , 79 | Nick Purvis , 80 | Robert Phan , 81 | Srini Singanallur , 82 | Yogesh Natarajan 83 | 84 | -------------------------------------------------------------------------------- /lib/Pogo/Dispatcher/ControlPort/Status.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::Dispatcher::ControlPort::Status; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | use Log::Log4perl qw(:easy); 7 | use AnyEvent; 8 | use AnyEvent::Strict; 9 | use JSON qw( to_json ); 10 | use Pogo; 11 | use Pogo::Util qw( http_response_json ); 12 | 13 | ########################################### 14 | sub app { 15 | ########################################### 16 | my ( $class, $dispatcher ) = @_; 17 | 18 | return sub { 19 | my ( $env ) = @_; 20 | 21 | return http_response_json( 22 | { pogo_version => $Pogo::VERSION, 23 | workers => [ $dispatcher->{ wconn_pool }->workers_connected ], 24 | } 25 | ); 26 | }; 27 | } 28 | 29 | 1; 30 | 31 | __END__ 32 | 33 | =head1 NAME 34 | 35 | Pogo::Dispatcher::ControlPort::Status - Pogo Dispatcher PSGI ControlPort 36 | 37 | =head1 SYNOPSIS 38 | 39 | use Pogo::Dispatcher::ControlPort; 40 | 41 | my $app = Pogo::Dispatcher::ControlPort->app(); 42 | 43 | =head1 DESCRIPTION 44 | 45 | PSGI app for Pogo Dispatcher. 46 | 47 | =head1 LICENSE 48 | 49 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 50 | 51 | Licensed under the Apache License, Version 2.0 (the "License"); 52 | you may not use this file except in compliance with the License. 53 | You may obtain a copy of the License at 54 | 55 | http://www.apache.org/licenses/LICENSE-2.0 56 | 57 | Unless required by applicable law or agreed to in writing, software 58 | distributed under the License is distributed on an "AS IS" BASIS, 59 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 60 | See the License for the specific language governing permissions and 61 | imitations under the License. 62 | 63 | =head1 AUTHORS 64 | 65 | Mike Schilli 66 | Ian Bettinger 67 | 68 | Many thanks to the following folks for implementing the 69 | original version of Pogo: 70 | 71 | Andrew Sloane , 72 | Michael Fischer , 73 | Nicholas Harteau , 74 | Nick Purvis , 75 | Robert Phan , 76 | Srini Singanallur , 77 | Yogesh Natarajan 78 | 79 | -------------------------------------------------------------------------------- /lib/Pogo/Plugin/ZooKeeper/Default.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::Plugin::ZooKeeper::Default; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | use Net::ZooKeeper; 7 | use Exporter qw( import ); 8 | our @ISA = qw( Exporter Net::ZooKeeper ); 9 | our @EXPORT_OK = qw( ZOK ZINVALIDSTATE ZCONNECTIONLOSS ); 10 | 11 | ########################################### 12 | sub new { 13 | ########################################### 14 | my ( $class, %options ) = @_; 15 | 16 | my $self = { %options, }; 17 | 18 | bless $self, $class; 19 | } 20 | 21 | ########################################### 22 | sub priority { 23 | ########################################### 24 | my ( $self ) = @_; 25 | 26 | return 10; 27 | } 28 | 29 | 1; 30 | 31 | __END__ 32 | 33 | =head1 NAME 34 | 35 | Pogo::Plugin::ZooKeeper::Default - Pogo default ZooKeeper plugin 36 | 37 | =head1 SYNOPSIS 38 | 39 | use Pogo::Plugin::ZooKeeper::Default; 40 | 41 | =head1 DESCRIPTION 42 | 43 | A plugin to load to Net::ZooKeeper. 44 | 45 | =head1 LICENSE 46 | 47 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 48 | 49 | Licensed under the Apache License, Version 2.0 (the "License"); 50 | you may not use this file except in compliance with the License. 51 | You may obtain a copy of the License at 52 | 53 | http://www.apache.org/licenses/LICENSE-2.0 54 | 55 | Unless required by applicable law or agreed to in writing, software 56 | distributed under the License is distributed on an "AS IS" BASIS, 57 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 58 | See the License for the specific language governing permissions and 59 | imitations under the License. 60 | 61 | =head1 AUTHORS 62 | 63 | Mike Schilli 64 | Ian Bettinger 65 | 66 | Many thanks to the following folks for implementing the 67 | original version of Pogo: 68 | 69 | Andrew Sloane , 70 | Michael Fischer , 71 | Nicholas Harteau , 72 | Nick Purvis , 73 | Robert Phan , 74 | Srini Singanallur , 75 | Yogesh Natarajan 76 | 77 | -------------------------------------------------------------------------------- /lib/Pogo/Worker/Task.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::Worker::Task; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | use Log::Log4perl qw(:easy); 7 | use AnyEvent; 8 | use AnyEvent::Strict; 9 | use Pogo::Util qw( make_accessor required_params_check id_gen ); 10 | use base 'Object::Event'; 11 | 12 | __PACKAGE__->make_accessor( $_ ) for qw( id rc message ); 13 | 14 | ########################################### 15 | sub new { 16 | ########################################### 17 | my ( $class, %options ) = @_; 18 | 19 | my $self = { 20 | required_params_check( \%options, [ qw( rc message ) ] ), 21 | %options, 22 | }; 23 | 24 | if( !defined $self->{ id } ) { 25 | $self->{ id } = id_gen( "generic-task" ); 26 | } 27 | 28 | bless $self, $class; 29 | 30 | return $self; 31 | } 32 | 33 | ########################################### 34 | sub ran_ok { 35 | ########################################### 36 | my( $self ) = @_; 37 | 38 | if( $self->{ rc } == 0 ) { 39 | return 1; 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | 1; 46 | 47 | __END__ 48 | 49 | =head1 NAME 50 | 51 | Pogo::Worker::Task - Pogo Worker Task 52 | 53 | =head1 SYNOPSIS 54 | 55 | use Pogo::Worker::Task; 56 | 57 | my $task = Pogo::Worker::Task->new(); 58 | 59 | =head1 DESCRIPTION 60 | 61 | Pogo::Worker::Task does this and that. 62 | 63 | =head1 METHODS 64 | 65 | =over 4 66 | 67 | =item C 68 | 69 | Constructor. 70 | 71 | =back 72 | 73 | =head1 LICENSE 74 | 75 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 76 | 77 | Licensed under the Apache License, Version 2.0 (the "License"); 78 | you may not use this file except in compliance with the License. 79 | You may obtain a copy of the License at 80 | 81 | http://www.apache.org/licenses/LICENSE-2.0 82 | 83 | Unless required by applicable law or agreed to in writing, software 84 | distributed under the License is distributed on an "AS IS" BASIS, 85 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 86 | See the License for the specific language governing permissions and 87 | imitations under the License. 88 | 89 | =head1 AUTHORS 90 | 91 | Mike Schilli 92 | Ian Bettinger 93 | 94 | Many thanks to the following folks for implementing the 95 | original version of Pogo: 96 | 97 | Andrew Sloane , 98 | Michael Fischer , 99 | Nicholas Harteau , 100 | Nick Purvis , 101 | Robert Phan , 102 | Srini Singanallur , 103 | Yogesh Natarajan 104 | 105 | -------------------------------------------------------------------------------- /t/001Basic.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use FindBin qw($Bin); 5 | use lib "$Bin/../lib"; 6 | use lib "$Bin/lib"; 7 | 8 | use PogoFake; 9 | use PogoTest; 10 | use Test::More; 11 | use Log::Log4perl qw(:easy); 12 | use Getopt::Std; 13 | use Pogo::Defaults qw( 14 | $POGO_DISPATCHER_WORKERCONN_HOST 15 | $POGO_DISPATCHER_WORKERCONN_PORT 16 | ); 17 | 18 | my $pogo; 19 | 20 | $pogo = PogoFake->new(); 21 | 22 | $pogo->reg_cb( dispatcher_wconn_worker_connect => sub { 23 | my( $c, $worker ) = @_; 24 | 25 | ok( 1, "worker connected #1" ); 26 | is( $worker, $POGO_DISPATCHER_WORKERCONN_HOST, "worker host #3" ); 27 | }); 28 | 29 | $pogo->reg_cb( dispatcher_wconn_prepare => sub { 30 | my( $c, $host, $port ) = @_; 31 | 32 | DEBUG "received dispatcher_prepare"; 33 | 34 | is( "$host:$port", 35 | "$POGO_DISPATCHER_WORKERCONN_HOST:$POGO_DISPATCHER_WORKERCONN_PORT", 36 | "dispatcher server_prepare cb #2" ); 37 | }); 38 | 39 | plan tests => 3; 40 | 41 | $pogo->start(); 42 | -------------------------------------------------------------------------------- /t/002Protocol.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use FindBin qw($Bin); 5 | use lib "$Bin/../lib"; 6 | use lib "$Bin/lib"; 7 | 8 | use PogoFake; 9 | use PogoTest; 10 | use Test::More; 11 | use Getopt::Std; 12 | use Log::Log4perl qw(:easy); 13 | 14 | my $pogo; 15 | 16 | $pogo = PogoFake->new(); 17 | 18 | $pogo->reg_cb( worker_dconn_cmd_recv => sub { 19 | my( $c, $task_id, $data ) = @_; 20 | 21 | DEBUG "Worker received command"; 22 | 23 | is( $data->{ command }, "command-by-dispatcher", 24 | "received dispatcher command #1" ); 25 | }); 26 | 27 | $pogo->reg_cb( dispatcher_wconn_cmd_recv => sub { 28 | my( $c, $data ) = @_; 29 | 30 | DEBUG "Dispatcher received command"; 31 | 32 | return if $data->{ command } ne "command-by-worker"; 33 | 34 | is( $data->{ command }, 35 | "command-by-worker", "received worker command #2" ); 36 | }); 37 | 38 | plan tests => 5; 39 | 40 | $pogo->reg_cb( worker_dconn_listening => sub { 41 | 42 | DEBUG "Dispatcher listening, triggering worker command"; 43 | $pogo->{ worker }->to_dispatcher( { command => "command-by-worker", 44 | task_id => "123" } ); 45 | }); 46 | 47 | my $dconn_acks = 0; 48 | 49 | $pogo->reg_cb( worker_dconn_ack => sub { 50 | my( $c ) = @_; 51 | 52 | return if $dconn_acks++ > 0; 53 | 54 | ok 1, "worker got dispatcher ack #3"; 55 | } ); 56 | 57 | $pogo->reg_cb( dispatcher_wconn_ack => sub { 58 | my( $c ) = @_; 59 | 60 | ok 1, "dispatcher got worker ack #4"; 61 | } ); 62 | 63 | $pogo->reg_cb( worker_dconn_qp_idle => sub { 64 | my( $c ) = @_; 65 | 66 | ok 1, "qp idle #5"; 67 | } ); 68 | 69 | $pogo->reg_cb( dispatcher_wconn_worker_connect => sub { 70 | 71 | DEBUG "Connection up, dispatcher sending command to worker"; 72 | $pogo->{ dispatcher }->to_worker( { task_data => { 73 | task_name => "blech", 74 | command => "command-by-dispatcher", 75 | }, 76 | host => "wonkhost", 77 | task_id => "123" } ); 78 | }); 79 | 80 | $pogo->start(); 81 | -------------------------------------------------------------------------------- /t/003QP.t: -------------------------------------------------------------------------------- 1 | 2 | use strict; 3 | use warnings; 4 | use FindBin qw($Bin); 5 | use lib "$Bin/../lib"; 6 | use lib "$Bin/lib"; 7 | 8 | use Test::More; 9 | use Log::Log4perl qw(:easy); 10 | 11 | # Log::Log4perl->easy_init({ level => $DEBUG, layout => "%F{1}-%L: %m%n" }); 12 | 13 | use Pogo::Util::QP; 14 | 15 | plan tests => 5; 16 | 17 | ################################### 18 | 19 | my $cv = AnyEvent->condvar; 20 | 21 | my $qp = Pogo::Util::QP->new( 22 | timeout => 1, 23 | retries => 1, 24 | ); 25 | 26 | $qp->reg_cb( "next", sub { 27 | my( $c, $item ) = @_; 28 | 29 | is $item, "foo", "next item foo"; 30 | 31 | # 'forget' to ack 32 | } ); 33 | 34 | $qp->reg_cb( "idle", sub { 35 | ok 1, "queue empty"; 36 | $cv->send(); 37 | } ); 38 | 39 | $qp->event( "push", "foo" ); 40 | 41 | $cv->recv(); 42 | 43 | ################################### 44 | 45 | $qp = Pogo::Util::QP->new( 46 | timeout => 1, 47 | retries => 1, 48 | ); 49 | 50 | my $cbs = 0; 51 | 52 | $qp->reg_cb( "next", sub { 53 | my( $c, $item ) = @_; 54 | 55 | $cbs++; 56 | $qp->event( "ack" ); 57 | } ); 58 | 59 | $qp->reg_cb( "idle", sub { 60 | ok 1, "queue empty"; 61 | is $cbs, 1, "only 1 callback"; 62 | $cv->send(); 63 | } ); 64 | 65 | $qp->event( "push", "bar" ); 66 | 67 | $cv->recv(); 68 | -------------------------------------------------------------------------------- /t/004WorkerPool.t: -------------------------------------------------------------------------------- 1 | 2 | use strict; 3 | use warnings; 4 | use FindBin qw($Bin); 5 | use lib "$Bin/../lib"; 6 | use lib "$Bin/lib"; 7 | 8 | use PogoFake; 9 | use PogoTest; 10 | use Test::More; 11 | use Data::Dumper; 12 | use Log::Log4perl qw(:easy); 13 | use Pogo::Defaults qw( 14 | $POGO_DISPATCHER_WORKERCONN_HOST 15 | $POGO_DISPATCHER_WORKERCONN_PORT 16 | ); 17 | 18 | my $pogo; 19 | 20 | $pogo = PogoFake->new(); 21 | 22 | # second worker 23 | my $worker2 = Pogo::Worker->new( 24 | delay_connect => sub { 0 }, 25 | dispatchers => [ 26 | "$POGO_DISPATCHER_WORKERCONN_HOST:$POGO_DISPATCHER_WORKERCONN_PORT" ] 27 | ); 28 | 29 | my $workers_connected = 0; 30 | 31 | $pogo->reg_cb( dispatcher_wconn_worker_connect => sub { 32 | my( $c, $worker ) = @_; 33 | 34 | $workers_connected++; 35 | 36 | ok( 1, "worker $workers_connected connected" ); 37 | 38 | if( $workers_connected == 2 ) { 39 | $pogo->{ dispatcher }->to_worker( { 40 | host => "wonkhost", 41 | task_data => { 42 | task_name => "test", 43 | command => "command-by-dispatcher", 44 | }, 45 | task_id => 123 } ); 46 | } 47 | }); 48 | 49 | $worker2->start(); 50 | 51 | my $cmds_received = 0; 52 | 53 | $pogo->{ worker }->reg_cb( "worker_dconn_cmd_recv", sub { 54 | my( $c, $cmd ) = @_; 55 | 56 | DEBUG "First worker received: ", Dumper( $cmd ); 57 | is ++$cmds_received, 1, "command received by *one* worker"; 58 | } ); 59 | 60 | $worker2->reg_cb( "worker_dconn_cmd_recv", sub { 61 | my( $c, $cmd ) = @_; 62 | 63 | DEBUG "Second worker received: ", Dumper( $cmd ); 64 | is ++$cmds_received, 1, "command received by *one* worker"; 65 | } ); 66 | 67 | plan tests => 3; 68 | 69 | $pogo->start(); 70 | -------------------------------------------------------------------------------- /t/005ZooKeeper.t: -------------------------------------------------------------------------------- 1 | 2 | use strict; 3 | use warnings; 4 | use FindBin qw($Bin); 5 | use lib "$Bin/lib"; 6 | use lib "$Bin/../lib"; 7 | 8 | use Test::More; 9 | use Data::Dumper; 10 | use Log::Log4perl qw(:easy); 11 | use PogoTest; 12 | 13 | our $nof_tests; 14 | 15 | BEGIN { 16 | eval q{use Net::ZooKeeper}; 17 | 18 | if( $@ ) { 19 | plan skip_all => "Net::ZooKeeper not installed"; 20 | } else { 21 | our $nof_tests = 2; 22 | plan tests => $nof_tests; 23 | } 24 | } 25 | 26 | use Pogo::AnyEvent::ZooKeeper; 27 | use Net::ZooKeeper qw(:errors :node_flags :acls); 28 | 29 | my $zk = Pogo::AnyEvent::ZooKeeper->new(); 30 | 31 | my $testpath = "/test-123"; 32 | 33 | SKIP: { 34 | 35 | my $cv = AnyEvent->condvar; 36 | 37 | $zk->reg_cb( "zk_connect_error", sub { $cv->send(); }); 38 | $zk->reg_cb( "zk_connect_ok", sub { $cv->send(); }); 39 | $zk->start(); 40 | 41 | $cv->recv(); 42 | 43 | if( ! $zk->ping() ) { 44 | skip "No ZooKeeper running on " . $zk->netloc(), $nof_tests; 45 | } 46 | 47 | ok 1, "ZooKeeper up on " . $zk->netloc(); 48 | 49 | my $del = AnyEvent->condvar(); 50 | $zk->delete( $testpath, sub { 51 | $del->send(); 52 | } ); 53 | $del->recv(); 54 | 55 | $zk->create( $testpath, "blech-value", 56 | 'flags' => ZOO_EPHEMERAL, 57 | 'acl' => ZOO_OPEN_ACL_UNSAFE, 58 | sub { 59 | my( $c, $rc ) = @_; 60 | is $rc, $testpath, "create"; 61 | } ); 62 | } 63 | -------------------------------------------------------------------------------- /t/006API.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use FindBin qw($Bin); 5 | use lib "$Bin/../lib"; 6 | use lib "$Bin/lib"; 7 | use JSON qw( from_json ); 8 | use Pogo::API; 9 | 10 | BEGIN { 11 | # to find the templates in t/tmpl 12 | chdir $Bin; 13 | } 14 | 15 | use PogoFake; 16 | use PogoTest; 17 | use AnyEvent::HTTP; 18 | use Test::More; 19 | use Log::Log4perl qw(:easy); 20 | use Getopt::Std; 21 | use Pogo::Defaults qw( 22 | $POGO_DISPATCHER_CONTROLPORT_PORT 23 | $POGO_DISPATCHER_CONTROLPORT_HOST 24 | $POGO_API_TEST_PORT 25 | $POGO_API_TEST_HOST 26 | ); 27 | 28 | my $pogo; 29 | 30 | $pogo = PogoFake->new(); 31 | 32 | $pogo->reg_cb( dispatcher_controlport_up => sub { 33 | my( $c ) = @_; 34 | 35 | ok( 1, "dispatcher controlport up #1" ); 36 | }); 37 | 38 | $pogo->reg_cb( dispatcher_wconn_worker_connect => sub { 39 | my( $c ) = @_; 40 | 41 | http_get 42 | "http://$POGO_DISPATCHER_CONTROLPORT_HOST:" . 43 | "$POGO_DISPATCHER_CONTROLPORT_PORT/status", 44 | sub { 45 | my( $html ) = @_; 46 | 47 | DEBUG "Response from server: [$html]"; 48 | 49 | my $data = from_json( $html ); 50 | 51 | my @workers = @{ $data->{ workers } }; 52 | 53 | is scalar @workers, 1, "One worker connected \#2"; 54 | like $workers[0], 55 | qr/$POGO_DISPATCHER_CONTROLPORT_HOST:\d+$/, "worker details \#3"; 56 | 57 | is $data->{ pogo_version }, $Pogo::VERSION, "pogo version \#4"; 58 | }; 59 | }); 60 | 61 | # Start up test API server 62 | my $api = Plack::Handler::AnyEvent::HTTPD->new( 63 | host => $POGO_API_TEST_HOST, 64 | port => $POGO_API_TEST_PORT, 65 | server_ready => 66 | tests( "http://$POGO_API_TEST_HOST:$POGO_API_TEST_PORT" ), 67 | ); 68 | 69 | $api->register_service( Pogo::API->app() ); 70 | 71 | plan tests => 6; 72 | 73 | $pogo->start(); 74 | 75 | # This gets called once the API server is up 76 | sub tests { 77 | my( $base_url ) = @_; 78 | 79 | return sub { 80 | http_get "$base_url/status", sub { 81 | my( $html ) = @_; 82 | my $data = from_json( $html ); 83 | is $data->{ pogo_version }, $Pogo::VERSION, "pogo version \#5"; 84 | }; 85 | 86 | http_get "$base_url/v1/ping", sub { 87 | my( $body ) = @_; 88 | my $data = from_json( $body ); 89 | is $data->{ response }->{ ping }, 'pong', "ping ponged \#6"; 90 | }; 91 | }; 92 | } 93 | -------------------------------------------------------------------------------- /t/007SSL.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use FindBin qw($Bin); 5 | use lib "$Bin/../lib"; 6 | use lib "$Bin/lib"; 7 | 8 | use PogoFake; 9 | use PogoTest; 10 | use Test::More; 11 | use Log::Log4perl qw(:easy); 12 | use Getopt::Std; 13 | use Pogo::Defaults qw( 14 | $POGO_DISPATCHER_WORKERCONN_HOST 15 | $POGO_DISPATCHER_WORKERCONN_PORT 16 | ); 17 | 18 | my $pogo; 19 | 20 | my $cdir = "$Bin/certs"; 21 | 22 | # $Object::Event::DEBUG = 2; 23 | 24 | $pogo = PogoFake->new( 25 | ssl => 1, 26 | worker_key => "$cdir/worker.key", 27 | worker_cert => "$cdir/worker.crt", 28 | dispatcher_key => "$cdir/dispatcher.key", 29 | dispatcher_cert => "$cdir/dispatcher.crt", 30 | ca_cert => "$cdir/ca.crt", 31 | ); 32 | 33 | #$pogo->reg_cb( worker_dconn_error => sub { 34 | # LOGDIE @_; 35 | #} ); 36 | 37 | $pogo->reg_cb( worker_dconn_connected => sub { 38 | my( $c, $worker ) = @_; 39 | 40 | ok( 1, "worker connected #4" ); 41 | is( $worker, $POGO_DISPATCHER_WORKERCONN_HOST, "worker host #5" ); 42 | }); 43 | 44 | $pogo->reg_cb( dispatcher_wconn_worker_connect => sub { 45 | my( $c, $worker ) = @_; 46 | 47 | ok( 1, "dispatcher: worker connected #1" ); 48 | is( $worker, $POGO_DISPATCHER_WORKERCONN_HOST, "worker host #3" ); 49 | }); 50 | 51 | $pogo->reg_cb( dispatcher_wconn_prepare => sub { 52 | my( $c, $host, $port ) = @_; 53 | 54 | DEBUG "received dispatcher_prepare"; 55 | 56 | is( "$host:$port", 57 | "$POGO_DISPATCHER_WORKERCONN_HOST:$POGO_DISPATCHER_WORKERCONN_PORT", 58 | "dispatcher server_prepare cb #2" ); 59 | }); 60 | 61 | plan tests => 5; 62 | 63 | $pogo->start(); 64 | -------------------------------------------------------------------------------- /t/008Command.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use FindBin qw($Bin); 5 | use lib "$Bin/../lib"; 6 | use lib "$Bin/lib"; 7 | use Pogo::Worker::Task::Command; 8 | use Sysadm::Install qw( bin_find ); 9 | 10 | use PogoTest; 11 | use PogoFake; 12 | use Test::More; 13 | use Log::Log4perl qw(:easy); 14 | use Getopt::Std; 15 | 16 | my $echo = bin_find( "echo" ); 17 | 18 | plan tests => 4; 19 | 20 | my $cv = AnyEvent->condvar; 21 | 22 | my $TEST_ID = "some-id"; 23 | 24 | my $task = Pogo::Worker::Task::Command->new( 25 | command => "$echo foo; $echo bar", 26 | id => $TEST_ID, 27 | ); 28 | 29 | my $gobbled_up = ""; 30 | 31 | $task->reg_cb( "on_stdout", sub { 32 | my( $c, $data ) = @_; 33 | 34 | $gobbled_up .= $data; 35 | }); 36 | 37 | $task->reg_cb( "on_finish", sub { 38 | my( $c ) = @_; 39 | 40 | is $c->rc(), 0, "success"; 41 | 42 | my $expected = "foo\nbar\n"; 43 | is $gobbled_up, $expected, "expected stdout data"; 44 | is $c->stdout(), $expected, "stdout() call"; 45 | 46 | is $c->id(), $TEST_ID, "task id ok"; 47 | $cv->send(); 48 | }); 49 | 50 | $task->start(); 51 | $cv->recv(); 52 | -------------------------------------------------------------------------------- /t/010Plugin.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Pogo::Plugin; 5 | use Test::More; 6 | 7 | plan tests => 2; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | } 13 | 14 | my $plugins = Pogo::Plugin->load( "Test" ); 15 | 16 | ok defined $plugins, "found plugin"; 17 | 18 | is ref $plugins, "Pogo::Plugin::Test::Default", "found default plugin"; 19 | -------------------------------------------------------------------------------- /t/011ZKPlugin.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use AnyEvent; 5 | use Pogo::Plugin; 6 | use Test::More; 7 | use Log::Log4perl qw(:easy); 8 | 9 | plan tests => 2; 10 | 11 | BEGIN { 12 | use FindBin qw( $Bin ); 13 | use lib "$Bin/lib"; 14 | use PogoTest; 15 | } 16 | 17 | require Pogo::AnyEvent::ZooKeeper; 18 | 19 | my $cv = AnyEvent->condvar(); 20 | 21 | my $zk; 22 | 23 | $zk = Pogo::AnyEvent::ZooKeeper->new( "bogushost" ); 24 | $zk->reg_cb( 25 | zk_connect_ok => sub { 26 | 27 | my $zv = AnyEvent->condvar(); 28 | $zk->create( "/foo", sub { $zv->send() } ); 29 | DEBUG "Waiting for create"; 30 | $zv->recv(); 31 | 32 | $zv = AnyEvent->condvar(); 33 | $zk->set( "/foo", "bar", sub { $zv->send() } ); 34 | DEBUG "Waiting for set"; 35 | $zv->recv(); 36 | 37 | my $value; 38 | $zv = AnyEvent->condvar(); 39 | $zk->get( "/foo", sub { $value = $_[1]; $zv->send(); } ); 40 | DEBUG "Waiting for get"; 41 | $zv->recv(); 42 | 43 | DEBUG "Testing"; 44 | is $value, "bar", "zk set/get"; 45 | $cv->send(); 46 | }, 47 | ); 48 | 49 | ok 1, "test"; 50 | 51 | DEBUG "Starting up"; 52 | $zk->start(); 53 | 54 | $cv->recv(); 55 | -------------------------------------------------------------------------------- /t/012Schedule.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use AnyEvent; 5 | use Pogo::Plugin; 6 | use Test::More; 7 | use Log::Log4perl qw(:easy); 8 | 9 | plan tests => 1; 10 | 11 | BEGIN { 12 | use FindBin qw( $Bin ); 13 | use lib "$Bin/lib"; 14 | use PogoTest; 15 | } 16 | 17 | use Pogo::Scheduler; 18 | 19 | my $s = Pogo::Scheduler->new(); 20 | 21 | my $task1 = "task1"; 22 | 23 | $s->reg_cb( "task_run", sub { 24 | my( $c, $task ) = @_; 25 | 26 | is $task, $task1, "task scheduled #1"; 27 | } ); 28 | 29 | $s->task_add( $task1 ); 30 | -------------------------------------------------------------------------------- /t/013Config.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use AnyEvent; 5 | use Pogo::Plugin; 6 | use Test::More; 7 | use Test::Deep; 8 | use Log::Log4perl qw(:easy); 9 | 10 | plan tests => 3; 11 | 12 | BEGIN { 13 | use FindBin qw( $Bin ); 14 | use lib "$Bin/lib"; 15 | use PogoTest; 16 | } 17 | 18 | use Pogo::Scheduler::Classic; 19 | 20 | my $s = Pogo::Scheduler::Classic->new(); 21 | 22 | $s->config_load( \ <<'EOT' ); 23 | tag: 24 | colo: 25 | north_america: 26 | - host1 27 | - host2 28 | - host3 29 | south_east_asia: 30 | - host4 31 | - host5 32 | - host6 33 | sequence: 34 | - $colo.north_america 35 | - $colo.south_east_asia 36 | EOT 37 | 38 | my $cfg = $s->config(); 39 | 40 | is "$cfg->{ sequence }->[0]", '$colo.north_america', "config sequence"; 41 | is "$cfg->{ sequence }->[1]", '$colo.south_east_asia', "config sequence"; 42 | 43 | my $struct = { a => { b => [ qw(c d) ] } }; 44 | 45 | my $paths = []; 46 | 47 | Pogo::Util::struct_traverse( $struct, { 48 | leaf => sub { 49 | my( $node, $path ) = @_; 50 | 51 | push @$paths, [@$path, $node]; 52 | } 53 | } ); 54 | 55 | cmp_deeply( $paths, [ [qw(a b d)], [qw(a b c)] ], "leaf_paths" ); 56 | 57 | -------------------------------------------------------------------------------- /t/014Sequence.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | use Pogo::Util::Bucketeer; 7 | 8 | my $nof_tests = 6; 9 | 10 | plan tests => $nof_tests; 11 | 12 | BEGIN { 13 | use FindBin qw( $Bin ); 14 | use lib "$Bin/lib"; 15 | use PogoTest; 16 | } 17 | 18 | use Pogo::Scheduler::Classic; 19 | my $scheduler = Pogo::Scheduler::Classic->new(); 20 | 21 | my $cv = AnyEvent->condvar(); 22 | 23 | $scheduler->config_load( \ <<'EOT' ); 24 | tag: 25 | colo: 26 | north_america: 27 | - host1 28 | - host2 29 | - host3 30 | south_east_asia: 31 | - host4 32 | - host5 33 | - host6 34 | sequence: 35 | - $colo.north_america 36 | - $colo.south_east_asia 37 | EOT 38 | 39 | my $bck = Pogo::Util::Bucketeer->new( 40 | buckets => [ 41 | [ qw( host1 host2 host3 ) ], 42 | [ qw( host4 host5 host6 ) ], 43 | ] ); 44 | 45 | my @timers = (); 46 | 47 | $scheduler->reg_cb( "task_run", sub { 48 | my( $c, $task ) = @_; 49 | 50 | my $host = $task->{ host }; 51 | 52 | ok $bck->item( $host ), "host $host in seq"; 53 | 54 | my $w = AnyEvent->timer( after => 0.1, cb => sub { 55 | # Crunch, crunch, crunch. Task done. Report back. 56 | DEBUG "Sending task_mark_done for task $task back to scheduler"; 57 | $scheduler->event( "task_mark_done", $task ); 58 | } ); 59 | 60 | push @timers, $w; 61 | 62 | $bck->all_done and $cv->send(); # quit 63 | } ); 64 | 65 | # schedule all hosts 66 | $scheduler->schedule( [ $scheduler->config_hosts() ] ); 67 | 68 | $cv->recv; 69 | -------------------------------------------------------------------------------- /t/015SeqAttr.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use AnyEvent; 5 | use Pogo::Plugin; 6 | use Test::More; 7 | use Log::Log4perl qw(:easy); 8 | use Pogo::Util::Bucketeer; 9 | use Pogo::Util; 10 | use Test::Deep; 11 | use YAML qw(Load); 12 | 13 | my $nof_tests = 1; 14 | 15 | plan tests => $nof_tests; 16 | 17 | BEGIN { 18 | use FindBin qw( $Bin ); 19 | use lib "$Bin/lib"; 20 | use PogoTest; 21 | } 22 | 23 | use Pogo::Scheduler::Classic; 24 | my $scheduler = Pogo::Scheduler::Classic->new(); 25 | 26 | my $cv = AnyEvent->condvar(); 27 | 28 | my $data = <<'EOT'; 29 | tag: 30 | frontend: 31 | - host1 32 | - host4 33 | backend: 34 | - host2 35 | - host5 36 | colo: 37 | north_america: 38 | - host1 39 | - host2 40 | - host3 41 | south_east_asia: 42 | - host4 43 | - host5 44 | - host6 45 | sequence: 46 | $frontend: 47 | - $colo.north_america 48 | - $colo.south_east_asia 49 | $backend: 50 | - $colo.south_east_asia 51 | - $colo.north_america 52 | EOT 53 | 54 | # threads: 55 | # 1) host5 -> host2 56 | # 2) host1 -> host4 57 | # 3) host3, host6 unconstrained 58 | 59 | $scheduler->config_load( \$data ) or 60 | die "Failed ot load config"; 61 | 62 | my @queue = (); 63 | 64 | $scheduler->reg_cb( "task_run", sub { 65 | my( $c, $task ) = @_; 66 | 67 | DEBUG "*** Scheduled host $task"; 68 | my $host = $task->{ host }; 69 | 70 | push @queue, $host; 71 | } ); 72 | 73 | $scheduler->schedule( [ $scheduler->config_hosts() ] ); 74 | 75 | # hosts 2/4 need to wait 76 | cmp_deeply( \@queue, 77 | [ qw(host5 host1 host3 host6) ], "task queue" ); 78 | 79 | __END__ 80 | 81 | use Data::Dumper; 82 | print Dumper( $scheduler ); 83 | 84 | __END__ 85 | # only frontends need to be in sequence, everything else can go 86 | # in parallel 87 | my $bck = Pogo::Util::Bucketeer->new( 88 | buckets => [ 89 | [ qw( host1 host2 host3 host5 host6 ) ], 90 | [ qw( host4 ) ], 91 | ], 92 | ); 93 | 94 | $scheduler->reg_cb( "task_run", sub { 95 | my( $c, $task ) = @_; 96 | 97 | ok $bck->item( $task ), "task $task in sync"; 98 | 99 | $bck->all_done() and $cv->send(); # quit 100 | } ); 101 | 102 | for my $task ( $bck->items() ) { 103 | $scheduler->task_add( $task ); 104 | } 105 | 106 | $scheduler->start(); 107 | 108 | $cv->recv; 109 | -------------------------------------------------------------------------------- /t/016Bucketeer.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | 7 | my $nof_tests = 12; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | plan tests => $nof_tests; 16 | 17 | use Pogo::Util::Bucketeer; 18 | 19 | my $bkt = Pogo::Util::Bucketeer->new( 20 | buckets => [ 21 | [ qw( host1 host2 host3 ) ], 22 | [ qw( host4 host5 ) ], 23 | ] 24 | ); 25 | 26 | my $bkt2 = Pogo::Util::Bucketeer->new( 27 | buckets => [ 28 | [ qw( host10 host12 ) ], 29 | ] 30 | ); 31 | 32 | my $thread = Pogo::Util::Bucketeer::Threaded->new(); 33 | $thread->bucketeer_add( $bkt ); 34 | $thread->bucketeer_add( $bkt2 ); 35 | 36 | ok !$thread->all_done(), "not all done"; 37 | 38 | ok $thread->item( "host2" ), "host2 in seq"; 39 | ok $thread->item( "host1" ), "host1 in seq"; 40 | ok !$thread->item( "host4" ), "host4 out of seq"; 41 | 42 | ok !$thread->all_done(), "not all done"; 43 | 44 | ok $thread->item( "host3" ), "host3 in seq"; 45 | ok $thread->item( "host4" ), "host4 in seq"; 46 | ok $thread->item( "host5" ), "host5 in seq"; 47 | ok !$thread->all_done(), "not all done"; 48 | 49 | ok $thread->item( "host12" ), "host11 (thread2) in seq"; 50 | ok $thread->item( "host10" ), "host10 (thread2) in seq"; 51 | 52 | ok $thread->all_done(), "all done"; 53 | -------------------------------------------------------------------------------- /t/017Tasks.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | 7 | my $nof_tests = 6; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | plan tests => $nof_tests; 16 | 17 | use Pogo::Scheduler::Task; 18 | use Pogo::Scheduler::Slot; 19 | 20 | my $slot = Pogo::Scheduler::Slot->new(); 21 | 22 | my @tasks = (); 23 | 24 | my $cv = AnyEvent->condvar(); 25 | 26 | $slot->reg_cb( "slot_done", sub { 27 | my( $c, $s ) = @_; 28 | ok 1, "received slot_done"; 29 | $cv->send(); 30 | } ); 31 | 32 | for( 1..4 ) { 33 | my $task = Pogo::Scheduler::Task->new( 34 | slot => $slot, 35 | ); 36 | push @tasks, $task; 37 | $slot->task_add( $task ); 38 | } 39 | 40 | while( my $task = $slot->task_next() ) { 41 | my $exp = shift @tasks; 42 | 43 | is "$task", "$exp", "next task"; 44 | 45 | $slot->task_mark_done( $task ); 46 | } 47 | 48 | is $slot->tasks_active(), 0, "no more active tasks"; 49 | 50 | $cv->recv(); 51 | -------------------------------------------------------------------------------- /t/018TasksEvent.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | 7 | my $nof_tests = 5; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | plan tests => $nof_tests; 16 | 17 | use Pogo::Scheduler::Task; 18 | use Pogo::Scheduler::Slot; 19 | 20 | my $slot = Pogo::Scheduler::Slot->new(); 21 | 22 | my @tasks = (); 23 | 24 | my $cv = AnyEvent->condvar(); 25 | 26 | $slot->reg_cb( "slot_done", sub { 27 | my( $c, $s ) = @_; 28 | ok 1, "received slot_done #1"; 29 | $cv->send(); 30 | } ); 31 | 32 | for( 1..4 ) { 33 | my $task = Pogo::Scheduler::Task->new( 34 | slot => $slot, 35 | ); 36 | push @tasks, $task; 37 | $slot->task_add( $task ); 38 | } 39 | 40 | $slot->reg_cb( "task_run", sub { 41 | my( $c, $t ) = @_; 42 | 43 | DEBUG "Running task $t"; 44 | ok 1, "task run $t"; 45 | 46 | $slot->task_mark_done( $t ); 47 | $slot->task_next(); 48 | } ); 49 | 50 | $slot->task_next(); 51 | 52 | $cv->recv(); 53 | -------------------------------------------------------------------------------- /t/019Thread.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | 7 | my $nof_tests = 6; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | plan tests => $nof_tests; 16 | 17 | use Pogo::Scheduler::Thread; 18 | use Pogo::Scheduler::Task; 19 | use Pogo::Scheduler::Slot; 20 | 21 | my $thread = Pogo::Scheduler::Thread->new(); 22 | my $slot = Pogo::Scheduler::Slot->new(); 23 | 24 | $thread->slot_add( $slot ); 25 | 26 | my @tasks = (); 27 | 28 | my $cv = AnyEvent->condvar(); 29 | 30 | $slot->reg_cb( "slot_done", sub { 31 | my( $c, $s ) = @_; 32 | ok 1, "received slot_done #1"; 33 | } ); 34 | 35 | $thread->reg_cb( "thread_done", sub { 36 | my( $c, $s ) = @_; 37 | ok 1, "received thread_done #2"; 38 | $cv->send(); 39 | } ); 40 | 41 | for( 1..4 ) { 42 | my $task = Pogo::Scheduler::Task->new( 43 | slot => $slot, 44 | ); 45 | push @tasks, $task; 46 | DEBUG "Adding task $task"; 47 | $slot->task_add( $task ); 48 | } 49 | 50 | $slot->reg_cb( "task_run", sub { 51 | my( $c, $t ) = @_; 52 | 53 | DEBUG "Test suite 'running' task $t"; 54 | ok 1, "task run $t"; 55 | 56 | $thread->task_mark_done( $t ); 57 | } ); 58 | 59 | $thread->start(); 60 | 61 | $cv->recv(); 62 | -------------------------------------------------------------------------------- /t/020TripleSeq.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | use Pogo::Util::Bucketeer; 7 | 8 | # three groups of hosts in the sequence, but no hosts in the 9 | # middle tier 10 | 11 | my $nof_tests = 6; 12 | 13 | plan tests => $nof_tests; 14 | 15 | BEGIN { 16 | use FindBin qw( $Bin ); 17 | use lib "$Bin/lib"; 18 | use PogoTest; 19 | } 20 | 21 | use Pogo::Scheduler::Classic; 22 | my $scheduler = Pogo::Scheduler::Classic->new(); 23 | 24 | my $cv = AnyEvent->condvar(); 25 | 26 | $scheduler->config_load( \ <<'EOT' ); 27 | tag: 28 | colo: 29 | one: 30 | - host1 31 | - host2 32 | - host3 33 | two: 34 | - host4 35 | - host5 36 | - host6 37 | three: 38 | - host7 39 | - host8 40 | - host9 41 | sequence: 42 | - $colo.one 43 | - $colo.two 44 | - $colo.three 45 | EOT 46 | 47 | my $bck = Pogo::Util::Bucketeer->new( 48 | buckets => [ 49 | [ qw( host1 host2 host3 ) ], 50 | [ qw( host7 host8 host9 ) ], 51 | ] ); 52 | 53 | my @timers = (); 54 | 55 | $scheduler->reg_cb( "task_run", sub { 56 | my( $c, $task ) = @_; 57 | 58 | my $host = $task->{ host }; 59 | 60 | ok $bck->item( $host ), "host $host in seq"; 61 | 62 | my $w = AnyEvent->timer( after => 0.1, cb => sub { 63 | # Crunch, crunch, crunch. Task done. Report back. 64 | DEBUG "Sending task_mark_done for task $task back to scheduler"; 65 | $scheduler->event( "task_mark_done", $task ); 66 | } ); 67 | 68 | push @timers, $w; 69 | 70 | $bck->all_done and $cv->send(); # quit 71 | } ); 72 | 73 | # schedule all hosts 74 | $scheduler->schedule( [ map { "host$_" } qw( 9 8 7 1 2 3 ) ] ); 75 | 76 | $cv->recv; 77 | -------------------------------------------------------------------------------- /t/021Constraint.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | use Pogo::Util::Bucketeer; 7 | 8 | my $nof_tests = 6; 9 | 10 | plan tests => $nof_tests; 11 | 12 | BEGIN { 13 | use FindBin qw( $Bin ); 14 | use lib "$Bin/lib"; 15 | use PogoTest; 16 | } 17 | 18 | use Pogo::Scheduler::Classic; 19 | my $scheduler = Pogo::Scheduler::Classic->new(); 20 | 21 | my $cv = AnyEvent->condvar(); 22 | 23 | $scheduler->config_load( \ <<'EOT' ); 24 | tag: 25 | colo: 26 | north_america: 27 | - host1 28 | - host2 29 | - host3 30 | south_east_asia: 31 | - host4 32 | - host5 33 | - host6 34 | sequence: 35 | - $colo.south_east_asia 36 | - $colo.north_america 37 | 38 | constraint: 39 | $colo.north_america: 40 | max_parallel: 3 41 | EOT 42 | 43 | my $bck = Pogo::Util::Bucketeer->new( 44 | buckets => [ 45 | [ qw( host4 host5 host6 ) ], 46 | [ qw( host1 host2 host3 ) ], 47 | ] ); 48 | 49 | my @timers = (); 50 | 51 | $scheduler->reg_cb( "task_run", sub { 52 | my( $c, $task ) = @_; 53 | 54 | my $host = $task->{ host }; 55 | 56 | ok $bck->item( $host ), "host $host in seq"; 57 | 58 | my $w = AnyEvent->timer( after => 0.1, cb => sub { 59 | # Crunch, crunch, crunch. Task done. Report back. 60 | DEBUG "Sending task_mark_done for task $task back to scheduler"; 61 | $scheduler->event( "task_mark_done", $task ); 62 | } ); 63 | 64 | push @timers, $w; 65 | 66 | $bck->all_done and $cv->send(); # quit 67 | } ); 68 | 69 | # schedule all hosts 70 | $scheduler->schedule( [ $scheduler->config_hosts() ] ); 71 | 72 | $cv->recv; 73 | -------------------------------------------------------------------------------- /t/022Hangs.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | 7 | my $nof_tests = 3; 8 | 9 | plan tests => $nof_tests; 10 | 11 | BEGIN { 12 | use FindBin qw( $Bin ); 13 | use lib "$Bin/lib"; 14 | use PogoTest; 15 | } 16 | 17 | use Pogo::Scheduler::Classic; 18 | my $scheduler = Pogo::Scheduler::Classic->new(); 19 | 20 | my $cv = AnyEvent->condvar(); 21 | 22 | $scheduler->config_load( \ <<'EOT' ); 23 | tag: 24 | colo: 25 | north_america: 26 | - host4 27 | - host5 28 | - host6 29 | 30 | constraint: 31 | $colo.north_america: 32 | max_parallel: 1 33 | 34 | sequence: 35 | - $colo.north_america 36 | EOT 37 | 38 | #print $scheduler->as_ascii(); 39 | 40 | my $max_hosts = 1; 41 | my $nof_hosts = 0; 42 | 43 | $scheduler->reg_cb( "task_run", sub { 44 | my( $c, $task ) = @_; 45 | 46 | $nof_hosts++; 47 | 48 | if( $nof_hosts > $max_hosts ) { 49 | die "Whoa! Violated max_parallel:1 setting"; 50 | } 51 | 52 | my $host = $task->{ host }; 53 | 54 | ok 1, "got host $task"; 55 | } ); 56 | 57 | $scheduler->reg_cb( "waiting", sub { 58 | my( $c, $thread, $slot ) = @_; 59 | 60 | DEBUG "Waiting on thread $thread slot $slot"; 61 | ok 1, "waiting"; 62 | 63 | $cv->send(); 64 | } ); 65 | 66 | # schedule all hosts 67 | $scheduler->schedule( [ $scheduler->config_hosts() ] ); 68 | 69 | $cv->recv; 70 | -------------------------------------------------------------------------------- /t/023NoSeqCon.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | 7 | my $nof_tests = 3; 8 | 9 | plan tests => $nof_tests; 10 | 11 | BEGIN { 12 | use FindBin qw( $Bin ); 13 | use lib "$Bin/lib"; 14 | use PogoTest; 15 | } 16 | 17 | use Pogo::Scheduler::Classic; 18 | my $scheduler = Pogo::Scheduler::Classic->new(); 19 | 20 | my $cv = AnyEvent->condvar(); 21 | 22 | $scheduler->config_load( \ <<'EOT' ); 23 | tag: 24 | colo: 25 | north_america: 26 | - host4 27 | - host5 28 | - host6 29 | 30 | constraint: 31 | $colo.north_america: 32 | max_parallel: 1 33 | EOT 34 | 35 | #print $scheduler->as_ascii(), "\n"; 36 | #use Data::Dumper; 37 | #print Dumper( $scheduler ); 38 | 39 | my $max = 1; 40 | my $hosts_scheduled = 0; 41 | 42 | $scheduler->reg_cb( "task_run", sub { 43 | my( $c, $task ) = @_; 44 | 45 | DEBUG "Received task_run for task $task"; 46 | 47 | my $host = $task->host(); 48 | 49 | $hosts_scheduled++; 50 | 51 | if( $hosts_scheduled > $max ) { 52 | die "Constraint violated, $hosts_scheduled hosts scheduled but ", 53 | "only $max allowed."; 54 | } 55 | 56 | ok 1, "got host $task"; 57 | } ); 58 | 59 | $scheduler->reg_cb( "waiting", sub { 60 | my( $c, $thread, $slot ) = @_; 61 | 62 | DEBUG "Waiting on thread $thread slot $slot"; 63 | ok 1, "waiting"; 64 | 65 | $cv->send(); 66 | } ); 67 | 68 | # schedule all hosts 69 | $scheduler->schedule( [ $scheduler->config_hosts() ] ); 70 | 71 | $cv->recv; 72 | -------------------------------------------------------------------------------- /t/024SlotConstr.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | 7 | my $nof_tests = 2; 8 | 9 | plan tests => $nof_tests; 10 | 11 | BEGIN { 12 | use FindBin qw( $Bin ); 13 | use lib "$Bin/lib"; 14 | use PogoTest; 15 | } 16 | 17 | use Pogo::Scheduler::Slot; 18 | use Pogo::Scheduler::Task; 19 | 20 | my $slot = Pogo::Scheduler::Slot->new(); 21 | 22 | my $constraint = Pogo::Scheduler::Constraint->new( 23 | max_parallel => 1 24 | ); 25 | 26 | $slot->task_add( Pogo::Scheduler::Task->new( 27 | constraints => [ $constraint ], 28 | slot => $slot, 29 | host => "foo", 30 | ) ); 31 | $slot->task_add( Pogo::Scheduler::Task->new( 32 | constraints => [ $constraint ], 33 | slot => $slot, 34 | host => "bar", 35 | ) ); 36 | 37 | $slot->reg_cb( "task_run", sub { 38 | my( $c, $task ) = @_; 39 | 40 | ok 1, "Running task $task"; 41 | 42 | # report back that task is done 43 | $slot->event( "task_mark_done", $task ); 44 | } ); 45 | 46 | my $cv = AnyEvent->condvar(); 47 | 48 | $slot->reg_cb( "slot_done", sub { 49 | my( $c ) = @_; 50 | 51 | $cv->send(); 52 | } ); 53 | 54 | # start as many tasks as possible in parallel 55 | $slot->start(); 56 | 57 | $cv->recv(); 58 | -------------------------------------------------------------------------------- /t/025MultSeq.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | use Pogo::Util::Bucketeer; 7 | 8 | my $nof_tests = 8; 9 | 10 | plan tests => $nof_tests; 11 | 12 | BEGIN { 13 | use FindBin qw( $Bin ); 14 | use lib "$Bin/lib"; 15 | use PogoTest; 16 | } 17 | 18 | use Pogo::Scheduler::Classic; 19 | my $scheduler = Pogo::Scheduler::Classic->new(); 20 | 21 | my $cv = AnyEvent->condvar(); 22 | 23 | $scheduler->config_load( \ <<'EOT' ); 24 | tag: 25 | north: 26 | - host[1-2] 27 | south: 28 | - host[3-4] 29 | east: 30 | - host[5-6] 31 | west: 32 | - host{7,8} 33 | 34 | sequence: 35 | horizontal: 36 | - $south 37 | - $north 38 | vertical: 39 | - $west 40 | - $east 41 | EOT 42 | 43 | my $bck = Pogo::Util::Bucketeer->new( 44 | buckets => [ 45 | [ qw( host3 host4 host7 host8 ) ], 46 | [ qw( host1 host2 host5 host6 ) ], 47 | ] ); 48 | 49 | my @timers = (); 50 | 51 | $scheduler->reg_cb( "task_run", sub { 52 | my( $c, $task ) = @_; 53 | 54 | my $host = $task->{ host }; 55 | 56 | ok $bck->item( $host ), "host $host in seq"; 57 | 58 | my $w = AnyEvent->timer( after => 0.1, cb => sub { 59 | # Crunch, crunch, crunch. Task done. Report back. 60 | DEBUG "Sending task_mark_done for task $task back to scheduler"; 61 | $scheduler->event( "task_mark_done", $task ); 62 | } ); 63 | 64 | push @timers, $w; 65 | 66 | $bck->all_done and $cv->send(); # quit 67 | } ); 68 | 69 | # schedule all hosts 70 | $scheduler->schedule( [ $scheduler->config_hosts() ] ); 71 | 72 | #print $scheduler->as_ascii(), "\n"; 73 | 74 | $cv->recv; 75 | -------------------------------------------------------------------------------- /t/027HostSeq.t: -------------------------------------------------------------------------------- 1 | 2 | use warnings; 3 | use strict; 4 | use Test::More; 5 | use Log::Log4perl qw(:easy); 6 | use Pogo::Util::Bucketeer; 7 | 8 | # three groups of hosts in the sequence, but no hosts in the 9 | # middle tier 10 | 11 | my $nof_tests = 3; 12 | 13 | plan tests => $nof_tests; 14 | 15 | BEGIN { 16 | use FindBin qw( $Bin ); 17 | use lib "$Bin/lib"; 18 | use PogoTest; 19 | } 20 | 21 | use Pogo::Scheduler::Classic; 22 | my $scheduler = Pogo::Scheduler::Classic->new(); 23 | 24 | my $cv = AnyEvent->condvar(); 25 | 26 | $scheduler->config_load( \ <<'EOT' ); 27 | tag: 28 | sequence: 29 | - host3 30 | - host2 31 | - host1 32 | EOT 33 | 34 | my $bck = Pogo::Util::Bucketeer->new( 35 | buckets => [ 36 | [ qw( host3 ) ], 37 | [ qw( host2 ) ], 38 | [ qw( host1 ) ], 39 | ] ); 40 | 41 | my @timers = (); 42 | 43 | $scheduler->reg_cb( "task_run", sub { 44 | my( $c, $task ) = @_; 45 | 46 | my $host = $task->{ host }; 47 | 48 | DEBUG "Running host $host"; 49 | 50 | ok $bck->item( $host ), "host $host in seq"; 51 | 52 | my $w = AnyEvent->timer( after => 0.1, cb => sub { 53 | # Crunch, crunch, crunch. Task done. Report back. 54 | DEBUG "Sending task_mark_done for task $task back to scheduler"; 55 | $scheduler->event( "task_mark_done", $task ); 56 | } ); 57 | 58 | push @timers, $w; 59 | 60 | $bck->all_done and $cv->send(); # quit 61 | } ); 62 | 63 | # schedule all hosts 64 | $scheduler->schedule( [ map { "host$_" } qw( 1 2 3 ) ] ); 65 | 66 | $cv->recv; 67 | -------------------------------------------------------------------------------- /t/028PogoOne.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | 6 | my $nof_tests = 3; 7 | plan tests => $nof_tests; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | use Pogo::One; 16 | use Pogo::Job; 17 | use Pogo::Util::Bucketeer; 18 | 19 | # use Log::Log4perl qw(:easy); 20 | # Log::Log4perl->easy_init( { level => $DEBUG, category => 'main' } ); 21 | 22 | my $main = AnyEvent->condvar(); 23 | 24 | my $pogo = Pogo::One->new(); 25 | 26 | my $job = Pogo::Job->new( 27 | task_name => "test", 28 | range => [ qw(host1 host2) ], 29 | config => <<'EOT', 30 | tag: 31 | sequence: 32 | - host3 33 | - host2 34 | - host1 35 | EOT 36 | ); 37 | 38 | $pogo->reg_cb( "pogo_one_job_submitted", sub { 39 | my( $c, $job ) = @_; 40 | 41 | ok 1, "job submitted #1"; 42 | } ); 43 | 44 | $pogo->reg_cb( "pogo_one_ready", sub { 45 | 46 | $pogo->job_submit( 47 | $job, 48 | ); 49 | } ); 50 | 51 | my $bck = Pogo::Util::Bucketeer->new( 52 | buckets => [ 53 | [ qw( host2 ) ], 54 | [ qw( host1 ) ], 55 | ] ); 56 | 57 | $pogo->reg_cb( "worker_task_active", sub { 58 | my( $c, $task ) = @_; 59 | 60 | DEBUG "Worker running task ", $task->as_string(); 61 | } ); 62 | 63 | my $seq = 0; 64 | 65 | $pogo->reg_cb( "worker_task_done", sub { 66 | my( $c, $task) = @_; 67 | 68 | DEBUG "Worker done with task ", $task->id(); 69 | $seq++; 70 | my $host = $task->host(); 71 | ok $bck->item( $host ), "host $host in seq #$seq"; 72 | 73 | if( $seq == 2 ) { 74 | $main->send(); 75 | } 76 | } ); 77 | 78 | $pogo->start(); 79 | $main->recv(); 80 | -------------------------------------------------------------------------------- /t/029WorkerRemoteCmd.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | 6 | my $nof_tests = 2; 7 | plan tests => $nof_tests; 8 | 9 | # use Log::Log4perl qw(:easy); 10 | # Log::Log4perl->easy_init( { level => $DEBUG, layout => "%F{1}:%L> %m%n" } ); 11 | 12 | BEGIN { 13 | use FindBin qw( $Bin ); 14 | use lib "$Bin/lib"; 15 | use PogoTest; 16 | } 17 | 18 | use Pogo::One; 19 | use Pogo::Job; 20 | use Pogo::Worker::Task::Command::Remote; 21 | 22 | my $scriptbin = "$Bin/../bin"; 23 | 24 | my $cmd = Pogo::Worker::Task::Command::Remote->new( 25 | ssh => "$scriptbin/pogo-test-ssh-sim", 26 | pogo_pw => "$scriptbin/pogo-pw", 27 | command => "$scriptbin/pogo-test-ls-sim", 28 | user => "wombel", 29 | password => "pass", 30 | host => "this.host.does.not.exist", 31 | ); 32 | 33 | my $cv = AnyEvent->condvar(); 34 | 35 | $cmd->reg_cb( "on_finish", sub { 36 | my( $c, $rc ) = @_; 37 | 38 | DEBUG "rc=$rc"; 39 | is $rc, 0, "rc ok"; 40 | like $c->stdout(), qr/foo.*bar/s, "stdout"; 41 | 42 | $cv->send(); 43 | } ); 44 | 45 | $cmd->start(); 46 | 47 | $cv->recv(); 48 | -------------------------------------------------------------------------------- /t/030EndToEnd.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | 6 | my $nof_tests = 4; 7 | plan tests => $nof_tests; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | use Pogo::One; 16 | use Pogo::Client::Async; 17 | use Pogo::Job; 18 | use Pogo::Util::Bucketeer; 19 | use Data::Dumper; 20 | use Pogo::Util::Bucketeer; 21 | 22 | # use Log::Log4perl qw(:easy); 23 | # Log::Log4perl->easy_init( { level => $DEBUG, category => 'main' } ); 24 | 25 | my $main = AnyEvent->condvar(); 26 | 27 | my $pogo = Pogo::One->new( 28 | ssh => "$Bin/../bin/pogo-test-ssh-sim", 29 | ); 30 | 31 | my $client = Pogo::Client::Async->new( 32 | api_base_url => $pogo->api_server()->base_url(), 33 | ); 34 | 35 | my $bck = Pogo::Util::Bucketeer->new( 36 | buckets => [ 37 | [ qw( host2 ) ], 38 | [ qw( host1 ) ], 39 | ] ); 40 | 41 | $client->reg_cb( "client_job_submit_ok", sub { 42 | my( $c, $resp, $job ) = @_; 43 | INFO "Job submitted."; 44 | } ); 45 | 46 | $client->reg_cb( "client_job_submit_fail", sub { 47 | my( $c, $resp, $job ) = @_; 48 | ERROR "Job submission failed: ", Dumper( $resp ); 49 | $main->send(); 50 | } ); 51 | 52 | my $job = Pogo::Job->new( 53 | task_name => "ssh", 54 | range => [ qw(host1 host2) ], 55 | command => "date", 56 | config => <<'EOT', 57 | tag: 58 | sequence: 59 | - host3 60 | - host2 61 | - host1 62 | EOT 63 | ); 64 | 65 | $pogo->reg_cb( "pogo_one_ready", sub { 66 | DEBUG "Pogo one is ready."; 67 | 68 | $client->job_submit( $job->as_hash() ); 69 | } ); 70 | 71 | my $seq = 0; 72 | 73 | $pogo->reg_cb( worker_task_done => sub { 74 | my( $c, $task ) = @_; 75 | 76 | DEBUG "Worker done with task ", $task->id(); 77 | $seq++; 78 | 79 | my $task_string = $task->as_string(); 80 | my $host = $task->host(); 81 | 82 | ok $bck->item( $host ), "host $host in seq #$seq"; 83 | 84 | if( $seq == 2 ) { 85 | $main->send(); 86 | } 87 | 88 | is $task->rc(), 0, "worker command succeeded ($host)"; 89 | }); 90 | 91 | $pogo->start(); 92 | $main->recv(); 93 | -------------------------------------------------------------------------------- /t/031Tags.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | 6 | my $nof_tests = 7; 7 | plan tests => $nof_tests; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | use Log::Log4perl qw(:easy); 16 | # Log::Log4perl->easy_init( { level => $DEBUG, category => 'main' } ); 17 | # Log::Log4perl->easy_init( $DEBUG ); 18 | 19 | use Pogo::Scheduler::Config; 20 | 21 | my $cfg = Pogo::Scheduler::Config->new(); 22 | 23 | $cfg->load( <<'EOT' ); 24 | tag: 25 | colo.usa: 26 | - host1 27 | colo.mexico: 28 | - host2 29 | EOT 30 | 31 | my $members = $cfg->members( "colo" ); # host1, host2 32 | 33 | is scalar @$members, 2, "member ok"; 34 | is $members->[0], "host1", "member ok"; 35 | is $members->[1], "host2", "member ok"; 36 | 37 | my $mexico = $cfg->members( "colo.mexico" ); # host2 38 | 39 | is scalar @$mexico, 1, "child ok"; 40 | is $mexico->[0], "host2", "child ok"; 41 | 42 | # custom tag resolver 43 | $members = $cfg->members( "Example bonk schtonk" ); 44 | is $members->[0], "foo", "external tag resolver member ok"; 45 | is $members->[1], "bar", "external tag resolver member ok"; 46 | -------------------------------------------------------------------------------- /t/032TagExternal.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | 6 | my $nof_tests = 1; 7 | plan tests => $nof_tests; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | use Log::Log4perl qw(:easy); 16 | # Log::Log4perl->easy_init( { level => $DEBUG, category => 'main' } ); 17 | # Log::Log4perl->easy_init( $DEBUG ); 18 | 19 | use Pogo::Plugin; 20 | my $tagex = Pogo::Plugin->load('TagExternal',{ 21 | required_methods => [ 'members' ] } ); 22 | 23 | my $members = $tagex->members( "bonkgroup" ); 24 | 25 | is $members->[0], "foo", "example plugin"; 26 | -------------------------------------------------------------------------------- /t/033Cache.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | 6 | my $nof_tests = 2; 7 | plan tests => $nof_tests; 8 | 9 | BEGIN { 10 | use FindBin qw( $Bin ); 11 | use lib "$Bin/lib"; 12 | use PogoTest; 13 | } 14 | 15 | use Log::Log4perl qw(:easy); 16 | # Log::Log4perl->easy_init( { level => $DEBUG, category => 'main' } ); 17 | 18 | use Pogo::Util::Cache; 19 | my $cache = Pogo::Util::Cache->new( expire => 0.1 ); 20 | 21 | $cache->set( "foo", "bar" ); 22 | 23 | is $cache->get( "foo" ), "bar", "item cached"; 24 | 25 | my $cv = AnyEvent->condvar(); 26 | 27 | my $timer = AnyEvent->timer( after => 0.2, cb => sub { 28 | is $cache->get( "foo" ), undef, "item expired"; 29 | $cv->send(); 30 | } ); 31 | 32 | $cv->recv(); 33 | -------------------------------------------------------------------------------- /t/034PonyExpress.pm: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | use Pogo::API; 6 | use Pogo::Dispatcher; 7 | use Pogo::Dispatcher::PonyExpress; 8 | 9 | my $nof_tests = 1; 10 | plan tests => $nof_tests; 11 | 12 | BEGIN { 13 | use FindBin qw( $Bin ); 14 | use lib "$Bin/lib"; 15 | use PogoTest; 16 | } 17 | 18 | use Log::Log4perl qw(:easy); 19 | # Log::Log4perl->easy_init( { level => $DEBUG } ); 20 | 21 | my $cv = AnyEvent->condvar(); 22 | 23 | my $dispatcher = Pogo::Dispatcher->new(); 24 | 25 | $dispatcher->reg_cb( "dispatcher_controlport_message_received", sub { 26 | my( $c, $data ) = @_; 27 | 28 | is $data->[0], "hello", "message received"; 29 | $cv->send(); 30 | } ); 31 | 32 | $dispatcher->start(); 33 | 34 | 35 | my $api_server = Pogo::API->new(); 36 | $api_server->standalone(); 37 | 38 | my $pe = Pogo::Dispatcher::PonyExpress->new( 39 | peers => [ "0.0.0.0" ], 40 | ); 41 | 42 | $pe->send( ["hello"] ); 43 | 44 | # start event loop 45 | $cv->recv(); 46 | -------------------------------------------------------------------------------- /t/035Password.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | use Pogo::API; 6 | use Pogo::Dispatcher; 7 | use Pogo::Dispatcher::PonyExpress; 8 | use Pogo::Defaults qw( 9 | @POGO_DISPATCHER_TEST_CONTROLPORT_NETLOCS 10 | @POGO_DISPATCHER_TEST_WORKERCONN_NETLOCS 11 | ); 12 | 13 | my $nof_tests = 4; 14 | plan tests => $nof_tests; 15 | 16 | BEGIN { 17 | use FindBin qw( $Bin ); 18 | use lib "$Bin/lib"; 19 | use PogoTest; 20 | } 21 | 22 | use Log::Log4perl qw(:easy); 23 | # Log::Log4perl->easy_init( { level => $DEBUG } ); 24 | 25 | my $cv = AnyEvent->condvar(); 26 | 27 | my @dispatchers = (); 28 | 29 | my @dispatcher_cps = @POGO_DISPATCHER_TEST_CONTROLPORT_NETLOCS; 30 | my @dispatcher_wcs = @POGO_DISPATCHER_TEST_WORKERCONN_NETLOCS; 31 | 32 | my $pw_updates_expected = 2; 33 | 34 | for ( 1 .. scalar @POGO_DISPATCHER_TEST_CONTROLPORT_NETLOCS ) { 35 | 36 | my( $cp_host, $cp_port ) = split /:/, shift @dispatcher_cps; 37 | my( $wc_host, $wc_port ) = split /:/, shift @dispatcher_wcs; 38 | 39 | my $dispatcher = Pogo::Dispatcher->new( 40 | controlport_host => $cp_host, 41 | controlport_port => $cp_port, 42 | workerconn_host => $wc_host, 43 | workerconn_port => $wc_port, 44 | ); 45 | 46 | push @dispatchers, $dispatcher; 47 | 48 | $dispatcher->reg_cb( "dispatcher_password_update_received", sub { 49 | my( $c, $jobid ) = @_; 50 | 51 | is $jobid, "z12345", "password update received"; 52 | } ); 53 | 54 | $dispatcher->reg_cb( "dispatcher_password_update_done", sub { 55 | my( $c, $jobid ) = @_; 56 | 57 | my $p = $dispatcher->{ password_cache }->get( "z12345" ); 58 | 59 | is $p->{ foo }, "bar", "password saved"; 60 | 61 | if( --$pw_updates_expected == 0 ) { 62 | $cv->send(); 63 | } 64 | } ); 65 | 66 | $dispatcher->start(); 67 | } 68 | 69 | my $api_server = Pogo::API->new(); 70 | $api_server->standalone(); 71 | 72 | my $pe = Pogo::Dispatcher::PonyExpress->new( 73 | peers => [ @POGO_DISPATCHER_TEST_CONTROLPORT_NETLOCS ], 74 | ); 75 | 76 | $pe->send( { method => "password", 77 | jobid => "z12345", 78 | passwords => { foo => "bar" } } ); 79 | 80 | # start event loop 81 | $cv->recv(); 82 | -------------------------------------------------------------------------------- /t/036PasswordCrypt.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | use Sysadm::Install qw( slurp ); 6 | use Pogo::Client::Util qw( password_encrypt password_decrypt ); 7 | 8 | my $nof_tests = 4; 9 | plan tests => $nof_tests; 10 | 11 | BEGIN { 12 | use FindBin qw( $Bin ); 13 | use lib "$Bin/lib"; 14 | use PogoTest; 15 | } 16 | 17 | use Log::Log4perl qw(:easy); 18 | 19 | my $cert = "$Bin/certs/worker.crt"; 20 | my $privkey = "$Bin/certs/worker.key"; 21 | 22 | my $crypt = password_encrypt( $cert, "abc" ); 23 | 24 | ok length($crypt) > 100, "password encrypted"; 25 | 26 | my $clear = password_decrypt( $privkey, $crypt ); 27 | 28 | is $clear, "abc", "clear text"; 29 | 30 | my $cert_data = slurp $cert; 31 | 32 | $crypt = password_encrypt( $cert, "abc" ); 33 | 34 | ok length($crypt) > 100, "password encrypted"; 35 | 36 | my $privkey_string = slurp $privkey; 37 | 38 | $clear = password_decrypt( \$privkey_string, $crypt ); 39 | is $clear, "abc", "clear text"; 40 | -------------------------------------------------------------------------------- /t/037SSH-Agent.t: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | use strict; 3 | use warnings; 4 | use Test::More; 5 | use Sysadm::Install qw( slurp ); 6 | use POSIX qw( PIPE_BUF ); 7 | 8 | my $nof_tests = 3; 9 | plan tests => $nof_tests; 10 | 11 | BEGIN { 12 | use FindBin qw( $Bin ); 13 | use lib "$Bin/lib"; 14 | } 15 | 16 | use Log::Log4perl qw(:easy); 17 | # Log::Log4perl->easy_init( { level => $DEBUG, layout => "%F{1}-%L: %m%n" } ); 18 | 19 | use Pogo::Util::SSH::Agent; 20 | 21 | my $agent = Pogo::Util::SSH::Agent->new(); 22 | 23 | my $cv = AnyEvent->condvar(); 24 | 25 | $agent->reg_cb( "ssh_key_added_ok", sub { 26 | ok 0, "long key accepted"; 27 | $cv->send(); 28 | } ); 29 | 30 | $agent->reg_cb( "ssh_key_added_fail", sub { 31 | ok 1, "long key rejected"; 32 | $cv->send(); 33 | } ); 34 | 35 | $agent->reg_cb( "shutdown_complete", sub { 36 | ok 1, "shutdown_complete"; 37 | } ); 38 | 39 | $agent->reg_cb( "ssh_agent_ready", sub { 40 | my( $auth_sock, $agent_pid ) = @_; 41 | 42 | ok 1, "auth socket reported"; 43 | 44 | $agent->key_add( "x" x ( PIPE_BUF + 1 ) ); 45 | } ); 46 | 47 | $agent->start(); 48 | 49 | $cv->recv(); 50 | 51 | $agent->shutdown(); 52 | -------------------------------------------------------------------------------- /t/certs/README: -------------------------------------------------------------------------------- 1 | These certificates are for testing only. Their private keys are exposed 2 | as well, so DO NOT USE them in production, because they won't provide any 3 | security. 4 | -------------------------------------------------------------------------------- /t/certs/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIC6TCCAlICCQDG/oYp70c5ujANBgkqhkiG9w0BAQUFADCBuDELMAkGA1UEBhMC 3 | VVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28x 4 | PzA9BgNVBAoUNlNsb3BweSBDQSBJbmMuIC0gV2UgYXBwcm92ZSBBbnl0aGluZyB3 5 | aXRob3V0IGNoZWNraW5nITELMAkGA1UECxMCSVQxFjAUBgNVBAMTDXNvbWV3aGVy 6 | ZS5jb20xFjAUBgkqhkiG9w0BCQEWB2FAYi5jb20wHhcNMTIwMzAxMTc1ODI1WhcN 7 | MTMwMzAxMTc1ODI1WjCBuDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju 8 | aWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xPzA9BgNVBAoUNlNsb3BweSBDQSBJ 9 | bmMuIC0gV2UgYXBwcm92ZSBBbnl0aGluZyB3aXRob3V0IGNoZWNraW5nITELMAkG 10 | A1UECxMCSVQxFjAUBgNVBAMTDXNvbWV3aGVyZS5jb20xFjAUBgkqhkiG9w0BCQEW 11 | B2FAYi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALJynoMNF166SjRy 12 | UXKgdYvlFdVnkZv50agvM7q96j8vSPTaHW/0NvVKS/gtWMOagbh5Txb87TivsS3p 13 | VODrn9VPD/JcI+l0Cr9R/LJ543oU6cEqiU4B/ttq83c6KxG7t+p1vy62tU8EoP1M 14 | uVm0FHkgDOR1fd6n9sw0WaWok8NZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAoJGo 15 | QGw6P3IMeMvMs8mxT1rimywljfg7f57pFhVbx0fU7jFiEuJOeLVXJiauV1+VrsZj 16 | G9HWEGr+LKCCSfMOtoNPQ9Ydmeub6irfbsN8MrOlWOXcl4HZshd1sbcC3NAogPyY 17 | HBvSvA1cl5VSGLwStSQ4RtUCNFx6Lcmrq9uLQT4= 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /t/certs/dispatcher.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXQIBAAKBgQDRaVfMwgCUcTq+Jocqs1p768ITUkHohioun2otc/yEGyqrtxof 3 | rC7MGAS1+oHR+2ZdyWEzf1yReX9h8n9K1oosCWkftcK8rdKR+Buv/z0mC3noO5Az 4 | DchtU00n1dr+LkxygOQhVHD/C51lpSAoUX/sXJaUxcSW9QMvsE9dOzOWdQIDAQAB 5 | AoGBAIYRsXqQAhsHWxp+RC9cYGPSDpCcK0IZE0yCF1I+Xb6ePfVt5rW8YMGd5vYz 6 | CYZMM797vFViBvvEE3+75y8cp5xcDHGmdmGkJLfMLJqqwI9qC6QRRMrcTJhVhSQ9 7 | E9BY0BeBJ+A1AEFgXPsnLYck7bdsyVJ+ih1SzJefY4f6/RiJAkEA/15LYuEKxjGt 8 | OMChPKc4jQY/35VibAF1O15jnU5xVtngxkkKoEpi8LA0wbxygy6oCFcF7n4+VZeD 9 | hZKR4pk4LwJBANHt8o50dLelNrH6pr+WqKrKNeeiWEIQDy4lDsQGe5uKuobuZnef 10 | afwpUQd02lzEKkkXKMdPWkO3zW56zltkDpsCQQCjhs+BhxhuKDuDnx7hBzgYXosi 11 | creu8BQRK3Vgs22yrxzX/Mf4Mwo+lKeD9FfkF0l05b0fpunlx3tqWpxe3bzzAkAF 12 | wmdzLRK+rxOvEldczj9WYDHWZwfQ2CvyciXTjvH5NHclmIjLI15/AossjzImdWNL 13 | mg0OWsj5LqO+MjRTIY2dAkA94MlJw6YeQsmmR5MFTgb1SaPjHCMHGVVVA2EdNuFN 14 | XBG9nONzpYibKW9wTFuUNCDSLXy74bsO9bP4isgWaP9R 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /t/certs/worker.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICWwIBAAKBgQCanitfH5gFIGBuBzw+W4tixAwe9oG7E9H84v5l957x4fjpYCdW 3 | qY3m6spiqMQqqRqk1akDl/u+GhTPAHZ2NBnFFqPV2Qf2sFRTTqBFEQofBsKaxucx 4 | +zimkcIqWKrIQgS5gD5MfBBg1n523odzgWLmm8rw4vbQSNhaqme7luALuwIDAQAB 5 | AoGAL4eDqaAaqSjEu835lOmrNVcyqqn4QzvahzR4I3w1HgHq9EKclSVV+7AdOqrK 6 | cpq9GAKeC/7CYjO+RcvMnpVxfgwTdcGjy926EcoPlmDV2oEyQ9/FwJA0aeOu2CcA 7 | +LPgDNoZtxyiP0lXUIYyJUy2GV4Bygudi6IMBy75dHOnzHECQQDMvQTv1H2o1Mzs 8 | dFythyHx0MvCiSArp7246hM2Jtj/QJgnJzwh7xphpk2QwrWFBfe3tCqDLbiJcNyl 9 | PncTQze/AkEAwVSb1OALF6McgU/qHI0wLU6o2BMkuD+iBAOTnentN4X7jgVvrWVc 10 | kn7UyA3xNeI0pwDXb1Gnf0MvTH3UMYVLBQJAB1tneQLGvTFgZ8LKrcWkV58sI0Jw 11 | MIFnlOR8aj69H3b/wLBtPb7s0MN8GA6XHT+YpjZILMyQzAeNNjbnan7I2wJAOUav 12 | xCl8H8ybLVRXr43EsCeVri49urhfb4D/wtEDDmgLVtAVffGBs4UP1RUMWUJjBvcg 13 | 3EH8tZ9Z6/d7XhB3YQJAJWZr0CKU+Y87aYXptX8b3Jxj3j549roLgQQyWB90HItO 14 | +mea8OdwMD+WUH9yHhdFS76sLCpHMvJ7EB8reRlGhQ== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /t/cfgs/one.cfg: -------------------------------------------------------------------------------- 1 | tag: 2 | # no tags 3 | sequence: 4 | - host3 5 | - host2 6 | - host1 7 | -------------------------------------------------------------------------------- /t/cfgs/triple.cfg: -------------------------------------------------------------------------------- 1 | # sample configuration file 2 | 3 | tag: 4 | colo: 5 | one: 6 | - host1 7 | - host2 8 | - host3 9 | two: 10 | - host4 11 | - host5 12 | - host6 13 | three: 14 | - host7 15 | - host8 16 | - host9 17 | sequence: 18 | foo: 19 | - $colo.one 20 | - $colo.two 21 | bar: 22 | - $colo.three 23 | -------------------------------------------------------------------------------- /t/keys/nopp: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEA1fbGvcRmGy6oVrtbVqqjMM3LEVgUkzvCZhsLxdj2ptvWex8U 3 | vatlYUqtdlKg03dwf8XBdi4zLOpu6zPEFi8XvaxaBeBz7NxmF9CDIzuWw1NM+mZP 4 | ukGPYyzXWDWfVGLJGFYtqrAYtKoAaO+46EW2V2sfaTWcCjUdvGVl0/7klfiNnR80 5 | iwBbuv0UOCVE4D7Vz3phUHuVGFs/1FLCOyXVZyDrQPHVkW4AT1RjDjMyHm0w/cs1 6 | YI2wKU0kKKFdHmBbQXw2twMWZbCteYUENRASh/BUeNVNDznqlrFSID+38KiMqT/O 7 | u1qImTOehXsOiXlI9i2ZCfCmEmEAYq0LQC838QIBIwKCAQBn7OQwSXNsSdy8aaFk 8 | nAYfBN75y7I44oL+ZOh2CkvqpUrrWD1GLq2Vp+3aYqXjDiCzFujwQlNe9YZU++Lm 9 | NCF5YlecdFWQTcswI3LlOjNI7fIwetZEhj5UvgIyKKx5cc9jl5KGGwSvhcWvT914 10 | Idw5FsYdKKrgYvEvnvbx8NVtaTU+mWxoRe0PYXMsiI3oEvSYl9HLkQUqbhN1Y5T+ 11 | Zuoog9i0c+cTfgDFqoCB5JA5rzAB/5o3cwlg9urPMIDbf0tE1hsaFuNwuKR8x7QY 12 | RLW1shULyye9wO6VAxnQwS68mXhjJEVJFCa3himwWf7RRC6zQ5dlf31MJQis8REG 13 | g/vbAoGBAPZiAfRfHS/wbwj0qu1NuAPRlGyMINaK2JdV1GABBkLmDg5wsLrGgK6C 14 | EVuiP2yQ9vPReR5jlkoZ3lC+PH0yJ8hvvQEC0HV+WI++jyMTYvpTptYcEGs/U7Pm 15 | 7RGhDCsZiPbmkGFum46b5kQkiDj7HrNENSYHi+CpDTWrdgSMhlYFAoGBAN5Q0lHr 16 | y60jXAAF6Lrw9mHw6Z8wTkqBctrJC7cBLZJLxy23Fj8MNTIYL0okSmBh/n/7B50/ 17 | gwd0+f8LHyHsFGFEBmdRTsyk6wdQpgTvtjivJiXbE4/975bIRWWzS3fpayVvCmYu 18 | wqpHOSKqk+cMsBduEvAEQCzbniJEGYlL5HH9AoGAd6vyUh+R1XTIN4zIDNybNQ4G 19 | Q1oBUkNwhAUeAr6rRRCnvd72wR6WRiHrLIIBjIDs+hVJdSkOe8Nr+1UWEOx5uSBU 20 | fNV7McEGcbRUJvrJrMmLjJFJzbELZgJzJdHhVsNCho0+0D0Juku4/IbF0oiZ4gsv 21 | wgOqVy2KEsD+zwJtIncCgYEA1/a9rqqLV7vy+LVIexX2qEkddhGrI841Dwxxx7gA 22 | Yjr8AIX4WoDjN/o8kSqRZPF64rlX2pV3+J2FI6RnYsgTzDNz71ZMjEhvSO9CMK5Z 23 | PmEAfIusmoGm6j7kVCqD05JK0+g1/Nz3nhlNciIMBQUC1O6WDbr8g1kABAejxzPH 24 | +bMCgYEAhtn+/SlcPRSbh90Ghv2ys67ga3cTFj+hXCotVkvfGGu5nA29QXxkka2y 25 | xx//lsBuHAHFq2rcqktz4VERCgg4nT3v33j13vRFEZpkMl33aYXnc1vvIur8NZHE 26 | hNV0NLsHq/b8VjnRzNBWqjKQXeIUurGtt2Bso/xGkYRFEfUim88= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /t/keys/nopp.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1fbGvcRmGy6oVrtbVqqjMM3LEVgUkzvCZhsLxdj2ptvWex8UvatlYUqtdlKg03dwf8XBdi4zLOpu6zPEFi8XvaxaBeBz7NxmF9CDIzuWw1NM+mZPukGPYyzXWDWfVGLJGFYtqrAYtKoAaO+46EW2V2sfaTWcCjUdvGVl0/7klfiNnR80iwBbuv0UOCVE4D7Vz3phUHuVGFs/1FLCOyXVZyDrQPHVkW4AT1RjDjMyHm0w/cs1YI2wKU0kKKFdHmBbQXw2twMWZbCteYUENRASh/BUeNVNDznqlrFSID+38KiMqT/Ou1qImTOehXsOiXlI9i2ZCfCmEmEAYq0LQC838Q== mschilli@pyramidlake.corp.yahoo.com 2 | -------------------------------------------------------------------------------- /t/keys/pp: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,AB36C419B6881DFB 4 | 5 | BBKsWvHi5hdXEkOrqaJ2VvbH8cT+Q7yyfDBkbD99IerORGthZRyN+sdKsXmR3idP 6 | Ig1La/a39u90tLGSCjbL8dLdeSr8mD4a8cVPqShYOUQxOw/mhHdkh0gN1eFl6/nD 7 | g5/q9XuOZIXZtzOuM1VX6DUT3BQlU7225rbspJfHh/F+UKWRGv55wfy4YYyHbHcE 8 | En7IPP/JrfUlSkTDZ0wXUJJLEfmXY96SOsAduy+UdFcXcNryzZwhy36bmWbhvM9p 9 | RPgN6SFBhGfbzRXD8cq7iBvXAEx0qCbqBs1VveO3kMbKv8tuW6Pk7irjITd2EUSq 10 | eISpOd8yEUCMxjvc2ngQi8DNnJjmxjOaUtL17VZiklUt/HAStmIe7AzlpfwmtyDu 11 | XVwvWbRHXxOmm0sYBehKFY6/IyPw79iJlgyPCS19kN3wviOFkx/Jlsx3cZcEXWdm 12 | BtHcEqn/QDOqLVQFnQSGd0vltYtvs7NSoI9MTwKYDfiK4dlpxRLlOUiihL4lqAO9 13 | xJHbNLAqdraQnmIygDGKdHxAtWp6e+pNjl4Las4llCoT7/jn3jbk0kDUpTEwdPzB 14 | MqskY1zbhbK9V4jO3d5YwVEeG/khd8w6RujcgPUSfuGdec4arT8L6rIzjm5l5IVc 15 | iiUnb94rKm37xsXJLkmALUL96fIDvwLfRCP7l0XLYGxFOF5zickO0dfVRLwXR6Mg 16 | 9eQ+nQZx1Ff0h8bWWMEDuaIjjDoql2dz52C4jBaIQZJpb0TraPSGpKgJlkOUv1x+ 17 | sM3fa7huMJ07bYghAimkYzwAc2kQcOltJZonXLC//evDrjff5LR2fjTdj5aTHrcl 18 | jXIWyMxCJXSLMzu/iAC0Zruuc97jr6Rf4s/9gElwYeTC1uXbm+7OGgpywZlrjNHL 19 | GTHj4UxH8KQ8B3TEa/2GG5g8ZZir9AOmBLtmqM6K+qvUgobX3g2pO95NLBa2o5at 20 | G6DVMw0t8pFD71tDSjgtbBC5+4nQXx+35ip2Wr9v/Gg4lCD4Dmtp2LMnHTaJfjLy 21 | 7QEHiRWCMZ6RmEVA+kWZqcJdrY3dLynxn9PzkUqQwk9OTb7QGSnaID8iQsFbP/XO 22 | UkSZin3wJy7HVBc4E6WIe3MR5MHussHQanD1paGUcebkbDVhbBenuJyfikejJ/F/ 23 | 4cPl6K0K4FwZPID8vXPGH+9jd24AEjMkMTZbYsLhhPK3vvhIChfBr70bUpggw2uI 24 | Atag7LVlndmGTft49iWZHegNuzgUOr00EbL6zGOOVyWtSpL1/EuGvScYF4qXLQ/o 25 | gVyk2U3wEDPtsW6jMaiDHAN9WP/JM8pT441pFcttQ75es5i5B8xG/E4tyA5fNB3B 26 | SdyfI+1Ndwfxkfzzf0BHRYoH0YBIhDLMOnVeJZev3Mm9hAFpz7nuHyWsCS1+UvgY 27 | Z4DDXJcg2XWGIfzX82A9/sibwarwO0nqSmqmxeHEJ/OoWFxnJheIWVrKYmZKr8wm 28 | FWM+7A9Sz80mVGaB4Ctwc5BHILEe/36kPtgRuY4BVGw2s0StfVfhN78CZrjCYt0y 29 | Y3rRBQGrohxM/4ufmm6eArEFLETTkppwwkPNTLRTA6lwdNYKCD9AkA== 30 | -----END RSA PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /t/keys/pp.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA50tygNV3hKPIYc7MCiZidUzU3YvlndYkyNsc9jIwiZg+6BLPOLc/KdZtGPIi3KszvjWnfCB9CtBTSdCcULCXdAC6bN44wbZTqUWBUJfBRlC8Q3rjPBmvRHlpV4puKWMmDf9lHpHdZKRb6IMcaDBBQUF0nJYGzDsBQxYbPuC2a+undAEXunYCd++Drb1qqIia52PXJcocWT3tbcfleuWfWYJzAXywzSPF3B6xEHEDO7tND/c0cnYrpTcLEWMSS1GogVpemLhvzRKOeu2+woLwVk9bRKuBIz0N8Vqbht3QNXizvncYnRWnR5GBi+PDj6K8d7OLSXAU24OIWRQLoZ7z9Q== mschilli@pyramidlake.corp.yahoo.com 2 | -------------------------------------------------------------------------------- /t/lib/Pogo/Plugin/Test/Default.pm: -------------------------------------------------------------------------------- 1 | ########################################### 2 | package Pogo::Plugin::Test::Default; 3 | ########################################### 4 | use strict; 5 | use warnings; 6 | 7 | ########################################### 8 | sub new { 9 | ########################################### 10 | my($class, %options) = @_; 11 | 12 | my $self = { 13 | %options, 14 | }; 15 | 16 | bless $self, $class; 17 | } 18 | 19 | ########################################### 20 | sub priority { 21 | ########################################### 22 | my($self) = @_; 23 | 24 | return 10; 25 | } 26 | 27 | 1; 28 | 29 | __END__ 30 | 31 | =head1 NAME 32 | 33 | Pogo::Plugin::Test::Default - Pogo test plugin 34 | 35 | =head1 SYNOPSIS 36 | 37 | use Pogo::Plugin::Test::Default; 38 | 39 | my $testplugin = Pogo::Plugin::Test::Default->new(); 40 | 41 | =head1 DESCRIPTION 42 | 43 | A plugin to test the Pogo plugin framework. 44 | 45 | =head1 LICENSE 46 | 47 | Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 48 | 49 | Licensed under the Apache License, Version 2.0 (the "License"); 50 | you may not use this file except in compliance with the License. 51 | You may obtain a copy of the License at 52 | 53 | http://www.apache.org/licenses/LICENSE-2.0 54 | 55 | Unless required by applicable law or agreed to in writing, software 56 | distributed under the License is distributed on an "AS IS" BASIS, 57 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 58 | See the License for the specific language governing permissions and 59 | imitations under the License. 60 | 61 | =head1 AUTHORS 62 | 63 | Mike Schilli 64 | Ian Bettinger 65 | 66 | Many thanks to the following folks for implementing the 67 | original version of Pogo: 68 | 69 | Andrew Sloane , 70 | Michael Fischer , 71 | Nicholas Harteau , 72 | Nick Purvis , 73 | Robert Phan , 74 | Srini Singanallur , 75 | Yogesh Natarajan 76 | 77 | -------------------------------------------------------------------------------- /t/lib/PogoTest.pm: -------------------------------------------------------------------------------- 1 | 2 | use Log::Log4perl qw(:easy); 3 | use Getopt::Std; 4 | 5 | getopts( "v", \my %opts ); 6 | 7 | if( $opts{ v } ) { 8 | Log::Log4perl->easy_init({ level => $DEBUG, layout => "%F{2}-%L: %m%n" }); 9 | DEBUG "Verbose mode"; 10 | } 11 | 12 | 1; 13 | -------------------------------------------------------------------------------- /t/tmpl/index.tmpl: -------------------------------------------------------------------------------- 1 |

Pogo

2 | 3 | Hello there. 4 | -------------------------------------------------------------------------------- /tmpl/index.tmpl: -------------------------------------------------------------------------------- 1 |

Pogo

2 | 3 | Hello there. 4 | -------------------------------------------------------------------------------- /ui/assets/pogo.css: -------------------------------------------------------------------------------- 1 | .oss.yui3-skin-sam .pogo-datatablegroup .yui3-tabview-list { 2 | text-align: right; 3 | padding-right: 2%; 4 | } 5 | .yui3-datatable-col-command { 6 | font-family: "Lucida Console", monospace; 7 | font-size: 90%; 8 | } 9 | 10 | .metadata code { 11 | font-family: "Lucida Console", monospace; 12 | font-size: 90%; 13 | overflow: auto; 14 | margin: 0 auto; 15 | padding: 5px; 16 | width: 90%; 17 | border: 1px solid #ddd; 18 | background-color: #fefefe; 19 | } 20 | 21 | .metadata span { 22 | word-break: break-all; 23 | word-wrap: break-word; 24 | } 25 | 26 | .metadata .yui3-g { 27 | margin-top: 15px; 28 | } 29 | 30 | .yui3-datatable-col-duration1 span { 31 | display: inline-block; 32 | text-indent: -9000px; 33 | } 34 | .yui3-datatable-col-duration1 span.duration { 35 | background-color: green; 36 | } 37 | 38 | .yui3-paginator { 39 | margin-top: 10px; 40 | text-align: center; 41 | } 42 | 43 | iframe { 44 | width: 100%; 45 | height: 500px; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pogo 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 |
15 | Pogo 16 | 17 |
this is
18 |
19 |
20 |
21 | 22 | 23 |
24 | 25 |
26 |
27 | 28 | 29 |
30 | 43 |
44 | 45 | 46 | 47 | 48 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /ui/js/build/pogo-app/pogo-app-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-app",function(a){a.namespace("Pogo").App=new a.Base.create("pogo-app",a.App,[],{views:{home:{type:"Pogo.View.Dashboard"},user:{type:"Pogo.View.User"},job:{type:"Pogo.View.Job"},host:{type:"Pogo.View.Host"}},handleHome:function(b){a.one("title").set("text","Pogo - Home");this.showView("home");},handleUser:function(c){var b=c.params.name;a.one("title").set("text","Pogo - "+b+"'s Jobs");this.showView("user",{user:b});},handleJob:function(c){var d=c.params.jobid,b=new a.Pogo.Model.Job({jobid:d});b.after("load",function(){a.one("title").set("text","Pogo - Job "+d);this.showView("job",{model:b});},this);b.load();},handleHost:function(d){var e=d.params.jobid,b=d.params.hostname,c=new a.Pogo.Model.Job({jobid:e});c.after("load",function(){a.one("title").set("text","Pogo - Job "+e+" Host: "+b);this.showView("host",{model:c,host:b});},this);c.load();},handleInvalidPage:function(b){a.one("title").set("text","Pogo - Unknown request: "+b.path);this.showView("home");},render:function(){a.one(".oss-tools-content a").set("href",a.Pogo.Env.root);return this;}},{ATTRS:{serverRouting:{value:true},viewContainer:{value:"#application-content"},routes:{value:[{path:a.Pogo.Env.root,callback:"handleHome"},{path:a.Pogo.Env.root+"user/:name",callback:"handleUser"},{path:a.Pogo.Env.root+"job/:jobid",callback:"handleJob"},{path:a.Pogo.Env.root+"job/:jobid/:hostname",callback:"handleHost"},{path:"*",callback:"handleInvalidPage"}]}}});},"@VERSION@",{requires:["base","app","pogo-view-dashboard","pogo-view-user","pogo-view-job","pogo-view-host","pogo-model-job"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-env/pogo-env-debug.js: -------------------------------------------------------------------------------- 1 | YUI.add('pogo-env', function(Y) { 2 | 3 | /*globals Y,window */ 4 | /** 5 | * The Env module contains static references to global constants 6 | * @module Env 7 | * @namespace Y.Pogo 8 | */ 9 | 10 | /** 11 | * The Env class contains static references to global constants 12 | * @class Env 13 | * @static 14 | */ 15 | Y.namespace('Pogo').Env = { 16 | /** 17 | * Root of the webserver 18 | * @parameter root 19 | * @type String 20 | * @default '/' 21 | * @static 22 | */ 23 | root: '/pogo/', 24 | 25 | /** 26 | * Root URL for the API calls 27 | * @parameter WSRoot 28 | * @type String 29 | * @static 30 | */ 31 | WSRoot: "http://" + window.location.hostname + ":7657/v1", 32 | 33 | /** 34 | * Template for the jobs WS call 35 | * @parameter jobsWS 36 | * @type String 37 | * @static 38 | */ 39 | jobsWS: "{root}/jobs?{params}&cb={callback}", 40 | 41 | /** 42 | * Template for the job WS call 43 | * @parameter jobWS 44 | * @type String 45 | * @static 46 | */ 47 | jobWS: "{root}/jobs/{jobid}?cb={callback}", 48 | 49 | /** 50 | * Template for the job log WS call 51 | * @parameter jobLogWS 52 | * @type String 53 | * @static 54 | */ 55 | jobLogWS: "{root}/jobs/{jobid}/log?cb={callback}", 56 | 57 | /** 58 | * Template for the job hosts list WS call 59 | * @parameter jobHostsWS 60 | * @type String 61 | * @static 62 | */ 63 | jobHostsWS: "{root}/jobs/{jobid}/hosts?cb={callback}", 64 | 65 | /** 66 | * Template for the job host WS call 67 | * @parameter jobHostWS 68 | * @type String 69 | * @static 70 | */ 71 | jobHostWS: "{root}/jobs/{jobid}/hosts/{hostname}?cb={callback}" 72 | }; 73 | 74 | 75 | /** 76 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 77 | * 78 | * Licensed under the Apache License, Version 2.0 (the "License"); you 79 | * may not use this file except in compliance with the License. You may 80 | * obtain a copy of the License at 81 | * 82 | * http://www.apache.org/licenses/LICENSE-2.0 83 | * 84 | * Unless required by applicable law or agreed to in writing, software 85 | * distributed under the License is distributed on an "AS IS" BASIS, 86 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 87 | * See the License for the specific language governing permissions and 88 | * imitations under the License. 89 | */ 90 | 91 | 92 | }, '@VERSION@' ); 93 | -------------------------------------------------------------------------------- /ui/js/build/pogo-env/pogo-env-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-env",function(a){a.namespace("Pogo").Env={root:"/pogo/",WSRoot:"http://"+window.location.hostname+":7657/v1",jobsWS:"{root}/jobs?{params}&cb={callback}",jobWS:"{root}/jobs/{jobid}?cb={callback}",jobLogWS:"{root}/jobs/{jobid}/log?cb={callback}",jobHostsWS:"{root}/jobs/{jobid}/hosts?cb={callback}",jobHostWS:"{root}/jobs/{jobid}/hosts/{hostname}?cb={callback}"};},"@VERSION@"); -------------------------------------------------------------------------------- /ui/js/build/pogo-env/pogo-env.js: -------------------------------------------------------------------------------- 1 | YUI.add('pogo-env', function(Y) { 2 | 3 | /*globals Y,window */ 4 | /** 5 | * The Env module contains static references to global constants 6 | * @module Env 7 | * @namespace Y.Pogo 8 | */ 9 | 10 | /** 11 | * The Env class contains static references to global constants 12 | * @class Env 13 | * @static 14 | */ 15 | Y.namespace('Pogo').Env = { 16 | /** 17 | * Root of the webserver 18 | * @parameter root 19 | * @type String 20 | * @default '/' 21 | * @static 22 | */ 23 | root: '/pogo/', 24 | 25 | /** 26 | * Root URL for the API calls 27 | * @parameter WSRoot 28 | * @type String 29 | * @static 30 | */ 31 | WSRoot: "http://" + window.location.hostname + ":7657/v1", 32 | 33 | /** 34 | * Template for the jobs WS call 35 | * @parameter jobsWS 36 | * @type String 37 | * @static 38 | */ 39 | jobsWS: "{root}/jobs?{params}&cb={callback}", 40 | 41 | /** 42 | * Template for the job WS call 43 | * @parameter jobWS 44 | * @type String 45 | * @static 46 | */ 47 | jobWS: "{root}/jobs/{jobid}?cb={callback}", 48 | 49 | /** 50 | * Template for the job log WS call 51 | * @parameter jobLogWS 52 | * @type String 53 | * @static 54 | */ 55 | jobLogWS: "{root}/jobs/{jobid}/log?cb={callback}", 56 | 57 | /** 58 | * Template for the job hosts list WS call 59 | * @parameter jobHostsWS 60 | * @type String 61 | * @static 62 | */ 63 | jobHostsWS: "{root}/jobs/{jobid}/hosts?cb={callback}", 64 | 65 | /** 66 | * Template for the job host WS call 67 | * @parameter jobHostWS 68 | * @type String 69 | * @static 70 | */ 71 | jobHostWS: "{root}/jobs/{jobid}/hosts/{hostname}?cb={callback}" 72 | }; 73 | 74 | 75 | /** 76 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 77 | * 78 | * Licensed under the Apache License, Version 2.0 (the "License"); you 79 | * may not use this file except in compliance with the License. You may 80 | * obtain a copy of the License at 81 | * 82 | * http://www.apache.org/licenses/LICENSE-2.0 83 | * 84 | * Unless required by applicable law or agreed to in writing, software 85 | * distributed under the License is distributed on an "AS IS" BASIS, 86 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 87 | * See the License for the specific language governing permissions and 88 | * imitations under the License. 89 | */ 90 | 91 | 92 | }, '@VERSION@' ); 93 | -------------------------------------------------------------------------------- /ui/js/build/pogo-formatters/pogo-formatters-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-formatters",function(a){a.namespace("Pogo").Formatters={idFormatter:function(b){b.cell.setContent(a.Lang.sub('{id}',{root:a.Pogo.Env.root,id:b.value}));return false;},commandFormatter:function(c){var b=a.Pogo.Formatters.truncateText(c.value);c.cell.setContent(a.Lang.sub('{command_trunc}',{command:a.Escape.html(c.value),command_trunc:b}));return false;},timeFormatter:function(c){var b=a.DataType.Date.format(new Date(c.value*1000),{format:"%x %X"});return b;},userFormatter:function(b){b.cell.setContent(a.Lang.sub('{username}',{root:a.Pogo.Env.root,username:b.value}));return false;},targetFormatter:function(c){var b=c.value.join(", ");c.cell.setContent(a.Lang.sub('{targets_trunc}',{targets:a.Escape.html(b),targets_trunc:a.Pogo.Formatters.truncateText(b)}));return false;},hostFormatter:function(b){b.cell.setContent(a.Lang.sub('{hostname}',{root:a.Pogo.Env.root,jobid:b.data.jobid,hostname:b.value}));return false;},truncateText:function(c,b){b=b||20;return c.length>b-3?a.Escape.html(c.substring(0,b)+"..."):a.Escape.html(c);}};},"@VERSION@",{requires:["escape","pogo-env","datatype-date"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-loader/pogo-loader-debug.js: -------------------------------------------------------------------------------- 1 | 2 | // Note: this file is auto-generated by meta_join.js. Don't Modify me ! 3 | YUI().use(function(Y) { 4 | 5 | /** 6 | * YUI 3 module metadata 7 | * @module pogo-loader 8 | */ 9 | var CONFIG = { 10 | groups: { 11 | 'pogo': { 12 | base: '/pogo/js/build/', 13 | combine: false, 14 | modules: {"pogo-app":{"path":"pogo-app/pogo-app-min.js","requires":["base","app","pogo-view-dashboard","pogo-view-user","pogo-view-job","pogo-view-host","pogo-model-job"]},"pogo-env":{"path":"pogo-env/pogo-env-min.js","requires":[]},"pogo-formatters":{"path":"pogo-formatters/pogo-formatters-min.js","requires":["escape","pogo-env","datatype-date"]},"pogo-model-host":{"path":"pogo-model-host/pogo-model-host-min.js","requires":["base","model"]},"pogo-model-hostslist":{"path":"pogo-model-hostslist/pogo-model-hostslist-min.js","requires":["base","model-list","pogo-model-host"]},"pogo-model-job":{"path":"pogo-model-job/pogo-model-job-min.js","requires":["base","model","pogo-env","json-parse","jsonp"]},"pogo-model-jobslist":{"path":"pogo-model-jobslist/pogo-model-jobslist-min.js","requires":["base","model-list","pogo-env","querystring-stringify","jsonp","pogo-model-job"]},"pogo-view-dashboard":{"path":"pogo-view-dashboard/pogo-view-dashboard-min.js","requires":["base","pogo-view-multidatatable"]},"pogo-view-host":{"path":"pogo-view-host/pogo-view-host-min.js","requires":["base","view","pogo-view-jobmetadata","pogo-view-hostlog"]},"pogo-view-hostlog":{"path":"pogo-view-hostlog/pogo-view-hostlog-min.js","requires":["base","view"]},"pogo-view-job":{"path":"pogo-view-job/pogo-view-job-min.js","requires":["base","view","pogo-model-hostslist","pogo-view-jobmetadata","pogo-view-jobhostdata"]},"pogo-view-jobhostdata":{"path":"pogo-view-jobhostdata/pogo-view-jobhostdata-min.js","requires":["base","view"]},"pogo-view-jobmetadata":{"path":"pogo-view-jobmetadata/pogo-view-jobmetadata-min.js","requires":["base","view"]},"pogo-view-multidatatable":{"path":"pogo-view-multidatatable/pogo-view-multidatatable-min.js","requires":["base","view","datatable","pogo-model-jobslist","tabview","pogo-formatters","gallery-paginator-dev-preview"]},"pogo-view-user":{"path":"pogo-view-user/pogo-view-user-min.js","requires":["base","pogo-view-multidatatable"]}} 15 | } 16 | } 17 | }; 18 | 19 | if(typeof YUI_config === 'undefined') { YUI_config = {groups:{}}; } 20 | Y.mix(YUI_config.groups, CONFIG.groups); 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /ui/js/build/pogo-loader/pogo-loader-min.js: -------------------------------------------------------------------------------- 1 | YUI().use(function(b){var a={groups:{"pogo":{base:"/pogo/js/build/",combine:false,modules:{"pogo-app":{"path":"pogo-app/pogo-app-min.js","requires":["base","app","pogo-view-dashboard","pogo-view-user","pogo-view-job","pogo-view-host","pogo-model-job"]},"pogo-env":{"path":"pogo-env/pogo-env-min.js","requires":[]},"pogo-formatters":{"path":"pogo-formatters/pogo-formatters-min.js","requires":["escape","pogo-env","datatype-date"]},"pogo-model-host":{"path":"pogo-model-host/pogo-model-host-min.js","requires":["base","model"]},"pogo-model-hostslist":{"path":"pogo-model-hostslist/pogo-model-hostslist-min.js","requires":["base","model-list","pogo-model-host"]},"pogo-model-job":{"path":"pogo-model-job/pogo-model-job-min.js","requires":["base","model","pogo-env","json-parse","jsonp"]},"pogo-model-jobslist":{"path":"pogo-model-jobslist/pogo-model-jobslist-min.js","requires":["base","model-list","pogo-env","querystring-stringify","jsonp","pogo-model-job"]},"pogo-view-dashboard":{"path":"pogo-view-dashboard/pogo-view-dashboard-min.js","requires":["base","pogo-view-multidatatable"]},"pogo-view-host":{"path":"pogo-view-host/pogo-view-host-min.js","requires":["base","view","pogo-view-jobmetadata","pogo-view-hostlog"]},"pogo-view-hostlog":{"path":"pogo-view-hostlog/pogo-view-hostlog-min.js","requires":["base","view"]},"pogo-view-job":{"path":"pogo-view-job/pogo-view-job-min.js","requires":["base","view","pogo-model-hostslist","pogo-view-jobmetadata","pogo-view-jobhostdata"]},"pogo-view-jobhostdata":{"path":"pogo-view-jobhostdata/pogo-view-jobhostdata-min.js","requires":["base","view"]},"pogo-view-jobmetadata":{"path":"pogo-view-jobmetadata/pogo-view-jobmetadata-min.js","requires":["base","view"]},"pogo-view-multidatatable":{"path":"pogo-view-multidatatable/pogo-view-multidatatable-min.js","requires":["base","view","datatable","pogo-model-jobslist","tabview","pogo-formatters","gallery-paginator-dev-preview"]},"pogo-view-user":{"path":"pogo-view-user/pogo-view-user-min.js","requires":["base","pogo-view-multidatatable"]}}}}};if(typeof YUI_config==="undefined"){YUI_config={groups:{}};}b.mix(YUI_config.groups,a.groups);}); -------------------------------------------------------------------------------- /ui/js/build/pogo-loader/pogo-loader.js: -------------------------------------------------------------------------------- 1 | 2 | // Note: this file is auto-generated by meta_join.js. Don't Modify me ! 3 | YUI().use(function(Y) { 4 | 5 | /** 6 | * YUI 3 module metadata 7 | * @module pogo-loader 8 | */ 9 | var CONFIG = { 10 | groups: { 11 | 'pogo': { 12 | base: '/pogo/js/build/', 13 | combine: false, 14 | modules: {"pogo-app":{"path":"pogo-app/pogo-app-min.js","requires":["base","app","pogo-view-dashboard","pogo-view-user","pogo-view-job","pogo-view-host","pogo-model-job"]},"pogo-env":{"path":"pogo-env/pogo-env-min.js","requires":[]},"pogo-formatters":{"path":"pogo-formatters/pogo-formatters-min.js","requires":["escape","pogo-env","datatype-date"]},"pogo-model-host":{"path":"pogo-model-host/pogo-model-host-min.js","requires":["base","model"]},"pogo-model-hostslist":{"path":"pogo-model-hostslist/pogo-model-hostslist-min.js","requires":["base","model-list","pogo-model-host"]},"pogo-model-job":{"path":"pogo-model-job/pogo-model-job-min.js","requires":["base","model","pogo-env","json-parse","jsonp"]},"pogo-model-jobslist":{"path":"pogo-model-jobslist/pogo-model-jobslist-min.js","requires":["base","model-list","pogo-env","querystring-stringify","jsonp","pogo-model-job"]},"pogo-view-dashboard":{"path":"pogo-view-dashboard/pogo-view-dashboard-min.js","requires":["base","pogo-view-multidatatable"]},"pogo-view-host":{"path":"pogo-view-host/pogo-view-host-min.js","requires":["base","view","pogo-view-jobmetadata","pogo-view-hostlog"]},"pogo-view-hostlog":{"path":"pogo-view-hostlog/pogo-view-hostlog-min.js","requires":["base","view"]},"pogo-view-job":{"path":"pogo-view-job/pogo-view-job-min.js","requires":["base","view","pogo-model-hostslist","pogo-view-jobmetadata","pogo-view-jobhostdata"]},"pogo-view-jobhostdata":{"path":"pogo-view-jobhostdata/pogo-view-jobhostdata-min.js","requires":["base","view"]},"pogo-view-jobmetadata":{"path":"pogo-view-jobmetadata/pogo-view-jobmetadata-min.js","requires":["base","view"]},"pogo-view-multidatatable":{"path":"pogo-view-multidatatable/pogo-view-multidatatable-min.js","requires":["base","view","datatable","pogo-model-jobslist","tabview","pogo-formatters","gallery-paginator-dev-preview"]},"pogo-view-user":{"path":"pogo-view-user/pogo-view-user-min.js","requires":["base","pogo-view-multidatatable"]}} 15 | } 16 | } 17 | }; 18 | 19 | if(typeof YUI_config === 'undefined') { YUI_config = {groups:{}}; } 20 | Y.mix(YUI_config.groups, CONFIG.groups); 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /ui/js/build/pogo-model-host/pogo-model-host-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-model-host",function(a){a.namespace("Pogo.Model").Host=a.Base.create("pogo-model-host",a.Model,[],{},{ATTRS:{host:{value:""},state:{value:""},rc:{value:""},start_time:{value:""},finish_time:{value:""},duration:{value:""},jobid:{value:""},job_start:{value:0},job_finish:{value:0},job_duration:{value:0}}});},"@VERSION@",{requires:["base","model"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-model-hostslist/pogo-model-hostslist-debug.js: -------------------------------------------------------------------------------- 1 | YUI.add('pogo-model-hostslist', function(Y) { 2 | 3 | /*globals Y */ 4 | /** 5 | * The Host Module is responsible for storing info for one or more hosts, and displaying them 6 | * @module host 7 | * @namespace Y.Pogo.Model 8 | * @requires base,modellist,pogo-model-host 9 | */ 10 | 11 | /** 12 | * The Host modellist is a convenience for storing a list of host models 13 | * @class HostsList 14 | * @extends Y.ModelList 15 | * @constructor 16 | * @param {object} config Configuration object: See Configuration Attributes 17 | */ 18 | Y.namespace('Pogo.Model').HostsList = Y.Base.create('pogo-model-hostslist', Y.ModelList, [], { 19 | /** 20 | * Store results in Y.Pogo.Model.Host model objects 21 | * @parameter model 22 | * @type Object 23 | * @default Y.Pogo.Model.Host 24 | * @private 25 | */ 26 | model: Y.Pogo.Model.Host 27 | }); 28 | 29 | 30 | /** 31 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 32 | * 33 | * Licensed under the Apache License, Version 2.0 (the "License"); you 34 | * may not use this file except in compliance with the License. You may 35 | * obtain a copy of the License at 36 | * 37 | * http://www.apache.org/licenses/LICENSE-2.0 38 | * 39 | * Unless required by applicable law or agreed to in writing, software 40 | * distributed under the License is distributed on an "AS IS" BASIS, 41 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 42 | * See the License for the specific language governing permissions and 43 | * imitations under the License. 44 | */ 45 | 46 | 47 | }, '@VERSION@' ,{requires:['base','model-list','pogo-model-host']}); 48 | -------------------------------------------------------------------------------- /ui/js/build/pogo-model-hostslist/pogo-model-hostslist-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-model-hostslist",function(a){a.namespace("Pogo.Model").HostsList=a.Base.create("pogo-model-hostslist",a.ModelList,[],{model:a.Pogo.Model.Host});},"@VERSION@",{requires:["base","model-list","pogo-model-host"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-model-hostslist/pogo-model-hostslist.js: -------------------------------------------------------------------------------- 1 | YUI.add('pogo-model-hostslist', function(Y) { 2 | 3 | /*globals Y */ 4 | /** 5 | * The Host Module is responsible for storing info for one or more hosts, and displaying them 6 | * @module host 7 | * @namespace Y.Pogo.Model 8 | * @requires base,modellist,pogo-model-host 9 | */ 10 | 11 | /** 12 | * The Host modellist is a convenience for storing a list of host models 13 | * @class HostsList 14 | * @extends Y.ModelList 15 | * @constructor 16 | * @param {object} config Configuration object: See Configuration Attributes 17 | */ 18 | Y.namespace('Pogo.Model').HostsList = Y.Base.create('pogo-model-hostslist', Y.ModelList, [], { 19 | /** 20 | * Store results in Y.Pogo.Model.Host model objects 21 | * @parameter model 22 | * @type Object 23 | * @default Y.Pogo.Model.Host 24 | * @private 25 | */ 26 | model: Y.Pogo.Model.Host 27 | }); 28 | 29 | 30 | /** 31 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 32 | * 33 | * Licensed under the Apache License, Version 2.0 (the "License"); you 34 | * may not use this file except in compliance with the License. You may 35 | * obtain a copy of the License at 36 | * 37 | * http://www.apache.org/licenses/LICENSE-2.0 38 | * 39 | * Unless required by applicable law or agreed to in writing, software 40 | * distributed under the License is distributed on an "AS IS" BASIS, 41 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 42 | * See the License for the specific language governing permissions and 43 | * imitations under the License. 44 | */ 45 | 46 | 47 | }, '@VERSION@' ,{requires:['base','model-list','pogo-model-host']}); 48 | -------------------------------------------------------------------------------- /ui/js/build/pogo-model-job/pogo-model-job-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-model-job",function(a){a.namespace("Pogo.Model").Job=a.Base.create("pogo-model-job",a.Model,[],{initializer:function(){this.after("logChange",this.calculateFinishTime,this);this.after("load",this.calculateFinishTime,this);this.calculateFinishTime();},calculateFinishTime:function(){var c=this.get("log"),b,d;if(c&&a.Lang.isArray(c)&&c.length){b=c[c.length-1].time;d=b-this.get("start_time");this.set("finish_time",b,{silent:true});this.set("duration",d,{silent:true});}},prepareJobURL:function(b,c,d){return a.Lang.sub(b,{root:a.Pogo.Env.WSRoot,callback:c,jobid:d||this.get("jobid")});},rangeSetter:function(c){if(!a.Lang.isArray(c)){try{c=a.JSON.parse(c);}catch(b){}}return a.Lang.isArray(c)?c:[];},sync:function(d,b,f){if(d==="read"){var e=function(g){if(g.response&&g.response.job&&a.Lang.isObject(g.response.job)){f(null,g.response.job);}else{f("Could not load job");}},c=function(){f("Could not load job");};a.jsonp(a.Pogo.Env.jobWS,{on:{success:e,failure:c,timeout:c},context:this,format:a.bind(this.prepareJobURL,this),timeout:2000});}else{f("Invalid Action");}},idAttribute:"jobid"},{ATTRS:{jobid:{value:""},user:{value:""},run_as:{value:""},posthook:{value:""},timeout:{value:""},prehook:{value:""},requesthost:{value:""},invoked_as:{value:""},namespace:{value:""},client:{value:""},retry:{value:""},job_timeout:{value:""},state:{value:""},start_time:{value:""},finish_time:{value:""},log:{value:[]},command:{value:""},range:{value:[],setter:"rangeSetter"},host_count:{value:""},job_status:{value:""},hosts:{value:[]},end_time:{value:""}}});},"@VERSION@",{requires:["base","model","pogo-env","json-parse","jsonp"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-model-jobslist/pogo-model-jobslist-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-model-jobslist",function(a){a.namespace("Pogo.Model").JobsList=a.Base.create("pogo-model-jobslist",a.ModelList,[],{model:a.Pogo.Model.Job,prepareJobsURL:function(b,c,d){return a.Lang.sub(b,{root:a.Pogo.Env.WSRoot,callback:c,params:a.QueryString.stringify(d||this.get("params"))});},sync:function(d,b,f){if(d==="read"){var e=function(g){if(g.response&&g.response.jobs&&a.Lang.isArray(g.response.jobs)){f(null,g.response.jobs);}else{f("Could not load jobs");}},c=function(){f("Could not load jobs");};a.jsonp(a.Pogo.Env.jobsWS,{on:{success:e,failure:c,timeout:c},context:this,format:a.bind(this.prepareJobsURL,this),timeout:2000});}else{f("Invalid Action: "+d);}}},{ATTRS:{params:{value:{}}}});},"@VERSION@",{requires:["base","model-list","pogo-env","querystring-stringify","jsonp","pogo-model-job"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-view-dashboard/pogo-view-dashboard-debug.js: -------------------------------------------------------------------------------- 1 | YUI.add('pogo-view-dashboard', function(Y) { 2 | 3 | /*globals Y */ 4 | /** 5 | * The Views Module contains views for displaying data 6 | * @module views 7 | * @namespace Y.Pogo.View 8 | * @requires base,pogo-view-multidatatable 9 | */ 10 | 11 | /** 12 | * The Dashboard View is a means to allow customization of the dashboard beyond the defaults in MultiDatatable. 13 | * @class Dashboard 14 | * @extends Y.Pogo.View.MutiDatatable 15 | * @constructor 16 | * @param {object} config Configuration object: See Configuration Attributes 17 | */ 18 | Y.namespace('Pogo.View').Dashboard = new Y.Base.create('pogo-view-dashboard', Y.Pogo.View.MultiDatatable, []); 19 | 20 | 21 | /** 22 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 23 | * 24 | * Licensed under the Apache License, Version 2.0 (the "License"); you 25 | * may not use this file except in compliance with the License. You may 26 | * obtain a copy of the License at 27 | * 28 | * http://www.apache.org/licenses/LICENSE-2.0 29 | * 30 | * Unless required by applicable law or agreed to in writing, software 31 | * distributed under the License is distributed on an "AS IS" BASIS, 32 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 33 | * See the License for the specific language governing permissions and 34 | * imitations under the License. 35 | */ 36 | 37 | 38 | }, '@VERSION@' ,{requires:['base','pogo-view-multidatatable']}); 39 | -------------------------------------------------------------------------------- /ui/js/build/pogo-view-dashboard/pogo-view-dashboard-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-view-dashboard",function(a){a.namespace("Pogo.View").Dashboard=new a.Base.create("pogo-view-dashboard",a.Pogo.View.MultiDatatable,[]);},"@VERSION@",{requires:["base","pogo-view-multidatatable"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-view-dashboard/pogo-view-dashboard.js: -------------------------------------------------------------------------------- 1 | YUI.add('pogo-view-dashboard', function(Y) { 2 | 3 | /*globals Y */ 4 | /** 5 | * The Views Module contains views for displaying data 6 | * @module views 7 | * @namespace Y.Pogo.View 8 | * @requires base,pogo-view-multidatatable 9 | */ 10 | 11 | /** 12 | * The Dashboard View is a means to allow customization of the dashboard beyond the defaults in MultiDatatable. 13 | * @class Dashboard 14 | * @extends Y.Pogo.View.MutiDatatable 15 | * @constructor 16 | * @param {object} config Configuration object: See Configuration Attributes 17 | */ 18 | Y.namespace('Pogo.View').Dashboard = new Y.Base.create('pogo-view-dashboard', Y.Pogo.View.MultiDatatable, []); 19 | 20 | 21 | /** 22 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 23 | * 24 | * Licensed under the Apache License, Version 2.0 (the "License"); you 25 | * may not use this file except in compliance with the License. You may 26 | * obtain a copy of the License at 27 | * 28 | * http://www.apache.org/licenses/LICENSE-2.0 29 | * 30 | * Unless required by applicable law or agreed to in writing, software 31 | * distributed under the License is distributed on an "AS IS" BASIS, 32 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 33 | * See the License for the specific language governing permissions and 34 | * imitations under the License. 35 | */ 36 | 37 | 38 | }, '@VERSION@' ,{requires:['base','pogo-view-multidatatable']}); 39 | -------------------------------------------------------------------------------- /ui/js/build/pogo-view-host/pogo-view-host-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-view-host",function(a){a.namespace("Pogo.View").Host=a.Base.create("pogo-view-host",a.View,[],{initializer:function(){var c=this.get("model"),d,b=this.get("host");this.metadataView=new a.Pogo.View.JobMetaData({model:c});this.logView=new a.Pogo.View.HostLog();d=c.get("hosts")[b]||{log:""};this.logView.set("logURL",d.log);this.render();this.metadataView.addTarget(this);this.logView.addTarget(this);},destructor:function(){this.metadataView.destroy();this.logView.destroy();delete this.metadataView;delete this.logView;},template:"

{host} for {user} via {jobid}

",render:function(){var c=a.one(a.config.doc.createDocumentFragment()),b=this.get("model");c.append(a.Node.create(a.Lang.sub(this.template,{host:this.get("host"),jobid:b.get("id"),user:b.get("user")})));c.append(this.metadataView.render().get("container"));c.append(this.logView.render().get("container"));this.get("container").setContent(c);return this;}},{ATTRS:{host:{value:""}}});},"@VERSION@",{requires:["base","view","pogo-view-jobmetadata","pogo-view-hostlog"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-view-hostlog/pogo-view-hostlog-debug.js: -------------------------------------------------------------------------------- 1 | YUI.add('pogo-view-hostlog', function(Y) { 2 | 3 | /*globals Y */ 4 | /** 5 | * The Views Module contains views for displaying data 6 | * @module views 7 | * @namespace Y.Pogo.View 8 | * @requires base,view,datatable,pogo-formatters 9 | */ 10 | 11 | /** 12 | * Displays host log information 13 | * @class HostLog 14 | * @extends Y.View 15 | * @constructor 16 | * @param {object} config Configuration object: See Configuration Attributes 17 | */ 18 | Y.namespace('Pogo.View').HostLog = new Y.Base.create('pogo-view-hostlog', Y.View, [], { 19 | /** 20 | * Setup model event 21 | * @method initializer 22 | * @private 23 | */ 24 | initializer: function () { 25 | this.after('logURLChange', this.render, this); 26 | }, 27 | 28 | /** 29 | * The html template for the view (not including the datatable) 30 | * @property template 31 | * @type string 32 | * @protected 33 | */ 34 | template: '

Log

', 35 | 36 | /** 37 | * Renders the view 38 | * @method render 39 | * @return {Object} A reference to this view 40 | */ 41 | render: function () { 42 | var container = this.get('container'); 43 | 44 | container.setContent(Y.Lang.sub(this.template, { 45 | log: this.get('logURL') || "about:blank" 46 | })); 47 | return this; 48 | } 49 | }, { 50 | ATTRS: { 51 | /** 52 | * logURL 53 | * @attribute logURL 54 | * @type String 55 | * @default 'about:blank' 56 | */ 57 | logURL: { 58 | value: 'about:blank' 59 | } 60 | } 61 | }); 62 | 63 | 64 | }, '@VERSION@' ,{requires:['base','view']}); 65 | -------------------------------------------------------------------------------- /ui/js/build/pogo-view-hostlog/pogo-view-hostlog-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-view-hostlog",function(a){a.namespace("Pogo.View").HostLog=new a.Base.create("pogo-view-hostlog",a.View,[],{initializer:function(){this.after("logURLChange",this.render,this);},template:'

Log

',render:function(){var b=this.get("container");b.setContent(a.Lang.sub(this.template,{log:this.get("logURL")||"about:blank"}));return this;}},{ATTRS:{logURL:{value:"about:blank"}}});},"@VERSION@",{requires:["base","view"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-view-hostlog/pogo-view-hostlog.js: -------------------------------------------------------------------------------- 1 | YUI.add('pogo-view-hostlog', function(Y) { 2 | 3 | /*globals Y */ 4 | /** 5 | * The Views Module contains views for displaying data 6 | * @module views 7 | * @namespace Y.Pogo.View 8 | * @requires base,view,datatable,pogo-formatters 9 | */ 10 | 11 | /** 12 | * Displays host log information 13 | * @class HostLog 14 | * @extends Y.View 15 | * @constructor 16 | * @param {object} config Configuration object: See Configuration Attributes 17 | */ 18 | Y.namespace('Pogo.View').HostLog = new Y.Base.create('pogo-view-hostlog', Y.View, [], { 19 | /** 20 | * Setup model event 21 | * @method initializer 22 | * @private 23 | */ 24 | initializer: function () { 25 | this.after('logURLChange', this.render, this); 26 | }, 27 | 28 | /** 29 | * The html template for the view (not including the datatable) 30 | * @property template 31 | * @type string 32 | * @protected 33 | */ 34 | template: '

Log

', 35 | 36 | /** 37 | * Renders the view 38 | * @method render 39 | * @return {Object} A reference to this view 40 | */ 41 | render: function () { 42 | var container = this.get('container'); 43 | 44 | container.setContent(Y.Lang.sub(this.template, { 45 | log: this.get('logURL') || "about:blank" 46 | })); 47 | return this; 48 | } 49 | }, { 50 | ATTRS: { 51 | /** 52 | * logURL 53 | * @attribute logURL 54 | * @type String 55 | * @default 'about:blank' 56 | */ 57 | logURL: { 58 | value: 'about:blank' 59 | } 60 | } 61 | }); 62 | 63 | 64 | }, '@VERSION@' ,{requires:['base','view']}); 65 | -------------------------------------------------------------------------------- /ui/js/build/pogo-view-job/pogo-view-job-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-view-job",function(a){a.namespace("Pogo.View").Job=a.Base.create("pogo-view-job",a.View,[],{initializer:function(){var b=this.get("model"),c=new a.Pogo.Model.HostsList(),d=b.get("id");a.each(b.get("hosts"),function(f,e){f.jobid=d;f.host=e;f.duration=f.finish_time-f.start_time;f.job_start=b.get("start_time");f.job_finish=b.get("finish_time")||(new Date()).getTime()/1000;f.job_duration=b.get("duration");c.add(f);},this);this.metadataView=new a.Pogo.View.JobMetaData({model:b});this.hostsView=new a.Pogo.View.JobHostData({modelList:c,jobid:b.get("id")});this.metadataView.addTarget(this);this.hostsView.addTarget(this);},destructor:function(){this.metadataView.destroy();this.hostsView.destroy();delete this.metadataView;delete this.hostsView;},template:"

{jobid} for {user}

",render:function(){var c=a.one(a.config.doc.createDocumentFragment()),b=this.get("model");c.append(a.Node.create(a.Lang.sub(this.template,{jobid:b.get("id"),user:b.get("user")})));c.append(this.metadataView.render().get("container"));c.append(this.hostsView.render().get("container"));this.get("container").setContent(c);return this;}});},"@VERSION@",{requires:["base","view","pogo-model-hostslist","pogo-view-jobmetadata","pogo-view-jobhostdata"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-view-jobhostdata/pogo-view-jobhostdata-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-view-jobhostdata",function(a){a.namespace("Pogo.View").JobHostData=new a.Base.create("pogo-view-jobhostdata",a.View,[],{initializer:function(){var b=this.get("modelList");b.after("load",this.render,this);b.after("destroy",this.destroy,this);},template:'

{jobid}\'s Hosts

',render:function(){var d,e,b=this.get("container"),c=this.get("modelList");b.setContent(a.Lang.sub(this.template,{jobid:this.get("jobid")}));e=b.one(".hostdata");d=new a.DataTable({columns:[{label:"Host",key:"host",nodeFormatter:a.Pogo.Formatters.hostFormatter},{label:"State",key:"state",width:"100px"},{label:"Time Started",key:"start_time",formatter:function(g){var f=a.Pogo.Formatters.timeFormatter(g);f+=" (+"+Math.floor(g.data.start_time-g.data.job_start)+"s)";return f;},width:"195px"},{label:"Duration",key:"duration",formatter:function(f){return f.value+"s";},width:"75px"},{label:"Timeline",key:"duration",nodeFormatter:function(h){var f=Math.floor(h.value/h.data.job_duration*100),g=Math.floor((h.data.start_time-h.data.job_start)/h.data.job_duration*100);h.cell.setContent(a.Node.create(a.Lang.sub('{per_start}{per}',{per_start:g,per:f,status:h.data.state})));return false;},width:"250px"}],data:c});d.render(e);return this;}},{ATTRS:{jobid:{value:""}}});},"@VERSION@",{requires:["base","view"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-view-jobmetadata/pogo-view-jobmetadata-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-view-jobmetadata",function(a){a.namespace("Pogo.View").JobMetaData=new a.Base.create("pogo-view-jobmetadata",a.View,[],{initializer:function(){var b=this.get("model");b.after("change",this.render,this);b.after("load",this.render,this);b.after("destroy",this.destroy,this);},buttonTemplate:'',table:'

Command

{command}
'+'

Invoked As

{invoked_as}
'+'
'+'

Request Host

{requesthost}
'+'

Retry

{retry}
'+'

Timeout

{timeout}
'+'

Start Time

{start_time}
'+'

End Time

{finish_time}
'+'

State

{state}
'+"
",template:'{buttonTemplate}

Metadata

',render:function(){var f,b=this.get("container"),c=this.get("model"),d=c.toJSON(),e="";d.start_time=a.Pogo.Formatters.timeFormatter({value:d.start_time});d.finish_time=a.Pogo.Formatters.timeFormatter({value:d.finish_time});if(a.Array.indexOf(["ready","waiting","running","gathering"],d.state)>-1){e=this.buttonTemplate;}b.setContent(a.Lang.sub(this.template,{jobid:c.get("id"),user:c.get("user"),buttonTemplate:e,table:a.Lang.sub(this.table,d)}));return this;}});},"@VERSION@",{requires:["base","view"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-view-multidatatable/pogo-view-multidatatable-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-view-multidatatable",function(a){a.namespace("Pogo.View").MultiDatatable=new a.Base.create("pogo-view-multidatatable",a.View,[],{setupPaginator:function(b){var c=new a.Paginator({itemsPerPage:this.get("limit"),totalItems:5,page:this.get("offset")});c.render(b);return c;},setupDatatable:function(b,j,f){var g,d,c,e,h,k,i;if(a.Lang.isString(b)){k=this.get("container").one("."+b);i=this.get("container").one("."+b+"-pg");}c=this.parameterMixIn(f);c=this.limitMixIn(c);g=new a.Pogo.Model.JobsList({params:c});d=new a.DataTable({columns:j});d.render(k);d.set("message","Loading...");h=this.setupPaginator(i);e=function(m){var n=(h.get("page")-1)*h.get("itemsPerPage"),l=n+h.get("itemsPerPage");d.set("data",g._items.slice(n,l));};h.after("pageChange",e,this);g.after("load",e,this);g.load(function(l,m){if(l){alert("Could not load data:\n"+l);d.set("message","Error when loading data.");h.set("totalItems",m.meta.count||5);}});},setupDatatables:function(){var c=this.get("dtCols"),b=this.get("tables");a.each(b,function(d){this.setupDatatable(d.className,c,d.params);},this);},template:"

{title}

",render:function(){var h,g,b=this.get("container"),c=this.get("tables"),e={children:[]},f,d='
';a.each(c,function(j){var i={label:j.label,content:a.Lang.sub(d,{className:j.className})};e.children.push(i);},this);f=new a.TabView(e);b.addClass("pogo-datatablegroup");b.setContent(a.Lang.sub(this.template,{title:this.get("title")}));f.onceAfter("render",this.setupDatatables,this);f.render(b);return this;},parameterMixIn:function(b){return b;},limitMixIn:function(e){var b=this.get("limit"),d=this.get("offset"),c={max:b};if(d){c.offset=d;}return a.mix(e,c);}},{ATTRS:{title:{value:"Pogo Jobs"},limit:{value:25},offset:{value:1},dtCols:{value:[{key:"jobid",label:"Pogo ID",nodeFormatter:a.Pogo.Formatters.idFormatter},{key:"user",label:"User",nodeFormatter:a.Pogo.Formatters.userFormatter},{key:"state",label:"State"},{key:"start_time",label:"Start Time",formatter:a.Pogo.Formatters.timeFormatter},{key:"command",label:"Command",nodeFormatter:a.Pogo.Formatters.commandFormatter},{key:"range",label:"Targets",nodeFormatter:a.Pogo.Formatters.targetFormatter},{key:"host_count",label:"Hosts"}]},tables:{value:[{label:"Active",className:"dt-active",params:{active:1}},{label:"All",className:"dt-all",params:{}}]}}});},"@VERSION@",{requires:["base","view","datatable","pogo-model-jobslist","tabview","pogo-formatters","gallery-paginator-dev-preview"]}); -------------------------------------------------------------------------------- /ui/js/build/pogo-view-user/pogo-view-user-min.js: -------------------------------------------------------------------------------- 1 | YUI.add("pogo-view-user",function(a){a.namespace("Pogo.View").User=new a.Base.create("pogo-view-user",a.Pogo.View.MultiDatatable,[],{parameterMixIn:function(b){b.user=this.get("user");return b;},getTitle:function(){return this.get("user")+"'s Jobs";}},{ATTRS:{user:{value:""},title:{getter:"getTitle"},dtCols:{value:[{key:"jobid",label:"Pogo ID",nodeFormatter:a.Pogo.Formatters.idFormatter},{key:"state",label:"State"},{key:"start_time",label:"Start Time",formatter:a.Pogo.Formatters.timeFormatter},{key:"command",label:"Command",nodeFormatter:a.Pogo.Formatters.commandFormatter},{key:"range",label:"Targets",nodeFormatter:a.Pogo.Formatters.targetFormatter},{key:"host_count",label:"Hosts"}]}}});},"@VERSION@",{requires:["base","pogo-view-multidatatable"]}); -------------------------------------------------------------------------------- /ui/js/src/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | pogo 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ui/js/src/default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-app/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-app 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-app.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,app,pogo-view-dashboard,pogo-view-user,pogo-view-job,pogo-view-host,pogo-model-job 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-app/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-app/tests/pogo-app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-app tests 6 | 7 | 8 | 9 | 10 |

pogo-app Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-env/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-env 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-env.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | #component.requires= 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-env/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-env/js/pogo-env.js: -------------------------------------------------------------------------------- 1 | /*globals Y,window */ 2 | /** 3 | * The Env module contains static references to global constants 4 | * @module Env 5 | * @namespace Y.Pogo 6 | */ 7 | 8 | /** 9 | * The Env class contains static references to global constants 10 | * @class Env 11 | * @static 12 | */ 13 | Y.namespace('Pogo').Env = { 14 | /** 15 | * Root of the webserver 16 | * @parameter root 17 | * @type String 18 | * @default '/' 19 | * @static 20 | */ 21 | root: '/pogo/', 22 | 23 | /** 24 | * Root URL for the API calls 25 | * @parameter WSRoot 26 | * @type String 27 | * @static 28 | */ 29 | WSRoot: "http://" + window.location.hostname + ":7657/v1", 30 | 31 | /** 32 | * Template for the jobs WS call 33 | * @parameter jobsWS 34 | * @type String 35 | * @static 36 | */ 37 | jobsWS: "{root}/jobs?{params}&cb={callback}", 38 | 39 | /** 40 | * Template for the job WS call 41 | * @parameter jobWS 42 | * @type String 43 | * @static 44 | */ 45 | jobWS: "{root}/jobs/{jobid}?cb={callback}", 46 | 47 | /** 48 | * Template for the job log WS call 49 | * @parameter jobLogWS 50 | * @type String 51 | * @static 52 | */ 53 | jobLogWS: "{root}/jobs/{jobid}/log?cb={callback}", 54 | 55 | /** 56 | * Template for the job hosts list WS call 57 | * @parameter jobHostsWS 58 | * @type String 59 | * @static 60 | */ 61 | jobHostsWS: "{root}/jobs/{jobid}/hosts?cb={callback}", 62 | 63 | /** 64 | * Template for the job host WS call 65 | * @parameter jobHostWS 66 | * @type String 67 | * @static 68 | */ 69 | jobHostWS: "{root}/jobs/{jobid}/hosts/{hostname}?cb={callback}" 70 | }; 71 | 72 | 73 | /** 74 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 75 | * 76 | * Licensed under the Apache License, Version 2.0 (the "License"); you 77 | * may not use this file except in compliance with the License. You may 78 | * obtain a copy of the License at 79 | * 80 | * http://www.apache.org/licenses/LICENSE-2.0 81 | * 82 | * Unless required by applicable law or agreed to in writing, software 83 | * distributed under the License is distributed on an "AS IS" BASIS, 84 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 85 | * See the License for the specific language governing permissions and 86 | * imitations under the License. 87 | */ 88 | -------------------------------------------------------------------------------- /ui/js/src/pogo-env/tests/pogo-env.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-env tests 6 | 7 | 8 | 9 | 10 |

pogo-env Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-formatters/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-formatters 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-formatters.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=escape,pogo-env,datatype-date 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-formatters/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-formatters/tests/pogo-formatters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-formatters tests 6 | 7 | 8 | 9 | 10 |

pogo-formatters Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-loader/build.properties: -------------------------------------------------------------------------------- 1 | register.skip=true 2 | 3 | component.jsfiles=loader.js 4 | 5 | component=pogo-loader 6 | 7 | component.use= 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-loader/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | pogo Build File 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ui/js/src/pogo-loader/js/loader.js: -------------------------------------------------------------------------------- 1 | 2 | // Note: this file is auto-generated by meta_join.js. Don't Modify me ! 3 | YUI().use(function(Y) { 4 | 5 | /** 6 | * YUI 3 module metadata 7 | * @module pogo-loader 8 | */ 9 | var CONFIG = { 10 | groups: { 11 | 'pogo': { 12 | base: '/pogo/js/build/', 13 | combine: false, 14 | modules: {"pogo-app":{"path":"pogo-app/pogo-app-min.js","requires":["base","app","pogo-view-dashboard","pogo-view-user","pogo-view-job","pogo-view-host","pogo-model-job"]},"pogo-formatters":{"path":"pogo-formatters/pogo-formatters-min.js","requires":["escape","pogo-env","datatype-date"]},"pogo-model-host":{"path":"pogo-model-host/pogo-model-host-min.js","requires":["base","model"]},"pogo-model-hostslist":{"path":"pogo-model-hostslist/pogo-model-hostslist-min.js","requires":["base","model-list","pogo-model-host"]},"pogo-env":{"path":"pogo-env/pogo-env-min.js","requires":[]},"pogo-model-job":{"path":"pogo-model-job/pogo-model-job-min.js","requires":["base","model","pogo-env","json-parse","jsonp"]},"pogo-model-jobslist":{"path":"pogo-model-jobslist/pogo-model-jobslist-min.js","requires":["base","model-list","pogo-env","querystring-stringify","jsonp","pogo-model-job"]},"pogo-view-dashboard":{"path":"pogo-view-dashboard/pogo-view-dashboard-min.js","requires":["base","pogo-view-multidatatable"]},"pogo-view-host":{"path":"pogo-view-host/pogo-view-host-min.js","requires":["base","view","pogo-view-jobmetadata","pogo-view-hostlog"]},"pogo-view-hostlog":{"path":"pogo-view-hostlog/pogo-view-hostlog-min.js","requires":["base","view"]},"pogo-view-job":{"path":"pogo-view-job/pogo-view-job-min.js","requires":["base","view","pogo-model-hostslist","pogo-view-jobmetadata","pogo-view-jobhostdata"]},"pogo-view-jobhostdata":{"path":"pogo-view-jobhostdata/pogo-view-jobhostdata-min.js","requires":["base","view"]},"pogo-view-jobmetadata":{"path":"pogo-view-jobmetadata/pogo-view-jobmetadata-min.js","requires":["base","view"]},"pogo-view-multidatatable":{"path":"pogo-view-multidatatable/pogo-view-multidatatable-min.js","requires":["base","view","datatable","pogo-model-jobslist","tabview","pogo-formatters","gallery-paginator-dev-preview"]},"pogo-view-user":{"path":"pogo-view-user/pogo-view-user-min.js","requires":["base","pogo-view-multidatatable"]}} 15 | } 16 | } 17 | }; 18 | 19 | if(typeof YUI_config === 'undefined') { YUI_config = {groups:{}}; } 20 | Y.mix(YUI_config.groups, CONFIG.groups); 21 | 22 | }); -------------------------------------------------------------------------------- /ui/js/src/pogo-model-host/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-model-host 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-model-host.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,model 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-host/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-host/tests/pogo-model-host.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-model-host tests 6 | 7 | 8 | 9 | 10 |

pogo-model-host Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-hostslist/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-model-hostslist 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-model-hostslist.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,model-list,pogo-model-host 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-hostslist/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-hostslist/js/pogo-model-hostslist.js: -------------------------------------------------------------------------------- 1 | /*globals Y */ 2 | /** 3 | * The Host Module is responsible for storing info for one or more hosts, and displaying them 4 | * @module host 5 | * @namespace Y.Pogo.Model 6 | * @requires base,modellist,pogo-model-host 7 | */ 8 | 9 | /** 10 | * The Host modellist is a convenience for storing a list of host models 11 | * @class HostsList 12 | * @extends Y.ModelList 13 | * @constructor 14 | * @param {object} config Configuration object: See Configuration Attributes 15 | */ 16 | Y.namespace('Pogo.Model').HostsList = Y.Base.create('pogo-model-hostslist', Y.ModelList, [], { 17 | /** 18 | * Store results in Y.Pogo.Model.Host model objects 19 | * @parameter model 20 | * @type Object 21 | * @default Y.Pogo.Model.Host 22 | * @private 23 | */ 24 | model: Y.Pogo.Model.Host 25 | }); 26 | 27 | 28 | /** 29 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 30 | * 31 | * Licensed under the Apache License, Version 2.0 (the "License"); you 32 | * may not use this file except in compliance with the License. You may 33 | * obtain a copy of the License at 34 | * 35 | * http://www.apache.org/licenses/LICENSE-2.0 36 | * 37 | * Unless required by applicable law or agreed to in writing, software 38 | * distributed under the License is distributed on an "AS IS" BASIS, 39 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 40 | * See the License for the specific language governing permissions and 41 | * imitations under the License. 42 | */ 43 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-hostslist/tests/pogo-model-hostslist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-model-hostslist tests 6 | 7 | 8 | 9 | 10 |

pogo-model-hostslist Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-job/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-model-job 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-model-job.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,model,pogo-env,json-parse,jsonp 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-job/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-job/tests/pogo-model-job.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-model-job tests 6 | 7 | 8 | 9 | 10 |

pogo-model-job Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-jobslist/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-model-jobslist 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-model-jobslist.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,model-list,pogo-env,querystring-stringify,jsonp,pogo-model-job 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-jobslist/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-model-jobslist/tests/pogo-model-jobslist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-model-jobslist tests 6 | 7 | 8 | 9 | 10 |

pogo-model-jobslist Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-dashboard/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-view-dashboard 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-view-dashboard.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,pogo-view-multidatatable 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-dashboard/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-dashboard/js/pogo-view-dashboard.js: -------------------------------------------------------------------------------- 1 | /*globals Y */ 2 | /** 3 | * The Views Module contains views for displaying data 4 | * @module views 5 | * @namespace Y.Pogo.View 6 | * @requires base,pogo-view-multidatatable 7 | */ 8 | 9 | /** 10 | * The Dashboard View is a means to allow customization of the dashboard beyond the defaults in MultiDatatable. 11 | * @class Dashboard 12 | * @extends Y.Pogo.View.MutiDatatable 13 | * @constructor 14 | * @param {object} config Configuration object: See Configuration Attributes 15 | */ 16 | Y.namespace('Pogo.View').Dashboard = new Y.Base.create('pogo-view-dashboard', Y.Pogo.View.MultiDatatable, []); 17 | 18 | 19 | /** 20 | * Copyright (c) 2010-2012 Yahoo! Inc. All rights reserved. 21 | * 22 | * Licensed under the Apache License, Version 2.0 (the "License"); you 23 | * may not use this file except in compliance with the License. You may 24 | * obtain a copy of the License at 25 | * 26 | * http://www.apache.org/licenses/LICENSE-2.0 27 | * 28 | * Unless required by applicable law or agreed to in writing, software 29 | * distributed under the License is distributed on an "AS IS" BASIS, 30 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 31 | * See the License for the specific language governing permissions and 32 | * imitations under the License. 33 | */ 34 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-dashboard/tests/pogo-view-dashboard.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-view-dashboard tests 6 | 7 | 8 | 9 | 10 |

pogo-view-dashboard Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-host/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-view-host 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-view-host.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,view,pogo-view-jobmetadata,pogo-view-hostlog 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-host/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-host/tests/pogo-view-host.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-view-host tests 6 | 7 | 8 | 9 | 10 |

pogo-view-host Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-hostlog/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-view-hostlog 3 | # The list of files which should be concatenated to create the component. 4 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 5 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 6 | component.jsfiles=pogo-view-hostlog.js 7 | 8 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 9 | component.requires=base,view 10 | 11 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 12 | #component.supersedes= 13 | 14 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 15 | #component.optional= 16 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-hostlog/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-hostlog/js/pogo-view-hostlog.js: -------------------------------------------------------------------------------- 1 | /*globals Y */ 2 | /** 3 | * The Views Module contains views for displaying data 4 | * @module views 5 | * @namespace Y.Pogo.View 6 | * @requires base,view,datatable,pogo-formatters 7 | */ 8 | 9 | /** 10 | * Displays host log information 11 | * @class HostLog 12 | * @extends Y.View 13 | * @constructor 14 | * @param {object} config Configuration object: See Configuration Attributes 15 | */ 16 | Y.namespace('Pogo.View').HostLog = new Y.Base.create('pogo-view-hostlog', Y.View, [], { 17 | /** 18 | * Setup model event 19 | * @method initializer 20 | * @private 21 | */ 22 | initializer: function () { 23 | this.after('logURLChange', this.render, this); 24 | }, 25 | 26 | /** 27 | * The html template for the view (not including the datatable) 28 | * @property template 29 | * @type string 30 | * @protected 31 | */ 32 | template: '

Log

', 33 | 34 | /** 35 | * Renders the view 36 | * @method render 37 | * @return {Object} A reference to this view 38 | */ 39 | render: function () { 40 | var container = this.get('container'); 41 | 42 | container.setContent(Y.Lang.sub(this.template, { 43 | log: this.get('logURL') || "about:blank" 44 | })); 45 | return this; 46 | } 47 | }, { 48 | ATTRS: { 49 | /** 50 | * logURL 51 | * @attribute logURL 52 | * @type String 53 | * @default 'about:blank' 54 | */ 55 | logURL: { 56 | value: 'about:blank' 57 | } 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-hostlog/tests/pogo-view-jobhostdata.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-view-jobhostdata tests 6 | 7 | 8 | 9 | 10 |

pogo-view-jobhostdata Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-job/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-view-job 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-view-job.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,view,pogo-model-hostslist,pogo-view-jobmetadata,pogo-view-jobhostdata 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-job/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-job/tests/pogo-view-job.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-view-job tests 6 | 7 | 8 | 9 | 10 |

pogo-view-job Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-jobhostdata/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-view-jobhostdata 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-view-jobhostdata.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,view 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-jobhostdata/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-jobhostdata/tests/pogo-view-jobhostdata.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-view-jobhostdata tests 6 | 7 | 8 | 9 | 10 |

pogo-view-jobhostdata Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-jobmetadata/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-view-jobmetadata 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-view-jobmetadata.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,view 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-jobmetadata/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-jobmetadata/tests/pogo-view-jobmetadata.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-view-jobmetadata tests 6 | 7 | 8 | 9 | 10 |

pogo-view-jobmetadata Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-multidatatable/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-view-multidatatable 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-view-multidatatable.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,view,datatable,pogo-model-jobslist,tabview,pogo-formatters,gallery-paginator-dev-preview 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-multidatatable/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-multidatatable/tests/pogo-view-multidatatable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-view-multidatatable tests 6 | 7 | 8 | 9 | 10 |

pogo-view-multidatatable Tests

11 | 37 | 38 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-user/build.properties: -------------------------------------------------------------------------------- 1 | # The name of the component. E.g. event, attribute, widget 2 | component=pogo-view-user 3 | 4 | # The list of files which should be concatenated to create the component. 5 | # NOTE: For a css component (e.g. cssfonts, cssgrids etc.) use component.cssfiles instead. 6 | # component.jsfiles=test.js, testHelperClass.js, testSubComponentClass.js 7 | component.jsfiles=pogo-view-user.js 8 | 9 | # The list of modules this component requires. Used to set up the Y.add module call for YUI 3. 10 | component.requires=base,pogo-view-multidatatable 11 | 12 | # The list of modules this component supersedes. Used to set up the Y.add module call for YUI 3. 13 | #component.supersedes= 14 | 15 | # The list of modules that are optional for this module. Used to set up the Y.add module call for YUI 3. 16 | #component.optional= 17 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-user/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pogo Build File 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ui/js/src/pogo-view-user/tests/pogo-view-user.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | pogo-view-user tests 6 | 7 | 8 | 9 | 10 |

pogo-view-user Tests

11 | 37 | 38 | --------------------------------------------------------------------------------