Validate that a composed Dockerfile is valid
(&self, content: &str)
| 149 | |
| 150 | /// Validate that a composed Dockerfile is valid |
| 151 | pub fn validate_dockerfile(&self, content: &str) -> Result<()> { |
| 152 | let mut has_from = false; |
| 153 | let mut has_workdir = false; |
| 154 | let mut has_user = false; |
| 155 | |
| 156 | for line in content.lines() { |
| 157 | let trimmed = line.trim(); |
| 158 | |
| 159 | if trimmed.starts_with("FROM ") { |
| 160 | has_from = true; |
| 161 | } else if trimmed.starts_with("WORKDIR ") { |
| 162 | has_workdir = true; |
| 163 | } else if trimmed.starts_with("USER ") { |
| 164 | has_user = true; |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | if !has_from { |
| 169 | return Err(anyhow::anyhow!( |
| 170 | "Dockerfile must contain at least one FROM instruction" |
| 171 | )); |
| 172 | } |
| 173 | |
| 174 | if !has_workdir { |
| 175 | return Err(anyhow::anyhow!( |
| 176 | "Dockerfile should contain a WORKDIR instruction" |
| 177 | )); |
| 178 | } |
| 179 | |
| 180 | if !has_user { |
| 181 | return Err(anyhow::anyhow!( |
| 182 | "Dockerfile should contain a USER instruction for security" |
| 183 | )); |
| 184 | } |
| 185 | |
| 186 | Ok(()) |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | /// Result of composing Docker layers |