Merge branch 'host-checkmate' into 'master'
New host: checkmate See merge request private-void/depot!44
This commit is contained in:
commit
cf037e684f
15 changed files with 127 additions and 22 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
services.acme-client = {
|
services.acme-client = {
|
||||||
nodes.client = [ "VEGAS" "prophet" ];
|
nodes.client = [ "checkmate" "VEGAS" "prophet" ];
|
||||||
nixos.client = ./client.nix;
|
nixos.client = ./client.nix;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 NO562A 1bb8hrQQunFIVGRUkg9QrAKof4tAAV8D1KRavicuaFY
|
-> ssh-ed25519 NO562A L8hpKYttTvdcgFE0dutUUaUE8PFJ6vL1pUtf9qyrG3s
|
||||||
y6X5aiD66+jBrfA9u3k3UrWQSEAd9yadLa0j2LgS9GY
|
pWu4g9K6JIIRqstPodUEKrAKtPFJ6zanBK6N64jMw18
|
||||||
-> ssh-ed25519 5/zT0w Ke3Ymtxr2Kvp4piYChcTfBxNnBO4MlYPxVMNqC6z5X4
|
-> ssh-ed25519 5/zT0w m1YXyS/RJEtc79mY39jfierPxzP/Tj11VfJA2VjFtB8
|
||||||
CHzxDO2LIUHNjCr4O3hkA/9MSD6LXD3YUQVhtCKp3So
|
5VeWMX7EQ3d+z4M8Nc2uRbrhr37KbSJsKOSAAIsyVqk
|
||||||
-> ssh-ed25519 d3WGuA qPlzxEKYYe7QYBhsQuO/MI5IikwqjXVZutQL23aq2WQ
|
-> ssh-ed25519 TCgorQ ITq5QOMfdpJNpXv7EH3FXaZvUyfCMbeEfAZwq27YAl4
|
||||||
esQyjMbfaWYmtg9CAcHY/WJnsPZiZPITufIQ5TkGzEc
|
fHVxtu2wwQDylXFFUgmEwIoTGrltKeSqgYvVdIl/UVs
|
||||||
-> ssh-ed25519 6YMlxg YajTOEPRSF/oMzlU4D0DC7DiBL22OxLBNTUN77wMwRY
|
-> ssh-ed25519 d3WGuA 9NGFoevYhPhU6tu88PplKtBrw/wP6ESfhAmRe9nV01s
|
||||||
RNZFOE7KV6UffoFUTcdnfrgz6wptvkvkZfR7H3GKs0g
|
dBqxeoIv1KGANbooK1s0Lr6c7khJN1nnfua6rFyV78E
|
||||||
-> hI!f;r}-grease |@)
|
-> ssh-ed25519 6YMlxg oPkKqmsaV95qpewGlWcoaXqTJt2feAmH6TL3CqzymxI
|
||||||
PVxV1yo85W0ceDE3nuYqdfYoRIQkwyp1VK1WIkxQjBMIs5kIx0Fw+WjdHT6wv/HH
|
NMC1SRCdbGtrd+jsCZTz8Dwaf4TFT/JoV8Twih2iDMw
|
||||||
Xh+qLqlgBfehoy28KZ52gsNRlDHN
|
-> =|z4N-grease
|
||||||
--- +rOxrlTfSf4+mvHe8WZB1+xT0Jo/YxzEbEbIyOpLOS0
|
03zbvyP3U5X8meDamKgLoK8UQe4nFi8e4ycdkPyacFTHk9vp+y4cI2vnEtAz
|
||||||
4´éì ·†É. ß„þÞÄp—ûZ¨¶ïO)üB<C3BC>~¬ac£ˆTv†•Ú{_¥…UÛÜÕÄÖ<C384>Ä8=U¶P¹î0¾a"A¾TV…<56>„Ür1Ôèn¦<6E>NÜé{
7¦À¥HòdþÏîu×çïðÚHgæe{{0d²ëM‹Xy›ÐóÁ™^<5E>4RWoÌm¾çzßç–-)Jö9!7.ÏoуҊ®9ôe+a´&+‰‡]z}κ4R×çš‚)ñÕŠ[<5B>ž4¯ûAÖÀ±Oã3D/¯’X¿Ä@7ýÁTRÀÒµç6Âã€]‹/ ß½$ê_Hàj‰w°ØØK(ý<>ᓦ9<C2A6>npŽ;HõhbÞÚ2€›Ç<1F>Yw;W‘æÄ0<C384>‚I6¿¾
|
--- xEJd9gIQxtWG43mtFiuhZWPb7ajMIYNeA/8MMuFpe2s
|
||||||
|
‰Ìóû uä·u'T€²Ùv<• /_ÞßhïÙZº'ß!þ@ìkL%#Ê—Ö‘²@MFdo
9Ù‡Ò2 ú/´ù—nV[}—kÇ#úÓÛ©NंŽ>{¨Q4Ÿ|‚àv*AôíøR…nÆmi!q¸š<11>©Ü?ÈÚç÷›ò
HÏ7(È9è¤jÜ`^l6ðM-²>¹À„q[œ…_
|
||||||
|
_G‘}3<>è)ÿõ6k‘òq¾ôš’/p„<1B>Ü2bˆæ™¤>wŸú?><3E>|ÙÂΩÂÜÛôkÆ]AnŠžüŠ†Ø뉎^W&Œœ¼c÷CURQLz÷ º» ïó˜=”~‘Fo¹«©öî ÃÞ@(ó¹&Ó‰<C393>a,QÒ°F ª}æP
|
|
@ -9,7 +9,7 @@
|
||||||
};
|
};
|
||||||
services.monitoring = {
|
services.monitoring = {
|
||||||
nodes = {
|
nodes = {
|
||||||
client = [ "VEGAS" "prophet" ];
|
client = [ "checkmate" "VEGAS" "prophet" ];
|
||||||
};
|
};
|
||||||
nixos = {
|
nixos = {
|
||||||
client = ./client.nix;
|
client = ./client.nix;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
nodes.host = [ "VEGAS" "prophet" ];
|
nodes.host = [ "checkmate" "VEGAS" "prophet" ];
|
||||||
nixos.host = [ ./nginx.nix ];
|
nixos.host = [ ./nginx.nix ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ in
|
||||||
vars.patroni = {
|
vars.patroni = {
|
||||||
etcdNodes = lib.genAttrs cfg.nodes.etcd (name: config.links."patroni-etcd-node-peer-${name}");
|
etcdNodes = lib.genAttrs cfg.nodes.etcd (name: config.links."patroni-etcd-node-peer-${name}");
|
||||||
etcdNodesClient = lib.genAttrs cfg.nodes.etcd (name: config.links."patroni-etcd-node-client-${name}");
|
etcdNodesClient = lib.genAttrs cfg.nodes.etcd (name: config.links."patroni-etcd-node-client-${name}");
|
||||||
etcdExtraNodes = [ "fly=http://10.1.1.151:2380" ];
|
|
||||||
passwords = {
|
passwords = {
|
||||||
PATRONI_REPLICATION_PASSWORD = ./passwords/replication.age;
|
PATRONI_REPLICATION_PASSWORD = ./passwords/replication.age;
|
||||||
PATRONI_SUPERUSER_PASSWORD = ./passwords/superuser.age;
|
PATRONI_SUPERUSER_PASSWORD = ./passwords/superuser.age;
|
||||||
|
@ -35,7 +34,7 @@ in
|
||||||
services.patroni = {
|
services.patroni = {
|
||||||
nodes = {
|
nodes = {
|
||||||
worker = [ "VEGAS" "prophet" ];
|
worker = [ "VEGAS" "prophet" ];
|
||||||
etcd = [ "VEGAS" "prophet" ];
|
etcd = [ "checkmate" "VEGAS" "prophet" ];
|
||||||
haproxy = [ "VEGAS" "prophet" ];
|
haproxy = [ "VEGAS" "prophet" ];
|
||||||
};
|
};
|
||||||
nixos = {
|
nixos = {
|
||||||
|
|
|
@ -12,7 +12,7 @@ in
|
||||||
services.etcd = {
|
services.etcd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
dataDir = "/srv/storage/private/etcd";
|
dataDir = "/srv/storage/private/etcd";
|
||||||
initialCluster = (map mkMember cluster.config.services.patroni.nodes.etcd) ++ vars.patroni.etcdExtraNodes;
|
initialCluster = map mkMember cluster.config.services.patroni.nodes.etcd;
|
||||||
listenPeerUrls = lib.singleton vars.patroni.etcdNodes.${vars.hostName}.url;
|
listenPeerUrls = lib.singleton vars.patroni.etcdNodes.${vars.hostName}.url;
|
||||||
listenClientUrls = lib.singleton vars.patroni.etcdNodesClient.${vars.hostName}.url;
|
listenClientUrls = lib.singleton vars.patroni.etcdNodesClient.${vars.hostName}.url;
|
||||||
};
|
};
|
||||||
|
@ -20,6 +20,7 @@ in
|
||||||
# run on any architecture
|
# run on any architecture
|
||||||
environment.ETCD_UNSUPPORTED_ARCH = pkgs.go.GOARCH;
|
environment.ETCD_UNSUPPORTED_ARCH = pkgs.go.GOARCH;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
TimeoutStartSec = "900s";
|
||||||
RestartSec = "5s";
|
RestartSec = "5s";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
services.websites = {
|
services.websites = {
|
||||||
nodes = {
|
nodes = {
|
||||||
host = [ "VEGAS" "prophet" ];
|
host = [ "checkmate" "VEGAS" "prophet" ];
|
||||||
};
|
};
|
||||||
nixos = {
|
nixos = {
|
||||||
host = ./host.nix;
|
host = ./host.nix;
|
||||||
|
|
|
@ -14,12 +14,23 @@ in
|
||||||
{
|
{
|
||||||
vars = {
|
vars = {
|
||||||
mesh = {
|
mesh = {
|
||||||
|
checkmate = config.links.mesh-node-checkmate.extra;
|
||||||
VEGAS = config.links.mesh-node-VEGAS.extra;
|
VEGAS = config.links.mesh-node-VEGAS.extra;
|
||||||
prophet = config.links.mesh-node-prophet.extra;
|
prophet = config.links.mesh-node-prophet.extra;
|
||||||
};
|
};
|
||||||
inherit meshNet;
|
inherit meshNet;
|
||||||
};
|
};
|
||||||
links = {
|
links = {
|
||||||
|
mesh-node-checkmate = {
|
||||||
|
ipv4 = getExtAddr hosts.checkmate;
|
||||||
|
extra = {
|
||||||
|
meshIp = "10.1.1.32";
|
||||||
|
inherit meshNet;
|
||||||
|
pubKey = "fZMB9CDCWyBxPnsugo3Uxm/TIDP3VX54uFoaoC0bP3U=";
|
||||||
|
privKeyFile = ./mesh-keys/checkmate.age;
|
||||||
|
extraRoutes = [];
|
||||||
|
};
|
||||||
|
};
|
||||||
mesh-node-VEGAS = {
|
mesh-node-VEGAS = {
|
||||||
ipv4 = getExtAddr hosts.VEGAS;
|
ipv4 = getExtAddr hosts.VEGAS;
|
||||||
extra = {
|
extra = {
|
||||||
|
@ -43,7 +54,7 @@ in
|
||||||
};
|
};
|
||||||
services.wireguard = {
|
services.wireguard = {
|
||||||
nodes = {
|
nodes = {
|
||||||
mesh = [ "VEGAS" "prophet" ];
|
mesh = [ "checkmate" "VEGAS" "prophet" ];
|
||||||
};
|
};
|
||||||
nixos = {
|
nixos = {
|
||||||
mesh = ./mesh.nix;
|
mesh = ./mesh.nix;
|
||||||
|
|
12
cluster/services/wireguard/mesh-keys/checkmate.age
Normal file
12
cluster/services/wireguard/mesh-keys/checkmate.age
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 NO562A rE85lK37XeM803mXkugmTjfAp3LNqKy2yuGGbY4IOAM
|
||||||
|
nDielwqyuaW72OKiUBgFPWK45aZhh768+MskQ5+vhUs
|
||||||
|
-> ssh-ed25519 5/zT0w QxXHVLpk2qeXjO8c3a0cQ1oKk3fUn9+yIoHAK1hLYgQ
|
||||||
|
d4s/F2ck8Z4AsCQReghxj+M0JjBYKoMpfU+K21AzwFg
|
||||||
|
-> ssh-ed25519 TCgorQ lqg5aPJuj5NPEAgAaw52lwpQ++eWPxO4BITdpLKoZFg
|
||||||
|
KS0kRB2K/+/+U2xfr2VE09XdjVvIflTweU93Vy7Okr8
|
||||||
|
-> ?).-grease =%LA 5cVQvduw
|
||||||
|
gs9TPdbaRJVf50LDiUdlg7Vr4LUfg2Kj2bPAbN2f2z4LKDnSbWHkJ6B3EfOMDxTN
|
||||||
|
KmX8mGCi7QBGOfb1EY3h5cDgteBXiLN4aLh6kpCe0F3/DQ
|
||||||
|
--- vLjmBMfCrvOuF1ww5UcHQAmBUo0LgIuJKcNEDlOCZ3g
|
||||||
|
ß<EFBFBD>&„îd!¾Žqƒ©H<oÄžˆ×“5ç屃бÝ0&Ÿ<>ý⬻¯3~Ù´ð5Œ<35>§Ž÷Ñ¡“Ko)å6³üWÜ°‹
|
27
hosts/checkmate/default.nix
Normal file
27
hosts/checkmate/default.nix
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
tools: {
|
||||||
|
ssh.id = with tools.dns; {
|
||||||
|
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINImnMfEzUBU5qiuu05DMPrddTGypOtr+cL1/yQN2GFn";
|
||||||
|
hostNames = subResolve "checkmate" "node";
|
||||||
|
};
|
||||||
|
|
||||||
|
interfaces = {
|
||||||
|
primary = {
|
||||||
|
addr = "10.0.243.198";
|
||||||
|
addrPublic = "152.67.73.164";
|
||||||
|
link = "ens3";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
hypr = {
|
||||||
|
id = "12D3KooWL84sAtq1QTYwb7gVbhSNX5ZUfVt4kgYKz8pdif1zpGUh";
|
||||||
|
addr = "10.100.3.32";
|
||||||
|
listenPort = 995;
|
||||||
|
};
|
||||||
|
|
||||||
|
enterprise = {
|
||||||
|
subdomain = "node";
|
||||||
|
};
|
||||||
|
|
||||||
|
arch = "x86_64";
|
||||||
|
nixos = import ./system.nix;
|
||||||
|
}
|
12
hosts/checkmate/hardware-configuration.nix
Normal file
12
hosts/checkmate/hardware-configuration.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{ modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||||
|
];
|
||||||
|
fileSystems."/boot" = { device = "/dev/disk/by-partlabel/boot"; fsType = "vfat"; };
|
||||||
|
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
|
||||||
|
boot.initrd.kernelModules = [ "nvme" ];
|
||||||
|
fileSystems."/" = { device = "/dev/disk/by-partlabel/rootfs"; fsType = "xfs"; };
|
||||||
|
swapDevices = [ { device = "/dev/disk/by-partlabel/swap"; } ];
|
||||||
|
}
|
38
hosts/checkmate/system.nix
Normal file
38
hosts/checkmate/system.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{ aspect, inputs, hosts, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
# Hardware
|
||||||
|
./hardware-configuration.nix
|
||||||
|
|
||||||
|
inputs.agenix.nixosModules.age
|
||||||
|
|
||||||
|
aspect.modules.hyprspace
|
||||||
|
aspect.modules.sss
|
||||||
|
]
|
||||||
|
++ aspect.sets.server;
|
||||||
|
|
||||||
|
# Use the systemd-boot EFI boot loader.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
networking.hostName = "checkmate";
|
||||||
|
networking.nameservers = [ hosts.VEGAS.interfaces.vstub.addr ];
|
||||||
|
|
||||||
|
time.timeZone = "Europe/Zurich";
|
||||||
|
|
||||||
|
networking.useDHCP = false;
|
||||||
|
networking.interfaces.ens3.useDHCP = true;
|
||||||
|
|
||||||
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|
||||||
|
services.openssh.enable = true;
|
||||||
|
|
||||||
|
zramSwap.enable = true;
|
||||||
|
zramSwap.algorithm = "zstd";
|
||||||
|
|
||||||
|
system.stateVersion = "21.11";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ in with tools.dns; {
|
||||||
VEGAS = import ./VEGAS tools;
|
VEGAS = import ./VEGAS tools;
|
||||||
prophet = import ./prophet tools;
|
prophet = import ./prophet tools;
|
||||||
soda = import ./soda tools;
|
soda = import ./soda tools;
|
||||||
|
checkmate = import ./checkmate tools;
|
||||||
|
|
||||||
# Non-NixOS machine metadata
|
# Non-NixOS machine metadata
|
||||||
AnimusAlpha = let hostNames = [ "alpha.animus.com" "animus.com" ]; in {
|
AnimusAlpha = let hostNames = [ "alpha.animus.com" "animus.com" ]; in {
|
||||||
|
|
|
@ -7,7 +7,7 @@ in with hosts;
|
||||||
"cluster/services/dns/pdns-admin-oidc-secrets.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"cluster/services/dns/pdns-admin-oidc-secrets.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
"cluster/services/dns/pdns-admin-salt.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"cluster/services/dns/pdns-admin-salt.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
"cluster/services/dns/pdns-admin-secret.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"cluster/services/dns/pdns-admin-secret.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
"cluster/services/dns/pdns-api-key.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
"cluster/services/dns/pdns-api-key.age".publicKeys = max ++ map systemKeys [ checkmate VEGAS prophet ];
|
||||||
"cluster/services/dns/pdns-db-credentials.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
"cluster/services/dns/pdns-db-credentials.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
||||||
"cluster/services/hercules-ci-multi-agent/secrets/hci-cache-config.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
"cluster/services/hercules-ci-multi-agent/secrets/hci-cache-config.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
||||||
"cluster/services/hercules-ci-multi-agent/secrets/hci-cache-credentials-prophet.age".publicKeys = max ++ map systemKeys [ prophet ];
|
"cluster/services/hercules-ci-multi-agent/secrets/hci-cache-credentials-prophet.age".publicKeys = max ++ map systemKeys [ prophet ];
|
||||||
|
@ -24,6 +24,7 @@ in with hosts;
|
||||||
"cluster/services/patroni/passwords/replication.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
"cluster/services/patroni/passwords/replication.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
||||||
"cluster/services/patroni/passwords/rewind.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
"cluster/services/patroni/passwords/rewind.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
||||||
"cluster/services/patroni/passwords/superuser.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
"cluster/services/patroni/passwords/superuser.age".publicKeys = max ++ map systemKeys [ VEGAS prophet ];
|
||||||
|
"cluster/services/wireguard/mesh-keys/checkmate.age".publicKeys = max ++ map systemKeys [ checkmate ];
|
||||||
"cluster/services/wireguard/mesh-keys/VEGAS.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"cluster/services/wireguard/mesh-keys/VEGAS.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
"cluster/services/wireguard/mesh-keys/prophet.age".publicKeys = max ++ map systemKeys [ prophet ];
|
"cluster/services/wireguard/mesh-keys/prophet.age".publicKeys = max ++ map systemKeys [ prophet ];
|
||||||
"secrets/coturn-static-auth.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"secrets/coturn-static-auth.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
|
@ -40,6 +41,7 @@ in with hosts;
|
||||||
"secrets/hydra-builder-key.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"secrets/hydra-builder-key.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
"secrets/hydra-db-credentials.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"secrets/hydra-db-credentials.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
"secrets/hydra-s3.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"secrets/hydra-s3.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
|
"secrets/hyprspace-key-checkmate.age".publicKeys = max ++ map systemKeys [ checkmate ];
|
||||||
"secrets/hyprspace-key-VEGAS.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"secrets/hyprspace-key-VEGAS.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
"secrets/hyprspace-key-prophet.age".publicKeys = max ++ map systemKeys [ prophet ];
|
"secrets/hyprspace-key-prophet.age".publicKeys = max ++ map systemKeys [ prophet ];
|
||||||
"secrets/keycloak-dbpass.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
"secrets/keycloak-dbpass.age".publicKeys = max ++ map systemKeys [ VEGAS ];
|
||||||
|
|
BIN
secrets/hyprspace-key-checkmate.age
Normal file
BIN
secrets/hyprspace-key-checkmate.age
Normal file
Binary file not shown.
Loading…
Reference in a new issue