@@ -36,6 +36,7 @@ impl std::error::Error for ContainerfileError {}
3636
3737pub fn generate ( config : & Config , agent : Option < & dyn Agent > ) -> Result < String , ContainerfileError > {
3838 match config. base_image . image . as_str ( ) {
39+ "fedora" => Ok ( fedora ( config, agent) ) ,
3940 "ubuntu" => Ok ( ubuntu ( config, agent) ) ,
4041 image => Err ( ContainerfileError :: NotSupported {
4142 image : image. to_string ( ) ,
@@ -93,6 +94,56 @@ USER sandbox
9394 )
9495}
9596
97+ fn fedora ( config : & Config , agent : Option < & dyn Agent > ) -> String {
98+ let tag = & config. base_image . tag ;
99+ let agent_section = agent
100+ . map ( |a| format ! ( "{}\n \n " , a. install( ) ) )
101+ . unwrap_or_default ( ) ;
102+ format ! (
103+ r#"# System base
104+ FROM registry.fedoraproject.org/fedora:{tag} AS system
105+
106+ ENV PYTHONDONTWRITEBYTECODE=1 \
107+ PYTHONUNBUFFERED=1
108+
109+ WORKDIR /sandbox
110+
111+ # Core system dependencies
112+ RUN dnf install -y --setopt=install_weak_deps=False \
113+ bind-utils \
114+ ca-certificates \
115+ curl \
116+ iproute \
117+ iptables \
118+ iputils \
119+ net-tools \
120+ nftables \
121+ nmap-ncat \
122+ openssh-server \
123+ procps-ng \
124+ traceroute \
125+ which \
126+ && dnf clean all
127+
128+ RUN groupadd -r supervisor && useradd -r -g supervisor -s /usr/sbin/nologin supervisor && \
129+ groupadd -r sandbox && useradd -r -g sandbox -d /sandbox -s /bin/bash sandbox
130+
131+ # Final base image
132+ FROM system AS final
133+
134+ RUN printf 'export PS1="\\u@\\h:\\w\\$ "\n' \
135+ > /sandbox/.bashrc && \
136+ printf '[ -f ~/.bashrc ] && . ~/.bashrc\n' > /sandbox/.profile && \
137+ chown sandbox:sandbox /sandbox/.bashrc /sandbox/.profile && \
138+ chown -R sandbox:sandbox /sandbox
139+
140+ USER sandbox
141+
142+ {agent_section}ENTRYPOINT ["/bin/bash"]
143+ "#
144+ )
145+ }
146+
96147#[ cfg( test) ]
97148mod tests {
98149 use super :: * ;
@@ -171,22 +222,51 @@ mod tests {
171222 }
172223
173224 #[ test]
174- fn fedora_returns_not_supported ( ) {
175- let err = generate ( & fedora_config ( ) , None ) . unwrap_err ( ) ;
176- assert_eq ! (
177- err,
178- ContainerfileError :: NotSupported {
179- image: "fedora" . to_string( )
180- }
225+ fn fedora_generates_successfully ( ) {
226+ assert ! ( generate( & fedora_config( ) , None ) . is_ok( ) ) ;
227+ }
228+
229+ #[ test]
230+ fn fedora_containerfile_contains_tag ( ) {
231+ let content = generate ( & fedora_config ( ) , None ) . unwrap ( ) ;
232+ assert ! ( content. contains( "FROM registry.fedoraproject.org/fedora:latest AS system" ) ) ;
233+ }
234+
235+ #[ test]
236+ fn fedora_containerfile_tag_is_substituted ( ) {
237+ let content = generate ( & fedora_config ( ) , None ) . unwrap ( ) ;
238+ assert ! ( !content. contains( "{tag}" ) ) ;
239+ }
240+
241+ #[ test]
242+ fn fedora_with_agent_includes_install ( ) {
243+ let content = generate ( & fedora_config ( ) , Some ( & MockAgent ) ) . unwrap ( ) ;
244+ assert ! ( content. contains( "RUN echo mock-agent" ) ) ;
245+ }
246+
247+ #[ test]
248+ fn fedora_agent_install_runs_as_sandbox_user ( ) {
249+ let content = generate ( & fedora_config ( ) , Some ( & MockAgent ) ) . unwrap ( ) ;
250+ let user_pos = content. find ( "USER sandbox" ) . unwrap ( ) ;
251+ let install_pos = content. find ( "RUN echo mock-agent" ) . unwrap ( ) ;
252+ assert ! (
253+ install_pos > user_pos,
254+ "agent install must appear after USER sandbox"
181255 ) ;
182256 }
183257
258+ #[ test]
259+ fn fedora_without_agent_omits_install ( ) {
260+ let content = generate ( & fedora_config ( ) , None ) . unwrap ( ) ;
261+ assert ! ( !content. contains( "RUN echo mock-agent" ) ) ;
262+ }
263+
184264 #[ test]
185265 fn not_supported_error_message ( ) {
186266 let err = ContainerfileError :: NotSupported {
187- image : "fedora " . to_string ( ) ,
267+ image : "centos " . to_string ( ) ,
188268 } ;
189- assert_eq ! ( err. to_string( ) , "base image 'fedora ' is not supported" ) ;
269+ assert_eq ! ( err. to_string( ) , "base image 'centos ' is not supported" ) ;
190270 }
191271
192272 #[ test]
0 commit comments