10 cfg = config.services.waagent;
12 # Format for waagent.conf
25 description = "atom (bool, string, int or float) or null";
27 atom = either singleAtom (listOf singleAtom) // {
28 description = singleAtom.description + " or a list of them";
32 either atom (attrsOf atom)
34 description = atom.description + "or an attribute set of them";
40 # Transform non-attribute values
43 # Transform bool to "y" or "n"
45 (if x then "y" else "n")
46 # Concatenate list items with comma
47 else if (isList x) then
48 concatStringsSep "," (map transform x)
52 # Convert to format of waagent.conf
55 if builtins.isAttrs value then
57 (mapAttrsToList (k: v: recurse (path ++ [ k ]) v))
63 name = concatStringsSep "." path;
69 pipe (recurse [ ] attrs) [
70 # Filter out null values and emoty lists
71 (filter (kv: kv.value != null && kv.value != [ ]))
72 # Transform to Key=Value form, then concatenate
73 (map (kv: "${kv.name}=${transform kv.value}"))
74 (concatStringsSep "\n")
77 pkgs.writeText name (convert value);
80 settingsType = types.submodule {
81 freeformType = settingsFormat.type;
86 default = !config.services.cloud-init.enable;
87 defaultText = literalExpression "!config.services.cloud-init.enable";
89 Whether to enable provisioning functionality in the agent.
91 If provisioning is disabled, SSH host and user keys in the image are preserved
92 and configuration in the Azure provisioning API is ignored.
94 Set to `false` if cloud-init is used for provisioning tasks.
107 Which provisioning agent to use.
113 Format = mkEnableOption ''
114 If set to `true`, waagent formats and mounts the resource disk that the platform provides,
115 unless the file system type in `ResourceDisk.FileSystem` is set to `ntfs`.
116 The agent makes a single Linux partition (ID 83) available on the disk.
117 This partition isn't formatted if it can be successfully mounted.
119 This configuration has no effect if resource disk is managed by cloud-init.
122 FileSystem = mkOption {
126 The file system type for the resource disk.
127 If the string is `X`, then `mkfs.X` should be present in the environment.
128 You can add additional filesystem packages using `services.waagent.extraPackages`.
130 This configuration has no effect if resource disk is managed by cloud-init.
134 MountPoint = mkOption {
136 default = "/mnt/resource";
138 This option specifies the path at which the resource disk is mounted.
139 The resource disk is a temporary disk and might be emptied when the VM is deprovisioned.
141 This configuration has no effect if resource disk is managed by cloud-init.
145 MountOptions = mkOption {
146 type = with types; listOf str;
153 This option specifies disk mount options to be passed to the `mount -o` command.
154 For more information, see the `mount(8)` manual page.
158 EnableSwap = mkEnableOption ''
159 If enabled, the agent creates a swap file (`/swapfile`) on the resource disk
160 and adds it to the system swap space.
162 This configuration has no effect if resource disk is managed by cloud-init.
165 SwapSizeMB = mkOption {
169 Specifies the size of the swap file in megabytes.
171 This configuration has no effect if resource disk is managed by cloud-init.
176 Logs.Verbose = lib.mkEnableOption ''
177 If you set this option, log verbosity is boosted.
178 Waagent logs to `/var/log/waagent.log` and uses the system logrotate functionality to rotate logs.
182 EnableRDMA = lib.mkEnableOption ''
183 If enabled, the agent attempts to install and then load an RDMA kernel driver
184 that matches the version of the firmware on the underlying hardware.
187 RootDeviceScsiTimeout = lib.mkOption {
188 type = types.nullOr types.int;
191 Configures the SCSI timeout in seconds on the OS disk and data drives.
192 If set to `null`, the system defaults are used.
198 Host = lib.mkOption {
199 type = types.nullOr types.str;
202 If you set http proxy, waagent will use is proxy to access the Internet.
206 Port = lib.mkOption {
207 type = types.nullOr types.int;
210 If you set http proxy, waagent will use this proxy to access the Internet.
215 AutoUpdate.Enable = lib.mkEnableOption ''
216 Enable or disable autoupdate for goal state processing.
222 options.services.waagent = {
223 enable = lib.mkEnableOption ''
224 Whether to enable the Windows Azure Linux Agent.
227 package = lib.mkPackageOption pkgs "waagent" { };
229 extraPackages = lib.mkOption {
232 Additional packages to add to the waagent {env}`PATH`.
234 example = lib.literalExpression "[ pkgs.powershell ]";
235 type = lib.types.listOf lib.types.package;
238 settings = lib.mkOption {
242 The waagent.conf configuration, see https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/agent-linux for documentation.
247 config = lib.mkIf cfg.enable {
250 assertion = (cfg.settings.HttpProxy.Host != null) -> (cfg.settings.HttpProxy.Port != null);
251 message = "Option services.waagent.settings.HttpProxy.Port must be set if services.waagent.settings.HttpProxy.Host is set.";
255 boot.initrd.kernelModules = [ "ata_piix" ];
256 networking.firewall.allowedUDPPorts = [ 68 ];
258 services.udev.packages = with pkgs; [ waagent ];
260 boot.initrd.services.udev = with pkgs; {
261 # Provide waagent-shipped udev rules in initrd too.
262 packages = [ waagent ];
263 # udev rules shell out to chmod, cut and readlink, which are all
264 # provided by pkgs.coreutils, which is in services.udev.path, but not
265 # boot.initrd.services.udev.binPackages.
266 binPackages = [ coreutils ];
269 networking.dhcpcd.persistent = true;
271 services.logrotate = {
273 settings."/var/log/waagent.log" = {
275 frequency = "monthly";
280 # Write settings to /etc/waagent.conf
281 environment.etc."waagent.conf".source = settingsFormat.generate "waagent.conf" cfg.settings;
283 systemd.targets.provisioned = {
284 description = "Services Requiring Azure VM provisioning to have finished";
287 systemd.services.consume-hypervisor-entropy = {
288 description = "Consume entropy in ACPI table provided by Hyper-V";
299 path = [ pkgs.coreutils ];
301 echo "Fetching entropy..."
302 cat /sys/firmware/acpi/tables/OEM0 > /dev/random
304 serviceConfig.Type = "oneshot";
305 serviceConfig.RemainAfterExit = true;
306 serviceConfig.StandardError = "journal+console";
307 serviceConfig.StandardOutput = "journal+console";
310 systemd.services.waagent = {
311 wantedBy = [ "multi-user.target" ];
313 "network-online.target"
314 ] ++ lib.optionals config.services.cloud-init.enable [ "cloud-init.service" ];
316 "network-online.target"
318 "sshd-keygen.service"
339 # for useradd, usermod
342 util-linux # for (u)mount, fdisk, sfdisk, mkswap
343 # waagent's Microsoft.CPlat.Core.RunCommandLinux needs lsof
346 ++ cfg.extraPackages;
347 description = "Windows Azure Agent Service";
348 unitConfig.ConditionPathExists = "/etc/waagent.conf";
350 ExecStart = "${lib.getExe cfg.package} -daemon";
353 Slice = "azure.slice";
354 CPUAccounting = true;
355 MemoryAccounting = true;
359 # waagent will generate files under /etc/sudoers.d during provisioning
360 security.sudo.extraConfig = ''
361 #includedir /etc/sudoers.d