terminal-quest 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/bin/terminal-quest.js +2 -0
- package/dist/App.d.ts +2 -0
- package/dist/App.js +33 -0
- package/dist/components/HintBar.d.ts +9 -0
- package/dist/components/HintBar.js +11 -0
- package/dist/components/MenuItem.d.ts +9 -0
- package/dist/components/MenuItem.js +9 -0
- package/dist/components/ObjectivePanel.d.ts +8 -0
- package/dist/components/ObjectivePanel.js +10 -0
- package/dist/components/ProgressBar.d.ts +8 -0
- package/dist/components/ProgressBar.js +10 -0
- package/dist/components/TerminalOutput.d.ts +11 -0
- package/dist/components/TerminalOutput.js +25 -0
- package/dist/components/TerminalPrompt.d.ts +10 -0
- package/dist/components/TerminalPrompt.js +46 -0
- package/dist/data/commands-meta.d.ts +17 -0
- package/dist/data/commands-meta.js +256 -0
- package/dist/data/stories/00-beginner-pc.d.ts +3 -0
- package/dist/data/stories/00-beginner-pc.js +841 -0
- package/dist/data/stories/01-first-server.d.ts +3 -0
- package/dist/data/stories/01-first-server.js +364 -0
- package/dist/data/stories/02-messy-project.d.ts +3 -0
- package/dist/data/stories/02-messy-project.js +433 -0
- package/dist/data/stories/03-log-detective.d.ts +3 -0
- package/dist/data/stories/03-log-detective.js +291 -0
- package/dist/data/stories/04-deploy-day.d.ts +3 -0
- package/dist/data/stories/04-deploy-day.js +337 -0
- package/dist/data/stories/05-git-incident.d.ts +3 -0
- package/dist/data/stories/05-git-incident.js +534 -0
- package/dist/data/stories/06-pipe-master.d.ts +3 -0
- package/dist/data/stories/06-pipe-master.js +377 -0
- package/dist/data/stories/07-dangerous-commands.d.ts +3 -0
- package/dist/data/stories/07-dangerous-commands.js +411 -0
- package/dist/data/stories/index.d.ts +4 -0
- package/dist/data/stories/index.js +14 -0
- package/dist/data/stories/k1-treasure-hunt.d.ts +3 -0
- package/dist/data/stories/k1-treasure-hunt.js +815 -0
- package/dist/data/types.d.ts +97 -0
- package/dist/data/types.js +2 -0
- package/dist/engine/Achievements.d.ts +5 -0
- package/dist/engine/Achievements.js +93 -0
- package/dist/engine/CommandHandler.d.ts +17 -0
- package/dist/engine/CommandHandler.js +177 -0
- package/dist/engine/HintEngine.d.ts +10 -0
- package/dist/engine/HintEngine.js +26 -0
- package/dist/engine/MissionEngine.d.ts +17 -0
- package/dist/engine/MissionEngine.js +84 -0
- package/dist/engine/TabCompletion.d.ts +14 -0
- package/dist/engine/TabCompletion.js +93 -0
- package/dist/engine/VirtualFS.d.ts +33 -0
- package/dist/engine/VirtualFS.js +276 -0
- package/dist/engine/commands/cat.d.ts +4 -0
- package/dist/engine/commands/cat.js +18 -0
- package/dist/engine/commands/cd.d.ts +4 -0
- package/dist/engine/commands/cd.js +12 -0
- package/dist/engine/commands/chmod.d.ts +4 -0
- package/dist/engine/commands/chmod.js +98 -0
- package/dist/engine/commands/clear.d.ts +4 -0
- package/dist/engine/commands/clear.js +4 -0
- package/dist/engine/commands/cp.d.ts +4 -0
- package/dist/engine/commands/cp.js +26 -0
- package/dist/engine/commands/cut.d.ts +4 -0
- package/dist/engine/commands/cut.js +76 -0
- package/dist/engine/commands/echo.d.ts +4 -0
- package/dist/engine/commands/echo.js +4 -0
- package/dist/engine/commands/find.d.ts +4 -0
- package/dist/engine/commands/find.js +60 -0
- package/dist/engine/commands/git.d.ts +4 -0
- package/dist/engine/commands/git.js +510 -0
- package/dist/engine/commands/grep.d.ts +4 -0
- package/dist/engine/commands/grep.js +127 -0
- package/dist/engine/commands/head.d.ts +4 -0
- package/dist/engine/commands/head.js +59 -0
- package/dist/engine/commands/help.d.ts +4 -0
- package/dist/engine/commands/help.js +32 -0
- package/dist/engine/commands/hint.d.ts +4 -0
- package/dist/engine/commands/hint.js +4 -0
- package/dist/engine/commands/index.d.ts +8 -0
- package/dist/engine/commands/index.js +51 -0
- package/dist/engine/commands/ls.d.ts +4 -0
- package/dist/engine/commands/ls.js +50 -0
- package/dist/engine/commands/man.d.ts +4 -0
- package/dist/engine/commands/man.js +51 -0
- package/dist/engine/commands/mkdir.d.ts +4 -0
- package/dist/engine/commands/mkdir.js +31 -0
- package/dist/engine/commands/mv.d.ts +4 -0
- package/dist/engine/commands/mv.js +15 -0
- package/dist/engine/commands/pwd.d.ts +4 -0
- package/dist/engine/commands/pwd.js +4 -0
- package/dist/engine/commands/rm.d.ts +4 -0
- package/dist/engine/commands/rm.js +49 -0
- package/dist/engine/commands/sort.d.ts +4 -0
- package/dist/engine/commands/sort.js +100 -0
- package/dist/engine/commands/tail.d.ts +4 -0
- package/dist/engine/commands/tail.js +59 -0
- package/dist/engine/commands/touch.d.ts +4 -0
- package/dist/engine/commands/touch.js +18 -0
- package/dist/engine/commands/uniq.d.ts +4 -0
- package/dist/engine/commands/uniq.js +61 -0
- package/dist/engine/commands/wc.d.ts +4 -0
- package/dist/engine/commands/wc.js +67 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/dist/screens/MissionBriefScreen.d.ts +9 -0
- package/dist/screens/MissionBriefScreen.js +27 -0
- package/dist/screens/MissionCompleteScreen.d.ts +9 -0
- package/dist/screens/MissionCompleteScreen.js +30 -0
- package/dist/screens/ProgressScreen.d.ts +8 -0
- package/dist/screens/ProgressScreen.js +24 -0
- package/dist/screens/SettingsScreen.d.ts +8 -0
- package/dist/screens/SettingsScreen.js +45 -0
- package/dist/screens/StorySelectScreen.d.ts +8 -0
- package/dist/screens/StorySelectScreen.js +81 -0
- package/dist/screens/TerminalScreen.d.ts +12 -0
- package/dist/screens/TerminalScreen.js +150 -0
- package/dist/screens/TitleScreen.d.ts +7 -0
- package/dist/screens/TitleScreen.js +27 -0
- package/dist/state/GameState.d.ts +8 -0
- package/dist/state/GameState.js +12 -0
- package/dist/state/ProgressStore.d.ts +9 -0
- package/dist/state/ProgressStore.js +45 -0
- package/dist/state/useGameState.d.ts +11 -0
- package/dist/state/useGameState.js +92 -0
- package/dist/utils/ascii-art.d.ts +4 -0
- package/dist/utils/ascii-art.js +22 -0
- package/dist/utils/colors.d.ts +17 -0
- package/dist/utils/colors.js +17 -0
- package/dist/utils/text.d.ts +4 -0
- package/dist/utils/text.js +28 -0
- package/package.json +58 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
const accessLogLines = [
|
|
2
|
+
'2024-01-15 08:00:01 192.168.1.1 GET /index.html 200',
|
|
3
|
+
'2024-01-15 08:00:15 192.168.1.2 POST /api/login 200',
|
|
4
|
+
'2024-01-15 08:01:30 192.168.1.3 GET /api/users 200',
|
|
5
|
+
'2024-01-15 08:02:45 192.168.1.1 GET /api/status 200',
|
|
6
|
+
'2024-01-15 08:03:10 10.0.0.5 GET /dashboard 200',
|
|
7
|
+
'2024-01-15 08:05:22 192.168.1.4 POST /api/data 200',
|
|
8
|
+
'2024-01-15 08:06:00 192.168.1.1 GET /api/users 200',
|
|
9
|
+
'2024-01-15 08:07:15 10.0.0.5 GET /api/config 200',
|
|
10
|
+
'2024-01-15 08:08:30 192.168.1.2 GET /index.html 200',
|
|
11
|
+
'2024-01-15 08:10:00 192.168.1.3 POST /api/upload 200',
|
|
12
|
+
'2024-01-15 08:12:45 192.168.1.1 GET /api/health 200',
|
|
13
|
+
'2024-01-15 08:15:00 10.0.0.5 POST /api/deploy 200',
|
|
14
|
+
'2024-01-15 08:18:30 192.168.1.5 GET /index.html 200',
|
|
15
|
+
'2024-01-15 08:20:10 192.168.1.2 GET /api/status 200',
|
|
16
|
+
'2024-01-15 08:22:00 192.168.1.4 GET /dashboard 200',
|
|
17
|
+
'2024-01-15 08:25:15 192.168.1.1 POST /api/data 200',
|
|
18
|
+
'2024-01-15 08:28:00 10.0.0.5 GET /api/users 200',
|
|
19
|
+
'2024-01-15 08:30:30 192.168.1.3 GET /api/health 200',
|
|
20
|
+
'2024-01-15 08:32:45 192.168.1.2 POST /api/login 200',
|
|
21
|
+
'2024-01-15 08:35:00 192.168.1.5 GET /api/status 200',
|
|
22
|
+
'2024-01-15 08:37:15 192.168.1.1 GET /dashboard 200',
|
|
23
|
+
'2024-01-15 08:40:00 10.0.0.5 POST /api/data 200',
|
|
24
|
+
'2024-01-15 08:42:30 192.168.1.4 GET /api/users 200',
|
|
25
|
+
'2024-01-15 08:45:00 192.168.1.3 GET /index.html 200',
|
|
26
|
+
'2024-01-15 08:47:15 192.168.1.2 GET /api/health 200',
|
|
27
|
+
'2024-01-15 08:50:00 192.168.1.1 POST /api/upload 200',
|
|
28
|
+
'2024-01-15 08:52:30 10.0.0.5 GET /api/config 200',
|
|
29
|
+
'2024-01-15 08:55:00 192.168.1.5 GET /dashboard 200',
|
|
30
|
+
'2024-01-15 08:57:15 192.168.1.4 POST /api/login 200',
|
|
31
|
+
'2024-01-15 09:00:00 192.168.1.3 GET /api/status 200',
|
|
32
|
+
'2024-01-15 09:02:30 192.168.1.2 GET /api/users 200',
|
|
33
|
+
'2024-01-15 09:05:00 192.168.1.1 GET /api/health 200',
|
|
34
|
+
'2024-01-15 09:07:15 10.0.0.5 POST /api/deploy 200',
|
|
35
|
+
'2024-01-15 09:10:00 192.168.1.5 GET /index.html 200',
|
|
36
|
+
'2024-01-15 09:12:30 192.168.1.4 GET /api/config 200',
|
|
37
|
+
'2024-01-15 09:15:00 192.168.1.3 POST /api/data 200',
|
|
38
|
+
'2024-01-15 09:17:15 192.168.1.2 GET /dashboard 200',
|
|
39
|
+
'2024-01-15 09:20:00 192.168.1.1 GET /api/users 200',
|
|
40
|
+
'2024-01-15 09:22:30 10.0.0.5 GET /api/status 200',
|
|
41
|
+
'2024-01-15 09:25:00 192.168.1.5 POST /api/login 200',
|
|
42
|
+
'2024-01-15 09:27:15 192.168.1.4 GET /api/health 200',
|
|
43
|
+
'2024-01-15 09:30:00 192.168.1.3 GET /index.html 200',
|
|
44
|
+
'2024-01-15 09:32:30 192.168.1.2 POST /api/upload 200',
|
|
45
|
+
'2024-01-15 09:35:00 192.168.1.1 GET /api/config 200',
|
|
46
|
+
'2024-01-15 09:37:15 10.0.0.5 GET /dashboard 200',
|
|
47
|
+
'2024-01-15 09:40:00 192.168.1.5 POST /api/data 500',
|
|
48
|
+
'2024-01-15 09:42:30 192.168.1.4 GET /api/users 500',
|
|
49
|
+
'2024-01-15 09:45:00 192.168.1.3 POST /api/deploy 500',
|
|
50
|
+
'2024-01-15 09:47:15 192.168.1.2 GET /api/status 500',
|
|
51
|
+
'2024-01-15 09:50:00 192.168.1.1 POST /api/data 500',
|
|
52
|
+
].join('\n');
|
|
53
|
+
const mission1FS = {
|
|
54
|
+
type: 'directory',
|
|
55
|
+
children: {
|
|
56
|
+
var: {
|
|
57
|
+
type: 'directory',
|
|
58
|
+
children: {
|
|
59
|
+
log: {
|
|
60
|
+
type: 'directory',
|
|
61
|
+
children: {
|
|
62
|
+
'access.log': {
|
|
63
|
+
type: 'file',
|
|
64
|
+
content: accessLogLines,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const mission2FS = {
|
|
73
|
+
type: 'directory',
|
|
74
|
+
children: {
|
|
75
|
+
var: {
|
|
76
|
+
type: 'directory',
|
|
77
|
+
children: {
|
|
78
|
+
log: {
|
|
79
|
+
type: 'directory',
|
|
80
|
+
children: {
|
|
81
|
+
'access.log': {
|
|
82
|
+
type: 'file',
|
|
83
|
+
content: accessLogLines,
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
const ipListLines = [
|
|
92
|
+
'192.168.1.1',
|
|
93
|
+
'10.0.0.5',
|
|
94
|
+
'192.168.1.2',
|
|
95
|
+
'192.168.1.1',
|
|
96
|
+
'192.168.1.3',
|
|
97
|
+
'10.0.0.5',
|
|
98
|
+
'192.168.1.1',
|
|
99
|
+
'192.168.1.4',
|
|
100
|
+
'192.168.1.2',
|
|
101
|
+
'192.168.1.1',
|
|
102
|
+
'10.0.0.5',
|
|
103
|
+
'192.168.1.5',
|
|
104
|
+
'192.168.1.1',
|
|
105
|
+
'192.168.1.3',
|
|
106
|
+
'192.168.1.2',
|
|
107
|
+
'192.168.1.1',
|
|
108
|
+
'10.0.0.5',
|
|
109
|
+
'192.168.1.4',
|
|
110
|
+
'192.168.1.1',
|
|
111
|
+
'192.168.1.5',
|
|
112
|
+
].join('\n');
|
|
113
|
+
const mission3FS = {
|
|
114
|
+
type: 'directory',
|
|
115
|
+
children: {
|
|
116
|
+
var: {
|
|
117
|
+
type: 'directory',
|
|
118
|
+
children: {
|
|
119
|
+
log: {
|
|
120
|
+
type: 'directory',
|
|
121
|
+
children: {
|
|
122
|
+
'ip-list.txt': {
|
|
123
|
+
type: 'file',
|
|
124
|
+
content: ipListLines,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
const mission4FS = {
|
|
133
|
+
type: 'directory',
|
|
134
|
+
children: {
|
|
135
|
+
var: {
|
|
136
|
+
type: 'directory',
|
|
137
|
+
children: {
|
|
138
|
+
log: {
|
|
139
|
+
type: 'directory',
|
|
140
|
+
children: {
|
|
141
|
+
'access.log': {
|
|
142
|
+
type: 'file',
|
|
143
|
+
content: accessLogLines,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
home: {
|
|
150
|
+
type: 'directory',
|
|
151
|
+
children: {
|
|
152
|
+
admin: {
|
|
153
|
+
type: 'directory',
|
|
154
|
+
children: {},
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
export const story03 = {
|
|
161
|
+
id: 'story-03',
|
|
162
|
+
title: 'ログ探偵',
|
|
163
|
+
description: 'サーバーで障害が発生。大量のログファイルから手がかりを見つけ、原因を特定しよう。',
|
|
164
|
+
emoji: '\u{1F50D}',
|
|
165
|
+
missions: [
|
|
166
|
+
{
|
|
167
|
+
id: 'mission-03-01',
|
|
168
|
+
title: 'ログファイルの調査',
|
|
169
|
+
description: 'head と tail コマンドでログファイルの最初と最後を確認しよう。',
|
|
170
|
+
narrative: '大量のログがある。まずはファイルの最初と最後を確認しよう。',
|
|
171
|
+
initialCwd: '/var/log',
|
|
172
|
+
newCommands: ['head', 'tail'],
|
|
173
|
+
initialFS: mission1FS,
|
|
174
|
+
objectives: [
|
|
175
|
+
{
|
|
176
|
+
id: 'obj-03-01-01',
|
|
177
|
+
description: 'ログファイルの最初の数行を確認する',
|
|
178
|
+
checks: [{ type: 'command_executed', command: 'head' }],
|
|
179
|
+
hints: [
|
|
180
|
+
{ level: 1, text: 'ファイルの先頭部分を表示するコマンドがあります。' },
|
|
181
|
+
{ level: 2, text: 'head コマンドでファイルの最初の数行を表示できます。' },
|
|
182
|
+
{ level: 3, text: '「head access.log」と入力してEnterを押してください。' },
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: 'obj-03-01-02',
|
|
187
|
+
description: 'ログファイルの最後の数行を確認して 500 エラーを発見する',
|
|
188
|
+
checks: [
|
|
189
|
+
{ type: 'command_executed', command: 'tail' },
|
|
190
|
+
{ type: 'output_contains', pattern: '500' },
|
|
191
|
+
],
|
|
192
|
+
hints: [
|
|
193
|
+
{ level: 1, text: 'ファイルの末尾を表示するコマンドがあります。' },
|
|
194
|
+
{ level: 2, text: 'tail コマンドでファイルの最後の数行を表示できます。' },
|
|
195
|
+
{ level: 3, text: '「tail access.log」と入力してEnterを押してください。' },
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: 'mission-03-02',
|
|
202
|
+
title: 'エラーの分析',
|
|
203
|
+
description: 'grep と wc コマンドで 500 エラーの件数を数えよう。',
|
|
204
|
+
narrative: '500エラーが出ている。何件あるか数えよう。',
|
|
205
|
+
initialCwd: '/var/log',
|
|
206
|
+
initialFS: mission2FS,
|
|
207
|
+
objectives: [
|
|
208
|
+
{
|
|
209
|
+
id: 'obj-03-02-01',
|
|
210
|
+
description: '500 エラーを含む行を抽出する',
|
|
211
|
+
checks: [
|
|
212
|
+
{ type: 'command_executed', command: 'grep' },
|
|
213
|
+
{ type: 'output_contains', pattern: '500' },
|
|
214
|
+
],
|
|
215
|
+
hints: [
|
|
216
|
+
{ level: 1, text: '特定の文字列を含む行だけを抽出するコマンドがあります。' },
|
|
217
|
+
{ level: 2, text: 'grep コマンドに検索パターンとファイル名を指定します。' },
|
|
218
|
+
{ level: 3, text: '「grep 500 access.log」と入力してEnterを押してください。' },
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
id: 'obj-03-02-02',
|
|
223
|
+
description: 'エラーの件数を数える(5件)',
|
|
224
|
+
checks: [{ type: 'output_contains', pattern: '5' }],
|
|
225
|
+
hints: [
|
|
226
|
+
{ level: 1, text: '行数を数えるコマンドとパイプを組み合わせましょう。' },
|
|
227
|
+
{ level: 2, text: 'grep の結果を wc -l にパイプで渡すと行数を数えられます。' },
|
|
228
|
+
{ level: 3, text: '「grep 500 access.log | wc -l」と入力してEnterを押してください。' },
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
id: 'mission-03-03',
|
|
235
|
+
title: 'アクセスパターンの分析',
|
|
236
|
+
description: 'sort と uniq コマンドでIPアドレスのアクセス頻度を調べよう。',
|
|
237
|
+
narrative: 'どのIPアドレスからアクセスが多いか調べよう。',
|
|
238
|
+
initialCwd: '/var/log',
|
|
239
|
+
newCommands: ['sort', 'uniq'],
|
|
240
|
+
initialFS: mission3FS,
|
|
241
|
+
objectives: [
|
|
242
|
+
{
|
|
243
|
+
id: 'obj-03-03-01',
|
|
244
|
+
description: 'IPアドレスをソートする',
|
|
245
|
+
checks: [{ type: 'command_executed', command: 'sort' }],
|
|
246
|
+
hints: [
|
|
247
|
+
{ level: 1, text: 'データを並び替えるコマンドがあります。' },
|
|
248
|
+
{ level: 2, text: 'sort コマンドで行を並び替えることができます。' },
|
|
249
|
+
{ level: 3, text: '「sort ip-list.txt」と入力してEnterを押してください。' },
|
|
250
|
+
],
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: 'obj-03-03-02',
|
|
254
|
+
description: 'ユニークなIPアドレスの一覧を出す',
|
|
255
|
+
checks: [{ type: 'command_executed', command: 'uniq' }],
|
|
256
|
+
hints: [
|
|
257
|
+
{ level: 1, text: '重複を除去するコマンドがあります。sort と組み合わせましょう。' },
|
|
258
|
+
{ level: 2, text: 'sort の結果をパイプで uniq に渡します。uniq -c で件数も表示できます。' },
|
|
259
|
+
{ level: 3, text: '「sort ip-list.txt | uniq -c」と入力してEnterを押してください。' },
|
|
260
|
+
],
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
id: 'mission-03-04',
|
|
266
|
+
title: 'レポート作成',
|
|
267
|
+
description: 'grep とリダイレクトを使って、調査結果をファイルに保存しよう。',
|
|
268
|
+
narrative: '調査結果をレポートファイルにまとめよう。',
|
|
269
|
+
initialCwd: '/var/log',
|
|
270
|
+
initialFS: mission4FS,
|
|
271
|
+
objectives: [
|
|
272
|
+
{
|
|
273
|
+
id: 'obj-03-04-01',
|
|
274
|
+
description: '500 エラー行をレポートファイルに出力する',
|
|
275
|
+
checks: [
|
|
276
|
+
{ type: 'file_exists', path: '/var/log/error-report.txt' },
|
|
277
|
+
{ type: 'file_contains', path: '/var/log/error-report.txt', pattern: '500' },
|
|
278
|
+
],
|
|
279
|
+
hints: [
|
|
280
|
+
{ level: 1, text: 'コマンドの出力をファイルに書き込む方法があります。' },
|
|
281
|
+
{ level: 2, text: 'リダイレクト(>)を使うと、コマンドの出力をファイルに保存できます。' },
|
|
282
|
+
{ level: 3, text: '「grep 500 access.log > error-report.txt」と入力してEnterを押してください。' },
|
|
283
|
+
],
|
|
284
|
+
},
|
|
285
|
+
],
|
|
286
|
+
},
|
|
287
|
+
],
|
|
288
|
+
unlockRequires: ['story-01'],
|
|
289
|
+
course: 'engineer',
|
|
290
|
+
};
|
|
291
|
+
//# sourceMappingURL=03-log-detective.js.map
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
const mission1FS = {
|
|
2
|
+
type: 'directory',
|
|
3
|
+
children: {
|
|
4
|
+
home: {
|
|
5
|
+
type: 'directory',
|
|
6
|
+
children: {
|
|
7
|
+
deploy: {
|
|
8
|
+
type: 'directory',
|
|
9
|
+
children: {
|
|
10
|
+
source: {
|
|
11
|
+
type: 'directory',
|
|
12
|
+
children: {
|
|
13
|
+
app: {
|
|
14
|
+
type: 'directory',
|
|
15
|
+
children: {
|
|
16
|
+
'index.js': {
|
|
17
|
+
type: 'file',
|
|
18
|
+
content: 'const app = require("./server");\napp.start();\n',
|
|
19
|
+
},
|
|
20
|
+
'server.js': {
|
|
21
|
+
type: 'file',
|
|
22
|
+
content: [
|
|
23
|
+
'const http = require("http");',
|
|
24
|
+
'module.exports = {',
|
|
25
|
+
' start() {',
|
|
26
|
+
' http.createServer((req, res) => {',
|
|
27
|
+
' res.end("OK");',
|
|
28
|
+
' }).listen(8080);',
|
|
29
|
+
' }',
|
|
30
|
+
'};',
|
|
31
|
+
].join('\n'),
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
config: {
|
|
36
|
+
type: 'directory',
|
|
37
|
+
children: {
|
|
38
|
+
'app.json': {
|
|
39
|
+
type: 'file',
|
|
40
|
+
content: '{"env": "production", "port": 8080}\n',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
'README.md': {
|
|
45
|
+
type: 'file',
|
|
46
|
+
content: '# Deploy App\n\nProduction application.\n',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
var: {
|
|
55
|
+
type: 'directory',
|
|
56
|
+
children: {
|
|
57
|
+
www: {
|
|
58
|
+
type: 'directory',
|
|
59
|
+
children: {},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const mission2FS = {
|
|
66
|
+
type: 'directory',
|
|
67
|
+
children: {
|
|
68
|
+
var: {
|
|
69
|
+
type: 'directory',
|
|
70
|
+
children: {
|
|
71
|
+
www: {
|
|
72
|
+
type: 'directory',
|
|
73
|
+
children: {
|
|
74
|
+
app: {
|
|
75
|
+
type: 'directory',
|
|
76
|
+
children: {
|
|
77
|
+
'start.sh': {
|
|
78
|
+
type: 'file',
|
|
79
|
+
content: [
|
|
80
|
+
'#!/bin/bash',
|
|
81
|
+
'echo "Starting application..."',
|
|
82
|
+
'node index.js',
|
|
83
|
+
].join('\n'),
|
|
84
|
+
permissions: '-rw-r--r--',
|
|
85
|
+
},
|
|
86
|
+
'config.json': {
|
|
87
|
+
type: 'file',
|
|
88
|
+
content: '{"env": "production", "port": 8080}\n',
|
|
89
|
+
},
|
|
90
|
+
'index.html': {
|
|
91
|
+
type: 'file',
|
|
92
|
+
content: [
|
|
93
|
+
'<!DOCTYPE html>',
|
|
94
|
+
'<html>',
|
|
95
|
+
'<head><title>App</title></head>',
|
|
96
|
+
'<body><h1>Welcome</h1></body>',
|
|
97
|
+
'</html>',
|
|
98
|
+
].join('\n'),
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
const mission3FS = {
|
|
109
|
+
type: 'directory',
|
|
110
|
+
children: {
|
|
111
|
+
var: {
|
|
112
|
+
type: 'directory',
|
|
113
|
+
children: {
|
|
114
|
+
www: {
|
|
115
|
+
type: 'directory',
|
|
116
|
+
children: {
|
|
117
|
+
app: {
|
|
118
|
+
type: 'directory',
|
|
119
|
+
children: {
|
|
120
|
+
'start.sh': {
|
|
121
|
+
type: 'file',
|
|
122
|
+
content: [
|
|
123
|
+
'#!/bin/bash',
|
|
124
|
+
'echo "Starting application..."',
|
|
125
|
+
'node index.js',
|
|
126
|
+
].join('\n'),
|
|
127
|
+
permissions: '-rwxr-xr-x',
|
|
128
|
+
},
|
|
129
|
+
'config.json': {
|
|
130
|
+
type: 'file',
|
|
131
|
+
content: '{"env": "production", "port": 8080}\n',
|
|
132
|
+
},
|
|
133
|
+
'index.html': {
|
|
134
|
+
type: 'file',
|
|
135
|
+
content: [
|
|
136
|
+
'<!DOCTYPE html>',
|
|
137
|
+
'<html>',
|
|
138
|
+
'<head><title>App</title></head>',
|
|
139
|
+
'<body><h1>Welcome</h1></body>',
|
|
140
|
+
'</html>',
|
|
141
|
+
].join('\n'),
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
'backup-old': {
|
|
146
|
+
type: 'directory',
|
|
147
|
+
children: {
|
|
148
|
+
'start.sh': {
|
|
149
|
+
type: 'file',
|
|
150
|
+
content: '#!/bin/bash\necho "Old version"\n',
|
|
151
|
+
},
|
|
152
|
+
'config.json': {
|
|
153
|
+
type: 'file',
|
|
154
|
+
content: '{"env": "staging", "port": 3000}\n',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
const mission4FS = {
|
|
165
|
+
type: 'directory',
|
|
166
|
+
children: {
|
|
167
|
+
var: {
|
|
168
|
+
type: 'directory',
|
|
169
|
+
children: {
|
|
170
|
+
www: {
|
|
171
|
+
type: 'directory',
|
|
172
|
+
children: {
|
|
173
|
+
app: {
|
|
174
|
+
type: 'directory',
|
|
175
|
+
children: {
|
|
176
|
+
'start.sh': {
|
|
177
|
+
type: 'file',
|
|
178
|
+
content: [
|
|
179
|
+
'#!/bin/bash',
|
|
180
|
+
'echo "Starting application..."',
|
|
181
|
+
'node index.js',
|
|
182
|
+
].join('\n'),
|
|
183
|
+
permissions: '-rwxr-xr-x',
|
|
184
|
+
},
|
|
185
|
+
'config.json': {
|
|
186
|
+
type: 'file',
|
|
187
|
+
content: '{"env":"production","port":8080,"debug":false}\n',
|
|
188
|
+
},
|
|
189
|
+
'index.html': {
|
|
190
|
+
type: 'file',
|
|
191
|
+
content: [
|
|
192
|
+
'<!DOCTYPE html>',
|
|
193
|
+
'<html>',
|
|
194
|
+
'<head><title>App</title></head>',
|
|
195
|
+
'<body><h1>Welcome</h1></body>',
|
|
196
|
+
'</html>',
|
|
197
|
+
].join('\n'),
|
|
198
|
+
},
|
|
199
|
+
static: {
|
|
200
|
+
type: 'directory',
|
|
201
|
+
children: {
|
|
202
|
+
'style.css': {
|
|
203
|
+
type: 'file',
|
|
204
|
+
content: 'body { font-family: sans-serif; margin: 0; }\n',
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
export const story04 = {
|
|
217
|
+
id: 'story-04',
|
|
218
|
+
title: 'デプロイの日',
|
|
219
|
+
description: 'いよいよ本番デプロイ。ファイルの権限設定やディレクトリのコピーなど、デプロイ手順を実行しよう。',
|
|
220
|
+
emoji: '\u{1F680}',
|
|
221
|
+
missions: [
|
|
222
|
+
{
|
|
223
|
+
id: 'mission-04-01',
|
|
224
|
+
title: 'デプロイ先の準備',
|
|
225
|
+
description: 'mkdir -p と cp -r でデプロイ先を準備しよう。',
|
|
226
|
+
narrative: 'デプロイ先のディレクトリを作成して、ソースをコピーしよう。',
|
|
227
|
+
initialCwd: '/home/deploy',
|
|
228
|
+
initialFS: mission1FS,
|
|
229
|
+
objectives: [
|
|
230
|
+
{
|
|
231
|
+
id: 'obj-04-01-01',
|
|
232
|
+
description: '/var/www/app ディレクトリを再帰的に作成する',
|
|
233
|
+
checks: [{ type: 'file_exists', path: '/var/www/app' }],
|
|
234
|
+
hints: [
|
|
235
|
+
{ level: 1, text: '深い階層のディレクトリを一度に作成するオプションがあります。' },
|
|
236
|
+
{ level: 2, text: 'mkdir に -p オプションをつけると、親ディレクトリも含めて作成できます。' },
|
|
237
|
+
{ level: 3, text: '「mkdir -p /var/www/app」と入力してEnterを押してください。' },
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
id: 'obj-04-01-02',
|
|
242
|
+
description: 'source の内容をデプロイ先にコピーする',
|
|
243
|
+
checks: [{ type: 'file_exists', path: '/var/www/app/README.md' }],
|
|
244
|
+
hints: [
|
|
245
|
+
{ level: 1, text: 'ディレクトリごとコピーするオプションがあります。' },
|
|
246
|
+
{ level: 2, text: 'cp に -r オプションをつけると、ディレクトリを再帰的にコピーできます。' },
|
|
247
|
+
{ level: 3, text: '「cp -r source/* /var/www/app/」と入力してEnterを押してください。' },
|
|
248
|
+
],
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: 'mission-04-02',
|
|
254
|
+
title: '権限の設定',
|
|
255
|
+
description: 'chmod コマンドでファイルの実行権限を設定しよう。',
|
|
256
|
+
narrative: 'デプロイしたファイルの実行権限を設定しよう。',
|
|
257
|
+
initialCwd: '/var/www/app',
|
|
258
|
+
newCommands: ['chmod'],
|
|
259
|
+
initialFS: mission2FS,
|
|
260
|
+
objectives: [
|
|
261
|
+
{
|
|
262
|
+
id: 'obj-04-02-01',
|
|
263
|
+
description: 'start.sh に実行権限を付与する',
|
|
264
|
+
checks: [{ type: 'command_executed', command: 'chmod' }],
|
|
265
|
+
hints: [
|
|
266
|
+
{ level: 1, text: 'ファイルの権限を変更するコマンドがあります。' },
|
|
267
|
+
{ level: 2, text: 'chmod コマンドで権限を変更します。+x で実行権限を追加できます。' },
|
|
268
|
+
{ level: 3, text: '「chmod +x start.sh」と入力してEnterを押してください。' },
|
|
269
|
+
],
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
id: 'mission-04-03',
|
|
275
|
+
title: 'バックアップ作成',
|
|
276
|
+
description: '古いバックアップを削除して、新しいバックアップを作ろう。',
|
|
277
|
+
narrative: '古いバックアップを削除して、新しいバックアップを作ろう。',
|
|
278
|
+
initialCwd: '/var/www',
|
|
279
|
+
initialFS: mission3FS,
|
|
280
|
+
objectives: [
|
|
281
|
+
{
|
|
282
|
+
id: 'obj-04-03-01',
|
|
283
|
+
description: '古いバックアップ(backup-old)を削除する',
|
|
284
|
+
checks: [{ type: 'file_not_exists', path: '/var/www/backup-old' }],
|
|
285
|
+
hints: [
|
|
286
|
+
{ level: 1, text: 'ディレクトリを削除するにはオプションが必要です。' },
|
|
287
|
+
{ level: 2, text: 'rm に -rf オプションをつけると、ディレクトリを中身ごと削除できます。' },
|
|
288
|
+
{ level: 3, text: '「rm -rf backup-old」と入力してEnterを押してください。' },
|
|
289
|
+
],
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
id: 'obj-04-03-02',
|
|
293
|
+
description: '現在の app を backup としてコピーする',
|
|
294
|
+
checks: [{ type: 'file_exists', path: '/var/www/backup' }],
|
|
295
|
+
hints: [
|
|
296
|
+
{ level: 1, text: 'ディレクトリをまるごとコピーしましょう。' },
|
|
297
|
+
{ level: 2, text: 'cp -r コマンドでディレクトリを再帰的にコピーできます。' },
|
|
298
|
+
{ level: 3, text: '「cp -r app backup」と入力してEnterを押してください。' },
|
|
299
|
+
],
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
id: 'mission-04-04',
|
|
305
|
+
title: '最終確認',
|
|
306
|
+
description: 'デプロイが完了したか最終確認しよう。',
|
|
307
|
+
narrative: 'デプロイが完了した。最終確認をしよう。',
|
|
308
|
+
initialCwd: '/var/www/app',
|
|
309
|
+
initialFS: mission4FS,
|
|
310
|
+
objectives: [
|
|
311
|
+
{
|
|
312
|
+
id: 'obj-04-04-01',
|
|
313
|
+
description: '全ファイルの一覧を表示する',
|
|
314
|
+
checks: [{ type: 'command_executed', command: 'find' }],
|
|
315
|
+
hints: [
|
|
316
|
+
{ level: 1, text: 'ディレクトリ内の全ファイルを再帰的に表示するコマンドがあります。' },
|
|
317
|
+
{ level: 2, text: 'find コマンドでカレントディレクトリ以下を全て表示できます。' },
|
|
318
|
+
{ level: 3, text: '「find .」と入力してEnterを押してください。' },
|
|
319
|
+
],
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
id: 'obj-04-04-02',
|
|
323
|
+
description: '設定ファイルの内容を確認して production であることを確かめる',
|
|
324
|
+
checks: [{ type: 'output_contains', pattern: 'production' }],
|
|
325
|
+
hints: [
|
|
326
|
+
{ level: 1, text: 'ファイルの内容を表示するコマンドで設定を確認しましょう。' },
|
|
327
|
+
{ level: 2, text: 'cat コマンドで config.json の内容を表示できます。' },
|
|
328
|
+
{ level: 3, text: '「cat config.json」と入力してEnterを押してください。' },
|
|
329
|
+
],
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
},
|
|
333
|
+
],
|
|
334
|
+
unlockRequires: ['story-02', 'story-03'],
|
|
335
|
+
course: 'engineer',
|
|
336
|
+
};
|
|
337
|
+
//# sourceMappingURL=04-deploy-day.js.map
|