@@ -781,6 +781,16 @@ export interface InitServiceOptions {
781
781
* @default - No files trigger restart
782
782
*/
783
783
readonly serviceRestartHandle ?: InitServiceRestartHandle ;
784
+
785
+ /**
786
+ * What service manager to use
787
+ *
788
+ * This needs to match the actual service manager on your Operating System.
789
+ * For example, Amazon Linux 1 uses SysVinit, but Amazon Linux 2 uses Systemd.
790
+ *
791
+ * @default ServiceManager.SYSVINIT for Linux images, ServiceManager.WINDOWS for Windows images
792
+ */
793
+ readonly serviceManager ?: ServiceManager ;
784
794
}
785
795
786
796
/**
@@ -806,6 +816,39 @@ export class InitService extends InitElement {
806
816
return new InitService ( serviceName , { enabled : false , ensureRunning : false } ) ;
807
817
}
808
818
819
+ /**
820
+ * Install a systemd-compatible config file for the given service
821
+ *
822
+ * This is a helper function to create a simple systemd configuration
823
+ * file that will allow running a service on the machine using `InitService.enable()`.
824
+ *
825
+ * Systemd allows many configuration options; this function does not pretend
826
+ * to expose all of them. If you need advanced configuration options, you
827
+ * can use `InitFile` to create exactly the configuration file you need
828
+ * at `/etc/systemd/system/${serviceName}.service`.
829
+ */
830
+ public static systemdConfigFile ( serviceName : string , options : SystemdConfigFileOptions ) : InitFile {
831
+ if ( ! options . command . startsWith ( '/' ) ) {
832
+ throw new Error ( `SystemD executables must use an absolute path, got '${ options . command } '` ) ;
833
+ }
834
+
835
+ const lines = [
836
+ '[Unit]' ,
837
+ ...( options . description ? [ `Description=${ options . description } ` ] : [ ] ) ,
838
+ ...( options . afterNetwork ?? true ? [ 'After=network.target' ] : [ ] ) ,
839
+ '[Service]' ,
840
+ `ExecStart=${ options . command } ` ,
841
+ ...( options . cwd ? [ `WorkingDirectory=${ options . cwd } ` ] : [ ] ) ,
842
+ ...( options . user ? [ `User=${ options . user } ` ] : [ ] ) ,
843
+ ...( options . group ? [ `Group=${ options . user } ` ] : [ ] ) ,
844
+ ...( options . keepRunning ?? true ? [ 'Restart=always' ] : [ ] ) ,
845
+ '[Install]' ,
846
+ 'WantedBy=multi-user.target' ,
847
+ ] ;
848
+
849
+ return InitFile . fromString ( `/etc/systemd/system/${ serviceName } .service` , lines . join ( '\n' ) ) ;
850
+ }
851
+
809
852
public readonly elementType = InitElementType . SERVICE . toString ( ) ;
810
853
811
854
private constructor ( private readonly serviceName : string , private readonly serviceOptions : InitServiceOptions ) {
@@ -814,11 +857,12 @@ export class InitService extends InitElement {
814
857
815
858
/** @internal */
816
859
public _bind ( options : InitBindOptions ) : InitElementConfig {
817
- const serviceManager = options . platform === InitPlatform . LINUX ? 'sysvinit' : 'windows' ;
860
+ const serviceManager = this . serviceOptions . serviceManager
861
+ ?? ( options . platform === InitPlatform . LINUX ? ServiceManager . SYSVINIT : ServiceManager . WINDOWS ) ;
818
862
819
863
return {
820
864
config : {
821
- [ serviceManager ] : {
865
+ [ serviceManagerToString ( serviceManager ) ] : {
822
866
[ this . serviceName ] : {
823
867
enabled : this . serviceOptions . enabled ,
824
868
ensureRunning : this . serviceOptions . ensureRunning ,
@@ -970,3 +1014,93 @@ function standardS3Auth(role: iam.IRole, bucketName: string) {
970
1014
} ,
971
1015
} ;
972
1016
}
1017
+
1018
+ /**
1019
+ * The service manager that will be used by InitServices
1020
+ *
1021
+ * The value needs to match the service manager used by your operating
1022
+ * system.
1023
+ */
1024
+ export enum ServiceManager {
1025
+ /**
1026
+ * Use SysVinit
1027
+ *
1028
+ * This is the default for Linux systems.
1029
+ */
1030
+ SYSVINIT ,
1031
+
1032
+ /**
1033
+ * Use Windows
1034
+ *
1035
+ * This is the default for Windows systems.
1036
+ */
1037
+ WINDOWS ,
1038
+
1039
+ /**
1040
+ * Use systemd
1041
+ */
1042
+ SYSTEMD ,
1043
+ }
1044
+
1045
+ function serviceManagerToString ( x : ServiceManager ) : string {
1046
+ switch ( x ) {
1047
+ case ServiceManager . SYSTEMD : return 'systemd' ;
1048
+ case ServiceManager . SYSVINIT : return 'sysvinit' ;
1049
+ case ServiceManager . WINDOWS : return 'windows' ;
1050
+ }
1051
+ }
1052
+
1053
+ /**
1054
+ * Options for creating a SystemD configuration file
1055
+ */
1056
+ export interface SystemdConfigFileOptions {
1057
+ /**
1058
+ * The command to run to start this service
1059
+ */
1060
+ readonly command : string ;
1061
+
1062
+ /**
1063
+ * The working directory for the command
1064
+ *
1065
+ * @default Root directory or home directory of specified user
1066
+ */
1067
+ readonly cwd ?: string ;
1068
+
1069
+ /**
1070
+ * A description of this service
1071
+ *
1072
+ * @default - No description
1073
+ */
1074
+ readonly description ?: string ;
1075
+
1076
+ /**
1077
+ * The user to execute the process under
1078
+ *
1079
+ * @default root
1080
+ */
1081
+ readonly user ?: string ;
1082
+
1083
+ /**
1084
+ * The group to execute the process under
1085
+ *
1086
+ * @default root
1087
+ */
1088
+ readonly group ?: string ;
1089
+
1090
+ /**
1091
+ * Keep the process running all the time
1092
+ *
1093
+ * Restarts the process when it exits for any reason other
1094
+ * than the machine shutting down.
1095
+ *
1096
+ * @default true
1097
+ */
1098
+ readonly keepRunning ?: boolean ;
1099
+
1100
+ /**
1101
+ * Start the service after the networking part of the OS comes up
1102
+ *
1103
+ * @default true
1104
+ */
1105
+ readonly afterNetwork ?: boolean ;
1106
+ }
0 commit comments