1 | "use strict";
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const Doer_1 = __importDefault(require("./Doer"));
|
7 | const VERSION = require('../package').version;
|
8 |
|
9 |
|
10 |
|
11 | class Generator extends Doer_1.default {
|
12 | |
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | generate(comments = true, stencila = false) {
|
19 | let dockerfile = '';
|
20 | if (comments) {
|
21 | dockerfile += `# Generated by Dockter ${VERSION} at ${new Date().toISOString()}
|
22 | # To stop Dockter generating this file and start editing it yourself,
|
23 | # rename it to "Dockerfile".\n`;
|
24 | }
|
25 | if (comments)
|
26 | dockerfile += '\n# This tells Docker which base image to use.\n';
|
27 | const baseIdentifier = this.baseIdentifier();
|
28 | dockerfile += `FROM ${baseIdentifier}\n`;
|
29 | if (!this.applies())
|
30 | return dockerfile;
|
31 | const aptRepos = this.aptRepos(baseIdentifier);
|
32 | let aptKeysCommand = this.aptKeysCommand(baseIdentifier);
|
33 | if (aptRepos.length || aptKeysCommand) {
|
34 | if (comments)
|
35 | dockerfile += '\n# This section installs system packages needed to add extra system repositories.';
|
36 | dockerfile += `
|
37 | RUN apt-get update \\
|
38 | && DEBIAN_FRONTEND=noninteractive apt-get install -y \\
|
39 | apt-transport-https \\
|
40 | ca-certificates \\
|
41 | curl \\
|
42 | software-properties-common
|
43 | `;
|
44 | }
|
45 | if (comments && (aptKeysCommand || aptRepos.length)) {
|
46 | dockerfile += '\n# This section adds system repositories required to install extra system packages.';
|
47 | }
|
48 | if (aptKeysCommand)
|
49 | dockerfile += `\nRUN ${aptKeysCommand}`;
|
50 | if (aptRepos.length)
|
51 | dockerfile += `\nRUN ${aptRepos.map(repo => `apt-add-repository "${repo}"`).join(' \\\n && ')}\n`;
|
52 |
|
53 | const envVars = this.envVars(baseIdentifier);
|
54 | if (envVars.length) {
|
55 | if (comments)
|
56 | dockerfile += '\n# This section sets environment variables within the image.';
|
57 | const pairs = envVars.map(([key, value]) => `${key}="${value.replace('"', '\\"')}"`);
|
58 | dockerfile += `\nENV ${pairs.join(' \\\n ')}\n`;
|
59 | }
|
60 | let aptPackages = this.aptPackages(baseIdentifier);
|
61 | if (aptPackages.length) {
|
62 | if (comments) {
|
63 | dockerfile += `
|
64 | # This section installs system packages required for your project
|
65 | # If you need extra system packages add them here.`;
|
66 | }
|
67 | dockerfile += `
|
68 | RUN apt-get update \\
|
69 | && DEBIAN_FRONTEND=noninteractive apt-get install -y \\
|
70 | ${aptPackages.join(' \\\n ')} \\
|
71 | && apt-get autoremove -y \\
|
72 | && apt-get clean \\
|
73 | && rm -rf /var/lib/apt/lists/*
|
74 | `;
|
75 | }
|
76 | if (stencila) {
|
77 | let stencilaInstall = this.stencilaInstall(baseIdentifier);
|
78 | if (stencilaInstall) {
|
79 | if (comments)
|
80 | dockerfile += '\n# This section runs commands to install Stencila execution hosts.';
|
81 | dockerfile += `\nRUN ${stencilaInstall}\n`;
|
82 | }
|
83 | }
|
84 |
|
85 | if (comments) {
|
86 | dockerfile += `
|
87 | # It's good practice to run Docker images as a non-root user.
|
88 | # This section creates a new user and its home directory as the default working directory.`;
|
89 | }
|
90 | dockerfile += `
|
91 | RUN useradd --create-home --uid 1001 -s /bin/bash dockteruser
|
92 | WORKDIR /home/dockteruser
|
93 | `;
|
94 | const installFiles = this.installFiles(baseIdentifier);
|
95 | const installCommand = this.installCommand(baseIdentifier);
|
96 | const projectFiles = this.projectFiles(baseIdentifier);
|
97 | const runCommand = this.runCommand(baseIdentifier);
|
98 |
|
99 | if (installCommand) {
|
100 | if (comments)
|
101 | dockerfile += '\n# This is a special comment to tell Dockter to manage the build from here on';
|
102 | dockerfile += `\n# dockter\n`;
|
103 | }
|
104 |
|
105 | if (installFiles.length) {
|
106 | if (comments)
|
107 | dockerfile += '\n# This section copies package requirement files into the image';
|
108 | dockerfile += '\n' + installFiles.map(([src, dest]) => `COPY ${src} ${dest}`).join('\n') + '\n';
|
109 | }
|
110 |
|
111 | if (installCommand) {
|
112 | if (comments)
|
113 | dockerfile += '\n# This section runs commands to install the packages specified in the requirement file/s';
|
114 | dockerfile += `\nRUN ${installCommand}\n`;
|
115 | }
|
116 |
|
117 | if (projectFiles.length) {
|
118 | if (comments)
|
119 | dockerfile += '\n# This section copies your project\'s files into the image';
|
120 | dockerfile += '\n' + projectFiles.map(([src, dest]) => `COPY ${src} ${dest}`).join('\n') + '\n';
|
121 | }
|
122 |
|
123 | if (comments)
|
124 | dockerfile += '\n# This sets the default user when the container is run';
|
125 | dockerfile += '\nUSER dockteruser\n';
|
126 |
|
127 | if (runCommand) {
|
128 | if (comments)
|
129 | dockerfile += '\n# This tells Docker the default command to run when the container is started';
|
130 | dockerfile += `\nCMD ${runCommand}\n`;
|
131 | }
|
132 |
|
133 | this.write('.Dockerfile', dockerfile);
|
134 | return dockerfile;
|
135 | }
|
136 |
|
137 | |
138 |
|
139 |
|
140 | applies() {
|
141 | return false;
|
142 | }
|
143 | |
144 |
|
145 |
|
146 | baseName() {
|
147 | return 'ubuntu';
|
148 | }
|
149 | |
150 |
|
151 |
|
152 | baseVersion() {
|
153 | return '18.04';
|
154 | }
|
155 | |
156 |
|
157 |
|
158 |
|
159 | baseVersionName(baseIdentifier) {
|
160 | let [name, version] = baseIdentifier.split(':');
|
161 | const lookup = {
|
162 | '14.04': 'trusty',
|
163 | '16.04': 'xenial',
|
164 | '18.04': 'bionic'
|
165 | };
|
166 | return lookup[version];
|
167 | }
|
168 | |
169 |
|
170 |
|
171 | baseIdentifier() {
|
172 | const joiner = this.baseVersion() === '' ? '' : ':';
|
173 | return `${this.baseName()}${joiner}${this.baseVersion()}`;
|
174 | }
|
175 | |
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 | envVars(sysVersion) {
|
182 | return [];
|
183 | }
|
184 | |
185 |
|
186 |
|
187 |
|
188 |
|
189 | aptKeysCommand(sysVersion) {
|
190 | return;
|
191 | }
|
192 | |
193 |
|
194 |
|
195 |
|
196 |
|
197 | aptRepos(sysVersion) {
|
198 | return [];
|
199 | }
|
200 | |
201 |
|
202 |
|
203 |
|
204 |
|
205 | aptPackages(sysVersion) {
|
206 | return [];
|
207 | }
|
208 | |
209 |
|
210 |
|
211 |
|
212 |
|
213 | stencilaInstall(sysVersion) {
|
214 | return;
|
215 | }
|
216 | |
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 | installFiles(sysVersion) {
|
224 | return [];
|
225 | }
|
226 | |
227 |
|
228 |
|
229 |
|
230 |
|
231 | installCommand(sysVersion) {
|
232 | return;
|
233 | }
|
234 | |
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 | projectFiles(sysVersion) {
|
241 | return [];
|
242 | }
|
243 | |
244 |
|
245 |
|
246 |
|
247 |
|
248 | runCommand(sysVersion) {
|
249 | return;
|
250 | }
|
251 | }
|
252 | exports.default = Generator;
|