rvd_front.pl 25.5 KB
Newer Older
1
2
3
4
#!/usr/bin/env perl
use warnings;
use strict;

5
use Carp qw(confess);
6
use Data::Dumper;
Francesc Guasch's avatar
Francesc Guasch committed
7
use Getopt::Long;
8
use Hash::Util qw(lock_hash);
9
use Mojolicious::Lite;
10
use YAML qw(LoadFile);
11
12
13

use lib 'lib';

14
use Ravada::Front;
Francesc Guasch's avatar
Francesc Guasch committed
15
16
17
use Ravada::Auth;

my $help;
18
19
my $FILE_CONFIG = "/etc/ravada.conf";

Francesc Guasch's avatar
Francesc Guasch committed
20
GetOptions(
21
     'config=s' => \$FILE_CONFIG
Francesc Guasch's avatar
Francesc Guasch committed
22
23
24
25
26
27
28
         ,help  => \$help
     ) or exit;

if ($help) {
    print "$0 [--help] [--config=$FILE_CONFIG]\n";
    exit;
}
29

30
our $RAVADA = Ravada::Front->new(config => $FILE_CONFIG);
31
our $TIMEOUT = 10;
32
our $USER;
Francesc Guasch's avatar
Francesc Guasch committed
33

34
35
our $DOCUMENT_ROOT = "/var/www";

Francesc Guasch's avatar
Francesc Guasch committed
36
37
init();
############################################################################3
38
39

any '/' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
40
    my $c = shift;
joansp's avatar
joansp committed
41
42
    return quick_start($c) if _logged_in($c);
    $c->redirect_to('/login');
Francesc Guasch's avatar
Francesc Guasch committed
43
44
};

Francesc Guasch's avatar
Francesc Guasch committed
45
46
47
48
49
50
any '/index.html' => sub {
    my $c = shift;
    return quick_start($c) if _logged_in($c);
    $c->redirect_to('/login');
};

51
52
any '/login' => sub {
    my $c = shift;
53
    return login($c);
54
55
};

Francesc Guasch's avatar
Francesc Guasch committed
56
57
58
59
60
61
62
63
64
any '/test' => sub {
    my $c = shift;
    my $logged = _logged_in($c);
    my $count = $c->session('count');
    $c->session(count => ++$count);

    my $name_mojo = $c->signed_cookie('mojolicious');

    my $dump_log = ''.(Dumper($logged) or '');
Francesc Guasch's avatar
Francesc Guasch committed
65
66
67
68
69
    return $c->render(text => "$count ".($name_mojo or '')."<br> ".$dump_log
        ."<br>"
        ."<script>alert(window.screen.availWidth"
        ."+\" \"+window.screen.availHeight)</script>"
    );
Francesc Guasch's avatar
Francesc Guasch committed
70
71
};

Francesc Guasch's avatar
Francesc Guasch committed
72
73
74
75
76
77
78
any '/logout' => sub {
    my $c = shift;
    $c->session(expires => 1);
    $c->session(login => undef);
    $c->redirect_to('/');
};

79
get '/anonymous' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
80
    my $c = shift;
81
#    $c->render(template => 'bases', base => list_bases());
82
    $USER = _anonymous_user($c);
83
    return list_bases_anonymous($c);
Francesc Guasch's avatar
Francesc Guasch committed
84
85
};

86
87
88
89
90
91
get '/anonymous_logout.html' => sub {
    my $c = shift;
    $c->session('anonymous_user' => '');
    return $c->redirect_to('/');
};

92
get '/anonymous/*.html' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
93
    my $c = shift;
94
95
96
97
98

    $c->stash(_anonymous => 1 , _logged_in => 0);
    my ($base_id) = $c->req->url->to_abs =~ m{/anonymous/(.*).html};
    my $base = $RAVADA->search_domain_by_id($base_id);

99
    $USER = _anonymous_user($c);
100
    return quick_start_domain($c,$base->id, $USER->name);
Francesc Guasch's avatar
Francesc Guasch committed
101
102
};

103
any '/machines' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
104
105
    my $c = shift;

Francesc Guasch's avatar
Francesc Guasch committed
106
107
    return login($c)            if !_logged_in($c);
    return access_denied($c)    if !$USER->is_admin;
108

109
    return domains($c);
Francesc Guasch's avatar
Francesc Guasch committed
110
111
112
};


113
any '/machines/new' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
114
115
116
    my $c = shift;

    return access_denied($c) if !_logged_in($c);
117
    return new_machine($c);
Francesc Guasch's avatar
Francesc Guasch committed
118
119
};

120
121
122
123
124
125
126
127
128
get '/domain/new.html' => sub {
    my $c = shift;

    return access_denied($c) if !_logged_in($c) || !$USER->is_admin();
    $c->stash(error => []);
    return $c->render(template => "bootstrap/new_machine");

};

Francesc Guasch's avatar
Francesc Guasch committed
129
130
131
132
133
134
135
136
any '/users' => sub {
    my $c = shift;

    return access_denied($c) if !_logged_in($c);
    return users($c);

};

137
138
get '/list_vm_types.json' => sub {
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
139
    $c->render(json => $RAVADA->list_vm_types);
140
141
};

142
143
get '/list_bases.json' => sub {
    my $c = shift;
144
    $c->render(json => $RAVADA->list_bases);
145
146
147
148
};

get '/list_images.json' => sub {
    my $c = shift;
149
    $c->render(json => $RAVADA->list_iso_images);
150
151
};

152
get '/list_machines.json' => sub {
153
    my $c = shift;
154
    # shouldn't this be "list_bases" ?
Francesc Guasch's avatar
Francesc Guasch committed
155
    $c->render(json => $RAVADA->list_domains);
156
};
Francesc Guasch's avatar
Francesc Guasch committed
157

158
159
160
161
162
163
164
get '/list_bases_anonymous.json' => sub {
    my $c = shift;

    # shouldn't this be "list_bases" ?
    $c->render(json => $RAVADA->list_bases_anonymous(_remote_ip($c)));
};

Laura Figuerola's avatar
Laura Figuerola committed
165
166
167
168
169
get '/list_users.json' => sub {
    my $c = shift;
    $c->render(json => $RAVADA->list_users);
};

Francesc Guasch's avatar
Francesc Guasch committed
170
get '/list_lxc_templates.json' => sub {
fv3rdugo's avatar
fv3rdugo committed
171
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
172
    $c->render(json => $RAVADA->list_lxc_templates);
fv3rdugo's avatar
fv3rdugo committed
173
174
};

joansp's avatar
udpate    
joansp committed
175
176
177
178
179
get '/pingbackend.json' => sub {

    my $c = shift;
    $c->render(json => $RAVADA->ping_backend);
};
fv3rdugo's avatar
fv3rdugo committed
180

181
182
# machine commands

Francesc Guasch's avatar
Francesc Guasch committed
183
get '/machine/info/*.json' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
184
185
186
    my $c = shift;
    return $c->redirect_to('/login') if !_logged_in($c);

Francesc Guasch's avatar
Francesc Guasch committed
187
188
189
    my ($id) = $c->req->url->to_abs->path =~ m{/(\d+)\.json};
    die "No id " if !$id;
    $c->render(json => $RAVADA->search_domain($id));
Francesc Guasch's avatar
Francesc Guasch committed
190
191
};

192
any '/machine/manage/*html' => sub {
193
    my $c = shift;
194
195
    return $c->redirect_to('/login') if !_logged_in($c);

196
197
198
    return manage_machine($c);
};

199
200
get '/machine/view/*.html' => sub {
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
201
202
    return $c->redirect_to('/login') if !_logged_in($c);

203
204
205
206
207
208
209
210
    return view_machine($c);
};

get '/machine/clone/*.html' => sub {
    my $c = shift;
    return clone_machine($c);
};

211
212
213
214
get '/machine/shutdown/*.html' => sub {
        my $c = shift;
        return shutdown_machine($c);
};
Francesc Guasch's avatar
Francesc Guasch committed
215
216
217
218
219
220
221

get '/machine/shutdown/*.json' => sub {
        my $c = shift;
        return shutdown_machine($c);
};


222
any '/machine/remove/*.html' => sub {
joansp's avatar
joansp committed
223
224
225
        my $c = shift;
        return remove_machine($c);
};
joansp's avatar
joansp committed
226
get '/machine/prepare/*.json' => sub {
Francesc Guasch's avatar
Francesc Guasch committed
227
228
229
230
        my $c = shift;
        return prepare_machine($c);
};

joansp's avatar
joansp committed
231
232
233
234
235
get '/machine/remove_b/*.json' => sub {
        my $c = shift;
        return remove_base($c);
};

joansp's avatar
joansp committed
236
get '/machine/screenshot/*.json' => sub {
237
238
239
240
        my $c = shift;
        return screenshot_machine($c);
};

joansp's avatar
joansp committed
241
242
243
244
245
246
247
248
249
250
251
252
253
254
get '/machine/pause/*.json' => sub {
        my $c = shift;
        return pause_machine($c);
};

get '/machine/resume/*.json' => sub {
        my $c = shift;
        return resume_machine($c);
};

get '/machine/start/*.json' => sub {
        my $c = shift;
        return start_machine($c);
};
joansp's avatar
joansp committed
255
256
257
258
259

get '/machine/clones/*.json' => sub {
        my $c = shift;
        return machine_num_clones($c);
};
Laura Figuerola's avatar
Laura Figuerola committed
260
261
262
263
264
265
266
##make admin

get '/users/make_admin/*.json' => sub {
       my $c = shift;
      return make_admin($c);
};

267
268
269
270
271
272
273
##remove admin

get '/users/remove_admin/*.json' => sub {
       my $c = shift;
       return remove_admin($c);
};

274
275
276
277
278
279
280
281
282
283
##############################################
#

get '/request/*.html' => sub {
    my $c = shift;
    my ($id) = $c->req->url->to_abs->path =~ m{/(\d+)\.html};

    return _show_request($c,$id);
};

Francesc Guasch's avatar
Francesc Guasch committed
284
285
286
287
288
get '/requests.json' => sub {
    my $c = shift;
    return list_requests($c);
};

fv3rdugo's avatar
fv3rdugo committed
289
290
291
292
293
any '/messages.html' => sub {
    my $c = shift;
    return access_denied($c) if !_logged_in($c);
    return messages($c);
};
joansp's avatar
joansp committed
294

joansp's avatar
joansp committed
295
get '/messages.json' => sub {
296
297
298
299
    my $c = shift;

    return $c->redirect_to('/login') if !_logged_in($c);

joansp's avatar
joansp committed
300
    return $c->render( json => [$USER->messages()] );
301
302
};

joansp's avatar
joansp committed
303
304
305
306
307
308
309
get '/messages/read/all.html' => sub {
    my $c = shift;
    return $c->redirect_to('/login') if !_logged_in($c);
    $USER->mark_all_messages_read;
    return $c->redirect_to("/messages.html");
};

joansp's avatar
joansp committed
310
311
312
313
314
315
316
317
get '/messages/read/*.html' => sub {
    my $c = shift;
    return $c->redirect_to('/login') if !_logged_in($c);
    my ($id) = $c->req->url->to_abs->path =~ m{/(\d+)\.html};
    $USER->mark_message_read($id);
    return $c->redirect_to("/messages.html");
};

joansp's avatar
joansp committed
318
319
320
321
322
323
324
325
get '/messages/read/*.json' => sub {
    my $c = shift;
    return $c->redirect_to('/login') if !_logged_in($c);
    my ($id) = $c->req->url->to_abs->path =~ m{/(\d+)\.json};
    $USER->mark_message_read($id);
    return $c->redirect_to("/messages.html");
};

joansp's avatar
joansp committed
326
327
328
329
330
331
332
333
get '/messages/unread/*.html' => sub {
    my $c = shift;
    return $c->redirect_to('/login') if !_logged_in($c);
    my ($id) = $c->req->url->to_abs->path =~ m{/(\d+)\.html};
    $USER->mark_message_unread($id);
    return $c->redirect_to("/messages.html");
};

joansp's avatar
joansp committed
334
get '/messages/view/*.html' => sub {
335
336
337
338
339
340
341
342
343
    my $c = shift;

    return $c->redirect_to('/login') if !_logged_in($c);

    my ($id_message) = $c->req->url->to_abs->path =~ m{/(\d+)\.html};

    return $c->render( json => $USER->show_message($id_message) );
};

344
any '/about' => sub {
fv3rdugo's avatar
fv3rdugo committed
345
    my $c = shift;
346
    return login($c)            if !_logged_in($c);
fv3rdugo's avatar
fv3rdugo committed
347

348
    $c->render(template => 'bootstrap/about');
fv3rdugo's avatar
fv3rdugo committed
349
350
};

351

352
353
354
355
356
357
358
any '/requirements' => sub {
    my $c = shift;
    return login($c)            if !_logged_in($c);

    $c->render(template => 'bootstrap/requirements');
};

359
360
###################################################

361
362
363
364
365
366
367
368
369
sub _init_error {
    my $c = shift;
    $c->stash(error_title => '');
    $c->stash(error => []);
    $c->stash(link => '');
    $c->stash(link_msg => '');

}

Francesc Guasch's avatar
Francesc Guasch committed
370
371
sub _logged_in {
    my $c = shift;
372

373
    confess "missing \$c" if !defined $c;
374
375
    $USER = undef;

376
    _init_error($c);
377
378
    $c->stash(_logged_in => undef , _user => undef, _anonymous => 1);

379
380
    my $login = $c->session('login');
    $USER = Ravada::Auth::SQL->new(name => $login)  if $login;
381
382

    $c->stash(_logged_in => $login );
383
    $c->stash(_user => $USER);
384
    $c->stash(_anonymous => !$USER);
385
386

    return $USER;
Francesc Guasch's avatar
Francesc Guasch committed
387
388
}

389

390
391
392
393
394
395
396
397
398
399
400
401
402
403
sub login {
    my $c = shift;

    return quick_start($c)    if _logged_in($c);

    my $login = $c->param('login');
    my $password = $c->param('password');
    my @error =();
    if ($c->param('submit') && $login) {
        push @error,("Empty login name")  if !length $login;
        push @error,("Empty password")  if !length $password;
    }

    if ( $login && $password ) {
404
405
406
        my $auth_ok;
        eval { $auth_ok = Ravada::Auth::login($login, $password)};
        if ( $auth_ok) {
407
            $c->session('login' => $login);
408
            return quick_start($c);
409
        } else {
410
            warn $@ if $@;
411
412
413
414
            push @error,("Access denied");
        }
    }
    $c->render(
joansp's avatar
joansp committed
415
416
                    template => 'bootstrap/start'
                      ,login => $login
417
418
419
420
421
                      ,error => \@error
    );

}

Francesc Guasch's avatar
Francesc Guasch committed
422
423
424
425
426
sub quick_start {
    my $c = shift;

    _logged_in($c);

427
428
429
430
431
    my $login = $c->param('login');
    my $password = $c->param('password');
    my $id_base = $c->param('id_base');

    my @error =();
Francesc Guasch's avatar
Francesc Guasch committed
432
    if ($c->param('submit')) {
433
434
435
436
437
        push @error,("Empty login name")  if !length $login;
        push @error,("Empty password")  if !length $password;
    }

    if ( $login && $password ) {
Francesc Guasch's avatar
Francesc Guasch committed
438
        if (Ravada::Auth::login($login, $password)) {
Francesc Guasch's avatar
Francesc Guasch committed
439
440
441
            $c->session('login' => $login);
        } else {
            push @error,("Access denied");
442
443
        }
    }
Francesc Guasch's avatar
Francesc Guasch committed
444
445
446
447
448
    if ( $c->param('submit') && _logged_in($c) && defined $id_base ) {

        return quick_start_domain($c, $id_base, ($login or $c->session('login')));

    }
Francesc Guasch's avatar
Francesc Guasch committed
449

450
    $c->render(
joansp's avatar
joansp committed
451
                    template => 'bootstrap/list_bases'
452
                    ,id_base => $id_base
joansp's avatar
joansp committed
453
                      ,login => $login
454
                  ,_anonymous => 0
455
                      ,error => \@error
Francesc Guasch's avatar
Francesc Guasch committed
456
457
    );
}
458

Francesc Guasch's avatar
Francesc Guasch committed
459
460
sub quick_start_domain {
    my ($c, $id_base, $name) = @_;
461

462
463
    return $c->redirect_to('/login') if !$USER;

464
    confess "Missing id_base" if !defined $id_base;
465
    $name = $c->session('login')    if !$name;
466

Francesc Guasch's avatar
Francesc Guasch committed
467
468
    my $base = $RAVADA->search_domain_by_id($id_base) or die "I can't find base $id_base";

469
    my $domain_name = $base->name."-".$name;
470
471
    my $domain = $RAVADA->search_clone(id_base => $base->id, id_owner => $USER->id);

472
    $domain = provision($c,  $id_base,  $domain_name)
Francesc Guasch's avatar
Francesc Guasch committed
473
474
        if !$domain;

475
    return show_failure($c, $domain_name) if !$domain;
Francesc Guasch's avatar
Francesc Guasch committed
476
477
478
479
    return show_link($c,$domain);

}

Francesc Guasch's avatar
Francesc Guasch committed
480
481
482
sub show_failure {
    my $c = shift;
    my $name = shift;
483
    $c->render(template => 'bootstrap/fail', name => $name);
Francesc Guasch's avatar
Francesc Guasch committed
484
485
}

Francesc Guasch's avatar
Francesc Guasch committed
486
487
488

#######################################################

Francesc Guasch's avatar
Francesc Guasch committed
489
490
sub domains {
    my $c = shift;
joansp's avatar
joansp committed
491
492

    my @error = ();
joansp's avatar
joansp committed
493

494
    $c->render(template => 'bootstrap/machines');
Francesc Guasch's avatar
Francesc Guasch committed
495
496
497

}

joansp's avatar
joansp committed
498
499
500
501
502
503
504
505
506
sub messages {
    my $c = shift;

    my @error = ();

    $c->render(template => 'bootstrap/messages');

}

Francesc Guasch's avatar
Francesc Guasch committed
507
sub users {
508
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
509
510
511
    my @users = $RAVADA->list_users();
    $c->render(template => 'bootstrap/users'
        ,users => \@users
Francesc Guasch's avatar
Francesc Guasch committed
512
    );
513

Francesc Guasch's avatar
Francesc Guasch committed
514
}
515
516


517
sub new_machine {
518
    my $c = shift;
519
    my @error = ();
520
    if ($c->param('submit')) {
Francesc Guasch's avatar
Francesc Guasch committed
521
        push @error,("Name is mandatory")   if !$c->param('name');
joansp's avatar
joansp committed
522
523
        req_new_domain($c);
        $c->redirect_to("/machines")    if !@error;
524
    }
525
526
    warn join("\n",@error) if @error;

joansp's avatar
joansp committed
527

528
529
};

530
sub req_new_domain {
Francesc Guasch's avatar
Francesc Guasch committed
531
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
532
    my $name = $c->param('name');
533
    my $req = $RAVADA->create_domain(
Francesc Guasch's avatar
Francesc Guasch committed
534
           name => $name
535
        ,id_iso => $c->param('id_iso')
536
        ,id_template => $c->param('id_template')
Francesc Guasch's avatar
Francesc Guasch committed
537
        ,vm=> $c->param('backend')
538
        ,id_owner => $USER->id
539
540
        ,memory => int($c->param('memory')*1024*1024)
        ,disk => int($c->param('disk')*1024*1024*1024)
Francesc Guasch's avatar
Francesc Guasch committed
541
542
    );

543
    return $req;
Francesc Guasch's avatar
Francesc Guasch committed
544
545
}

Francesc Guasch's avatar
Francesc Guasch committed
546
547
sub _show_request {
    my $c = shift;
548
549
550
551
552
553
554
555
556
557
558
559
560
561
    my $id_request = shift;

    my $request;
    if (!ref $id_request) {
        warn "opening request $id_request";
        eval { $request = Ravada::Request->open($id_request) };
        warn $@ if $@;
        return $c->render(data => "Request $id_request unknown")   if !$request;
    } else {
        $request = $id_request;
    }

    return $c->render(data => "Request $id_request unknown ".Dumper($request))
        if !$request->{id};
Francesc Guasch's avatar
Francesc Guasch committed
562
563
564
565
566

    $c->render(
         template => 'bootstrap/request'
        , request => $request
    );
567
568
569
570
571
572
573
574
575
576
577
578
    return if $request->status ne 'done';

    return $c->render(data => "Request $id_request error ".$request->error)
        if $request->error;

    my $name = $request->args('name');
    my $domain = $RAVADA->search_domain($name);

    if (!$domain) {
        return $c->render(data => "Request ".$request->status." , but I can't find domain $name");
    }
    return view_machine($c,$domain);
Francesc Guasch's avatar
Francesc Guasch committed
579
580
}

Francesc Guasch's avatar
Francesc Guasch committed
581
582
583
sub _search_req_base_error {
    my $name = shift;
}
584

585
sub access_denied {
joansp's avatar
joansp committed
586

587
    my $c = shift;
588
    my $msg = 'Access denied to '.$c->req->url->to_abs->path;
joansp's avatar
joansp committed
589

590
    $msg .= ' for user '.$USER->name if $USER;
joansp's avatar
joansp committed
591

592
    return $c->render(text => $msg);
593
594
}

595
596
sub base_id {
    my $name = shift;
597
    my $base = $RAVADA->search_domain($name);
598

599
    return $base->id;
600
601
}

602
sub provision {
603
604
    my $c = shift;
    my $id_base = shift;
605
    my $name = shift or confess "Missing name";
606
607
608
609

    die "Missing id_base "  if !defined $id_base;
    die "Missing name "     if !defined $name;

610
611
    my $domain = $RAVADA->search_domain(name => $name);
    return $domain if $domain;
612

613
614
    warn "requesting the creation of $name for ".$USER->id;

615
616
617
    my $req = Ravada::Request->create_domain(
             name => $name
        , id_base => $id_base
618
       , id_owner => $USER->id
619
    );
620
    $RAVADA->wait_request($req, 60);
Francesc Guasch's avatar
Francesc Guasch committed
621

622
    if ( $req->status ne 'done' ) {
623
        $c->stash(error_title => "Request ".$req->command." ".$req->status());
joansp's avatar
joansp committed
624
        $c->stash(error =>
625
626
627
628
            "Domain provisioning request not finished, status='".$req->status."'.");

        $c->stash(link => "/request/".$req->id.".html");
        $c->stash(link_msg => '');
629
        return;
630
    }
631
632
    $domain = $RAVADA->search_domain($name);
    if ( $req->error ) {
joansp's avatar
joansp committed
633
        $c->stash(error => $req->error)
Francesc Guasch's avatar
Francesc Guasch committed
634
    } elsif (!$domain) {
635
        $c->stash(error => "I dunno why but no domain $name");
Francesc Guasch's avatar
Francesc Guasch committed
636
    }
637
    return $domain;
638
639
640
641
}

sub show_link {
    my $c = shift;
642
    my $domain = shift or confess "Missing domain";
Francesc Guasch's avatar
Francesc Guasch committed
643

644
    confess "Domain is not a ref $domain " if !ref $domain;
645

646
    return access_denied($c) if $USER->id != $domain->id_owner && !$USER->is_admin;
647

648
    if ( !$domain->is_active ) {
649
        my $req = Ravada::Request->start_domain(name => $domain->name, uid => $USER->id);
650
651
652
653
654
655
656
657
658
659

        $RAVADA->wait_request($req);
        warn "ERROR: ".$req->error if $req->error();

        return $c->render(data => 'ERROR starting domain '.$req->error)
            if $req->error && $req->error !~ /already running/i;

        return $c->redirect_to("/request/".$req->id.".html")
            if !$req->status eq 'done';
    }
660
661
662
663
664
665
666
667
668
669
670
671
    if ( $domain->is_paused) {
        my $req = Ravada::Request->resume_domain(name => $domain->name, uid => $USER->id);

        $RAVADA->wait_request($req);
        warn "ERROR: ".$req->error if $req->error();

        return $c->render(data => 'ERROR resuming domain '.$req->error)
            if $req->error && $req->error !~ /already running/i;

        return $c->redirect_to("/request/".$req->id.".html")
            if !$req->status eq 'done';
    }
672

673
    my $uri = $domain->display($USER) if $domain->is_active;
674
    if (!$uri) {
Francesc Guasch's avatar
Francesc Guasch committed
675
        my $name = '';
676
677
        $name = $domain->name if $domain;
        $c->render(template => 'fail', name => $domain->name);
678
679
680
        return;
    }
    $c->redirect_to($uri);
681
    $c->render(template => 'bootstrap/run', url => $uri , name => $domain->name
Francesc Guasch's avatar
Francesc Guasch committed
682
                ,login => $c->session('login'));
683
684
}

685

686
sub check_back_running {
687
688
    #TODO;
    return 1;
689
690
}

Francesc Guasch's avatar
Francesc Guasch committed
691
sub init {
692
    check_back_running() or warn "CRITICAL: rvd_back is not running\n";
Francesc Guasch's avatar
Francesc Guasch committed
693
694
}

695
696
sub _search_requested_machine {
    my $c = shift;
Francesc Guasch's avatar
Francesc Guasch committed
697
    my ($id,$type) = $c->req->url->to_abs->path =~ m{/(\d+)\.(\w+)$};
698

Francesc Guasch's avatar
Francesc Guasch committed
699
    return show_failure($c,"I can't find id in ".$c->req->url->to_abs->path)
700
701
        if !$id;

702
    my $domain = $RAVADA->search_domain_by_id($id) or do {
703
        $c->stash( error => "Unknown domain id=$id");
704
705
        return;
    };
706
707
708

    return ($domain,$type) if wantarray;
    return $domain;
709
710
}

Laura Figuerola's avatar
Laura Figuerola committed
711
712
713
714
715
sub make_admin {
    my $c = shift;
    return login($c) if !_logged_in($c);

    my ($id) = $c->req->url->to_abs->path =~ m{/(\d+).json};
joansp's avatar
joansp committed
716

Laura Figuerola's avatar
Laura Figuerola committed
717
    warn "id usuari $id";
joansp's avatar
joansp committed
718

Laura Figuerola's avatar
Laura Figuerola committed
719
    Ravada::Auth::SQL::make_admin($id);
joansp's avatar
joansp committed
720

Laura Figuerola's avatar
Laura Figuerola committed
721
722
}

723
724
725
726
727
sub remove_admin {
    my $c = shift;
    return login($c) if !_logged_in($c);

    my ($id) = $c->req->url->to_abs->path =~ m{/(\d+).json};
joansp's avatar
joansp committed
728

729
    warn "id usuari $id";
joansp's avatar
joansp committed
730

731
    Ravada::Auth::SQL::remove_admin($id);
joansp's avatar
joansp committed
732

733
734
}

735
736
737
738
sub manage_machine {
    my $c = shift;
    return login($c) if !_logged_in($c);

Francesc Guasch's avatar
Francesc Guasch committed
739
    my ($domain) = _search_requested_machine($c);
740
741
742
    if (!$domain) {
        return $c->render(text => "Domain no found");
    }
743
    return access_denied($c)    if $domain->id_owner != $USER->id
744
        && !$USER->is_admin;
745

746
747
    Ravada::Request->shutdown_domain(name => $domain->name, uid => $USER->id)   if $c->param('shutdown');
    Ravada::Request->start_domain(name => $domain->name, uid => $USER->id)   if $c->param('start');
joansp's avatar
joansp committed
748
    Ravada::Request->pause_domain(name => $domain->name, uid => $USER->id)
749
750
751
        if $c->param('pause');

    Ravada::Request->resume_domain(name => $domain->name, uid => $USER->id)   if $c->param('resume');
752

753
    $c->stash(domain => $domain);
754
755
    $c->stash(uri => $c->req->url->to_abs);

756
    _enable_buttons($c, $domain);
757

758
    $c->render( template => 'bootstrap/manage_machine');
759
}
760
761
762
763

sub _enable_buttons {
    my $c = shift;
    my $domain = shift;
764
765
766
767
768
769
    warn "is_paused=".$domain->is_paused;
    if (($c->param('pause') && !$domain->is_paused)
        ||($c->param('resume') && $domain->is_paused)) {
        sleep 2;
        warn "  -> is_paused=".$domain->is_paused;
    }
770
771
    $c->stash(_shutdown_disabled => '');
    $c->stash(_shutdown_disabled => 'disabled') if !$domain->is_active;
772
773
774
775

    $c->stash(_start_disabled => '');
    $c->stash(_start_disabled => 'disabled')    if $domain->is_active;

776
777
778
779
780
781
782
783
784
    $c->stash(_pause_disabled => '');
    $c->stash(_pause_disabled => 'disabled')    if $domain->is_paused
                                                    || !$domain->is_active;

    $c->stash(_resume_disabled => '');
    $c->stash(_resume_disabled => 'disabled')    if !$domain->is_paused;



785
786
}

787
788
sub view_machine {
    my $c = shift;
789
790
    my $domain = shift;

791
792
    return login($c) if !_logged_in($c);

793
    $domain =  _search_requested_machine($c) if !$domain;
794
    return $c->render(template => 'bootstrap/fail') if !$domain;
795
    return show_link($c, $domain);
796
797
798
799
800
801
802
}

sub clone_machine {
    my $c = shift;
    return login($c) if !_logged_in($c);

    my $base = _search_requested_machine($c);
803
804
805
806
    if (!$base ) {
        $c->stash( error => "Unknown base ") if !$c->stash('error');
        return $c->render(template => 'bootstrap/fail');
    };
807
    return quick_start_domain($c, $base->id);
808
809
}

810
811
812
813
sub shutdown_machine {
    my $c = shift;
    return login($c) if !_logged_in($c);

joansp's avatar
joansp committed
814
815
    my ($domain, $type) = _search_requested_machine($c);
    my $req = Ravada::Request->shutdown_domain(name => $domain->name, uid => $USER->id);
816

Francesc Guasch's avatar
Francesc Guasch committed
817
818
    return $c->redirect_to('/machines') if $type eq 'html';
    return $c->render(json => { req => $req->id });
819
820
}

821
sub _do_remove_machine {
joansp's avatar
joansp committed
822
823
824
    my $c = shift;
    return login($c) if !_logged_in($c);

825
826
827
    my $domain = _search_requested_machine($c);

    my $req = Ravada::Request->remove_domain(
828
        name => $domain->name
829
        ,uid => $USER->id
830
    );
joansp's avatar
joansp committed
831

832
    return $c->redirect_to('/machines');
joansp's avatar
joansp committed
833
834
}

835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
sub remove_machine {
    my $c = shift;
    return login($c)    if !_logged_in($c);
    return _do_remove_machine($c,@_)   if $c->param('sure') && $c->param('sure') =~ /y/i;

    return $c->redirect_to('/machines')   if $c->param('sure')
                                            || $c->param('cancel');

    my $domain = _search_requested_machine($c);
    return $c->render( text => "Domain not found")  if !$domain;
    $c->stash(domain => $domain );

    warn "found domain ".$domain->name;

    return $c->render( template => 'bootstrap/remove_machine' );
}

joansp's avatar
joansp committed
852
853
854
855
856
857
858
859
860
861
862
863
864
sub remove_base {
  my $c = shift;
  return login($c)    if !_logged_in($c);

  my $domain = _search_requested_machine($c);

  my $req = Ravada::Request->remove_base(
      id_domain => $domain->id
      ,uid => $USER->id
  );

  $c->render(json => { request => $req->id});
}
865

866
867
868
869
870
871
872
873
874
875
876
877
878
sub screenshot_machine {
    my $c = shift;
    return login($c)    if !_logged_in($c);

    warn ref($c);

    my $domain = _search_requested_machine($c);

    my $file_screenshot = "$DOCUMENT_ROOT/img/screenshots/".$domain->id.".png";
    my $req = Ravada::Request->screenshot_domain (
        id_domain => $domain->id
        ,filename => $file_screenshot
    );
joansp's avatar
joansp committed
879
    $c->render(json => { request => $req->id});
880
881
}

Francesc Guasch's avatar
Francesc Guasch committed
882
883
884
885
886
887
sub prepare_machine {
    my $c = shift;
    return login($c)    if !_logged_in($c);

    my $domain = _search_requested_machine($c);

888
889
890
891
892
    my $file_screenshot = "$DOCUMENT_ROOT/img/screenshots/".$domain->id.".png";
    if (! -e $file_screenshot && $domain->can_screenshot() ) {
        if ( !$domain->is_active() ) {
            Ravada::Request->start_domain( name => $domain->name
                ,uid => $USER->id
Francesc Guasch's avatar
Francesc Guasch committed
893
            );
894
895
896
897
898
899
900
901
            sleep 3;
        }
        Ravada::Request->screenshot_domain (
            id_domain => $domain->id
            ,filename => $file_screenshot
        );
    }

Francesc Guasch's avatar
Francesc Guasch committed
902
    my $req = Ravada::Request->prepare_base(
Francesc Guasch's avatar
Francesc Guasch committed
903
        id_domain => $domain->id
904
        ,uid => $USER->id
Francesc Guasch's avatar
Francesc Guasch committed
905
906
    );

joansp's avatar
joansp committed
907
908
909
910
911
912
913
    $c->render(json => { request => $req->id});

}

sub start_machine {
    my $c = shift;
    return login($c) if !_logged_in($c);
Francesc Guasch's avatar
Francesc Guasch committed
914

joansp's avatar
joansp committed
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
    my ($domain, $type) = _search_requested_machine($c);
    my $req = Ravada::Request->start_domain(name => $domain->name, uid => $USER->id);

    return $c->render(json => { req => $req->id });
}

sub pause_machine {
    my $c = shift;
    return login($c) if !_logged_in($c);

    my ($domain, $type) = _search_requested_machine($c);
    my $req = Ravada::Request->pause_domain(name => $domain->name, uid => $USER->id);

    return $c->render(json => { req => $req->id });
}

sub resume_machine {
    my $c = shift;
    return login($c) if !_logged_in($c);

    my ($domain, $type) = _search_requested_machine($c);
    my $req = Ravada::Request->resume_domain(name => $domain->name, uid => $USER->id);

    return $c->render(json => { req => $req->id });
Francesc Guasch's avatar
Francesc Guasch committed
939
940
}

Laura Figuerola's avatar
Laura Figuerola committed
941
942


Francesc Guasch's avatar
Francesc Guasch committed
943
944
945
946
947
948
949
sub list_requests {
    my $c = shift;

    my $list_requests = $RAVADA->list_requests();
    $c->render(json => $list_requests);
}

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
sub list_bases_anonymous {
    my $c = shift;

    my $bases_anonymous = $RAVADA->list_bases_anonymous(_remote_ip($c));

    return access_denied($c)    if !scalar @$bases_anonymous;

    $c->render(template => 'bootstrap/list_bases'
        , _logged_in => undef
        , _anonymous => 1
        , _user => undef
    );
}

sub _remote_ip {
    my $c = shift;
    return (
            $c->req->headers->header('X-Forwarded-For')
                or
            $c->req->headers->header('Remote-Addr')
                or
            $c->tx->remote_address
    );
}

975
976
977
978
979
980
981
982
983
984
sub _anonymous_user {
    my $c = shift;

    $c->stash(_user => undef);
    my $name = $c->session('anonymous_user');

    if (!$name) {
        $name = _new_anonymous_user($c);
        $c->session(anonymous_user => $name);
    }
985
986
987
988
    my $user= Ravada::Auth::SQL->new( name => $name );

    confess "user ".$user->name." has no id, may not be in table users"
        if !$user->id;
989

990
991
992
993
994
995
996
997
998
999
1000
    return $user;
}

sub _random_name {
    my $length = shift;
    my $ret = 'O'.substr($$,3);
    my $max = ord('z') - ord('a');
    for ( 0 .. $length ) {
        my $n = int rand($max + 1);
        $ret .= chr(ord('a') + $n);
    }
For faster browsing, not all history is shown. View entire blame