59ad0ae5f97297a47305848229f56ce0de5e9b56
[cloudstore.git] / rsync-piper.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 use autodie;
6 use POSIX;
7 use File::Slurp;
8 use IO::Select;
9 use Time::HiRes;
10 use Data::Dump qw(dump);
11 use English;
12
13 my $dir = '/srv/cloudstore/var';
14 my $log_fifo = "$dir/rsyncd.log";
15 my $pid_file = "$dir/rsyncd.pid";
16 my $cfg_file   = "$dir/rsyncd.conf";
17 my $users    = "users";
18
19 mkdir $dir if ! -e $dir;
20
21 mkfifo $log_fifo, 0700 unless -p $log_fifo;
22
23 my $transfer_log = {
24         ip => '%a',
25         user => '%u',
26         host => '%h',
27         perms => '%B',
28         file => '%f',
29         updated => '%i',
30         len => '%l',
31         transfered => '%b',
32         module => '%m',
33         mtime => '%M',
34         op => '%o',
35         pid => '%p',
36         timestamp => '%t',
37 };
38
39 my $rsync_config = qq{
40
41 #uid = nobody
42 #gid = nogroup
43 #use chroot = yes
44 use chroot = no
45
46 #max connections = 4
47 lock file = $dir/rsyncd.lock
48
49 #syslog facility = local5
50 log file  = $log_fifo
51
52 transfer logging = yes
53 log format = transfer-log:} . join('|',values %$transfer_log) . qq{
54 max verbosity = 5
55
56 pid file  = $pid_file
57
58 # don't check secrets file permission (uid)
59 strict modes = no
60
61 pre-xfer exec = /srv/cloudstore/pre-xfer.sh
62 post-xfer exec = /srv/cloudstore/post-xfer.sh
63
64 [dpavlin]
65         path = /srv/cloudstore/users/dpavlin/blob
66         auth users = dpavlin
67         secrets file = /srv/cloudstore/secrets/dpavlin
68         read only = false
69
70 };
71
72 write_file $cfg_file, $rsync_config;
73 warn "created $cfg_file ", -s $cfg_file, " bytes\n";
74
75 if ( -e $pid_file ) {
76         my $pid = read_file $pid_file;
77         chomp($pid);
78         if ( kill 0, $pid ) {
79                 warn "found rsync pid $pid";
80         } else {
81                 unlink $pid_file;
82         }
83 }
84
85 if ( ! -e $pid_file ) {
86         my $exec = "rsync --daemon --config $cfg_file --no-detach --port=6501";
87         warn "START $exec\n";
88
89         die "could not fork\n" unless defined(my $pid = fork);
90         unless ($pid) {
91                 warn "start server with $exec\n";
92                 exec $exec || die $!;
93         }
94
95         warn "wait for pid file";
96         while ( ! -e $pid_file ) {
97                 sleep 1;
98         }
99 }
100
101
102 while(1) {
103         warn "# reading log output from $log_fifo\n";
104         open(my $log, '<', $log_fifo);
105         while( my $line = <$log> ) {
106                 print "LINE: $line";
107                 if ( $line =~ /transfer-log:(.+\|.+)/ ) {
108                         my %data;
109                         my @k = keys %$transfer_log;
110                         my @v = split(/\|/,$1);
111                         @data{@k} = @v ; # FIXME validate?
112                         print "transfer-log:",dump(\%data),$/;
113                 }
114         }
115         close($log);
116         sleep 1;
117 }
118