From 49255357459cd2f5661e5f6832ac1f611bb37967 Mon Sep 17 00:00:00 2001 From: Evan Cofsky Date: Tue, 29 Mar 2016 13:05:35 -0500 Subject: Adding support for software-properties-common to OS properties branch. The config-simple file now shows: 1. Adding PPAs 2. Adding apt keys from a remote keyserver 3. Adding apt sources 4. Installing signed packages from a new repository. --- src/Propellor/Property/Apt/PPA.hs | 121 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/Propellor/Property/Apt/PPA.hs (limited to 'src/Propellor/Property/Apt/PPA.hs') diff --git a/src/Propellor/Property/Apt/PPA.hs b/src/Propellor/Property/Apt/PPA.hs new file mode 100644 index 00000000..9831ff30 --- /dev/null +++ b/src/Propellor/Property/Apt/PPA.hs @@ -0,0 +1,121 @@ +-- | This module provides properties software-properties-common. +module Propellor.Property.Apt.PPA where + +import Data.List +import Control.Applicative +import Prelude +import Data.String.Utils +import Data.String (IsString(..)) +import Propellor.Base +import qualified Propellor.Property.Apt as Apt + +-- | Ensure it's installed in case it's not. It's part of Buntish's defaults so +-- one might assume... +installed :: Property DebianLike +installed = Apt.installed ["software-properties-common"] + +-- | Personal Package Archives are people's individual package contributions to +-- Ubuntu. There's a well-known format for adding them, and this type represents +-- that. It's also an instance of 'Show' and 'IsString' so it can work with +-- 'OverloadedStrings'. More on PPAs can be found at +-- +data PPA = PPA { + -- | The Launchpad account hosting this archive. + ppaAccount :: String, + -- | The + ppaArchive :: String +} deriving (Eq, Ord) + +instance Show PPA where + show p = concat ["ppa:", ppaAccount p, "/", ppaArchive p] + +instance IsString PPA where + -- | Parse strings like "ppa:zfs-native/stable" into a PPA. + fromString s = + let + [_, ppa] = split "ppa:" s + [acct, arch] = split "/" ppa + in + PPA acct arch + +-- | Adds a PPA to the local system repositories. +addPpa :: PPA -> Property DebianLike +addPpa p = + cmdPropertyEnv "apt-add-repository" ["--yes", show p] Apt.noninteractiveEnv + `assume` MadeChange + `describe` ("Added PPA " ++ (show p)) + `requires` installed + +-- | A repository key ID to be downloaded with apt-key. +data AptKeyId = AptKeyId { + akiName :: String, + akiId :: String, + akiServer :: String + } deriving (Eq, Ord) + +instance Show AptKeyId where + show k = unwords ["Apt Key", akiName k, akiId k, "from", akiServer k] + +-- | Adds an 'AptKeyId' from the specified GPG server. +addKeyId :: AptKeyId -> Property DebianLike +addKeyId keyId = + check keyTrusted akcmd + `describe` (unwords ["Add third-party Apt key", show keyId]) + where + akcmd = + tightenTargets $ cmdProperty "apt-key" ["adv", "--keyserver", akiServer keyId, "--recv-keys", akiId keyId] + keyTrusted = + let + pks ls = concatMap (drop 1 . split "/") + $ concatMap (take 1 . drop 1 . words) + $ filter (\l -> "pub" `isPrefixOf` l) + $ lines ls + nkid = take 8 (akiId keyId) + in + (isInfixOf [nkid] . pks) <$> readProcess "apt-key" ["list"] + +-- | An Apt source line that apt-add-repository will just add to +-- sources.list. It's also an instance of both 'Show' and 'IsString' to make +-- using 'OverloadedStrings' in the configuration file easier. +-- +-- | FIXME there's apparently an optional "options" fragment that I've +-- definitely not parsed here. +data AptSource = AptSource { + -- | The URL hosting the repository + asURL :: Apt.Url, + + -- | The operating system suite + asSuite :: String, + + -- | The list of components to install from this repository. + asComponents :: [String] + } deriving (Eq, Ord) + +instance Show AptSource where + show asrc = unwords ["deb", asURL asrc, asSuite asrc, unwords . asComponents $ asrc] + +instance IsString AptSource where + fromString s = + let + url:suite:comps = drop 1 . words $ s + in + AptSource url suite comps + +-- | A repository for apt-add-source, either a PPA or a regular repository line. +data AptRepository = AptRepositoryPPA PPA | AptRepositorySource AptSource + +-- | Adds an 'AptRepository' using apt-add-source. +addRepository :: AptRepository -> Property DebianLike +addRepository (AptRepositoryPPA p) = addPpa p +addRepository (AptRepositorySource src) = + check repoExists addSrc + `describe` unwords ["Adding APT repository", show src] + `requires` installed + where + allSourceLines = + readProcess "/bin/sh" ["-c", "cat /etc/apt/sources.list /etc/apt/sources.list.d/*"] + activeSources = map (\s -> fromString s :: AptSource ) + . filter (not . isPrefixOf "#") + . filter (/= "") . lines <$> allSourceLines + repoExists = isInfixOf [src] <$> activeSources + addSrc = cmdProperty "apt-add-source" [show src] -- cgit v1.2.3 From 73e61cdfadb10dcdbc2a8117ef82c413a67aeef0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 30 Mar 2016 16:31:46 -0400 Subject: improve comments --- src/Propellor/Property/Apt/PPA.hs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/Propellor/Property/Apt/PPA.hs') diff --git a/src/Propellor/Property/Apt/PPA.hs b/src/Propellor/Property/Apt/PPA.hs index 9831ff30..b708fae4 100644 --- a/src/Propellor/Property/Apt/PPA.hs +++ b/src/Propellor/Property/Apt/PPA.hs @@ -1,4 +1,6 @@ --- | This module provides properties software-properties-common. +-- | Maintainer: 2016 Evan Cofsky +-- +-- Personal Package Archives module Propellor.Property.Apt.PPA where import Data.List @@ -9,20 +11,19 @@ import Data.String (IsString(..)) import Propellor.Base import qualified Propellor.Property.Apt as Apt --- | Ensure it's installed in case it's not. It's part of Buntish's defaults so --- one might assume... +-- | Ensure software-properties-common is installed. installed :: Property DebianLike installed = Apt.installed ["software-properties-common"] --- | Personal Package Archives are people's individual package contributions to --- Ubuntu. There's a well-known format for adding them, and this type represents --- that. It's also an instance of 'Show' and 'IsString' so it can work with --- 'OverloadedStrings'. More on PPAs can be found at --- +-- | Personal Package Archives are people's individual package +-- contributions to the Buntish distro. There's a well-known format for +-- representing them, and this type represents that. It's also an instance +-- of 'Show' and 'IsString' so it can work with 'OverloadedStrings'. +-- More on PPAs can be found at data PPA = PPA { -- | The Launchpad account hosting this archive. ppaAccount :: String, - -- | The + -- | The name of the archive. ppaArchive :: String } deriving (Eq, Ord) -- cgit v1.2.3 From af53c3443bec6a47b88933f388cca253a05ed432 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 30 Mar 2016 16:33:54 -0400 Subject: layout and indents --- src/Propellor/Property/Apt/PPA.hs | 119 ++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 63 deletions(-) (limited to 'src/Propellor/Property/Apt/PPA.hs') diff --git a/src/Propellor/Property/Apt/PPA.hs b/src/Propellor/Property/Apt/PPA.hs index b708fae4..49fa9fa7 100644 --- a/src/Propellor/Property/Apt/PPA.hs +++ b/src/Propellor/Property/Apt/PPA.hs @@ -20,60 +20,58 @@ installed = Apt.installed ["software-properties-common"] -- representing them, and this type represents that. It's also an instance -- of 'Show' and 'IsString' so it can work with 'OverloadedStrings'. -- More on PPAs can be found at -data PPA = PPA { - -- | The Launchpad account hosting this archive. - ppaAccount :: String, - -- | The name of the archive. - ppaArchive :: String -} deriving (Eq, Ord) +data PPA = PPA + { ppaAccount :: String -- ^ The Launchpad account hosting this archive. + , ppaArchive :: String -- ^ The name of the archive. + } deriving (Eq, Ord) instance Show PPA where - show p = concat ["ppa:", ppaAccount p, "/", ppaArchive p] + show p = concat ["ppa:", ppaAccount p, "/", ppaArchive p] instance IsString PPA where - -- | Parse strings like "ppa:zfs-native/stable" into a PPA. - fromString s = - let - [_, ppa] = split "ppa:" s - [acct, arch] = split "/" ppa - in - PPA acct arch + -- | Parse strings like "ppa:zfs-native/stable" into a PPA. + fromString s = + let + [_, ppa] = split "ppa:" s + [acct, arch] = split "/" ppa + in + PPA acct arch -- | Adds a PPA to the local system repositories. addPpa :: PPA -> Property DebianLike addPpa p = - cmdPropertyEnv "apt-add-repository" ["--yes", show p] Apt.noninteractiveEnv - `assume` MadeChange - `describe` ("Added PPA " ++ (show p)) - `requires` installed + cmdPropertyEnv "apt-add-repository" ["--yes", show p] Apt.noninteractiveEnv + `assume` MadeChange + `describe` ("Added PPA " ++ (show p)) + `requires` installed -- | A repository key ID to be downloaded with apt-key. -data AptKeyId = AptKeyId { - akiName :: String, - akiId :: String, - akiServer :: String - } deriving (Eq, Ord) +data AptKeyId = AptKeyId + { akiName :: String + , akiId :: String + , akiServer :: String + } deriving (Eq, Ord) instance Show AptKeyId where - show k = unwords ["Apt Key", akiName k, akiId k, "from", akiServer k] + show k = unwords ["Apt Key", akiName k, akiId k, "from", akiServer k] -- | Adds an 'AptKeyId' from the specified GPG server. addKeyId :: AptKeyId -> Property DebianLike addKeyId keyId = - check keyTrusted akcmd - `describe` (unwords ["Add third-party Apt key", show keyId]) + check keyTrusted akcmd + `describe` (unwords ["Add third-party Apt key", show keyId]) where - akcmd = - tightenTargets $ cmdProperty "apt-key" ["adv", "--keyserver", akiServer keyId, "--recv-keys", akiId keyId] - keyTrusted = - let - pks ls = concatMap (drop 1 . split "/") - $ concatMap (take 1 . drop 1 . words) - $ filter (\l -> "pub" `isPrefixOf` l) - $ lines ls - nkid = take 8 (akiId keyId) - in - (isInfixOf [nkid] . pks) <$> readProcess "apt-key" ["list"] + akcmd = + tightenTargets $ cmdProperty "apt-key" ["adv", "--keyserver", akiServer keyId, "--recv-keys", akiId keyId] + keyTrusted = + let + pks ls = concatMap (drop 1 . split "/") + $ concatMap (take 1 . drop 1 . words) + $ filter (\l -> "pub" `isPrefixOf` l) + $ lines ls + nkid = take 8 (akiId keyId) + in + (isInfixOf [nkid] . pks) <$> readProcess "apt-key" ["list"] -- | An Apt source line that apt-add-repository will just add to -- sources.list. It's also an instance of both 'Show' and 'IsString' to make @@ -81,26 +79,21 @@ addKeyId keyId = -- -- | FIXME there's apparently an optional "options" fragment that I've -- definitely not parsed here. -data AptSource = AptSource { - -- | The URL hosting the repository - asURL :: Apt.Url, - - -- | The operating system suite - asSuite :: String, - - -- | The list of components to install from this repository. - asComponents :: [String] - } deriving (Eq, Ord) +data AptSource = AptSource + { asURL :: Apt.Url -- ^ The URL hosting the repository + , asSuite :: String -- ^ The operating system suite + , asComponents :: [String] -- ^ The list of components to install from this repository. + } deriving (Eq, Ord) instance Show AptSource where - show asrc = unwords ["deb", asURL asrc, asSuite asrc, unwords . asComponents $ asrc] + show asrc = unwords ["deb", asURL asrc, asSuite asrc, unwords . asComponents $ asrc] instance IsString AptSource where - fromString s = - let - url:suite:comps = drop 1 . words $ s - in - AptSource url suite comps + fromString s = + let + url:suite:comps = drop 1 . words $ s + in + AptSource url suite comps -- | A repository for apt-add-source, either a PPA or a regular repository line. data AptRepository = AptRepositoryPPA PPA | AptRepositorySource AptSource @@ -109,14 +102,14 @@ data AptRepository = AptRepositoryPPA PPA | AptRepositorySource AptSource addRepository :: AptRepository -> Property DebianLike addRepository (AptRepositoryPPA p) = addPpa p addRepository (AptRepositorySource src) = - check repoExists addSrc - `describe` unwords ["Adding APT repository", show src] - `requires` installed + check repoExists addSrc + `describe` unwords ["Adding APT repository", show src] + `requires` installed where - allSourceLines = - readProcess "/bin/sh" ["-c", "cat /etc/apt/sources.list /etc/apt/sources.list.d/*"] - activeSources = map (\s -> fromString s :: AptSource ) - . filter (not . isPrefixOf "#") - . filter (/= "") . lines <$> allSourceLines - repoExists = isInfixOf [src] <$> activeSources - addSrc = cmdProperty "apt-add-source" [show src] + allSourceLines = + readProcess "/bin/sh" ["-c", "cat /etc/apt/sources.list /etc/apt/sources.list.d/*"] + activeSources = map (\s -> fromString s :: AptSource ) + . filter (not . isPrefixOf "#") + . filter (/= "") . lines <$> allSourceLines + repoExists = isInfixOf [src] <$> activeSources + addSrc = cmdProperty "apt-add-source" [show src] -- cgit v1.2.3