1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.virtualisation.azure.agent;
8
9 waagent = with pkgs; stdenv.mkDerivation rec {
10 name = "waagent-2.0";
11 src = pkgs.fetchFromGitHub {
12 owner = "Azure";
13 repo = "WALinuxAgent";
14 rev = "1b3a8407a95344d9d12a2a377f64140975f1e8e4";
15 sha256 = "10byzvmpgrmr4d5mdn2kq04aapqb3sgr1admk13wjmy5cd6bwd2x";
16 };
17 buildInputs = [ makeWrapper python pythonPackages.wrapPython ];
18 runtimeDeps = [ findutils gnugrep gawk coreutils openssl openssh
19 nettools # for hostname
20 procps # for pidof
21 shadow # for useradd, usermod
22 utillinux # for (u)mount, fdisk, sfdisk, mkswap
23 parted
24 ];
25 pythonPath = [ pythonPackages.pyasn1 ];
26
27 configurePhase = false;
28 buildPhase = false;
29
30 installPhase = ''
31 substituteInPlace config/99-azure-product-uuid.rules \
32 --replace /bin/chmod "${coreutils}/bin/chmod"
33 mkdir -p $out/lib/udev/rules.d
34 cp config/*.rules $out/lib/udev/rules.d
35
36 mkdir -p $out/bin
37 cp waagent $out/bin/
38 chmod +x $out/bin/waagent
39
40 wrapProgram "$out/bin/waagent" \
41 --prefix PYTHONPATH : $PYTHONPATH \
42 --prefix PATH : "${makeSearchPath "bin" runtimeDeps}"
43 '';
44 };
45
46 provisionedHook = pkgs.writeScript "provisioned-hook" ''
47 #!${pkgs.stdenv.shell}
48 ${config.systemd.package}/bin/systemctl start provisioned.target
49 '';
50
51in
52
53{
54
55 ###### interface
56
57 options.virtualisation.azure.agent.enable = mkOption {
58 default = false;
59 description = "Whether to enable the Windows Azure Linux Agent.";
60 };
61
62 ###### implementation
63
64 config = mkIf cfg.enable {
65 assertions = [ {
66 assertion = pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64;
67 message = "Azure not currently supported on ${pkgs.stdenv.system}";
68 } {
69 assertion = config.networking.networkmanager.enable == false;
70 message = "Windows Azure Linux Agent is not compatible with NetworkManager";
71 } ];
72
73 boot.initrd.kernelModules = [ "ata_piix" ];
74 networking.firewall.allowedUDPPorts = [ 68 ];
75
76
77 environment.etc."waagent.conf".text = ''
78 #
79 # Windows Azure Linux Agent Configuration
80 #
81
82 Role.StateConsumer=${provisionedHook}
83
84 # Enable instance creation
85 Provisioning.Enabled=y
86
87 # Password authentication for root account will be unavailable.
88 Provisioning.DeleteRootPassword=n
89
90 # Generate fresh host key pair.
91 Provisioning.RegenerateSshHostKeyPair=y
92
93 # Supported values are "rsa", "dsa" and "ecdsa".
94 Provisioning.SshHostKeyPairType=ed25519
95
96 # Monitor host name changes and publish changes via DHCP requests.
97 Provisioning.MonitorHostName=y
98
99 # Decode CustomData from Base64.
100 Provisioning.DecodeCustomData=n
101
102 # Execute CustomData after provisioning.
103 Provisioning.ExecuteCustomData=n
104
105 # Format if unformatted. If 'n', resource disk will not be mounted.
106 ResourceDisk.Format=y
107
108 # File system on the resource disk
109 # Typically ext3 or ext4. FreeBSD images should use 'ufs2' here.
110 ResourceDisk.Filesystem=ext4
111
112 # Mount point for the resource disk
113 ResourceDisk.MountPoint=/mnt/resource
114
115 # Respond to load balancer probes if requested by Windows Azure.
116 LBProbeResponder=y
117
118 # Enable logging to serial console (y|n)
119 # When stdout is not enough...
120 # 'y' if not set
121 Logs.Console=y
122
123 # Enable verbose logging (y|n)
124 Logs.Verbose=n
125
126 # Root device timeout in seconds.
127 OS.RootDeviceScsiTimeout=300
128 '';
129
130 services.udev.packages = [ waagent ];
131
132 networking.dhcpcd.persistent = true;
133
134 services.logrotate = {
135 enable = true;
136 config = ''
137 /var/log/waagent.log {
138 compress
139 monthly
140 rotate 6
141 notifempty
142 missingok
143 }
144 '';
145 };
146
147 systemd.targets.provisioned = {
148 description = "Services Requiring Azure VM provisioning to have finished";
149 wantedBy = [ "sshd.service" ];
150 before = [ "sshd.service" ];
151 };
152
153
154 systemd.services.waagent = {
155 wantedBy = [ "sshd.service" ];
156 before = [ "sshd.service" ];
157 after = [ "ip-up.target" ];
158 wants = [ "ip-up.target" ];
159
160 path = [ pkgs.e2fsprogs ];
161 description = "Windows Azure Agent Service";
162 unitConfig.ConditionPathExists = "/etc/waagent.conf";
163 serviceConfig = {
164 ExecStart = "${waagent}/bin/waagent -daemon";
165 Type = "simple";
166 };
167 };
168
169 };
170
171}