A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

795 lines
25 KiB

2 years ago
2 years ago
4 years ago
  1. use crate::command_runner::{SetuidCommandRunner, StdCommandRunner};
  2. use crate::resources::{
  3. AcmeAccountKey, AcmeChallengesDir, AcmeChallengesNginxSnippet, AcmeRootCert, AcmeUser, Cert,
  4. CertChain, Cron, Csr, DefaultServer, Dir, File, GitCheckout, Key, KeyAndCertBundle,
  5. LoadedDirectory, MariaDbDatabase, MariaDbUser, NpmInstall, Owner, PhpFpmPool, PostgresqlDatabase,
  6. Resource, ServeCustom, ServePhp, ServeRedir, ServeService, ServeStatic, StoredDirectory,
  7. SystemdSocketService, User, UserForDomain, WordpressPlugin, WordpressTranslation,
  8. };
  9. use crate::static_files::LETS_ENCRYPT_R3;
  10. use crate::storage::SimpleStorage;
  11. use crate::storage::Storage;
  12. use crate::symbols::acme::Cert as CertSymbol;
  13. use crate::symbols::concat::Concat as ConcatSymbol;
  14. use crate::symbols::cron::Cron as CronSymbol;
  15. use crate::symbols::dir::Dir as DirSymbol;
  16. use crate::symbols::file::File as FileSymbol;
  17. use crate::symbols::git::Checkout as GitCheckoutSymbol;
  18. use crate::symbols::mariadb::{
  19. Database as MariaDbDatabaseSymbol, Dump as MariaDbDumpSymbol, User as MariaDbUserSymbol,
  20. };
  21. use crate::symbols::npm::Install as NpmInstallSymbol;
  22. use crate::symbols::owner::Owner as OwnerSymbol;
  23. use crate::symbols::postgresql::PostgreSQLDatabase as PostgreSQLDatabaseSymbol;
  24. use crate::symbols::saved_directory::{SavedDirectory as SavedDirectorySymbol, StorageDirection};
  25. use crate::symbols::systemd::{
  26. ReloadService as ReloadServiceSymbol, UserService as UserServiceSymbol,
  27. UserSession as SystemdUserSessionSymbol,
  28. };
  29. use crate::symbols::tls::Csr as CsrSymbol;
  30. use crate::symbols::tls::Key as KeySymbol;
  31. use crate::symbols::user::User as UserSymbol;
  32. use crate::symbols::wordpress::{
  33. Plugin as WordpressPluginSymbol, Translation as WordpressTranslationSymbol,
  34. };
  35. use crate::templates::nginx;
  36. use crate::templates::php::{
  37. fpm_pool_config as php_fpm_pool_config, FpmPoolConfig as PhpFpmPoolConfig,
  38. };
  39. use crate::templates::systemd::{
  40. nodejs_service as systemd_nodejs_service, socket_service as systemd_socket_service,
  41. };
  42. use crate::to_artifact::ToArtifact;
  43. use std::fmt::Display;
  44. use std::path::{Path, PathBuf};
  45. pub trait ImplementationBuilder<R> {
  46. type Prerequisites: ToArtifact;
  47. fn prerequisites(resource: &R) -> Self::Prerequisites;
  48. type Implementation;
  49. fn create(
  50. resource: &R,
  51. target: &R::Artifact,
  52. inputs: <Self::Prerequisites as ToArtifact>::Artifact,
  53. ) -> Self::Implementation
  54. where
  55. R: Resource;
  56. }
  57. #[derive(Debug)]
  58. pub struct DefaultBuilder;
  59. impl<D> ImplementationBuilder<Key<D>> for DefaultBuilder {
  60. type Prerequisites = ();
  61. fn prerequisites(_resource: &Key<D>) -> Self::Prerequisites {}
  62. type Implementation = KeySymbol<StdCommandRunner, PathBuf>;
  63. fn create(
  64. _resource: &Key<D>,
  65. target: &<Key<D> as Resource>::Artifact,
  66. (): <Self::Prerequisites as ToArtifact>::Artifact,
  67. ) -> Self::Implementation {
  68. KeySymbol::new(StdCommandRunner, target.clone().into())
  69. }
  70. }
  71. impl<D: Clone> ImplementationBuilder<Csr<D>> for DefaultBuilder {
  72. type Prerequisites = Key<D>;
  73. fn prerequisites(resource: &Csr<D>) -> Self::Prerequisites {
  74. Key(resource.0.clone())
  75. }
  76. type Implementation = CsrSymbol<StdCommandRunner, D, PathBuf, PathBuf>;
  77. fn create(
  78. resource: &Csr<D>,
  79. target: &<Csr<D> as Resource>::Artifact,
  80. key: <Self::Prerequisites as ToArtifact>::Artifact,
  81. ) -> Self::Implementation {
  82. CsrSymbol::new(
  83. StdCommandRunner,
  84. resource.0.clone(),
  85. key.into(),
  86. target.clone().into(),
  87. )
  88. }
  89. }
  90. impl<D: Clone> ImplementationBuilder<Cert<D>> for DefaultBuilder {
  91. type Prerequisites = (
  92. Csr<D>,
  93. AcmeRootCert,
  94. AcmeAccountKey,
  95. AcmeChallengesDir,
  96. AcmeUser,
  97. DefaultServer,
  98. );
  99. fn prerequisites(resource: &Cert<D>) -> Self::Prerequisites {
  100. (
  101. Csr(resource.0.clone()),
  102. AcmeRootCert,
  103. AcmeAccountKey,
  104. AcmeChallengesDir,
  105. AcmeUser,
  106. DefaultServer,
  107. )
  108. }
  109. type Implementation = CertSymbol<
  110. SetuidCommandRunner<'static, String, StdCommandRunner>,
  111. SetuidCommandRunner<'static, String, StdCommandRunner>,
  112. D,
  113. PathBuf,
  114. >;
  115. fn create(
  116. resource: &Cert<D>,
  117. target: &<Cert<D> as Resource>::Artifact,
  118. (csr, root_cert, account_key, challenges_dir, user_name, _): <Self::Prerequisites as ToArtifact>::Artifact,
  119. ) -> Self::Implementation {
  120. CertSymbol::new(
  121. resource.0.clone(),
  122. SetuidCommandRunner::new(user_name.0, &StdCommandRunner),
  123. root_cert.into(),
  124. account_key.into(),
  125. challenges_dir.into(),
  126. csr.into(),
  127. target.clone().into(),
  128. )
  129. }
  130. }
  131. impl<D: Clone> ImplementationBuilder<CertChain<D>> for DefaultBuilder {
  132. type Prerequisites = (Cert<D>, AcmeRootCert);
  133. fn prerequisites(resource: &CertChain<D>) -> Self::Prerequisites {
  134. (Cert(resource.0.clone()), AcmeRootCert)
  135. }
  136. type Implementation = ConcatSymbol<[PathBuf; 2], PathBuf, PathBuf>;
  137. fn create(
  138. _resource: &CertChain<D>,
  139. target: &<CertChain<D> as Resource>::Artifact,
  140. (cert, root_cert): <Self::Prerequisites as ToArtifact>::Artifact,
  141. ) -> Self::Implementation {
  142. ConcatSymbol::new([cert.into(), root_cert.into()], target.clone().into())
  143. }
  144. }
  145. impl<D: Clone> ImplementationBuilder<KeyAndCertBundle<D>> for DefaultBuilder {
  146. type Prerequisites = (CertChain<D>, Key<D>);
  147. fn prerequisites(resource: &KeyAndCertBundle<D>) -> Self::Prerequisites {
  148. (CertChain(resource.0.clone()), Key(resource.0.clone()))
  149. }
  150. type Implementation = ConcatSymbol<[PathBuf; 2], PathBuf, PathBuf>;
  151. fn create(
  152. _resource: &KeyAndCertBundle<D>,
  153. target: &<KeyAndCertBundle<D> as Resource>::Artifact,
  154. (cert_chain, key): <Self::Prerequisites as ToArtifact>::Artifact,
  155. ) -> Self::Implementation {
  156. ConcatSymbol::new([key.into(), cert_chain.into()], target.clone().into())
  157. }
  158. }
  159. impl<P: AsRef<Path> + Clone> ImplementationBuilder<File<P>> for DefaultBuilder {
  160. type Prerequisites = ();
  161. fn prerequisites(_resource: &File<P>) -> Self::Prerequisites {}
  162. type Implementation = FileSymbol<P, String>;
  163. fn create(
  164. resource: &File<P>,
  165. _target: &<File<P> as Resource>::Artifact,
  166. (): <Self::Prerequisites as ToArtifact>::Artifact,
  167. ) -> Self::Implementation {
  168. FileSymbol::new(resource.0.clone(), resource.1.clone())
  169. }
  170. }
  171. impl<'a, P: AsRef<Path> + Clone> ImplementationBuilder<GitCheckout<'a, P>> for DefaultBuilder {
  172. type Prerequisites = ();
  173. fn prerequisites(_resource: &GitCheckout<'a, P>) -> Self::Prerequisites {}
  174. type Implementation = GitCheckoutSymbol<StdCommandRunner, StdCommandRunner, P, &'a str, &'a str>;
  175. fn create(
  176. resource: &GitCheckout<'a, P>,
  177. _target: &<GitCheckout<'a, P> as Resource>::Artifact,
  178. (): <Self::Prerequisites as ToArtifact>::Artifact,
  179. ) -> Self::Implementation {
  180. GitCheckoutSymbol::new(resource.0.clone(), resource.1, resource.2, StdCommandRunner)
  181. }
  182. }
  183. impl ImplementationBuilder<DefaultServer> for DefaultBuilder {
  184. type Prerequisites = AcmeChallengesNginxSnippet;
  185. fn prerequisites(_resource: &DefaultServer) -> Self::Prerequisites {
  186. AcmeChallengesNginxSnippet
  187. }
  188. type Implementation = (
  189. FileSymbol<PathBuf, String>,
  190. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  191. );
  192. fn create(
  193. _resource: &DefaultServer,
  194. target: &<DefaultServer as Resource>::Artifact,
  195. challenges_snippet_path: <Self::Prerequisites as ToArtifact>::Artifact,
  196. ) -> Self::Implementation {
  197. (
  198. FileSymbol::new(
  199. target.clone().into(),
  200. nginx::default_server(challenges_snippet_path),
  201. ),
  202. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  203. )
  204. }
  205. }
  206. impl<D: AsRef<str> + Clone + Display> ImplementationBuilder<ServeCustom<D>> for DefaultBuilder {
  207. type Prerequisites = (CertChain<D>, Key<D>, AcmeChallengesNginxSnippet);
  208. fn prerequisites(resource: &ServeCustom<D>) -> Self::Prerequisites {
  209. (
  210. CertChain(resource.0.clone()),
  211. Key(resource.0.clone()),
  212. AcmeChallengesNginxSnippet,
  213. )
  214. }
  215. type Implementation = (
  216. FileSymbol<PathBuf, String>,
  217. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  218. );
  219. fn create(
  220. resource: &ServeCustom<D>,
  221. target: &<ServeCustom<D> as Resource>::Artifact,
  222. (cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  223. ) -> Self::Implementation {
  224. (
  225. FileSymbol::new(
  226. target.clone().into(),
  227. nginx::server_config(&resource.0, cert, key, &resource.1, challenges_snippet_path),
  228. ),
  229. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  230. )
  231. }
  232. }
  233. impl<D: Clone + Display, P: AsRef<Path>, C: Clone + Into<PhpFpmPoolConfig>>
  234. ImplementationBuilder<ServePhp<D, P, C>> for DefaultBuilder
  235. {
  236. type Prerequisites = (
  237. PhpFpmPool<D>,
  238. CertChain<D>,
  239. Key<D>,
  240. AcmeChallengesNginxSnippet,
  241. );
  242. fn prerequisites(resource: &ServePhp<D, P, C>) -> Self::Prerequisites {
  243. (
  244. PhpFpmPool(resource.0.clone(), resource.4.clone().into()),
  245. CertChain(resource.0.clone()),
  246. Key(resource.0.clone()),
  247. AcmeChallengesNginxSnippet,
  248. )
  249. }
  250. type Implementation = (
  251. FileSymbol<PathBuf, String>,
  252. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  253. );
  254. fn create(
  255. resource: &ServePhp<D, P, C>,
  256. target: &<ServePhp<D, P, C> as Resource>::Artifact,
  257. (pool, cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  258. ) -> Self::Implementation {
  259. (
  260. FileSymbol::new(
  261. target.clone().into(),
  262. nginx::server_config(
  263. &resource.0,
  264. cert,
  265. key,
  266. nginx::php_snippet(resource.2, &pool.0, &resource.1) + &resource.3,
  267. challenges_snippet_path,
  268. ),
  269. ),
  270. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  271. )
  272. }
  273. }
  274. impl<D: Clone + Display, P: Clone + AsRef<Path>> ImplementationBuilder<ServeService<D, P>>
  275. for DefaultBuilder
  276. {
  277. type Prerequisites = (
  278. SystemdSocketService<D, P>,
  279. CertChain<D>,
  280. Key<D>,
  281. AcmeChallengesNginxSnippet,
  282. );
  283. fn prerequisites(resource: &ServeService<D, P>) -> Self::Prerequisites {
  284. (
  285. SystemdSocketService(
  286. resource.0.clone(),
  287. resource.1,
  288. resource.2.clone(),
  289. resource.4.clone(),
  290. resource.5,
  291. ),
  292. CertChain(resource.0.clone()),
  293. Key(resource.0.clone()),
  294. AcmeChallengesNginxSnippet,
  295. )
  296. }
  297. type Implementation = (
  298. FileSymbol<PathBuf, String>,
  299. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  300. );
  301. fn create(
  302. resource: &ServeService<D, P>,
  303. target: &<ServeService<D, P> as Resource>::Artifact,
  304. (socket, cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  305. ) -> Self::Implementation {
  306. (
  307. FileSymbol::new(
  308. target.clone().into(),
  309. nginx::server_config(
  310. &resource.0,
  311. cert,
  312. key,
  313. nginx::proxy_snippet(&socket.0, &resource.3),
  314. challenges_snippet_path,
  315. ),
  316. ),
  317. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  318. )
  319. }
  320. }
  321. impl<D: AsRef<str> + Clone + Display> ImplementationBuilder<ServeRedir<D>> for DefaultBuilder {
  322. type Prerequisites = (CertChain<D>, Key<D>, AcmeChallengesNginxSnippet);
  323. fn prerequisites(resource: &ServeRedir<D>) -> Self::Prerequisites {
  324. (
  325. CertChain(resource.0.clone()),
  326. Key(resource.0.clone()),
  327. AcmeChallengesNginxSnippet,
  328. )
  329. }
  330. type Implementation = (
  331. FileSymbol<PathBuf, String>,
  332. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  333. );
  334. fn create(
  335. resource: &ServeRedir<D>,
  336. target: &<ServeRedir<D> as Resource>::Artifact,
  337. (cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  338. ) -> Self::Implementation {
  339. (
  340. FileSymbol::new(
  341. target.clone().into(),
  342. nginx::server_config(
  343. &resource.0,
  344. cert,
  345. key,
  346. nginx::redir_snippet(resource.1.as_ref()),
  347. challenges_snippet_path,
  348. ),
  349. ),
  350. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  351. )
  352. }
  353. }
  354. impl<D: AsRef<str> + Clone + Display, P: AsRef<Path>> ImplementationBuilder<ServeStatic<D, P>>
  355. for DefaultBuilder
  356. {
  357. type Prerequisites = (CertChain<D>, Key<D>, AcmeChallengesNginxSnippet);
  358. fn prerequisites(resource: &ServeStatic<D, P>) -> Self::Prerequisites {
  359. (
  360. CertChain(resource.0.clone()),
  361. Key(resource.0.clone()),
  362. AcmeChallengesNginxSnippet,
  363. )
  364. }
  365. type Implementation = (
  366. FileSymbol<PathBuf, String>,
  367. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, &'static str>,
  368. );
  369. fn create(
  370. resource: &ServeStatic<D, P>,
  371. target: &<ServeStatic<D, P> as Resource>::Artifact,
  372. (cert, key, challenges_snippet_path): <Self::Prerequisites as ToArtifact>::Artifact,
  373. ) -> Self::Implementation {
  374. (
  375. FileSymbol::new(
  376. target.clone().into(),
  377. nginx::server_config(
  378. &resource.0,
  379. cert,
  380. key,
  381. nginx::static_snippet(resource.1.as_ref()),
  382. challenges_snippet_path,
  383. ),
  384. ),
  385. ReloadServiceSymbol::new(StdCommandRunner, "nginx"),
  386. )
  387. }
  388. }
  389. impl<D: Clone> ImplementationBuilder<PhpFpmPool<D>> for DefaultBuilder {
  390. type Prerequisites = ();
  391. fn prerequisites(_resource: &PhpFpmPool<D>) -> Self::Prerequisites {}
  392. type Implementation = (
  393. FileSymbol<PathBuf, String>,
  394. ReloadServiceSymbol<StdCommandRunner, StdCommandRunner, String>,
  395. );
  396. fn create(
  397. resource: &PhpFpmPool<D>,
  398. (socket_path, conf_path, user_name, service_name): &<PhpFpmPool<D> as Resource>::Artifact,
  399. (): <Self::Prerequisites as ToArtifact>::Artifact,
  400. ) -> Self::Implementation {
  401. (
  402. FileSymbol::new(
  403. conf_path.clone().into(),
  404. php_fpm_pool_config(&user_name.0, &socket_path, &resource.1),
  405. ),
  406. ReloadServiceSymbol::new(StdCommandRunner, service_name.0.clone()),
  407. )
  408. }
  409. }
  410. impl<D, P: AsRef<Path>> ImplementationBuilder<SystemdSocketService<D, P>> for DefaultBuilder {
  411. type Prerequisites = ();
  412. fn prerequisites(_resource: &SystemdSocketService<D, P>) -> Self::Prerequisites {}
  413. type Implementation = (
  414. // First three could be parallel
  415. FileSymbol<PathBuf, String>,
  416. SystemdUserSessionSymbol<'static, String, StdCommandRunner>,
  417. OwnerSymbol<StdCommandRunner, StdCommandRunner, PathBuf, String>,
  418. UserServiceSymbol<'static, PathBuf, String, StdCommandRunner>,
  419. );
  420. fn create(
  421. resource: &SystemdSocketService<D, P>,
  422. (socket_path, conf_path, user_name): &<SystemdSocketService<D, P> as Resource>::Artifact,
  423. (): <Self::Prerequisites as ToArtifact>::Artifact,
  424. ) -> Self::Implementation {
  425. (
  426. FileSymbol::new(
  427. conf_path.clone().into(),
  428. if resource.4 {
  429. systemd_nodejs_service(&resource.2, socket_path, &resource.3)
  430. } else {
  431. systemd_socket_service(
  432. socket_path,
  433. resource.2.as_ref().to_str().unwrap(),
  434. &resource.3,
  435. "",
  436. )
  437. },
  438. ),
  439. SystemdUserSessionSymbol::new(user_name.0.clone(), &StdCommandRunner),
  440. OwnerSymbol::new(
  441. conf_path.as_ref().parent().unwrap().to_path_buf(),
  442. user_name.0.clone(),
  443. StdCommandRunner,
  444. ),
  445. UserServiceSymbol::new(
  446. socket_path.clone().into(),
  447. user_name.0.clone(),
  448. resource.1,
  449. &StdCommandRunner,
  450. ),
  451. )
  452. }
  453. }
  454. impl<P: Clone> ImplementationBuilder<Dir<P>> for DefaultBuilder {
  455. type Prerequisites = ();
  456. fn prerequisites(_resource: &Dir<P>) -> Self::Prerequisites {}
  457. type Implementation = DirSymbol<P>;
  458. fn create(
  459. resource: &Dir<P>,
  460. _target: &<Dir<P> as Resource>::Artifact,
  461. (): <Self::Prerequisites as ToArtifact>::Artifact,
  462. ) -> Self::Implementation {
  463. DirSymbol::new(resource.0.clone())
  464. }
  465. }
  466. impl<P: Clone + AsRef<Path>> ImplementationBuilder<NpmInstall<P>> for DefaultBuilder {
  467. type Prerequisites = ();
  468. fn prerequisites(_resource: &NpmInstall<P>) -> Self::Prerequisites {}
  469. type Implementation = NpmInstallSymbol<'static, P, StdCommandRunner>;
  470. fn create(
  471. resource: &NpmInstall<P>,
  472. _target: &<NpmInstall<P> as Resource>::Artifact,
  473. (): <Self::Prerequisites as ToArtifact>::Artifact,
  474. ) -> Self::Implementation {
  475. NpmInstallSymbol::new(resource.0.clone(), &StdCommandRunner)
  476. }
  477. }
  478. impl<P: Clone + AsRef<Path>> ImplementationBuilder<StoredDirectory<P>> for DefaultBuilder {
  479. type Prerequisites = ();
  480. fn prerequisites(_resource: &StoredDirectory<P>) -> Self::Prerequisites {}
  481. type Implementation = SavedDirectorySymbol<StdCommandRunner, StdCommandRunner, P, SimpleStorage>;
  482. fn create(
  483. resource: &StoredDirectory<P>,
  484. target: &<StoredDirectory<P> as Resource>::Artifact,
  485. (): <Self::Prerequisites as ToArtifact>::Artifact,
  486. ) -> Self::Implementation {
  487. SavedDirectorySymbol::new(
  488. resource.1.clone(),
  489. SimpleStorage::new(target.clone().into()),
  490. StorageDirection::Store,
  491. StdCommandRunner,
  492. )
  493. }
  494. }
  495. impl<P: Clone + AsRef<Path>> ImplementationBuilder<LoadedDirectory<P>> for DefaultBuilder {
  496. type Prerequisites = ();
  497. fn prerequisites(_resource: &LoadedDirectory<P>) -> Self::Prerequisites {}
  498. type Implementation = SavedDirectorySymbol<StdCommandRunner, StdCommandRunner, P, SimpleStorage>;
  499. fn create(
  500. resource: &LoadedDirectory<P>,
  501. target: &<LoadedDirectory<P> as Resource>::Artifact,
  502. (): <Self::Prerequisites as ToArtifact>::Artifact,
  503. ) -> Self::Implementation {
  504. SavedDirectorySymbol::new(
  505. resource.1.clone(),
  506. SimpleStorage::new(target.clone().into()),
  507. StorageDirection::Load,
  508. StdCommandRunner,
  509. )
  510. }
  511. }
  512. impl<D: Clone> ImplementationBuilder<UserForDomain<D>> for DefaultBuilder {
  513. type Prerequisites = ();
  514. fn prerequisites(_resource: &UserForDomain<D>) -> Self::Prerequisites {}
  515. type Implementation = UserSymbol<String, StdCommandRunner>;
  516. fn create(
  517. _resource: &UserForDomain<D>,
  518. (user_name, _home_path): &<UserForDomain<D> as Resource>::Artifact,
  519. (): <Self::Prerequisites as ToArtifact>::Artifact,
  520. ) -> Self::Implementation {
  521. UserSymbol::new(user_name.0.clone(), StdCommandRunner)
  522. }
  523. }
  524. impl ImplementationBuilder<User> for DefaultBuilder {
  525. type Prerequisites = ();
  526. fn prerequisites(_resource: &User) -> Self::Prerequisites {}
  527. type Implementation = UserSymbol<String, StdCommandRunner>;
  528. fn create(
  529. resource: &User,
  530. (): &<User as Resource>::Artifact,
  531. (): <Self::Prerequisites as ToArtifact>::Artifact,
  532. ) -> Self::Implementation {
  533. UserSymbol::new(resource.0.clone(), StdCommandRunner)
  534. }
  535. }
  536. impl<P: AsRef<Path> + Clone> ImplementationBuilder<Owner<P>> for DefaultBuilder {
  537. type Prerequisites = ();
  538. fn prerequisites(_resource: &Owner<P>) -> Self::Prerequisites {}
  539. type Implementation = OwnerSymbol<StdCommandRunner, StdCommandRunner, P, String>;
  540. fn create(
  541. resource: &Owner<P>,
  542. (): &<Owner<P> as Resource>::Artifact,
  543. (): <Self::Prerequisites as ToArtifact>::Artifact,
  544. ) -> Self::Implementation {
  545. OwnerSymbol::new(resource.1.clone(), resource.0.clone(), StdCommandRunner)
  546. }
  547. }
  548. impl ImplementationBuilder<AcmeUser> for DefaultBuilder {
  549. type Prerequisites = ();
  550. fn prerequisites(_resource: &AcmeUser) -> Self::Prerequisites {}
  551. type Implementation = UserSymbol<String, StdCommandRunner>;
  552. fn create(
  553. _resource: &AcmeUser,
  554. user_name: &<AcmeUser as Resource>::Artifact,
  555. (): <Self::Prerequisites as ToArtifact>::Artifact,
  556. ) -> Self::Implementation {
  557. UserSymbol::new(user_name.0.clone(), StdCommandRunner)
  558. }
  559. }
  560. impl ImplementationBuilder<AcmeChallengesDir> for DefaultBuilder {
  561. type Prerequisites = AcmeUser;
  562. fn prerequisites(_resource: &AcmeChallengesDir) -> Self::Prerequisites {
  563. AcmeUser
  564. }
  565. type Implementation = (
  566. DirSymbol<PathBuf>,
  567. OwnerSymbol<StdCommandRunner, StdCommandRunner, PathBuf, String>,
  568. );
  569. fn create(
  570. _resource: &AcmeChallengesDir,
  571. target: &<AcmeChallengesDir as Resource>::Artifact,
  572. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  573. ) -> Self::Implementation {
  574. (
  575. DirSymbol::new(target.clone().into()),
  576. OwnerSymbol::new(target.clone().into(), user_name.0, StdCommandRunner),
  577. )
  578. }
  579. }
  580. impl ImplementationBuilder<AcmeChallengesNginxSnippet> for DefaultBuilder {
  581. type Prerequisites = AcmeChallengesDir;
  582. fn prerequisites(_resource: &AcmeChallengesNginxSnippet) -> Self::Prerequisites {
  583. AcmeChallengesDir
  584. }
  585. type Implementation = FileSymbol<PathBuf, String>;
  586. fn create(
  587. _resource: &AcmeChallengesNginxSnippet,
  588. target: &<AcmeChallengesNginxSnippet as Resource>::Artifact,
  589. challenges_dir: <Self::Prerequisites as ToArtifact>::Artifact,
  590. ) -> Self::Implementation {
  591. FileSymbol::new(
  592. target.clone().into(),
  593. nginx::acme_challenges_snippet(challenges_dir),
  594. )
  595. }
  596. }
  597. impl ImplementationBuilder<AcmeAccountKey> for DefaultBuilder {
  598. type Prerequisites = AcmeUser;
  599. fn prerequisites(_resource: &AcmeAccountKey) -> Self::Prerequisites {
  600. AcmeUser
  601. }
  602. type Implementation = (
  603. KeySymbol<StdCommandRunner, PathBuf>,
  604. OwnerSymbol<StdCommandRunner, StdCommandRunner, PathBuf, String>,
  605. );
  606. fn create(
  607. _resource: &AcmeAccountKey,
  608. target: &<AcmeAccountKey as Resource>::Artifact,
  609. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  610. ) -> Self::Implementation {
  611. (
  612. KeySymbol::new(StdCommandRunner, target.clone().into()),
  613. OwnerSymbol::new(target.clone().into(), user_name.0, StdCommandRunner),
  614. )
  615. }
  616. }
  617. impl ImplementationBuilder<AcmeRootCert> for DefaultBuilder {
  618. type Prerequisites = ();
  619. fn prerequisites(_resource: &AcmeRootCert) -> Self::Prerequisites {}
  620. type Implementation = FileSymbol<PathBuf, &'static str>;
  621. fn create(
  622. _resource: &AcmeRootCert,
  623. target: &<AcmeRootCert as Resource>::Artifact,
  624. (): <Self::Prerequisites as ToArtifact>::Artifact,
  625. ) -> Self::Implementation {
  626. FileSymbol::new(target.clone().into(), LETS_ENCRYPT_R3)
  627. }
  628. }
  629. impl<D> ImplementationBuilder<MariaDbUser<D>> for DefaultBuilder {
  630. type Prerequisites = ();
  631. fn prerequisites(_resource: &MariaDbUser<D>) -> Self::Prerequisites {}
  632. type Implementation = MariaDbUserSymbol<'static, String, StdCommandRunner>;
  633. fn create(
  634. _resource: &MariaDbUser<D>,
  635. user_name: &<MariaDbUser<D> as Resource>::Artifact,
  636. _: <Self::Prerequisites as ToArtifact>::Artifact,
  637. ) -> Self::Implementation {
  638. MariaDbUserSymbol::new(user_name.0.clone(), &StdCommandRunner)
  639. }
  640. }
  641. impl<D: Clone> ImplementationBuilder<MariaDbDatabase<D>> for DefaultBuilder {
  642. type Prerequisites = MariaDbUser<D>;
  643. fn prerequisites(resource: &MariaDbDatabase<D>) -> Self::Prerequisites {
  644. MariaDbUser(resource.0.clone())
  645. }
  646. type Implementation = (
  647. MariaDbDatabaseSymbol<'static, String, SimpleStorage, StdCommandRunner>,
  648. MariaDbDumpSymbol<'static, String, StdCommandRunner, SimpleStorage>,
  649. );
  650. fn create(
  651. _resource: &MariaDbDatabase<D>,
  652. (db_name, _, data_path): &<MariaDbDatabase<D> as Resource>::Artifact,
  653. _: <Self::Prerequisites as ToArtifact>::Artifact,
  654. ) -> Self::Implementation {
  655. let db_dump = SimpleStorage::new(data_path.clone().into());
  656. (
  657. MariaDbDatabaseSymbol::new(db_name.0.clone(), db_dump.clone(), &StdCommandRunner),
  658. MariaDbDumpSymbol::new(db_name.0.clone(), db_dump, &StdCommandRunner),
  659. )
  660. }
  661. }
  662. impl<D: Clone> ImplementationBuilder<PostgresqlDatabase<D>> for DefaultBuilder {
  663. type Prerequisites = ();
  664. fn prerequisites(_: &PostgresqlDatabase<D>) -> Self::Prerequisites {}
  665. type Implementation = (PostgreSQLDatabaseSymbol<'static, String, String, StdCommandRunner>,);
  666. fn create(
  667. _resource: &PostgresqlDatabase<D>,
  668. (db_name, data_path): &<PostgresqlDatabase<D> as Resource>::Artifact,
  669. _: <Self::Prerequisites as ToArtifact>::Artifact,
  670. ) -> Self::Implementation {
  671. let db_dump = SimpleStorage::new(data_path.clone().into());
  672. (PostgreSQLDatabaseSymbol::new(
  673. db_name.0.clone(),
  674. db_dump.read_filename().unwrap().to_str().unwrap().into(),
  675. &StdCommandRunner,
  676. ),)
  677. }
  678. }
  679. impl<P: Clone + AsRef<Path>> ImplementationBuilder<WordpressPlugin<P>> for DefaultBuilder {
  680. type Prerequisites = Dir<PathBuf>;
  681. fn prerequisites(resource: &WordpressPlugin<P>) -> Self::Prerequisites {
  682. Dir(resource.0.as_ref().join("wp-content/plugins"))
  683. }
  684. type Implementation = WordpressPluginSymbol<'static, P, &'static str, StdCommandRunner>;
  685. fn create(
  686. resource: &WordpressPlugin<P>,
  687. (): &<WordpressPlugin<P> as Resource>::Artifact,
  688. _: <Self::Prerequisites as ToArtifact>::Artifact,
  689. ) -> Self::Implementation {
  690. WordpressPluginSymbol::new(resource.0.clone(), resource.1, &StdCommandRunner)
  691. }
  692. }
  693. impl<P: Clone + AsRef<Path>> ImplementationBuilder<WordpressTranslation<P>> for DefaultBuilder {
  694. type Prerequisites = Dir<PathBuf>;
  695. fn prerequisites(resource: &WordpressTranslation<P>) -> Self::Prerequisites {
  696. Dir(resource.0.as_ref().join("wp-content/languages"))
  697. }
  698. type Implementation =
  699. WordpressTranslationSymbol<'static, &'static str, PathBuf, StdCommandRunner>;
  700. fn create(
  701. resource: &WordpressTranslation<P>,
  702. (): &<WordpressTranslation<P> as Resource>::Artifact,
  703. _: <Self::Prerequisites as ToArtifact>::Artifact,
  704. ) -> Self::Implementation {
  705. WordpressTranslationSymbol::new(
  706. resource.0.as_ref().join("wp-content/languages"),
  707. resource.1,
  708. resource.2,
  709. &StdCommandRunner,
  710. )
  711. }
  712. }
  713. impl<D: Clone> ImplementationBuilder<Cron<D>> for DefaultBuilder {
  714. type Prerequisites = UserForDomain<D>;
  715. fn prerequisites(resource: &Cron<D>) -> Self::Prerequisites {
  716. UserForDomain(resource.0.clone())
  717. }
  718. type Implementation = CronSymbol<'static, String, String, StdCommandRunner>;
  719. fn create(
  720. resource: &Cron<D>,
  721. (): &<Cron<D> as Resource>::Artifact,
  722. user_name: <Self::Prerequisites as ToArtifact>::Artifact,
  723. ) -> Self::Implementation {
  724. CronSymbol::new((user_name.0).0, resource.1.clone(), &StdCommandRunner)
  725. }
  726. }