source: genappalpha/languages/docker/build_docker_footer.pl @ 1495

Last change on this file since 1495 was 1495, checked in by ehb, 2 years ago

Docker runs locally thru genapp with run directory mounted on container

File size: 4.9 KB
Line 
1# process each module with dependencies
2
3foreach my $mod ( keys %dependencies ) {
4    my $menu = $menus{ $mod };
5    print "checking $menu:$mod\n";
6    if ( $dependencies{ $mod } =~ /^_{2}dependencies__/ ) {
7        print "no dependencies\n";
8        $error .= "Module '$mod' : no dependencies defined, can not create docker container.\n";
9        next;
10    }
11    $depjson = decode_json( $dependencies{ $mod } );
12    $modjson = decode_json( $module_json{ $mod } );
13    if ( !$$modjson{'executable'} ) {
14        $error .= "Module '$mod' has no 'executable' defined.\n";
15        next;
16    }
17    print "executable is $$modjson{'executable'}\n";
18
19
20    # build up and output docker file based upon dependencies
21    # executable needs copying
22    my $out;
23    my $has_error;
24    my $has_base;
25    my @copys;
26    my $has_cpanm;
27   
28    for ( my $i = 0; $i < @$depjson; ++$i ) {
29        my $entry = $$depjson[$i];
30        if ( scalar ( keys %$entry ) != 1 ) {
31            $has_error++;
32            $error .= "Module '$mod' : dependencies entry " . ( $i + 1 ) . " '" . encode_json( $entry ) . "' does not have exactly 1 key\n";
33            break;
34        }
35
36        my $k = (keys %$entry)[0];
37        my $v = $$entry{$k};
38        $k = lc( $k );
39        if ( ref( $v ) ne 'ARRAY' ) {
40            my @v = ( $v );
41            $v = \@v;
42        }
43        # create command to build and post (?) dockerfile
44
45        for ( my $j = 0; $j < @$v; ++$j ) {
46            my $val = $$v[$j];
47            if ( length( ref( $val ) ) ) {
48                $error .= "Module '$mod' : dependencies entry " . ( $i + 1 ) . " '" . encode_json( $entry ) . "' improper value in list entry number " . ( $j + 1 ) . "\n";
49                $has_error++;
50                next;
51            }
52            if ( $k eq 'base' ) {
53                if ( $hasbase ) {
54                    $error .= "Module '$mod' : dependencies entry " . ( $i + 1 ) . " '" . encode_json( $entry ) . "' multiple 'base' tags found, only one allowed\n";
55                    $has_error;
56                    last;
57                }
58                $out .= "FROM $val\n";
59                $out .= "WORKDIR $bindir\n";
60                $has_base++;
61                next;
62            }
63            if ( !$has_base ) {
64                $warn .= "No 'base' entry found in first position, defaulting to 'ubuntu'\n";
65                $out .= "FROM ubuntu\n";
66                $out .= "WORKDIR $bindir\n";
67                $has_base++;
68                next;
69            }               
70            if ( $k eq 'cpan' ) {
71                if ( !$has_cpanm ) {
72                    $out .= "RUN curl -L http://cpanmin.us | perl - App::cpanminus\n";
73                    $out .= "RUN mv /usr/bin/perl /usr/bin/perl.save\n";
74                    $out .= "RUN ln -s /usr/local/bin/perl /usr/bin/perl\n";
75                    $has_cpanm++;
76                }
77                $out .= "RUN cpanm $val\n";
78                next;
79            }
80
81            if ( $k eq 'file' ) {
82                my $dest = $val;
83                $dest =~ s/^.*\///g;
84                $out .= "COPY $dest $dest\n";
85                $val = "$executable_path/$val" if $val !~ /^\//;
86                push @copys, $val;
87                next;
88            }
89
90            $error .= "Module '$mod' : dependencies entry " . ( $i + 1 ) . " '" . encode_json( $entry ) . "' unknown tag '$k'\n";
91            $has_error++;
92            last;
93        }
94    }
95
96    next if $has_error;
97
98    # add executable
99
100    $out .= "COPY $$modjson{'executable'} $$modjson{'executable'}\n";
101    push @copys, "$executable_path/$$modjson{'executable'}";
102
103    # add CMD
104
105    ## always run in $rundir ?
106    $out .= "WORKDIR $rundir\n";
107
108    ## straight form:
109    ## $out .= "CMD [\"$bindir/$$modjson{'executable'}\"]\n";
110
111    ## abaco MSG form:
112    $out .= "CMD $bindir/$$modjson{'executable'} `echo \$MSG`\n";
113
114    # write dockerfile
115    if ( !-d $menu ) {
116        if ( -e $menu ) {
117            $error .= "File $menu exists in output folder, but is not a directory\n";
118            next;
119        }
120        if ( !mkdir $menu ) {
121            $error .= "Could not create subdir $menu $!\n";
122            next;
123        }
124    }
125
126    my $destdir = "$menu/$mod";
127    if ( !-d $destdir ) {
128        if ( -e $destdir ) {
129            $error .= "File $destdir exists in output folder, but is not a directory\n";
130            next;
131        }
132        if ( !mkdir $destdir ) {
133            $error .= "Could not create subdir $destdir $!\n";
134            next;
135        }
136    }
137       
138    my $df = "$destdir/Dockerfile";
139    my $fh;
140    if ( !( open $fh, ">$df" ) ) {
141        $error .= "Could not create file $df for writing\n";
142        next;
143    }
144    print $fh $out;
145    close $fh;
146
147    # do copies
148    $cmd = "cp " . ( join " ", @copys ) . " $destdir/";
149    print "$cmd\n";
150    system( $cmd );
151
152    # build containers
153    $cmd = "cd $destdir && docker build -t genapp___application___${menu}_${mod} .";
154    print "$cmd\n";
155    system( $cmd );
156}
157   
158print "Warnings:\n$warn" if $warn;
159die "Errors:\n$error" if $error;
Note: See TracBrowser for help on using the repository browser.