diff options
| author | Joey Hess <joeyh@joeyh.name> | 2017-02-15 15:22:13 -0400 |
|---|---|---|
| committer | Joey Hess <joeyh@joeyh.name> | 2017-02-15 15:22:13 -0400 |
| commit | 4f29d576115d1bcbed60eacb3642523f1b5f480f (patch) | |
| tree | cb4b5ada932bbdea7c4ee97008fc871cd810b543 /src/Propellor/Property/Apt.hs | |
| parent | 6e3192f0d2e063f07d7a5d2b96648e9167cc576a (diff) | |
| parent | b29bab35747e6345a4818e5a77c53d029562e3c3 (diff) | |
Merge branch 'master' into joeyconfig
Diffstat (limited to 'src/Propellor/Property/Apt.hs')
| -rw-r--r-- | src/Propellor/Property/Apt.hs | 122 |
1 files changed, 114 insertions, 8 deletions
diff --git a/src/Propellor/Property/Apt.hs b/src/Propellor/Property/Apt.hs index 196fb345..9a55c367 100644 --- a/src/Propellor/Property/Apt.hs +++ b/src/Propellor/Property/Apt.hs @@ -62,10 +62,7 @@ binandsrc url suite = catMaybes return $ debLine bs url stdSections debCdn :: SourcesGenerator -debCdn = binandsrc "http://httpredir.debian.org/debian" - -kernelOrg :: SourcesGenerator -kernelOrg = binandsrc "http://mirrors.kernel.org/debian" +debCdn = binandsrc "http://deb.debian.org/debian" -- | Only available for Stable and Testing securityUpdates :: SourcesGenerator @@ -77,9 +74,6 @@ securityUpdates suite -- | Makes sources.list have a standard content using the Debian mirror CDN, -- with the Debian suite configured by the os. --- --- Since the CDN is sometimes unreliable, also adds backup lines using --- kernel.org. stdSourcesList :: Property Debian stdSourcesList = withOS "standard sources.list" $ \w o -> case o of (Just (System (Debian _ suite) _)) -> @@ -98,7 +92,56 @@ stdSourcesList' suite more = tightenTargets $ setSourcesList (concatMap (\gen -> gen suite) generators) `describe` ("standard sources.list for " ++ show suite) where - generators = [debCdn, kernelOrg, securityUpdates] ++ more + generators = [debCdn, securityUpdates] ++ more + +type PinPriority = Int + +-- | Adds an apt source for a suite, and pins that suite to a given pin value +-- (see apt_preferences(5)). Revert to drop the source and unpin the suite. +-- +-- If the requested suite is the host's OS suite, the suite is pinned, but no +-- source is added. That apt source should already be available, or you can use +-- a property like 'Apt.stdSourcesList'. +suiteAvailablePinned + :: DebianSuite + -> PinPriority + -> RevertableProperty Debian Debian +suiteAvailablePinned s pin = available <!> unavailable + where + available :: Property Debian + available = tightenTargets $ combineProperties (desc True) $ props + & File.hasContent prefFile (suitePinBlock "*" s pin) + & setSourcesFile + + unavailable :: Property Debian + unavailable = tightenTargets $ combineProperties (desc False) $ props + & File.notPresent sourcesFile + `onChange` update + & File.notPresent prefFile + + setSourcesFile :: Property Debian + setSourcesFile = withOS (desc True) $ \w o -> case o of + (Just (System (Debian _ hostSuite) _)) + | s /= hostSuite -> ensureProperty w $ + File.hasContent sourcesFile sources + `onChange` update + _ -> noChange + + -- Unless we are pinning a backports suite, filter out any backports + -- sources that were added by our generators. The user probably doesn't + -- want those to be pinned to the same value + sources = dropBackports $ concatMap (\gen -> gen s) generators + where + dropBackports + | "-backports" `isSuffixOf` (showSuite s) = id + | otherwise = filter (not . isInfixOf "-backports") + + generators = [debCdn, securityUpdates] + prefFile = "/etc/apt/preferences.d/20" ++ showSuite s ++ ".pref" + sourcesFile = "/etc/apt/sources.list.d/" ++ showSuite s ++ ".list" + + desc True = "Debian " ++ showSuite s ++ " pinned, priority " ++ show pin + desc False = "Debian " ++ showSuite s ++ " not pinned" setSourcesList :: [Line] -> Property DebianLike setSourcesList ls = sourcesList `File.hasContent` ls `onChange` update @@ -196,6 +239,50 @@ buildDepIn dir = cmdPropertyEnv "sh" ["-c", cmd] noninteractiveEnv where cmd = "cd '" ++ dir ++ "' && mk-build-deps debian/control --install --tool 'apt-get -y --no-install-recommends' --remove" +-- | The name of a package, a glob to match the names of packages, or a regexp +-- surrounded by slashes to match the names of packages. See +-- apt_preferences(5), "Regular expressions and glob(7) syntax" +type AptPackagePref = String + +-- | Pins a list of packages, package wildcards and/or regular expressions to a +-- list of suites and corresponding pin priorities (see apt_preferences(5)). +-- Revert to unpin. +-- +-- Each package, package wildcard or regular expression will be pinned to all of +-- the specified suites. +-- +-- Note that this will have no effect unless there is an apt source for each of +-- the suites. One way to add an apt source is 'Apt.suiteAvailablePinned'. +-- +-- For example, to obtain Emacs Lisp addon packages not present in your release +-- of Debian from testing, falling back to sid if they're not available in +-- testing, you could use +-- +-- > & Apt.suiteAvailablePinned Testing (-10) +-- > & Apt.suiteAvailablePinned Unstable (-10) +-- > & ["elpa-*"] `Apt.pinnedTo` [(Testing, 100), (Unstable, 50)] +pinnedTo + :: [AptPackagePref] + -> [(DebianSuite, PinPriority)] + -> RevertableProperty Debian Debian +pinnedTo ps pins = (\p -> pinnedTo' p pins) `applyToList` ps + `describe` unwords (("pinned to " ++ showSuites):ps) + where + showSuites = intercalate "," $ showSuite . fst <$> pins + +pinnedTo' + :: AptPackagePref + -> [(DebianSuite, PinPriority)] + -> RevertableProperty Debian Debian +pinnedTo' p pins = + (tightenTargets $ prefFile `File.hasContent` prefs) + <!> (tightenTargets $ File.notPresent prefFile) + where + prefs = foldr step [] pins + step (suite, pin) ls = ls ++ suitePinBlock p suite pin ++ [""] + prefFile = "/etc/apt/preferences.d/10propellor_" + ++ File.configFileName p <.> "pref" + -- | Package installation may fail becuse the archive has changed. -- Run an update in that case and retry. robustly :: Property DebianLike -> Property DebianLike @@ -349,5 +436,24 @@ hasForeignArch arch = check notAdded (add `before` update) add = cmdProperty "dpkg" ["--add-architecture", arch] `assume` MadeChange +-- | Disable the use of PDiffs for machines with high-bandwidth connections. +noPDiffs :: Property DebianLike +noPDiffs = tightenTargets $ "/etc/apt/apt.conf.d/20pdiffs" `File.hasContent` + [ "Acquire::PDiffs \"false\";" ] + +suitePin :: DebianSuite -> String +suitePin s = prefix s ++ showSuite s + where + prefix (Stable _) = "n=" + prefix _ = "a=" + +suitePinBlock :: AptPackagePref -> DebianSuite -> PinPriority -> [Line] +suitePinBlock p suite pin = + [ "Explanation: This file added by propellor" + , "Package: " ++ p + , "Pin: release " ++ suitePin suite + , "Pin-Priority: " ++ show pin + ] + dpkgStatus :: FilePath dpkgStatus = "/var/lib/dpkg/status" |
