module B9.B9Config.LibVirtLXC ( libVirtLXCConfigToCPDocument , defaultLibVirtLXCConfig , parseLibVirtLXCConfig , LibVirtLXCConfig(..) , networkId , LXCGuestCapability(..) , getEmulatorPath ) where import B9.DiskImages import B9.ExecEnv import Control.Lens ( makeLenses ) import Data.ConfigFile.B9Extras import Control.Monad.IO.Class import System.Environment.Blank as SysIO data LibVirtLXCConfig = LibVirtLXCConfig { useSudo :: Bool , emulator :: Maybe FilePath , virshURI :: FilePath , _networkId :: Maybe String , guestCapabilities :: [LXCGuestCapability] , guestRamSize :: RamSize } deriving (Read, Show, Eq) -- | Available linux capabilities for lxc containers. This maps directly to the -- capabilities defined in 'man 7 capabilities'. data LXCGuestCapability = CAP_MKNOD | CAP_AUDIT_CONTROL | CAP_AUDIT_READ | CAP_AUDIT_WRITE | CAP_BLOCK_SUSPEND | CAP_CHOWN | CAP_DAC_OVERRIDE | CAP_DAC_READ_SEARCH | CAP_FOWNER | CAP_FSETID | CAP_IPC_LOCK | CAP_IPC_OWNER | CAP_KILL | CAP_LEASE | CAP_LINUX_IMMUTABLE | CAP_MAC_ADMIN | CAP_MAC_OVERRIDE | CAP_NET_ADMIN | CAP_NET_BIND_SERVICE | CAP_NET_BROADCAST | CAP_NET_RAW | CAP_SETGID | CAP_SETFCAP | CAP_SETPCAP | CAP_SETUID | CAP_SYS_ADMIN | CAP_SYS_BOOT | CAP_SYS_CHROOT | CAP_SYS_MODULE | CAP_SYS_NICE | CAP_SYS_PACCT | CAP_SYS_PTRACE | CAP_SYS_RAWIO | CAP_SYS_RESOURCE | CAP_SYS_TIME | CAP_SYS_TTY_CONFIG | CAP_SYSLOG | CAP_WAKE_ALARM deriving (Read, Show, Eq) makeLenses ''LibVirtLXCConfig defaultLibVirtLXCConfig :: LibVirtLXCConfig defaultLibVirtLXCConfig = LibVirtLXCConfig True (Just "/usr/lib/libvirt/libvirt_lxc") "lxc:///" Nothing [ CAP_MKNOD , CAP_SYS_ADMIN , CAP_SYS_CHROOT , CAP_SETGID , CAP_SETUID , CAP_NET_BIND_SERVICE , CAP_SETPCAP , CAP_SYS_PTRACE , CAP_SYS_MODULE ] (RamSize 1 GB) cfgFileSection :: String cfgFileSection = "libvirt-lxc" useSudoK :: String useSudoK = "use_sudo" emulatorK :: String emulatorK = "emulator_path" -- NOTE: This variable name is also specified in the NIX build -- in @default.nix@. emulatorEnvVar :: String emulatorEnvVar = "B9_LIBVIRT_LXC" virshURIK :: String virshURIK = "connection" networkIdK :: String networkIdK = "network" guestCapabilitiesK :: String guestCapabilitiesK = "guest_capabilities" guestRamSizeK :: String guestRamSizeK = "guest_ram_size" libVirtLXCConfigToCPDocument :: LibVirtLXCConfig -> CPDocument -> Either CPError CPDocument libVirtLXCConfigToCPDocument c cp = do cp1 <- addSectionCP cp cfgFileSection cp2 <- setShowCP cp1 cfgFileSection useSudoK $ useSudo c cp3 <- setShowCP cp2 cfgFileSection emulatorK $ emulator c cp4 <- setCP cp3 cfgFileSection virshURIK $ virshURI c cp5 <- setShowCP cp4 cfgFileSection networkIdK $ _networkId c cp6 <- setShowCP cp5 cfgFileSection guestCapabilitiesK $ guestCapabilities c setShowCP cp6 cfgFileSection guestRamSizeK $ guestRamSize c parseLibVirtLXCConfig :: CPDocument -> Either CPError LibVirtLXCConfig parseLibVirtLXCConfig cp = let getr :: (CPGet a) => CPOptionSpec -> Either CPError a getr = readCP cp cfgFileSection in LibVirtLXCConfig <$> getr useSudoK <*> getr emulatorK <*> getr virshURIK <*> getr networkIdK <*> getr guestCapabilitiesK <*> getr guestRamSizeK -- | Return the path to @/usr/lib/libvirt/libexec/libvirt_lxc@ -- the 'emulatorK' field from the config file, or set the path -- in the environment variable named like the value in 'emulatorEnvVar' -- dictates. -- -- @since 0.5.66 getEmulatorPath :: MonadIO m => LibVirtLXCConfig -> m FilePath getEmulatorPath cfg = maybe fromEnv return (emulator cfg) where fromEnv = liftIO (SysIO.getEnvDefault emulatorEnvVar "/usr/lib/libexec/libvirt_lxc")