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

Last change on this file since 1627 was 1627, checked in by ehb, 3 years ago

languages:docker handle moduleid different from executable in containers for appconfig:resource:docker-local

File size: 5.5 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 %copymap;
27    my $has_cpanm;
28   
29    for ( my $i = 0; $i < @$depjson; ++$i ) {
30        my $entry = $$depjson[$i];
31        if ( scalar ( keys %$entry ) != 1 ) {
32            $has_error++;
33            $error .= "Module '$mod' : dependencies entry " . ( $i + 1 ) . " '" . encode_json( $entry ) . "' does not have exactly 1 key\n";
34            break;
35        }
36
37        my $k = (keys %$entry)[0];
38        my $v = $$entry{$k};
39        $k = lc( $k );
40        if ( ref( $v ) ne 'ARRAY' ) {
41            my @v = ( $v );
42            $v = \@v;
43        }
44        # create command to build and post (?) dockerfile
45
46        for ( my $j = 0; $j < @$v; ++$j ) {
47            my $val = $$v[$j];
48            if ( length( ref( $val ) ) ) {
49                $error .= "Module '$mod' : dependencies entry " . ( $i + 1 ) . " '" . encode_json( $entry ) . "' improper value in list entry number " . ( $j + 1 ) . "\n";
50                $has_error++;
51                next;
52            }
53            if ( $k eq 'base' ) {
54                if ( $hasbase ) {
55                    $error .= "Module '$mod' : dependencies entry " . ( $i + 1 ) . " '" . encode_json( $entry ) . "' multiple 'base' tags found, only one allowed\n";
56                    $has_error;
57                    last;
58                }
59                $out .= "FROM $val\n";
60                $out .= "WORKDIR $bindir\n";
61                $has_base++;
62                next;
63            }
64            if ( !$has_base ) {
65                $warn .= "No 'base' entry found in first position, defaulting to 'ubuntu'\n";
66                $out .= "FROM ubuntu\n";
67                $out .= "WORKDIR $bindir\n";
68                $has_base++;
69                next;
70            }               
71            if ( $k eq 'cpan' ) {
72                if ( !$has_cpanm ) {
73                    $out .= "RUN curl -L http://cpanmin.us | perl - App::cpanminus\n";
74                    $out .= "RUN mv /usr/bin/perl /usr/bin/perl.save\n";
75                    $out .= "RUN ln -s /usr/local/bin/perl /usr/bin/perl\n";
76                    $has_cpanm++;
77                }
78                $out .= "RUN cpanm $val\n";
79                next;
80            }
81
82            if ( $k eq 'file' ) {
83                my $dest = $val;
84                $dest =~ s/^.*\///g;
85                $out .= "COPY $dest $dest\n";
86                $val = "$executable_path/$val" if $val !~ /^\//;
87                push @copys, $val;
88                $copymap{ $val }++;
89                next;
90            }
91
92            $error .= "Module '$mod' : dependencies entry " . ( $i + 1 ) . " '" . encode_json( $entry ) . "' unknown tag '$k'\n";
93            $has_error++;
94            last;
95        }
96    }
97
98    # add executable
99
100    $out .= "COPY $$modjson{'executable'} $$modjson{'executable'}\n";
101    push @copys, "$executable_path/$$modjson{'executable'}";
102
103    ## if executable is not equal to module name, create symlink to enable appconfig:resource:docker*
104    if ( $$modjson{'executable'} ne $mod ) {
105        ### check if there is a clobber first, this is an error!
106        if ( $copymap{ $mod } ) {
107            $error .= "Module '$mod' : executable name does not match module id, yet there is a dependency of the same name\n";
108            $has_error++;
109        } else {
110            $out .= "RUN ln -s $$modjson{'executable'} $mod\n";
111        }
112    }
113   
114    next if $has_error;
115
116    # add CMD
117
118    ## always run in $rundir ?
119    $out .= "WORKDIR $rundir\n";
120
121    ## straight form:
122    ## $out .= "CMD [\"$bindir/$$modjson{'executable'}\"]\n";
123
124    ## abaco MSG form:
125    $out .= "CMD $bindir/$$modjson{'executable'} `echo \$MSG`\n";
126
127    # write dockerfile
128    if ( !-d $menu ) {
129        if ( -e $menu ) {
130            $error .= "File $menu exists in output folder, but is not a directory\n";
131            next;
132        }
133        if ( !mkdir $menu ) {
134            $error .= "Could not create subdir $menu $!\n";
135            next;
136        }
137    }
138
139    my $destdir = "$menu/$mod";
140    if ( !-d $destdir ) {
141        if ( -e $destdir ) {
142            $error .= "File $destdir exists in output folder, but is not a directory\n";
143            next;
144        }
145        if ( !mkdir $destdir ) {
146            $error .= "Could not create subdir $destdir $!\n";
147            next;
148        }
149    }
150       
151    my $df = "$destdir/Dockerfile";
152    my $fh;
153    if ( !( open $fh, ">$df" ) ) {
154        $error .= "Could not create file $df for writing\n";
155        next;
156    }
157    print $fh $out;
158    close $fh;
159
160    # do copies
161    $cmd = "cp " . ( join " ", @copys ) . " $destdir/";
162    print "$cmd\n";
163    system( $cmd );
164
165    # build containers
166    $cmd = "cd $destdir && docker build -t genapp___application___${menu}_${mod} .";
167    print "$cmd\n";
168    system( $cmd );
169}
170   
171print "Warnings:\n$warn" if $warn;
172die "Errors:\n$error" if $error;
Note: See TracBrowser for help on using the repository browser.