{-# LANGUAGE OverloadedStrings #-} {-| This contains a 'YamlObject' for Canonicals @cloud-init@. For some reason, cloud-config yaml documents __MUST__ contain @#cloud-config@ in the first line. This is documented in the . Otherwise, this is just a wrapper around 'YamlObject'. @Since 0.5.62 -} module B9.Artifact.Content.CloudConfigYaml ( CloudConfigYaml(..) , cloudConfigFileHeader ) where import B9.Artifact.Content.AST import B9.Artifact.Content.YamlObject import B9.Text import Control.Parallel.Strategies ( NFData ) import Data.Data ( Data , Typeable ) import Data.Text as Text import Data.Hashable ( Hashable ) import GHC.Generics ( Generic ) import Test.QuickCheck ( Arbitrary ) -- | Cloud-init @meta-data@ configuration Yaml. -- -- @cloud-config@ yaml documents contain: -- @#cloud-config@ as first line. -- -- @Since 0.5.62 newtype CloudConfigYaml = MkCloudConfigYaml { fromCloudConfigYaml :: YamlObject } deriving (Hashable, NFData, Eq, Data, Typeable, Generic, Arbitrary, Read, Show, Semigroup) -- | The header line, which must be the first line in the -- text file containing the cloud-config Yaml document. -- -- @Since 0.5.62 cloudConfigFileHeader :: Text cloudConfigFileHeader = "#cloud-config\n" instance FromAST CloudConfigYaml where fromAST ast = MkCloudConfigYaml <$> fromAST (fromCloudConfigYaml <$> ast) instance Textual CloudConfigYaml where parseFromText txt = do -- skip the optional header line let header = Text.take (Text.length cloudConfigFileHeader) txt txt' = if header == cloudConfigFileHeader then Text.drop (Text.length cloudConfigFileHeader) txt else txt y <- parseFromText txt' return (MkCloudConfigYaml y) renderToText (MkCloudConfigYaml y) = do txt <- renderToText y return (Text.unlines [cloudConfigFileHeader, txt])