Compare commits

...

20 Commits

Author SHA1 Message Date
Rui Sousa 869a68ee91 Remove dependencies of BlueWest.Ef.Methods 2023-11-04 15:35:19 +00:00
code liturgy 70dc2afd1f Bump more methods 2022-12-09 00:27:00 +00:00
code liturgy 78d8c8d0bd Add methods for the Apache Manager 2022-12-06 14:33:12 +00:00
code liturgy ce13a75aaa Bump Sharp.Augeas 2022-12-04 23:07:41 +00:00
code liturgy a8c22a0e94 Add methods for site and environments 2022-12-02 02:31:11 +00:00
code liturgy fc33b23559 Use augeas.sharp reference instead of nuget temporarely 2022-12-02 00:55:44 +00:00
code liturgy b12dd1c9b4 bump deps 2022-12-02 00:31:25 +00:00
code liturgy 311ebf95c9 bump frontend commit 2022-11-30 15:53:25 +00:00
code liturgy fad41d9cd7 Use migrations 2022-11-30 15:52:55 +00:00
code liturgy f57ad77aa8 Bump deps 2022-11-25 22:37:45 +00:00
code liturgy cab448857f Refactor 2022-11-25 22:36:15 +00:00
code liturgy 76732a0d63 Add Swagger frontend 2022-11-25 22:36:06 +00:00
code liturgy 712478814e Change style 2022-11-22 22:39:28 +00:00
code liturgy f2781b1dfc Updates 2022-11-22 15:05:35 +00:00
code liturgy 9e723df36c Import envs page component 2022-11-19 01:44:37 +00:00
code liturgy a8353a0dcb Bump deps 2022-11-18 20:10:12 +00:00
code liturgy 683861314c Bump deps 2022-11-18 20:08:55 +00:00
code liturgy 8e1d26d816 Bump mapto 2022-11-18 19:53:27 +00:00
code liturgy 67ed2c5583 Building 2022-11-18 18:58:39 +00:00
code liturgy 4ac5565174 Update modules 2022-11-18 18:35:35 +00:00
683 changed files with 76229 additions and 12332 deletions

8
.gitmodules vendored
View File

@ -1,15 +1,9 @@
[submodule "include/BlueWest.MapTo"]
path = include/BlueWest.MapTo
url = git@git.codeliturgy.com:P0/MapTo.git
[submodule "include/Math-Expression-Evaluator"]
path = include/Math-Expression-Evaluator
url = git@git.codeliturgy.com:P0/Math-Expression-Evaluator.git
[submodule "CodeLiturgy.Dashboard.Frontend"]
path = CodeLiturgy.Dashboard.Frontend
url = git@git.codeliturgy.com:P0/CodeLiturgy.Dashboard.Frontend.git
[submodule "include/BlueWest.EfMethods"]
path = include/BlueWest.EfMethods
url = git@git.codeliturgy.com:P0/BlueWest.EfGenerator.git
[submodule "include/Westwind.Scripting"]
path = include/Westwind.Scripting
url = https://github.com/RickStrahl/Westwind.Scripting.git
@ -21,4 +15,4 @@
url = git@git.codeliturgy.com:P0/CodeLiturgy.Dashboard.Frontend.git
[submodule "include/CodeLiturgy.RootUtils"]
path = include/CodeLiturgy.RootUtils
url = git@git.codeliturgy.com:P0/CodeLiturgy.RootUtils.git
url = git@git.codeliturgy.com:P0/CodeLiturgy.RootUtils.git

View File

@ -1,7 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="BlueWest-NoDocker" type="CompoundRunConfigurationType">
<toRun name="DockerComposeDbOnly" type="ShConfigurationType" />
<toRun name="BlueWest.Api: BlueWest.WebApi" type="LaunchSettings" />
<toRun name="CodeLiturgy.Views: BlueWest.WebApi" type="LaunchSettings" />
<method v="2" />
</configuration>
</component>

35
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/CodeLiturgy.Views/bin/Debug/net6.0/CodeLiturgy.Views.dll",
"args": [],
"cwd": "${workspaceFolder}/CodeLiturgy.Views",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

41
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/CodeLiturgy.Views/CodeLiturgy.Views.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/CodeLiturgy.Views/CodeLiturgy.Views.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/CodeLiturgy.Views/CodeLiturgy.Views.csproj"
],
"problemMatcher": "$msCompile"
}
]
}

@ -1 +1 @@
Subproject commit d8e4df2c5d247b02accbbd5c668c4427145806d3
Subproject commit 4d866501a7988c61075f8d3fb24b0a72d7c137b5

View File

@ -14,7 +14,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{D7BF4ADC-44AA-48B1-8406-8587775A0DC6}"
ProjectSection(SolutionItems) = preProject
docker-compose.yml = docker-compose.yml
BlueWest.Api\Dockerfile = BlueWest.Api\Dockerfile
CodeLiturgy.Views\Dockerfile = CodeLiturgy.Views\Dockerfile
docker-compose.db.only.yml = docker-compose.db.only.yml
EndProjectSection
EndProject
@ -26,9 +26,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeLiturgy.Views", "CodeLiturgy.Views\CodeLiturgy.Views.csproj", "{59714691-B930-416E-9B93-D91BAE37318F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sharp.Augeas", "include\Sharp.Augeas\Sharp.Augeas\Sharp.Augeas.csproj", "{F12DB2F1-2F2C-4A4C-BBAA-944AF5FB0E59}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sharp.Augeas.Test", "include\Sharp.Augeas\Sharp.Augeas.Test\Sharp.Augeas.Test.csproj", "{03308684-19AC-454B-8CD3-AB1C26B8BBBF}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sharp.Augeas", "include\Sharp.Augeas\Sharp.Augeas\Sharp.Augeas.csproj", "{25840113-CFD7-4B72-B096-E3EAA4A811DB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -44,10 +42,6 @@ Global
{E518C62D-768C-4885-9C9D-FD5761605B54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E518C62D-768C-4885-9C9D-FD5761605B54}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E518C62D-768C-4885-9C9D-FD5761605B54}.Release|Any CPU.Build.0 = Release|Any CPU
{72B37540-A12F-466E-A58F-7BA2B247CB74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72B37540-A12F-466E-A58F-7BA2B247CB74}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72B37540-A12F-466E-A58F-7BA2B247CB74}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72B37540-A12F-466E-A58F-7BA2B247CB74}.Release|Any CPU.Build.0 = Release|Any CPU
{30637214-EDE9-4C2E-BFD6-E4B163FA308B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30637214-EDE9-4C2E-BFD6-E4B163FA308B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30637214-EDE9-4C2E-BFD6-E4B163FA308B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -64,25 +58,19 @@ Global
{59714691-B930-416E-9B93-D91BAE37318F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59714691-B930-416E-9B93-D91BAE37318F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59714691-B930-416E-9B93-D91BAE37318F}.Release|Any CPU.Build.0 = Release|Any CPU
{F12DB2F1-2F2C-4A4C-BBAA-944AF5FB0E59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F12DB2F1-2F2C-4A4C-BBAA-944AF5FB0E59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F12DB2F1-2F2C-4A4C-BBAA-944AF5FB0E59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F12DB2F1-2F2C-4A4C-BBAA-944AF5FB0E59}.Release|Any CPU.Build.0 = Release|Any CPU
{03308684-19AC-454B-8CD3-AB1C26B8BBBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{03308684-19AC-454B-8CD3-AB1C26B8BBBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{03308684-19AC-454B-8CD3-AB1C26B8BBBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{03308684-19AC-454B-8CD3-AB1C26B8BBBF}.Release|Any CPU.Build.0 = Release|Any CPU
{25840113-CFD7-4B72-B096-E3EAA4A811DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25840113-CFD7-4B72-B096-E3EAA4A811DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25840113-CFD7-4B72-B096-E3EAA4A811DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25840113-CFD7-4B72-B096-E3EAA4A811DB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{72B37540-A12F-466E-A58F-7BA2B247CB74} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{30637214-EDE9-4C2E-BFD6-E4B163FA308B} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{08F4484E-5FD8-4590-A8D7-12FBE47120C8} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{BBF5E860-A880-450B-B6C9-EF92F6421B3D} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{F12DB2F1-2F2C-4A4C-BBAA-944AF5FB0E59} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{03308684-19AC-454B-8CD3-AB1C26B8BBBF} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
{25840113-CFD7-4B72-B096-E3EAA4A811DB} = {A1606EEC-6AC5-4779-B140-F57089F5A05F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F24E44CA-98BA-4B44-A1E1-57912CC5DCC3}

View File

@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Identity;
namespace CodeLiturgy.Data.Application.Users
{
/// <inheritdoc />
[MapFrom(typeof(ApplicationRoleUnique))]
public partial class ApplicationRole : IdentityRole<string>
{

View File

@ -2,7 +2,6 @@ using MapTo;
namespace CodeLiturgy.Data.Application.Users
{
[MapFrom(typeof(ApplicationRole))]
public partial class ApplicationRoleUnique
{
public string Id { get; set; }

View File

@ -6,7 +6,6 @@ namespace CodeLiturgy.Data.Application.Users
{
/// <inheritdoc />
[MapFrom(typeof(ApplicationRoleClaimUnique))]
public partial class ApplicationRoleClaim : IdentityRoleClaim<string>
{

View File

@ -2,7 +2,6 @@ using MapTo;
namespace CodeLiturgy.Data.Application.Users
{
[MapFrom(typeof(ApplicationRoleClaim))]
public partial class ApplicationRoleClaimUnique
{
public int Id { get; set; }

View File

@ -13,10 +13,12 @@ namespace CodeLiturgy.Data.Application.Users
/// <summary>
/// Application User in the Identity System.
/// </summary>
[MapFrom(typeof(ApplicationUserUnique))]
[UseUpdate]
public partial class ApplicationUser : IdentityUser<string>
{
public new string Id { get; set; }
public List<SiteEnvironment> Environments { get; set; }
public List<Site> Sites { get; set; }
}
}

View File

@ -3,7 +3,6 @@ using MapTo;
namespace CodeLiturgy.Data.Application.Users
{
[MapFrom(typeof(ApplicationUser))]
public partial class ApplicationUserUnique
{
public string Id { get; set; }

View File

@ -3,7 +3,6 @@ using MapTo;
namespace CodeLiturgy.Data.Application.Users
{
[MapFrom(typeof(ApplicationUserClaimUnique))]
/// <inheritdoc />
public partial class ApplicationUserClaim : IdentityUserClaim<string>

View File

@ -2,7 +2,6 @@ using MapTo;
namespace CodeLiturgy.Data.Application.Users
{
[MapFrom(typeof(ApplicationUserClaim))]
public partial class ApplicationUserClaimUnique
{
public int Id { get; set; }

View File

@ -7,7 +7,6 @@ namespace CodeLiturgy.Data.Application.Users
{
/// <inheritdoc />
[MapFrom(typeof(ApplicationUserRoleUnique))]
public partial class ApplicationUserRole : IdentityUserRole<string>
{

View File

@ -2,7 +2,6 @@ using MapTo;
namespace CodeLiturgy.Data.Application.Users
{
[MapFrom(typeof(ApplicationUserRole))]
public partial class ApplicationUserRoleUnique
{
public string UserId { get; set; }

View File

@ -1,8 +0,0 @@
namespace CodeLiturgy.Data.Application;
public enum EnvironmentType
{
Development,
Staging,
Production
}

View File

@ -1,34 +1,26 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using CodeLiturgy.Data.Application.Users;
using MapTo;
namespace CodeLiturgy.Data.Application
{
[MapFrom(new []
{
typeof(SiteUnique),
typeof(SiteCreate)
})]
public partial class Site
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get; set; }
public SiteEnvironment Environment { get; set; }
public string EnvironmentId { get; set; }
public string Domain { get; set; }
public ApplicationUser User { get; set; }
public string UserId { get; set; }
public string UrlAddress { get; set; }
public SiteType SiteType { get; set; }
public EnvironmentType EnvironmentType { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime LastChanged { get; set; }
}
}

View File

@ -2,18 +2,12 @@ using MapTo;
namespace CodeLiturgy.Data.Application
{
[MapFrom(typeof(Site))]
public partial class SiteCreate
{
public string Id { get; set; }
public string Name { get; set; }
public string Domain { get; set; }
public string Ip { get; set; }
public EnvironmentType EnvironmentType { get; set; }
public SiteType SiteType { get; set; }
}
}

View File

@ -1,17 +1,17 @@
using System.Collections.Generic;
using CodeLiturgy.Data.Application.Users;
using MapTo;
namespace CodeLiturgy.Data.Application
{
public class SiteEnvironment
public partial class SiteEnvironment
{
public string Id { get; set; }
public string Name { get; set; }
public ApplicationUser User { get; set; }
public string UserId { get; set; }
public List<Site> Sites { get; set; }
public ApplicationUser User { get; set; }
public List<Site> Sites { get; set; }
}
}

View File

@ -0,0 +1,11 @@
using System.Collections.Generic;
using CodeLiturgy.Data.Application.Users;
using MapTo;
namespace CodeLiturgy.Data.Application
{
public partial class SiteEnvironmentCreate
{
public string Name { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
using CodeLiturgy.Data.Application.Users;
using MapTo;
namespace CodeLiturgy.Data.Application
{
public partial class SiteEnvironmentUnique
{
public string Id { get; set; }
public string Name { get; set; }
public string UserId { get; set; }
public List<Site> Sites { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace CodeLiturgy.Data.Application
{
public enum SiteType
{
Development,
Staging,
Production
}
}

View File

@ -3,8 +3,6 @@ using MapTo;
namespace CodeLiturgy.Data.Application
{
[MapFrom(typeof(Site))]
public partial class SiteUnique
{
public string Id { get; set; }
@ -15,7 +13,7 @@ namespace CodeLiturgy.Data.Application
public string Ip { get; set; }
public EnvironmentType EnvironmentType { get; set; }
public SiteType SiteType { get; set; }
}
}

View File

@ -0,0 +1,26 @@
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace CodeLiturgy.Startup.Application
{
public class SwaggerEnumSchemaFilter : ISchemaFilter
{
/// <summary>
/// Apply Swagger OpenApi schema
/// </summary>
/// <param name="model">OpenApiSchema model</param>
/// <param name="context">Schema filter context</param>
public void Apply(OpenApiSchema model, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
model.Enum.Clear();
Enum.GetNames(context.Type)
.ToList()
.ForEach(n => model.Enum.Add(new OpenApiString(n)));
}
}
}
}

View File

@ -73,7 +73,7 @@ namespace CodeLiturgy.Data.Auth.Context.Users
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
identity.AddClaim(new Claim(ClaimTypes.MobilePhone, user.PhoneNumber));
//identity.AddClaim(new Claim(ClaimTypes.MobilePhone, user.PhoneNumber));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));

View File

@ -0,0 +1,15 @@
using Sharp.Augeas;
namespace CodeLiturgy.Views.Augeas;
public static class AugeasExtensions
{
public static AugSettings GetSettings()
{
// if DEBUG we use this
var rootDir = Environment.CurrentDirectory + "/Augeas/root";
var lensDir = Environment.CurrentDirectory + "/Augeas/lens";
return new AugSettings(rootDir, lensDir);
}
}

View File

@ -0,0 +1,126 @@
using Sharp.Augeas;
namespace CodeLiturgy.Views.Augeas
{
/// <summary>
/// Manager class for Augeas.
/// </summary>
public class AugeasManager
{
private readonly Sharp.Augeas.Augeas _augeas;
private AugSettings _augSettings;
/// <summary>
/// Cached List with the current apache configurations.
/// </summary>
public List<string> CurrentApacheConfigurations => _currentApacheConfigurations;
private List<string> _currentApacheConfigurations;
private const string ApachePath = "/etc/apache2/sites-available";
/// <summary>
/// Augeas Manager constructor.
/// </summary>
public AugeasManager()
{
_augSettings = AugeasExtensions.GetSettings();
_augeas = new Sharp.Augeas.Augeas(_augSettings);
RefreshApacheConfigurations();
}
/// <summary>
/// Write Changes to the disk
/// </summary>
/// <returns>Returns true if the save was successful.</returns>
public bool Save()
{
return _augeas.Save();
}
/// <summary>
/// Gets a preview of the configuration.
/// </summary>
/// <param name="site"></param>
/// <returns></returns>
public string GetPreview(string site)
{
if (!_currentApacheConfigurations.Contains(site))
{
return string.Empty;
}
var siteFullPath = $"{ApachePath}/{site}";
_augeas.LoadFile(siteFullPath);
var preview = _augeas.GetPreview($"/files{siteFullPath}");
return preview;
}
/// <summary>
/// Gets available Apache configurations.
/// </summary>
/// <param name="skip"></param>
/// <param name="take"></param>
/// <returns></returns>
public List<string> GetApacheAvailableConfigurations(int skip, int take)
{
var result = _currentApacheConfigurations
.Skip(skip)
.Take(take)
.ToList();
return _currentApacheConfigurations;
}
/// <summary>
/// Gets virtual host tree of a site.
/// </summary>
/// <param name="site">Name of the site.</param>
/// <returns></returns>
public SuperNode GetVirtualHostTree(string site)
{
if (!_currentApacheConfigurations.Contains(site))
{
return null;
}
var siteFullPath = $"{ApachePath}/{site}";
_augeas.LoadFile(siteFullPath);
var tree = _augeas.GetTree("VirtualHost",$"/files{siteFullPath}/VirtualHost/*");
return tree;
}
private void RefreshApacheConfigurations()
{
var apacheDir = _augSettings.root + ApachePath;
DirectoryInfo d = new DirectoryInfo(apacheDir);
FileInfo[] files = d.GetFiles("*.conf");
var result = files
.Select(x => x.Name)
.ToList();
_currentApacheConfigurations = result;
}
/// <summary>
/// Gets a directive.
/// </summary>
/// <param name="siteName"></param>
/// <param name="directiveName"></param>
/// <returns></returns>
public Directive GetDirective(string siteName, string directiveName)
{
var tree = GetVirtualHostTree(siteName);
var directive = tree.GetDirective(directiveName);
return directive;
}
}
}

View File

@ -0,0 +1,128 @@
(*
Module: Access
Parses /etc/security/access.conf
Author: Lorenzo Dalrio <lorenzo.dalrio@gmail.com>
About: Reference
Some examples of valid entries can be found in access.conf or "man access.conf"
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* Add a rule to permit login of all users from local sources (tty's, X, cron)
> set /files/etc/security/access.conf[0] +
> set /files/etc/security/access.conf[0]/user ALL
> set /files/etc/security/access.conf[0]/origin LOCAL
About: Configuration files
This lens applies to /etc/security/access.conf. See <filter>.
About: Examples
The <Test_Access> file contains various examples and tests.
*)
module Access =
autoload xfm
(* Group: Comments and empty lines *)
(* Variable: comment *)
let comment = Util.comment
(* Variable: empty *)
let empty = Util.empty
(* Group: Useful primitives *)
(* Variable: colon
* this is the standard field separator " : "
*)
let colon = del (Rx.opt_space . ":" . Rx.opt_space) " : "
(************************************************************************
* Group: ENTRY LINE
*************************************************************************)
(* View: access
* Allow (+) or deny (-) access
*)
let access = label "access" . store /[+-]/
(* Variable: identifier_re
Regex for user/group identifiers *)
let identifier_re = /[A-Za-z0-9_.\\-]+/
(* View: user_re
* Regex for user/netgroup fields
*)
let user_re = identifier_re - /[Ee][Xx][Cc][Ee][Pp][Tt]/
(* View: user
* user can be a username, username@hostname or a group
*)
let user = [ label "user"
. ( store user_re
| store Rx.word . Util.del_str "@"
. [ label "host" . store Rx.word ] ) ]
(* View: group
* Format is (GROUP)
*)
let group = [ label "group"
. Util.del_str "(" . store identifier_re . Util.del_str ")" ]
(* View: netgroup
* Format is @NETGROUP[@@NISDOMAIN]
*)
let netgroup =
[ label "netgroup" . Util.del_str "@" . store user_re
. [ label "nisdomain" . Util.del_str "@@" . store Rx.word ]? ]
(* View: user_list
* A list of users or netgroups to apply the rule to
*)
let user_list = Build.opt_list (user|group|netgroup) Sep.space
(* View: origin_list
* origin_list can be a single ipaddr/originname/domain/fqdn or a list of those values
*)
let origin_list =
let origin_re = Rx.no_spaces - /[Ee][Xx][Cc][Ee][Pp][Tt]/
in Build.opt_list [ label "origin" . store origin_re ] Sep.space
(* View: except
* The except operator makes it possible to write very compact rules.
*)
let except (lns:lens) = [ label "except" . Sep.space
. del /[Ee][Xx][Cc][Ee][Pp][Tt]/ "EXCEPT"
. Sep.space . lns ]
(* View: entry
* A valid entry line
* Definition:
* > entry ::= access ':' user ':' origin_list
*)
let entry = [ access . colon
. user_list
. (except user_list)?
. colon
. origin_list
. (except origin_list)?
. Util.eol ]
(************************************************************************
* Group: LENS & FILTER
*************************************************************************)
(* View: lns
The access.conf lens, any amount of
* <empty> lines
* <comments>
* <entry>
*)
let lns = (comment|empty|entry) *
(* Variable: filter *)
let filter = incl "/etc/security/access.conf"
(* xfm *)
let xfm = transform lns filter

View File

@ -0,0 +1,61 @@
(*
Module: ActiveMQ_Conf
ActiveMQ / FuseMQ conf module for Augeas
Author: Brian Redbeard <redbeard@dead-city.org>
About: Reference
This lens ensures that conf files included in ActiveMQ /FuseMQ are properly
handled by Augeas.
About: License
This file is licensed under the LGPL License.
About: Lens Usage
Sample usage of this lens in augtool:
* Get your current setup
> print /files/etc/activemq.conf
...
* Change ActiveMQ Home
> set /files/etc/activemq.conf/ACTIVEMQ_HOME /usr/share/activemq
Saving your file:
> save
About: Configuration files
This lens applies to relevant conf files located in /etc/activemq/ and
the file /etc/activemq.conf . See <filter>.
*)
module ActiveMQ_Conf =
autoload xfm
(* Variable: blank_val *)
let blank_val = del /^\z/
(* View: entry *)
let entry =
Build.key_value_line Rx.word Sep.space_equal Quote.any_opt
(* View: empty_entry *)
let empty_entry = Build.key_value_line Rx.word Sep.equal Quote.dquote_opt_nil
(* View: lns *)
let lns = (Util.empty | Util.comment | entry | empty_entry )*
(* Variable: filter *)
let filter = incl "/etc/activemq.conf"
. incl "/etc/activemq/*"
. excl "/etc/activemq/*.xml"
. excl "/etc/activemq/jmx.*"
. excl "/etc/activemq/jetty-realm.properties"
. excl "/etc/activemq/*.ts"
. excl "/etc/activemq/*.ks"
. excl "/etc/activemq/*.cert"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,41 @@
(*
Module: ActiveMQ_XML
ActiveMQ / FuseMQ XML module for Augeas
Author: Brian Redbeard <redbeard@dead-city.org>
About: Reference
This lens ensures that XML files included in ActiveMQ / FuseMQ are properly
handled by Augeas.
About: License
This file is licensed under the LGPL License.
About: Lens Usage
Sample usage of this lens in augtool:
* Get your current setup
> print /files/etc/activemq/activemq.xml
...
* Change OpenShift domain
> set /files/etc/openshift/broker.conf/CLOUD_DOMAIN ose.example.com
Saving your file:
> save
About: Configuration files
This lens applies to relevant XML files located in /etc/activemq/ . See <filter>.
*)
module ActiveMQ_XML =
autoload xfm
let lns = Xml.lns
let filter = (incl "/etc/activemq/*.xml")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,60 @@
(*
Module: AFS_cellalias
Parses AFS configuration file CellAlias
Author: Pat Riehecky <riehecky@fnal.gov>
About: Reference
This lens is targeted at the OpenAFS CellAlias file
About: Lens Usage
Sample usage of this lens in augtool
* Add a CellAlias for fnal.gov/files to fnal-files
> set /files/usr/vice/etc/CellAlias/target[99] fnal.gov/files
> set /files/usr/vice/etc/CellAlias/target[99]/linkname fnal-files
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module AFS_cellalias =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Comments and empty lines *)
(* View: eol *)
let eol = Util.eol
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* Group: separators *)
(* View: space
* Separation between key and value
*)
let space = Util.del_ws_spc
let target = /[^ \t\n#]+/
let linkname = Rx.word
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: entry *)
let entry = [ label "target" . store target . space . [ label "linkname" . store linkname . eol ] ]
(* View: lns *)
let lns = (empty | comment | entry)*
let xfm = transform lns (incl "/usr/vice/etc/CellAlias")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,89 @@
(*
Module: Aliases
Parses /etc/aliases
Author: David Lutterkort <lutter@redhat.com>
About: Reference
This lens tries to keep as close as possible to `man 5 aliases` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
See <lns>.
About: Configuration files
This lens applies to /etc/aliases.
About: Examples
The <Test_Aliases> file contains various examples and tests.
*)
module Aliases =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: basic tokens *)
(* Variable: word *)
let word = /[^|", \t\n]+/
(* Variable: name *)
let name = /([^ \t\n#:|@]+|"[^"|\n]*")/ (* " make emacs calm down *)
(* Variable: command
* a command can contain spaces, if enclosed in double quotes, the case
* without spaces is taken care with <word>
*)
let command = /(\|([^", \t\n]+|"[^"\n]+"))|("\|[^"\n]+")/
(* Group: Comments and empty lines *)
(* View: eol *)
let eol = Util.eol
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* Group: separators *)
(* View: colon
* Separation between the alias and it's destinations
*)
let colon = del /[ \t]*:[ \t]*/ ":\t"
(* View: comma
* Separation between multiple destinations
*)
let comma = del /[ \t]*,[ \t]*(\n[ \t]+)?/ ", "
(* Group: alias *)
(* View: destination
* Can be either a word (no spaces included) or a command with spaces
*)
let destination = ( word | command )
(* View: value_list
* List of destinations
*)
let value_list = Build.opt_list ([ label "value" . store destination]) comma
(* View: alias
* a name with one or more destinations
*)
let alias = [ seq "alias" .
[ label "name" . store name ] . colon .
value_list
] . eol
(* View: lns *)
let lns = (comment | empty | alias)*
let xfm = transform lns (incl "/etc/aliases")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,30 @@
(*
Module: Anaconda
Parses Anaconda's user interaction configuration files.
Author: Pino Toscano <ptoscano@redhat.com>
About: Reference
https://anaconda-installer.readthedocs.io/en/latest/user-interaction-config-file-spec.html
About: Configuration file
This lens applies to /etc/sysconfig/anaconda.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module Anaconda =
autoload xfm
let comment = IniFile.comment "#" "#"
let sep = IniFile.sep "=" "="
let entry = IniFile.entry IniFile.entry_re sep comment
let title = IniFile.title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = incl "/etc/sysconfig/anaconda"
let xfm = transform lns filter

View File

@ -0,0 +1,87 @@
(*
Module: Anacron
Parses /etc/anacrontab
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 anacrontab` where
possible.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
About: Configuration files
This lens applies to /etc/anacrontab. See <filter>.
About: Examples
The <Test_Anacron> file contains various examples and tests.
*)
module Anacron =
autoload xfm
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(************************************************************************
* View: shellvar
* A shell variable in crontab
*************************************************************************)
let shellvar = Cron.shellvar
(* View: period *)
let period = [ label "period" . store Rx.integer ]
(* Variable: period_name_re
The valid values for <period_name>. Currently only "monthly" *)
let period_name_re = "monthly"
(************************************************************************
* View: period_name
* In the format "@keyword"
*************************************************************************)
let period_name = [ label "period_name" . Util.del_str "@"
. store period_name_re ]
(************************************************************************
* View: delay
* The delay for an <entry>
*************************************************************************)
let delay = [ label "delay" . store Rx.integer ]
(************************************************************************
* View: job_identifier
* The job_identifier for an <entry>
*************************************************************************)
let job_identifier = [ label "job-identifier" . store Rx.word ]
(************************************************************************
* View: entry
* An anacrontab entry
*************************************************************************)
let entry = [ label "entry" . Util.indent
. ( period | period_name )
. Sep.space . delay
. Sep.space . job_identifier
. Sep.space . store Rx.space_in . Util.eol ]
(*
* View: lns
* The anacron lens
*)
let lns = ( Util.empty | Util.comment | shellvar | entry )*
(* Variable: filter *)
let filter = incl "/etc/anacrontab"
let xfm = transform lns filter

View File

@ -0,0 +1,59 @@
(*
Module: Approx
Parses /etc/approx/approx.conf
Author: David Lutterkort <lutter@redhat.com>
About: Reference
This lens tries to keep as close as possible to `man 5 approx.conf` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
See <lns>.
About: Configuration files
This lens applies to /etc/approx/approx.conf.
About: Examples
The <Test_Approx> file contains various examples and tests.
*)
module Approx =
autoload xfm
(* Variable: eol
An <Util.eol> *)
let eol = Util.eol
(* Variable: indent
An <Util.indent> *)
let indent = Util.indent
(* Variable: key_re *)
let key_re = /\$?[A-Za-z0-9_.-]+/
(* Variable: sep *)
let sep = /[ \t]+/
(* Variable: value_re *)
let value_re = /[^ \t\n](.*[^ \t\n])?/
(* View: comment *)
let comment = [ indent . label "#comment" . del /[#;][ \t]*/ "# "
. store /([^ \t\n].*[^ \t\n]|[^ \t\n])/ . eol ]
(* View: empty
An <Util.empty> *)
let empty = Util.empty
(* View: kv *)
let kv = [ indent . key key_re . del sep " " . store value_re . eol ]
(* View: lns *)
let lns = (empty | comment | kv) *
(* View: filter *)
let filter = incl "/etc/approx/approx.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,47 @@
(*
Module: Apt_Update_Manager
Parses files in /etc/update-manager
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to files in /etc/update-manager. See <filter>.
About: Examples
The <Test_Apt_Update_Manager> file contains various examples and tests.
*)
module Apt_Update_Manager =
autoload xfm
(* View: comment *)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
(* View: sep *)
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
(* View: title *)
let title = IniFile.title Rx.word
(* View: entry *)
let entry = IniFile.entry Rx.word sep comment
(* View: record *)
let record = IniFile.record title entry
(* View: lns *)
let lns = IniFile.lns record comment
(* Variable: filter *)
let filter = incl "/etc/update-manager/meta-release"
. incl "/etc/update-manager/release-upgrades"
. incl "/etc/update-manager/release-upgrades.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,25 @@
(* Module: AptCacherNGSecurity
Lens for config files like the one found in
/etc/apt-cacher-ng/security.conf
About: License
Copyright 2013 Erik B. Andersen; this file is licenced under the LGPL v2+.
*)
module AptCacherNGSecurity =
autoload xfm
(* Define a Username/PW pair *)
let authpair = [ key /[^ \t:\/]*/ . del /:/ ":" . store /[^: \t\n]*/ ]
(* Define a record. So far as I can tell, the only auth level supported is Admin *)
let record = [ key "AdminAuth". del /[ \t]*:[ \t]*/ ": ". authpair . Util.del_str "\n"]
(* Define the basic lens *)
let lns = ( record | Util.empty | Util.comment )*
let filter = incl "/etc/apt-cacher-ng/security.conf"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,151 @@
(*
Module: AptConf
Parses /etc/apt/apt.conf and /etc/apt/apt.conf.d/*
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 apt.conf`
where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to /etc/apt/apt.conf and /etc/apt/apt.conf.d/*.
See <filter>.
*)
module AptConf =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: eol
And <Util.eol> end of line *)
let eol = Util.eol
(* View: empty
A C-style empty line *)
let empty = Util.empty_any
(* View: indent
An indentation *)
let indent = Util.indent
(* View: comment_simple
A one-line comment, C-style *)
let comment_simple = Util.comment_c_style_or_hash
(* View: comment_multi
A multiline comment, C-style *)
let comment_multi = Util.comment_multiline
(* View: comment
A comment, either <comment_simple> or <comment_multi> *)
let comment = comment_simple | comment_multi
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: name_re
Regex for entry names *)
let name_re = /[A-Za-z][A-Za-z-]*/
(* View: name_re_colons
Regex for entry names with colons *)
let name_re_colons = /[A-Za-z][A-Za-z:-]*/
(* View: entry
An apt.conf entry, recursive
WARNING:
This lens exploits a put ambiguity
since apt.conf allows for both
APT { Clean-Installed { "true" } }
and APT::Clean-Installed "true";
but we're choosing to map them the same way
The recursive lens doesn't seem
to care and defaults to the first
item in the union.
This is why the APT { Clean-Installed { "true"; } }
form is listed first, since it supports
all subnodes (which Dpkg::Conf) doesn't.
Exchanging these two expressions in the union
makes tests fails since the tree cannot
be mapped back.
This situation results in existing
configuration being modified when the
associated tree is modified. For example,
changing the value of
APT::Clean-Installed "true"; to "false"
results in
APT { Clean-Installed "false"; }
(see unit tests)
*)
let rec entry_noeol =
let value =
Util.del_str "\"" . store /[^"\n]+/
. del /";?/ "\";" in
let opt_eol = del /[ \t\n]*/ "\n" in
let long_eol = del /[ \t]*\n+/ "\n" in
let list_elem = [ opt_eol . label "@elem" . value ] in
let eol_comment = del /([ \t\n]*\n)?/ "" . comment in
[ key name_re . Sep.space . value ]
| [ key name_re . del /[ \t\n]*\{/ " {" .
( (opt_eol . entry_noeol) |
list_elem |
eol_comment
)* .
del /[ \t\n]*\};?/ "\n};" ]
| [ key name_re . Util.del_str "::" . entry_noeol ]
let entry = indent . entry_noeol . eol
(* View: include
A file inclusion
/!\ The manpage is not clear on the syntax *)
let include =
[ indent . key "#include" . Sep.space
. store Rx.fspath . eol ]
(* View: clear
A list of variables to clear
/!\ The manpage is not clear on the syntax *)
let clear =
let name = [ label "name" . store name_re_colons ] in
[ indent . key "#clear" . Sep.space
. Build.opt_list name Sep.space
. eol ]
(************************************************************************
* Group: LENS AND FILTER
*************************************************************************)
(* View: lns
The apt.conf lens *)
let lns = (empty|comment|entry|include|clear)*
(* View: filter *)
let filter = incl "/etc/apt/apt.conf"
. incl "/etc/apt/apt.conf.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,69 @@
(*
Module: AptPreferences
Apt/preferences module for Augeas
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
*)
module AptPreferences =
autoload xfm
(************************************************************************
* Group: Entries
************************************************************************)
(* View: colon *)
let colon = del /:[ \t]*/ ": "
(* View: pin_gen
A generic pin
Parameters:
lbl:string - the label *)
let pin_gen (lbl:string) = store lbl
. [ label lbl . Sep.space . store Rx.no_spaces ]
(* View: pin_keys *)
let pin_keys =
let space_in = store /[^, \r\t\n][^,\n]*[^, \r\t\n]|[^, \t\n\r]/
in Build.key_value /[aclnov]/ Sep.equal space_in
(* View: pin_options *)
let pin_options =
let comma = Util.delim ","
in store "release" . Sep.space
. Build.opt_list pin_keys comma
(* View: version_pin *)
let version_pin = pin_gen "version"
(* View: origin_pin *)
let origin_pin = pin_gen "origin"
(* View: pin *)
let pin =
let pin_value = pin_options | version_pin | origin_pin
in Build.key_value_line "Pin" colon pin_value
(* View: entries *)
let entries = Build.key_value_line ("Explanation"|"Package"|"Pin-Priority")
colon (store Rx.space_in)
| pin
| Util.comment
(* View: record *)
let record = [ seq "record" . entries+ ]
(************************************************************************
* Group: Lens
************************************************************************)
(* View: lns *)
let lns = Util.empty* . (Build.opt_list record Util.eol+ . Util.empty*)?
(* View: filter *)
let filter = incl "/etc/apt/preferences"
. incl "/etc/apt/preferences.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,70 @@
(*
Module: Aptsources
Parsing /etc/apt/sources.list
*)
module Aptsources =
autoload xfm
(************************************************************************
* Group: Utility variables/functions
************************************************************************)
(* View: sep_ws *)
let sep_ws = Sep.space
(* View: eol *)
let eol = Util.del_str "\n"
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* View: word *)
let word = /[^][# \n\t]+/
(* View: uri *)
let uri =
let protocol = /[a-z+]+:/
in let path = /\/[^] \t]*/
in let path_brack = /\[[^]]+\]\/?/
in protocol? . path
| protocol . path_brack
(************************************************************************
* Group: Keywords
************************************************************************)
(* View: record *)
let record =
let option_sep = [ label "operation" . store /[+-]/]? . Sep.equal
in let option = Build.key_value /arch|trusted/ option_sep (store Rx.word)
in let options = [ label "options"
. Util.del_str "[" . Sep.opt_space
. Build.opt_list option Sep.space
. Sep.opt_space . Util.del_str "]"
. sep_ws ]
in [ Util.indent . seq "source"
. [ label "type" . store word ] . sep_ws
. options?
. [ label "uri" . store uri ] . sep_ws
. [ label "distribution" . store word ]
. [ label "component" . sep_ws . store word ]*
. del /[ \t]*(#.*)?/ ""
. eol ]
(************************************************************************
* Group: Lens
************************************************************************)
(* View: lns *)
let lns = ( comment | empty | record ) *
(* View: filter *)
let filter = (incl "/etc/apt/sources.list")
. (incl "/etc/apt/sources.list.d/*")
. Util.stdexcl
let xfm = transform lns filter
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,39 @@
(* Authinfo2 module for Augeas *)
(* Author: Nicolas Gif <ngf18490@pm.me> *)
(* Heavily based on DPUT module by Raphael Pinson *)
(* <raphink@gmail.com> *)
(* *)
module Authinfo2 =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re "#"
let sep = IniFile.sep IniFile.sep_re ":"
(************************************************************************
* ENTRY
*************************************************************************)
let entry =
IniFile.entry_generic_nocomment (key IniFile.entry_re) sep IniFile.comment_re comment
(************************************************************************
* TITLE & RECORD
*************************************************************************)
let title = IniFile.title IniFile.record_re
let record = IniFile.record title entry
(************************************************************************
* LENS & FILTER
*************************************************************************)
let lns = IniFile.lns record comment
let filter = (incl (Sys.getenv("HOME") . "/.s3ql/authinfo2"))
let xfm = transform lns filter

View File

@ -0,0 +1,72 @@
(*
Module: Authorized_Keys
Parses SSH authorized_keys
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
About: Reference
This lens tries to keep as close as possible to `man 5 authorized_keys` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to SSH authorized_keys. See <filter>.
About: Examples
The <Test_Authorized_Keys> file contains various examples and tests.
*)
module Authorized_Keys =
autoload xfm
(* View: option
A key option *)
let option =
let kv_re = "command" | "environment" | "from"
| "permitopen" | "principals" | "tunnel"
in let flag_re = "cert-authority" | "no-agent-forwarding"
| "no-port-forwarding" | "no-pty" | "no-user-rc"
| "no-X11-forwarding"
in let option_value = Util.del_str "\""
. store /((\\\\")?[^\\\n"]*)+/
. Util.del_str "\""
in Build.key_value kv_re Sep.equal option_value
| Build.flag flag_re
(* View: key_options
A list of key <option>s *)
let key_options = [ label "options" . Build.opt_list option Sep.comma ]
(* View: key_type *)
let key_type =
let key_type_re = /ecdsa-sha2-nistp[0-9]+/ | /ssh-[a-z0-9]+/
in [ label "type" . store key_type_re ]
(* View: key_comment *)
let key_comment = [ label "comment" . store Rx.space_in ]
(* View: authorized_key *)
let authorized_key =
[ label "key"
. (key_options . Sep.space)?
. key_type . Sep.space
. store Rx.no_spaces
. (Sep.space . key_comment)?
. Util.eol ]
(* View: lns
The authorized_keys lens
*)
let lns = ( Util.empty | Util.comment | authorized_key)*
(* Variable: filter *)
let filter = incl (Sys.getenv("HOME") . "/.ssh/authorized_keys")
let xfm = transform lns filter

View File

@ -0,0 +1,85 @@
(*
Module: AuthselectPam
Parses /etc/authselect/custom/*/*-auth and
/etc/authselect/custom/*/postlogin files
Author: Heston Snodgrass <heston.snodgrass@puppet.com> based on pam.aug by David Lutterkort <lutter@redhat.com>
About: Reference
This lens tries to keep as close as possible to `man pam.conf` where
possible. This lens supports authselect templating syntax as
can be found in `man authselect-profiles`.
About: Licence
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
About: Configuration files
This lens also autoloads /etc/authselect/custom/*/*-auth and
/etc/authselect/custom/*/postlogin because these files are PAM template
files on machines that have authselect custom profiles.
*)
module AuthselectPam =
autoload xfm
(* The Pam space does not work for certain parts of the authselect syntax so we need our own whitespace *)
let reg_ws = del /([ \t])/ " "
(* This is close the the same as argument from pam.aug, but curly braces are accounted for *)
let argument = /(\[[^]{}#\n]+\]|[^[{#\n \t\\][^#\n \t\\]*)/
(* The various types of conditional statements that can exist in authselect PAM files *)
let authselect_conditional_type = /(continue if|stop if|include if|exclude if|imply|if)/
(* Basic logical operators supported by authselect templates *)
let authselect_logic_stmt = [ reg_ws . key /(and|or|not)/ ]
(* authselect features inside conditional templates *)
let authselect_feature = [ label "feature" . Quote.do_dquote (store /([a-z0-9-]+)/) ]
(* authselect templates can substitute text if a condition is met. *)
(* The sytax for this is `<conditional>:<what to sub on true>|<what to sub on false>` *)
(* Both result forms are optional *)
let authselect_on_true = [ label "on_true" . Util.del_str ":" . store /([^#{}:|\n\\]+)/ ]
let authselect_on_false = [ label "on_false" . Util.del_str "|" . store /([^#{}:|\n\\]+)/ ]
(* Features in conditionals can be grouped together so that logical operations can be resolved for the entire group *)
let authselect_feature_group = [ label "feature_group" . Util.del_str "(" .
authselect_feature . authselect_logic_stmt .
reg_ws . authselect_feature . (authselect_logic_stmt . reg_ws . authselect_feature)* .
Util.del_str ")" ]
(* Represents a single, full authselect conditional template *)
let authselect_conditional = [ Pam.space .
Util.del_str "{" .
label "authselect_conditional" . store authselect_conditional_type .
authselect_logic_stmt* .
( reg_ws . authselect_feature | reg_ws . authselect_feature_group) .
authselect_on_true? .
authselect_on_false? .
Util.del_str "}" ]
(* Shared with PamConf *)
let record = [ label "optional" . del "-" "-" ]? .
[ label "type" . store Pam.types ] .
Pam.space .
[ label "control" . store Pam.control] .
Pam.space .
[ label "module" . store Pam.word ] .
(authselect_conditional | [ Pam.space . label "argument" . store argument ])* .
Pam.comment_or_eol
let record_svc = [ seq "record" . Pam.indent . record ]
let lns = ( Pam.empty | Pam.comment | Pam.include | record_svc ) *
let filter = incl "/etc/authselect/custom/*/*-auth"
. incl "/etc/authselect/custom/*/postlogin"
. Util.stdexcl
let xfm = transform lns filter
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,125 @@
(*
Module: Automaster
Parses autofs' auto.master files
Author: Dominic Cleal <dcleal@redhat.com>
About: Reference
See auto.master(5)
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to /etc/auto.master, auto_master and /etc/auto.master.d/*
files.
About: Examples
The <Test_Automaster> file contains various examples and tests.
*)
module Automaster =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: eol *)
let eol = Util.eol
(* View: empty *)
let empty = Util.empty
(* View: comment *)
let comment = Util.comment
(* View mount *)
let mount = /[^+ \t\n#]+/
(* View: type
yp, file, dir etc but not ldap *)
let type = Rx.word - /ldap/
(* View: format
sun, hesoid *)
let format = Rx.word
(* View: name *)
let name = /[^: \t\n]+/
(* View: host *)
let host = /[^:# \n\t]+/
(* View: dn *)
let dn = /[^:# \n\t]+/
(* An option label can't contain comma, comment, equals, or space *)
let optlabel = /[^,#= \n\t]+/
let spec = /[^,# \n\t][^ \n\t]*/
(* View: optsep *)
let optsep = del /[ \t,]+/ ","
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: map_format *)
let map_format = [ label "format" . store format ]
(* View: map_type *)
let map_type = [ label "type" . store type ]
(* View: map_name *)
let map_name = [ label "map" . store name ]
(* View: map_generic
Used for all except LDAP maps which are parsed further *)
let map_generic = ( map_type . ( Sep.comma . map_format )? . Sep.colon )?
. map_name
(* View: map_ldap_name
Split up host:dc=foo into host/map nodes *)
let map_ldap_name = ( [ label "host" . store host ] . Sep.colon )?
. [ label "map" . store dn ]
(* View: map_ldap *)
let map_ldap = [ label "type" . store "ldap" ]
. ( Sep.comma . map_format )? . Sep.colon
. map_ldap_name
(* View: comma_spc_sep_list
Parses options either for filesystems or autofs *)
let comma_spc_sep_list (l:string) =
let value = [ label "value" . Util.del_str "=" . store Rx.neg1 ] in
let lns = [ label l . store optlabel . value? ] in
Build.opt_list lns optsep
(* View: map_mount
Mountpoint and whitespace, followed by the map info *)
let map_mount = [ seq "map" . store mount . Util.del_ws_tab
. ( map_generic | map_ldap )
. ( Util.del_ws_spc . comma_spc_sep_list "opt" )?
. Util.eol ]
(* map_master
"+" to include more master entries and optional whitespace *)
let map_master = [ seq "map" . store "+" . Util.del_opt_ws ""
. ( map_generic | map_ldap )
. ( Util.del_ws_spc . comma_spc_sep_list "opt" )?
. Util.eol ]
(* View: lns *)
let lns = ( empty | comment | map_mount | map_master ) *
(* Variable: filter *)
let filter = incl "/etc/auto.master"
. incl "/etc/auto_master"
. incl "/etc/auto.master.d/*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,131 @@
(*
Module: Automounter
Parses automounter file based maps
Author: Dominic Cleal <dcleal@redhat.com>
About: Reference
See autofs(5)
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to /etc/auto.*, auto_*, excluding known scripts.
About: Examples
The <Test_Automounter> file contains various examples and tests.
*)
module Automounter =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: eol *)
let eol = Util.eol
(* View: empty *)
let empty = Util.empty
(* View: comment *)
let comment = Util.comment
(* View: path *)
let path = /[^-+#: \t\n][^#: \t\n]*/
(* View: hostname *)
let hostname = /[^-:#\(\), \n\t][^:#\(\), \n\t]*/
(* An option label can't contain comma, comment, equals, or space *)
let optlabel = /[^,#:\(\)= \n\t]+/
let spec = /[^,#:\(\)= \n\t][^ \n\t]*/
(* View: weight *)
let weight = Rx.integer
(* View: map_name *)
let map_name = /[^: \t\n]+/
(* View: entry_multimount_sep
Separator for multimount entries, permits line spanning with "\" *)
let entry_multimount_sep = del /[ \t]+(\\\\[ \t]*\n[ \t]+)?/ " "
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: entry_key
Key for a map entry *)
let entry_mkey = store path
(* View: entry_path
Path component of an entry location *)
let entry_path = [ label "path" . store path ]
(* View: entry_host
Host component with optional weight of an entry location *)
let entry_host = [ label "host" . store hostname
. ( Util.del_str "(" . [ label "weight"
. store weight ] . Util.del_str ")" )? ]
(* View: comma_sep_list
Parses options for filesystems *)
let comma_sep_list (l:string) =
let value = [ label "value" . Util.del_str "=" . store Rx.neg1 ] in
let lns = [ label l . store optlabel . value? ] in
Build.opt_list lns Sep.comma
(* View: entry_options *)
let entry_options = Util.del_str "-" . comma_sep_list "opt" . Util.del_ws_tab
(* View: entry_location
A single location with one or more hosts, and one path *)
let entry_location = ( entry_host . ( Sep.comma . entry_host )* )?
. Sep.colon . entry_path
(* View: entry_locations
Multiple locations (each with one or more hosts), separated by spaces *)
let entry_locations = [ label "location" . counter "location"
. [ seq "location" . entry_location ]
. ( [ Util.del_ws_spc . seq "location" . entry_location ] )* ]
(* View: entry_multimount
Parses one of many mountpoints given for a multimount line *)
let entry_multimount = entry_mkey . Util.del_ws_tab . entry_options? . entry_locations
(* View: entry_multimounts
Parses multiple mountpoints given on an entry line *)
let entry_multimounts = [ label "mount" . counter "mount"
. [ seq "mount" . entry_multimount ]
. ( [ entry_multimount_sep . seq "mount" . entry_multimount ] )* ]
(* View: entry
A single map entry from start to finish, including multi-mounts *)
let entry = [ seq "entry" . entry_mkey . Util.del_ws_tab . entry_options?
. ( entry_locations | entry_multimounts ) . Util.eol ]
(* View: include
An include line starting with a "+" and a map name *)
let include = [ seq "entry" . store "+" . Util.del_opt_ws ""
. [ label "map" . store map_name ] . Util.eol ]
(* View: lns *)
let lns = ( empty | comment | entry | include ) *
(* Variable: filter
Exclude scripts/executable maps from here *)
let filter = incl "/etc/auto.*"
. incl "/etc/auto_*"
. excl "/etc/auto.master"
. excl "/etc/auto_master"
. excl "/etc/auto.net"
. excl "/etc/auto.smb"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,45 @@
(*
Module: Avahi
Avahi module for Augeas
Author: Athir Nuaimi <athir@nuaimi.com>
avahi-daemon.conf is a standard INI File.
*)
module Avahi =
autoload xfm
(************************************************************************
* Group: INI File settings
* avahi-daemon.conf only supports "# as commentary and "=" as separator
*************************************************************************)
(* View: comment *)
let comment = IniFile.comment "#" "#"
(* View: sep *)
let sep = IniFile.sep "=" "="
(************************************************************************
* Group: Entry
*************************************************************************)
(* View: entry *)
let entry = IniFile.indented_entry IniFile.entry_re sep comment
(************************************************************************
* Group: Record
*************************************************************************)
(* View: title *)
let title = IniFile.indented_title IniFile.record_re
(* View: record *)
let record = IniFile.record title entry
(************************************************************************
* Group: Lens and filter
*************************************************************************)
(* View: lns *)
let lns = IniFile.lns record comment
(* View: filter *)
let filter = (incl "/etc/avahi/avahi-daemon.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,40 @@
(*
Module: BackupPCHosts
Parses /etc/backuppc/hosts
About: Reference
This lens tries to keep as close as possible to `man backuppc` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to /etc/backuppc/hosts. See <filter>.
*)
module BackupPCHosts =
autoload xfm
(* View: word *)
let word = /[^#, \n\t\/]+/
(* View: record *)
let record =
let moreusers = Build.opt_list [ label "moreusers" . store word ] Sep.comma in
[ seq "host"
. [ label "host" . store word ] . Util.del_ws_tab
. [ label "dhcp" . store word ] . Util.del_ws_tab
. [ label "user" . store word ]
. (Util.del_ws_tab . moreusers)?
. (Util.comment|Util.eol) ]
(* View: lns *)
let lns = ( Util.empty | Util.comment | record ) *
(* View: filter *)
let filter = incl "/etc/backuppc/hosts"
let xfm = transform lns filter

View File

@ -0,0 +1,130 @@
(* BB-hosts module for Augeas *)
(* Author: Raphael Pinson <raphink@gmail.com> *)
(* *)
(* Supported : *)
(* *)
(* Todo : *)
(* *)
module BBhosts =
autoload xfm
(* Define useful shortcuts *)
let eol = Util.eol
let eol_no_spc = Util.del_str "\n"
let sep_spc = Sep.space
let sep_opt_spc = Sep.opt_space
let word = store /[^|;# \n\t]+/
let value_to_eol = store /[^ \t][^\n]+/
let ip = store Rx.ipv4
let url = store /https?:[^# \n\t]+/
let word_cont = store /[^;# \n\t]+/
(* Define comments and empty lines *)
let comment = Util.comment
let empty = Util.empty
(* Define host *)
let host_ip = [ label "ip" . ip ]
let host_fqdn = [ label "fqdn" . sep_spc . word ]
let host_test_url = [ label "url" . url ]
let host_test_cont (kw:string) = [ store /!?/ . key kw .
(Util.del_str ";" .
[ label "url" . word_cont ] .
(Util.del_str ";" . [ label "keyword" . word ])?
)?
]
(* DOWNTIME=[columns:]day:starttime:endtime:cause[,day:starttime:endtime:cause] *)
let host_test_downtime =
let probe = [ label "probe" . store (Rx.word | "*") ]
in let probes = Build.opt_list probe Sep.comma
in let day = [ label "day" . store (Rx.word | "*") ]
in let starttime = [ label "starttime" . store Rx.integer ]
in let endtime = [ label "endtime" . store Rx.integer ]
in let cause = [ label "cause" . Util.del_str "\"" . store /[^"]*/ . Util.del_str "\"" ]
in [ key "DOWNTIME" . Sep.equal
. (probes . Sep.colon)?
. day . Sep.colon
. starttime . Sep.colon
. endtime . Sep.colon
. cause
]
let host_test_flag_value = [ label "value" . Util.del_str ":"
. store Rx.word ]
let host_test_flag (kw:regexp) = [ store /!?/ . key kw
. host_test_flag_value? ]
let host_test = host_test_cont "cont"
| host_test_cont "contInsecure"
| host_test_cont "dns"
| host_test_flag "BBDISPLAY"
| host_test_flag "BBNET"
| host_test_flag "BBPAGER"
| host_test_flag "CDB"
| host_test_flag "GTM"
| host_test_flag "XYMON"
| host_test_flag "ajp13"
| host_test_flag "bbd"
| host_test_flag "clamd"
| host_test_flag "cupsd"
| host_test_flag "front"
| host_test_flag /ftps?/
| host_test_flag /imap[2-4s]?/
| host_test_flag /ldaps?/
| host_test_flag /nntps?/
| host_test_flag "noconn"
| host_test_flag "nocont"
| host_test_flag "noping"
| host_test_flag "notrends"
| host_test_flag "oratns"
| host_test_flag /pop-?[2-3]?s?/
| host_test_flag "qmqp"
| host_test_flag "qmtp"
| host_test_flag "rsync"
| host_test_flag /smtps?/
| host_test_flag "spamd"
| host_test_flag /ssh[1-2]?/
| host_test_flag /telnets?/
| host_test_flag "vnc"
| host_test_url
| host_test_downtime
let host_test_list = Build.opt_list host_test sep_spc
let host_opts = [ label "probes" . sep_spc . Util.del_str "#" . (sep_opt_spc . host_test_list)? ]
let host = [ label "host" . host_ip . host_fqdn . host_opts . eol ]
(* Define group-compress and group-only *)
let group_compress = [ key /group(-compress)?/ . (sep_spc . value_to_eol)? . eol_no_spc .
( comment | empty | host)*
]
let group_only_col = [ label "col" . word ]
let group_only_cols = sep_spc . group_only_col . ( Util.del_str "|" . group_only_col )*
let group_only = [ key "group-only" . group_only_cols . sep_spc . value_to_eol . eol_no_spc .
( comment | empty | host)*
]
(* Define page *)
let page_title = [ label "title" . sep_spc . value_to_eol ]
let page = [ key "page" . sep_spc . word . page_title? . eol_no_spc .
( comment | empty | host )* . ( group_compress | group_only )*
]
(* Define lens *)
let lns = (comment | empty)* . page*
let filter = incl "/etc/bb/bb-hosts"
let xfm = transform lns filter

View File

@ -0,0 +1,130 @@
(*
Module: BootConf
Parses (Open)BSD-stype /etc/boot.conf
Author: Jasper Lievisse Adriaanse <jasper@jasper.la>
About: Reference
This lens is used to parse the second-stage bootstrap configuration
file, /etc/boot.conf as found on OpenBSD. The format is largely MI,
with MD parts included:
http://www.openbsd.org/cgi-bin/man.cgi?query=boot.conf&arch=i386
About: Usage Example
To be documented
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Configuration files
This lens applies to /etc/boot.conf.
See <filter>.
*)
module BootConf =
autoload xfm
(************************************************************************
* Utility variables/functions
************************************************************************)
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* View: eol *)
let eol = Util.eol
(* View: fspath *)
let fspath = Rx.fspath
(* View: space *)
let space = Sep.space
(* View: word *)
let word = Rx.word
(************************************************************************
* View: key_opt_value_line
* A subnode with a keyword, an optional part consisting of a separator
* and a storing lens, and an end of line
*
* Parameters:
* kw:regexp - the pattern to match as key
* sto:lens - the storing lens
************************************************************************)
let key_opt_value_line (kw:regexp) (sto:lens) =
[ key kw . (space . sto)? . eol ]
(************************************************************************
* Commands
************************************************************************)
(* View: single_command
single command such as 'help' or 'time' *)
let single_command =
let line_re = /help|time|reboot/
in [ Util.indent . key line_re . eol ]
(* View: ls
ls [directory] *)
let ls = Build.key_value_line
"ls" space (store fspath)
let set_cmd = "addr"
| "debug"
| "device"
| "howto"
| "image"
| "timeout"
| "tty"
(* View: set
set [varname [value]] *)
let set = Build.key_value
"set" space
(key_opt_value_line set_cmd (store Rx.space_in))
(* View: stty
stty [device [speed]] *)
let stty =
let device = [ label "device" . store fspath ]
in let speed = [ label "speed" . store Rx.integer ]
in key_opt_value_line "stty" (device . (space . speed)?)
(* View: echo
echo [args] *)
let echo = Build.key_value_line
"echo" space (store word)
(* View: boot
boot [image [-acds]]
XXX: the last arguments are not always needed, so make them optional *)
let boot =
let image = [ label "image" . store fspath ]
in let arg = [ label "arg" . store word ]
in Build.key_value_line "boot" space (image . space . arg)
(* View: machine
machine [command] *)
let machine =
let machine_entry = Build.key_value ("comaddr"|"memory")
space (store word)
| Build.flag ("diskinfo"|"regs")
in Build.key_value_line
"machine" space
(Build.opt_list
machine_entry
space)
(************************************************************************
* Lens
************************************************************************)
(* View: command *)
let command = boot | echo | ls | machine | set | stty
(* View: lns *)
let lns = ( empty | comment | command | single_command )*
(* Variable: filter *)
let filter = (incl "/etc/boot.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,420 @@
(*
Module: Build
Generic functions to build lenses
Author: Raphael Pinson <raphink@gmail.com>
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Reference
This file provides generic functions to build Augeas lenses
*)
module Build =
let eol = Util.eol
(************************************************************************
* Group: GENERIC CONSTRUCTIONS
************************************************************************)
(************************************************************************
* View: brackets
* Put a lens inside brackets
*
* Parameters:
* l:lens - the left bracket lens
* r: lens - the right bracket lens
* lns:lens - the lens to put inside brackets
************************************************************************)
let brackets (l:lens) (r:lens) (lns:lens) = l . lns . r
(************************************************************************
* Group: LIST CONSTRUCTIONS
************************************************************************)
(************************************************************************
* View: list
* Build a list of identical lenses separated with a given separator
* (at least 2 elements)
*
* Parameters:
* lns:lens - the lens to repeat in the list
* sep:lens - the separator lens, which can be taken from the <Sep> module
************************************************************************)
let list (lns:lens) (sep:lens) = lns . ( sep . lns )+
(************************************************************************
* View: opt_list
* Same as <list>, but there might be only one element in the list
*
* Parameters:
* lns:lens - the lens to repeat in the list
* sep:lens - the separator lens, which can be taken from the <Sep> module
************************************************************************)
let opt_list (lns:lens) (sep:lens) = lns . ( sep . lns )*
(************************************************************************
* Group: LABEL OPERATIONS
************************************************************************)
(************************************************************************
* View: xchg
* Replace a pattern with a different label in the tree,
* thus emulating a key but allowing to replace the keyword
* with a different value than matched
*
* Parameters:
* m:regexp - the pattern to match
* d:string - the default value when a node in created
* l:string - the label to apply for such nodes
************************************************************************)
let xchg (m:regexp) (d:string) (l:string) = del m d . label l
(************************************************************************
* View: xchgs
* Same as <xchg>, but the pattern is the default string
*
* Parameters:
* m:string - the string to replace, also used as default
* l:string - the label to apply for such nodes
************************************************************************)
let xchgs (m:string) (l:string) = xchg m m l
(************************************************************************
* Group: SUBNODE CONSTRUCTIONS
************************************************************************)
(************************************************************************
* View: key_value_line
* A subnode with a keyword, a separator and a storing lens,
* and an end of line
*
* Parameters:
* kw:regexp - the pattern to match as key
* sep:lens - the separator lens, which can be taken from the <Sep> module
* sto:lens - the storing lens
************************************************************************)
let key_value_line (kw:regexp) (sep:lens) (sto:lens) =
[ key kw . sep . sto . eol ]
(************************************************************************
* View: key_value_line_comment
* Same as <key_value_line>, but allows to have a comment in the end of a line
* and an end of line
*
* Parameters:
* kw:regexp - the pattern to match as key
* sep:lens - the separator lens, which can be taken from the <Sep> module
* sto:lens - the storing lens
* comment:lens - the comment lens, which can be taken from <Util>
************************************************************************)
let key_value_line_comment (kw:regexp) (sep:lens) (sto:lens) (comment:lens) =
[ key kw . sep . sto . (eol|comment) ]
(************************************************************************
* View: key_value
* Same as <key_value_line>, but does not end with an end of line
*
* Parameters:
* kw:regexp - the pattern to match as key
* sep:lens - the separator lens, which can be taken from the <Sep> module
* sto:lens - the storing lens
************************************************************************)
let key_value (kw: regexp) (sep:lens) (sto:lens) =
[ key kw . sep . sto ]
(************************************************************************
* View: key_ws_value
*
* Store a key/value pair where key and value are separated by whitespace
* and the value goes to the end of the line. Leading and trailing
* whitespace is stripped from the value. The end of line is consumed by
* this lens
*
* Parameters:
* kw:regexp - the pattern to match as key
************************************************************************)
let key_ws_value (kw:regexp) =
key_value_line kw Util.del_ws_spc (store Rx.space_in)
(************************************************************************
* View: flag
* A simple flag subnode, consisting of a single key
*
* Parameters:
* kw:regexp - the pattern to match as key
************************************************************************)
let flag (kw:regexp) = [ key kw ]
(************************************************************************
* View: flag_line
* A simple flag line, consisting of a single key
*
* Parameters:
* kw:regexp - the pattern to match as key
************************************************************************)
let flag_line (kw:regexp) = [ key kw . eol ]
(************************************************************************
* Group: BLOCK CONSTRUCTIONS
************************************************************************)
(************************************************************************
* View: block_generic
* A block enclosed in brackets
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should include <Util.empty>
* or its equivalent if necessary.
* entry_noindent:lens - the entry to be stored inside the block,
* without indentation.
* This entry should not include <Util.empty>
* entry_noeol:lens - the entry to be stored inside the block,
* without eol.
* This entry should not include <Util.empty>
* entry_noindent_noeol:lens - the entry to be stored inside the block,
* without indentation or eol.
* This entry should not include <Util.empty>
* comment:lens - the comment lens used in the block
* comment_noindent:lens - the comment lens used in the block,
* without indentation.
* ldelim_re:regexp - regexp for the left delimiter
* rdelim_re:regexp - regexp for the right delimiter
* ldelim_default:string - default value for the left delimiter
* rdelim_default:string - default value for the right delimiter
************************************************************************)
let block_generic
(entry:lens) (entry_noindent:lens)
(entry_noeol:lens) (entry_noindent_noeol:lens)
(comment:lens) (comment_noindent:lens)
(ldelim_re:regexp) (rdelim_re:regexp)
(ldelim_default:string) (rdelim_default:string) =
let block_single = entry_noindent_noeol | comment_noindent
in let block_start = entry_noindent | comment_noindent
in let block_middle = (entry | comment)*
in let block_end = entry_noeol | comment
in del ldelim_re ldelim_default
. ( ( block_start . block_middle . block_end )
| block_single )
. del rdelim_re rdelim_default
(************************************************************************
* View: block_setdefault
* A block enclosed in brackets
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should not include <Util.empty>,
* <Util.comment> or <Util.comment_noindent>,
* should not be indented or finish with an eol.
* ldelim_re:regexp - regexp for the left delimiter
* rdelim_re:regexp - regexp for the left delimiter
* ldelim_default:string - default value for the left delimiter
* rdelim_default:string - default value for the right delimiter
************************************************************************)
let block_setdelim (entry:lens)
(ldelim_re:regexp)
(rdelim_re:regexp)
(ldelim_default:string)
(rdelim_default:string) =
block_generic (Util.empty | Util.indent . entry . eol)
(entry . eol) (Util.indent . entry) entry
Util.comment Util.comment_noindent
ldelim_re rdelim_re
ldelim_default rdelim_default
(* Variable: block_ldelim_re *)
let block_ldelim_re = /[ \t\n]+\{[ \t\n]*/
(* Variable: block_rdelim_re *)
let block_rdelim_re = /[ \t\n]*\}/
(* Variable: block_ldelim_default *)
let block_ldelim_default = " {\n"
(* Variable: block_rdelim_default *)
let block_rdelim_default = "}"
(************************************************************************
* View: block
* A block enclosed in brackets
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should not include <Util.empty>,
* <Util.comment> or <Util.comment_noindent>,
* should not be indented or finish with an eol.
************************************************************************)
let block (entry:lens) = block_setdelim entry
block_ldelim_re block_rdelim_re
block_ldelim_default block_rdelim_default
(* Variable: block_ldelim_newlines_re *)
let block_ldelim_newlines_re = /[ \t\n]*\{([ \t\n]*\n)?/
(* Variable: block_rdelim_newlines_re *)
let block_rdelim_newlines_re = /[ \t]*\}/
(* Variable: block_ldelim_newlines_default *)
let block_ldelim_newlines_default = "\n{\n"
(* Variable: block_rdelim_newlines_default *)
let block_rdelim_newlines_default = "}"
(************************************************************************
* View: block_newline
* A block enclosed in brackets, with newlines forced
* and indentation defaulting to a tab.
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should not include <Util.empty>,
* <Util.comment> or <Util.comment_noindent>,
* should be indented and finish with an eol.
************************************************************************)
let block_newlines (entry:lens) (comment:lens) =
del block_ldelim_newlines_re block_ldelim_newlines_default
. ((entry | comment) . (Util.empty | entry | comment)*)?
. del block_rdelim_newlines_re block_rdelim_newlines_default
(************************************************************************
* View: block_newlines_spc
* A block enclosed in brackets, with newlines forced
* and indentation defaulting to a tab. The opening brace
* must be preceded by whitespace
*
* Parameters:
* entry:lens - the entry to be stored inside the block.
* This entry should not include <Util.empty>,
* <Util.comment> or <Util.comment_noindent>,
* should be indented and finish with an eol.
************************************************************************)
let block_newlines_spc (entry:lens) (comment:lens) =
del (/[ \t\n]/ . block_ldelim_newlines_re) block_ldelim_newlines_default
. ((entry | comment) . (Util.empty | entry | comment)*)?
. del block_rdelim_newlines_re block_rdelim_newlines_default
(************************************************************************
* View: named_block
* A named <block> enclosed in brackets
*
* Parameters:
* kw:regexp - the regexp for the block name
* entry:lens - the entry to be stored inside the block
* this entry should not include <Util.empty>
************************************************************************)
let named_block (kw:regexp) (entry:lens) = [ key kw . block entry . eol ]
(************************************************************************
* Group: COMBINATORICS
************************************************************************)
(************************************************************************
* View: combine_two_ord
* Combine two lenses, ensuring first lens is first
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
************************************************************************)
let combine_two_ord (a:lens) (b:lens) = a . b
(************************************************************************
* View: combine_two
* Combine two lenses
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
************************************************************************)
let combine_two (a:lens) (b:lens) =
combine_two_ord a b | combine_two_ord b a
(************************************************************************
* View: combine_two_opt_ord
* Combine two lenses optionally, ensuring first lens is first
* (a, and optionally b)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
************************************************************************)
let combine_two_opt_ord (a:lens) (b:lens) = a . b?
(************************************************************************
* View: combine_two_opt
* Combine two lenses optionally
* (either a, b, or both, in any order)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
************************************************************************)
let combine_two_opt (a:lens) (b:lens) =
combine_two_opt_ord a b | combine_two_opt_ord b a
(************************************************************************
* View: combine_three_ord
* Combine three lenses, ensuring first lens is first
* (a followed by either b, c, in any order)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
* c:lens - the third lens
************************************************************************)
let combine_three_ord (a:lens) (b:lens) (c:lens) =
combine_two_ord a (combine_two b c)
(************************************************************************
* View: combine_three
* Combine three lenses
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
* c:lens - the third lens
************************************************************************)
let combine_three (a:lens) (b:lens) (c:lens) =
combine_three_ord a b c
| combine_three_ord b a c
| combine_three_ord c b a
(************************************************************************
* View: combine_three_opt_ord
* Combine three lenses optionally, ensuring first lens is first
* (a followed by either b, c, or any of them, in any order)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
* c:lens - the third lens
************************************************************************)
let combine_three_opt_ord (a:lens) (b:lens) (c:lens) =
combine_two_opt_ord a (combine_two_opt b c)
(************************************************************************
* View: combine_three_opt
* Combine three lenses optionally
* (either a, b, c, or any of them, in any order)
*
* Parameters:
* a:lens - the first lens
* b:lens - the second lens
* c:lens - the third lens
************************************************************************)
let combine_three_opt (a:lens) (b:lens) (c:lens) =
combine_three_opt_ord a b c
| combine_three_opt_ord b a c
| combine_three_opt_ord c b a

View File

@ -0,0 +1,89 @@
(*
Module: Cachefilesd
Parses /etc/cachefilesd.conf
Author: Pat Riehecky <riehecky@fnal.gov>
About: Reference
This lens tries to keep as close as possible to `man 5 cachefilesd.conf` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
See <lns>.
About: Configuration files
This lens applies to /etc/cachefilesd.conf.
About: Examples
The <Test_Cachefilesd> file contains various examples and tests.
*)
module Cachefilesd =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Comments and empty lines *)
(* View: eol *)
let eol = Util.eol
(* View: comment *)
let comment = Util.comment
(* View: empty *)
let empty = Util.empty
(* Group: separators *)
(* View: space
* Separation between key and value
*)
let space = Util.del_ws_spc
(* View: colon
* Separation between selinux attributes
*)
let colon = Sep.colon
(* Group: entries *)
(* View: entry_key
* The key for an entry in the config file
*)
let entry_key = Rx.word
(* View: entry_value
* The value for an entry may contain all sorts of things
*)
let entry_value = /[A-Za-z0-9_.-:%]+/
(* View: nocull
* The nocull key has different syntax than the rest
*)
let nocull = /nocull/i
(* Group: config *)
(* View: cacheconfig
* This is a simple "key value" setup
*)
let cacheconfig = [ key (entry_key - nocull) . space
. store entry_value . eol ]
(* View: nocull
* This is a either present, and therefore active or missing and
* not active
*)
let nocull_entry = [ key nocull . eol ]
(* View: lns *)
let lns = (empty | comment | cacheconfig | nocull_entry)*
let xfm = transform lns (incl "/etc/cachefilesd.conf")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,54 @@
(*
Module: Carbon
Parses Carbon's configuration files
Author: Marc Fournier <marc.fournier@camptocamp.com>
About: Reference
This lens is based on the conf/*.conf.example files from the Carbon
package.
About: Configuration files
This lens applies to most files in /etc/carbon/. See <filter>.
NB: whitelist.conf and blacklist.conf use a different syntax. This lens
doesn't support them.
About: Usage Example
(start code)
$ augtool
augtool> ls /files/etc/carbon/carbon.conf/
cache/ = (none)
relay/ = (none)
aggregator/ = (none)
augtool> get /files/etc/carbon/carbon.conf/cache/ENABLE_UDP_LISTENER
/files/etc/carbon/carbon.conf/cache/ENABLE_UDP_LISTENER = False
augtool> set /files/etc/carbon/carbon.conf/cache/ENABLE_UDP_LISTENER True
augtool> save
Saved 1 file(s)
(end code)
The <Test_Carbon> file also contains various examples.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module Carbon =
autoload xfm
let comment = IniFile.comment "#" "#"
let sep = IniFile.sep "=" "="
let entry = IniFile.entry IniFile.entry_re sep comment
let title = IniFile.title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = incl "/etc/carbon/carbon.conf"
. incl "/etc/carbon/relay-rules.conf"
. incl "/etc/carbon/rewrite-rules.conf"
. incl "/etc/carbon/storage-aggregation.conf"
. incl "/etc/carbon/storage-schemas.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,26 @@
(* Ceph module for Augeas
Author: Pavel Chechetin <pchechetin@mirantis.com>
ceph.conf is a standard INI File with whitespaces in the title.
*)
module Ceph =
autoload xfm
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
let entry_re = /[A-Za-z0-9_.-][A-Za-z0-9 _.-]*[A-Za-z0-9_.-]/
let entry = IniFile.indented_entry entry_re sep comment
let title = IniFile.indented_title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/ceph/ceph.conf")
. (incl (Sys.getenv("HOME") . "/.ceph/config"))
let xfm = transform lns filter

View File

@ -0,0 +1,120 @@
(*
Module: cgconfig
Parses /etc/cgconfig.conf
Author:
Ivana Hutarova Varekova <varekova@redhat.com>
Raphael Pinson <raphink@gmail.com>
About: Licence
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* print all mounted cgroups
print /files/etc/cgconfig.conf/mount
About: Configuration files
This lens applies to /etc/cgconfig.conf. See <filter>.
*)
module Cgconfig =
autoload xfm
let indent = Util.indent
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let id = /[a-zA-Z0-9_\/.-]+/
let name = /[^#= \n\t{}\/]+/
let cont_name = /(cpuacct|cpu|devices|ns|cpuset|memory|freezer|net_cls|blkio|hugetlb|perf_event)/
let role_name = /(admin|task)/
let id_name = /(uid|gid|fperm|dperm)/
let address = /[^#; \n\t{}]+/
let qaddress = address|/"[^#;"\n\t{}]+"/
let lbracket = del /[ \t\n]*\{/ " {"
let rbracket = del /[ \t]*\}/ "}"
let eq = indent . Util.del_str "=" . indent
(******************************************
* Function to deal with abc=def; entries
******************************************)
let key_value (key_rx:regexp) (val_rx:regexp) =
[ indent . key key_rx . eq . store val_rx
. indent . Util.del_str ";" ]
(* Function to deal with bracketted entries *)
let brack_entry_base (lnsa:lens) (lnsb:lens) =
[ indent . lnsa . lbracket . lnsb . rbracket ]
let brack_entry_key (kw:regexp) (lns:lens) =
let lnsa = key kw in
brack_entry_base lnsa lns
let brack_entry (kw:regexp) (lns:lens) =
let full_lns = (lns | comment | empty)* in
brack_entry_key kw full_lns
(******************************************
* control groups
******************************************)
let permission_setting = key_value id_name address
(* task setting *)
let t_info = brack_entry "task" permission_setting
(* admin setting *)
let a_info = brack_entry "admin" permission_setting
(* permissions setting *)
let perm_info =
let ce = (comment|empty)* in
let perm_info_lns = ce .
((t_info . ce . (a_info . ce)?)
|(a_info . ce . (t_info . ce)?))? in
brack_entry_key "perm" perm_info_lns
let variable_setting = key_value name qaddress
(* controllers setting *)
let controller_info =
let lnsa = label "controller" . store cont_name in
let lnsb = ( variable_setting | comment | empty ) * in
brack_entry_base lnsa lnsb
(* group { ... } *)
let group_data =
let lnsa = key "group" . Util.del_ws_spc . store id in
let lnsb = ( perm_info | controller_info | comment | empty )* in
brack_entry_base lnsa lnsb
(*************************************************
* mount point
*************************************************)
(* controller = mount_point; *)
let mount_point = key_value name address
(* mount { .... } *)
let mount_data = brack_entry "mount" mount_point
(****************************************************
* namespace
****************************************************)
(* controller = cgroup; *)
let namespace_instance = key_value name address
(* namespace { .... } *)
let namespace = brack_entry "namespace" namespace_instance
let lns = ( comment | empty | mount_data | group_data | namespace )*
let xfm = transform lns (incl "/etc/cgconfig.conf")

View File

@ -0,0 +1,85 @@
(*
Module: cgrules
Parses /etc/cgrules.conf
Author:
Raphael Pinson <raphink@gmail.com>
Ivana Hutarova Varekova <varekova@redhat.com>
About: Licence
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool:
About: Configuration files
This lens applies to /etc/cgconfig.conf. See <filter>.
*)
module Cgrules =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Separators *)
(* Variable: ws *)
let ws = del /[ \t]+/ " "
(* Group: Comments and empty lines *)
(* Variable: eol *)
let eol = Util.eol
(* Variable: comment *)
let comment = Util.comment
(* Variable: empty *)
let empty = Util.empty
(* Group: Generic primitive definitions *)
(* Variable: name *)
let name = /[^@%# \t\n][^ \t\n]*/
(* Variable: ctrl_key *)
let ctrl_key = /[^ \t\n\/]+/
(* Variable: ctrl_value *)
let ctrl_value = /[^ \t\n]+/
(************************************************************************
* Group: CONTROLLER
*************************************************************************)
(* Variable: controller *)
let controller = ws . [ key ctrl_key . ws . store ctrl_value ]
let more_controller = Util.del_str "%" . controller . eol
(************************************************************************
* Group: RECORDS
*************************************************************************)
let generic_record (lbl:string) (lns:lens) =
[ label lbl . lns
. controller . eol
. more_controller* ]
(* Variable: user_record *)
let user_record = generic_record "user" (store name)
(* Variable: group_record *)
let group_record = generic_record "group" (Util.del_str "@" . store name)
(************************************************************************
* Group: LENS & FILTER
*************************************************************************)
(* View: lns
The main lens, any amount of
* <empty> lines
* <comment>
* <user_record>
* <group_record>
*)
let lns = ( empty | comment | user_record | group_record )*
let xfm = transform lns (incl "/etc/cgrules.conf")

View File

@ -0,0 +1,155 @@
(*
Module: Channels
Parses channels.conf files
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
See http://linuxtv.org/vdrwiki/index.php/Syntax_of_channels.conf
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to channels.conf files.
About: Examples
The <Test_Channels> file contains various examples and tests.
*)
module Channels =
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: eol *)
let eol = Util.eol
(* View: comment *)
let comment = Util.comment_generic /;[ \t]*/ "; "
(* View: equal *)
let equal = Sep.equal
(* View: colon *)
let colon = Sep.colon
(* View: comma *)
let comma = Sep.comma
(* View: semicol *)
let semicol = Util.del_str ";"
(* View: plus *)
let plus = Util.del_str "+"
(* View: arroba *)
let arroba = Util.del_str "@"
(* View: no_colon *)
let no_colon = /[^: \t\n][^:\n]*[^: \t\n]|[^:\n]/
(* View: no_semicolon *)
let no_semicolon = /[^;\n]+/
(************************************************************************
* Group: FUNCTIONS
*************************************************************************)
(* View: field
A generic field *)
let field (name:string) (sto:regexp) = [ label name . store sto ]
(* View: field_no_colon
A <field> storing <no_colon> *)
let field_no_colon (name:string) = field name no_colon
(* View: field_int
A <field> storing <Rx.integer> *)
let field_int (name:string) = field name Rx.integer
(* View: field_word
A <field> storing <Rx.word> *)
let field_word (name:string) = field name Rx.word
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: vpid *)
let vpid =
let codec =
[ equal . label "codec" . store Rx.integer ]
in let vpid_entry (lbl:string) =
[ label lbl . store Rx.integer . codec? ]
in vpid_entry "vpid"
. ( plus . vpid_entry "vpid_pcr" )?
(* View: langs *)
let langs =
let lang =
[ label "lang" . store Rx.word ]
in Build.opt_list lang plus
(* View: apid *)
let apid =
let codec =
[ arroba . label "codec" . store Rx.integer ]
in let options =
equal . ( (langs . codec?) | codec )
in let apid_entry (lbl:string) =
[ label lbl . store Rx.integer . options? ]
in Build.opt_list (apid_entry "apid") comma
. ( semicol
. Build.opt_list (apid_entry "apid_dolby") comma )?
(* View: tpid *)
let tpid =
let tpid_bylang =
[ label "tpid_bylang" . store Rx.integer
. (equal . langs)? ]
in field_int "tpid"
. ( semicol . Build.opt_list tpid_bylang comma )?
(* View: caid *)
let caid =
let caid_entry =
[ label "caid" . store Rx.word ]
in Build.opt_list caid_entry comma
(* View: entry *)
let entry = [ label "entry" . store no_semicolon
. (semicol . field_no_colon "provider")? . colon
. field_int "frequency" . colon
. field_word "parameter" . colon
. field_word "signal_source" . colon
. field_int "symbol_rate" . colon
. vpid . colon
. apid . colon
. tpid . colon
. caid . colon
. field_int "sid" . colon
. field_int "nid" . colon
. field_int "tid" . colon
. field_int "rid" . eol ]
(* View: entry_or_comment *)
let entry_or_comment = entry | comment
(* View: group *)
let group =
[ Util.del_str ":" . label "group"
. store no_colon . eol
. entry_or_comment* ]
(* View: lns *)
let lns = entry_or_comment* . group*

View File

@ -0,0 +1,408 @@
(*
Module: Chrony
Parses the chrony config file
Author: Pat Riehecky <riehecky@fnal.gov>
About: Reference
This lens tries to keep as close as possible to chrony config syntax
See http://chrony.tuxfamily.org/manual.html#Configuration-file
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to /etc/chrony.conf
See <filter>.
*)
module Chrony =
autoload xfm
(************************************************************************
* Group: Import provided expressions
************************************************************************)
(* View: empty *)
let empty = Util.empty
(* View: eol *)
let eol = Util.eol
(* View: space *)
let space = Sep.space
(* Variable: email_addr *)
let email_addr = Rx.email_addr
(* Variable: word *)
let word = Rx.word
(* Variable: integer *)
let integer = Rx.relinteger
(* Variable: decimal *)
let decimal = Rx.reldecimal
(* Variable: ip *)
let ip = Rx.ip
(* Variable: path *)
let path = Rx.fspath
(************************************************************************
* Group: Create required expressions
************************************************************************)
(* Variable: number *)
let number = integer | decimal | decimal . /[eE]/ . integer
(* Variable: address_re *)
let address_re = Rx.ip | Rx.hostname
(*
View: comment
from 4.2.1 of the upstream doc
Chrony comments start with: ! ; # or % and must be on their own line
*)
let comment = Util.comment_generic /[ \t]*[!;#%][ \t]*/ "# "
(* Variable: no_space
No spaces or comment characters
*)
let no_space = /[^ \t\r\n!;#%]+/
(* Variable: cmd_options
Server/Peer/Pool options with values
*)
let cmd_options = "asymmetry"
| "filter"
| "key"
| /maxdelay((dev)?ratio)?/
| /(min|max)poll/
| /(min|max)samples/
| "maxsources"
| "mindelay"
| "offset"
| "polltarget"
| "port"
| "presend"
| "version"
(* Variable: cmd_flags
Server/Peer/Pool options without values
*)
let cmd_flags = "auto_offline"|"iburst"|"noselect"|"offline"|"prefer"
|"require"|"trust"|"xleave"|"burst"|"nts"
(* Variable: ntp_source
Server/Peer/Pool key names
*)
let ntp_source = "server"|"peer"|"pool"
(* Variable: allowdeny_types
Key names for access configuration
*)
let allowdeny_types = "allow"|"deny"|"cmdallow"|"cmddeny"
(* Variable: hwtimestamp_options
HW timestamping options with values
*)
let hwtimestamp_options = "minpoll"|"precision"|"rxcomp"|"txcomp"
|"minsamples"|"maxsamples"|"rxfilter"
(* Variable: hwtimestamp_flags
HW timestamping options without values
*)
let hwtimestamp_flags = "nocrossts"
(* Variable: local_options
local options with values
*)
let local_options = "stratum"|"distance"
(* Variable: local_flags
local options without values
*)
let local_flags = "orphan"
(* Variable: ratelimit_options
Rate limiting options with values
*)
let ratelimit_options = "interval"|"burst"|"leak"
(* Variable: refclock_options
refclock options with values
*)
let refclock_options = "refid"|"lock"|"poll"|"dpoll"|"filter"|"rate"
|"minsamples"|"maxsamples"|"offset"|"delay"
|"precision"|"maxdispersion"|"stratum"|"width"
(* Variable: refclock_flags
refclock options without values
*)
let refclock_flags = "noselect"|"pps"|"prefer"|"require"|"tai"|"trust"
(* Variable: flags
Options without values
*)
let flags = "dumponexit"
| "generatecommandkey"
| "lock_all"
| "manual"
| "noclientlog"
| "nosystemcert"
| "rtconutc"
| "rtcsync"
(* Variable: log_flags
log has a specific options list
*)
let log_flags = "measurements"|"rawmeasurements"|"refclocks"|"rtc"
|"statistics"|"tempcomp"|"tracking"
(* Variable: simple_keys
Options with single values
*)
let simple_keys = "acquisitionport" | "authselectmode" | "bindacqaddress"
| "bindaddress" | "bindcmdaddress" | "bindacqdevice"
| "bindcmddevice" | "binddevice" | "clientloglimit"
| "clockprecision" | "combinelimit" | "commandkey"
| "cmdport" | "corrtimeratio" | "driftfile"
| "dscp"
| "dumpdir" | "hwclockfile" | "include" | "keyfile"
| "leapsecmode" | "leapsectz" | "linux_freq_scale"
| "linux_hz" | "logbanner" | "logchange" | "logdir"
| "maxclockerror" | "maxdistance" | "maxdrift"
| "maxjitter" | "maxsamples" | "maxslewrate"
| "maxntsconnections"
| "maxupdateskew" | "minsamples" | "minsources"
| "nocerttimecheck" | "ntsdumpdir" | "ntsntpserver"
| "ntsport" | "ntsprocesses" | "ntsrefresh" | "ntsrotate"
| "ntsservercert" | "ntsserverkey" | "ntstrustedcerts"
| "ntpsigndsocket" | "pidfile"
| "port" | "reselectdist" | "rtcautotrim" | "rtcdevice"
| "rtcfile" | "sched_priority" | "stratumweight" | "user"
(************************************************************************
* Group: Make some sub-lenses for use in later lenses
************************************************************************)
(* View: host_flags *)
let host_flags = [ space . key cmd_flags ]
(* View: host_options *)
let host_options = [ space . key cmd_options . space . store number ]
(* View: log_flag_list *)
let log_flag_list = [ space . key log_flags ]
(* View: store_address *)
let store_address = [ label "address" . store address_re ]
(************************************************************************
* Group: Lenses for parsing out sections
************************************************************************)
(* View: all_flags
options without any arguments
*)
let all_flags = [ Util.indent . key flags . eol ]
(* View: kv
options with only one arg can be directly mapped to key = value
*)
let kv = [ Util.indent . key simple_keys . space . (store no_space) . eol ]
(* Property: Options with multiple values
Each of these gets their own parsing block
- server|peer|pool <address> <options>
- allow|deny|cmdallow|cmddeny [all] [<address[/subnet]>]
- log <options>
- broadcast <interval> <address> <optional port>
- fallbackdrift <min> <max>
- hwtimestamp <interface> <options>
- initstepslew <threshold> <addr> <optional extra addrs>
- local <options>
- mailonchange <emailaddress> <threshold>
- makestep <threshold> <limit>
- maxchange <threshold> <delay> <limit>
- ratelimit|cmdratelimit|ntsratelimit <options>
- refclock <driver> <parameter> <options>
- smoothtime <maxfreq> <maxwander> <options>
- tempcomp <sensorfile> <interval> (<t0> <k0> <k1> <k2> | <pointfile> )
- confdir|sourcedir <directories>
*)
(* View: host_list
Find all NTP sources and their flags/options
*)
let host_list = [ Util.indent . key ntp_source
. space . store address_re
. ( host_flags | host_options )*
. eol ]
(* View: allowdeny
allow/deny/cmdallow/cmddeny has a specific syntax
*)
let allowdeny = [ Util.indent . key allowdeny_types
. [ space . key "all" ]?
. ( space . store ( no_space - "all" ) )?
. eol ]
(* View: log_list
log has a specific options list
*)
let log_list = [ Util.indent . key "log" . log_flag_list+ . eol ]
(* View: bcast
broadcast has specific syntax
*)
let bcast = [ Util.indent . key "broadcast"
. space . [ label "interval" . store integer ]
. space . store_address
. ( space . [ label "port" . store integer ] )?
. eol ]
(* View: bcast
confdir and sourcedir have specific syntax
*)
let dir_list = [ Util.indent . key /(conf|source)dir/
. [ label "directory" . space . store no_space ]+
. eol ]
(* View: fdrift
fallbackdrift has specific syntax
*)
let fdrift = [ Util.indent . key "fallbackdrift"
. space . [ label "min" . store integer ]
. space . [ label "max" . store integer ]
. eol ]
(* View: hwtimestamp
hwtimestamp has specific syntax
*)
let hwtimestamp = [ Util.indent . key "hwtimestamp"
. space . [ label "interface" . store no_space ]
. ( space . ( [ key hwtimestamp_flags ]
| [ key hwtimestamp_options . space
. store no_space ] )
)*
. eol ]
(* View: istepslew
initstepslew has specific syntax
*)
let istepslew = [ Util.indent . key "initstepslew"
. space . [ label "threshold" . store number ]
. ( space . store_address )+
. eol ]
(* View: local
local has specific syntax
*)
let local = [ Util.indent . key "local"
. ( space . ( [ key local_flags ]
| [ key local_options . space . store no_space ] )
)*
. eol ]
(* View: email
mailonchange has specific syntax
*)
let email = [ Util.indent . key "mailonchange" . space
. [ label "emailaddress" . store email_addr ]
. space
. [ label "threshold" . store number ]
. eol ]
(* View: makestep
makestep has specific syntax
*)
let makestep = [ Util.indent . key "makestep"
. space
. [ label "threshold" . store number ]
. space
. [ label "limit" . store integer ]
. eol ]
(* View: maxchange
maxchange has specific syntax
*)
let maxchange = [ Util.indent . key "maxchange"
. space
. [ label "threshold" . store number ]
. space
. [ label "delay" . store integer ]
. space
. [ label "limit" . store integer ]
. eol ]
(* View: ratelimit
ratelimit/cmdratelimit has specific syntax
*)
let ratelimit = [ Util.indent . key /(cmd|nts)?ratelimit/
. [ space . key ratelimit_options
. space . store no_space ]*
. eol ]
(* View: refclock
refclock has specific syntax
*)
let refclock = [ Util.indent . key "refclock"
. space
. [ label "driver" . store word ]
. space
. [ label "parameter" . store no_space ]
. ( space . ( [ key refclock_flags ]
| [ key refclock_options . space . store no_space ] )
)*
. eol ]
(* View: smoothtime
smoothtime has specific syntax
*)
let smoothtime = [ Util.indent . key "smoothtime"
. space
. [ label "maxfreq" . store number ]
. space
. [ label "maxwander" . store number ]
. ( space . [ key "leaponly" ] )?
. eol ]
(* View: tempcomp
tempcomp has specific syntax
*)
let tempcomp = [ Util.indent . key "tempcomp"
. space
. [ label "sensorfile" . store path ]
. space
. [ label "interval" . store number ]
. space
. ( [ label "t0" . store number ] . space
. [ label "k0" . store number ] . space
. [ label "k1" . store number ] . space
. [ label "k2" . store number ]
| [ label "pointfile" . store path ] )
. eol ]
(************************************************************************
* Group: Final lense summary
************************************************************************)
(* View: settings
* All supported chrony settings
*)
let settings = host_list | allowdeny | log_list | bcast | fdrift | istepslew
| local | email | makestep | maxchange | refclock | smoothtime
| dir_list | hwtimestamp | ratelimit | tempcomp | kv | all_flags
(*
* View: lns
* The crony lens
*)
let lns = ( empty | comment | settings )*
(* View: filter
* The files parsed by default
*)
let filter = incl "/etc/chrony.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,55 @@
(*
Module: ClamAV
Parses ClamAV clamd and freshclam configuration files.
Author: Andrew Colin Kissa <andrew@topdog.za.net>
Baruwa Enterprise Edition http://www.baruwa.com
About: License
This file is licensed under the LGPL v2+.
About: Configuration files
This lens applies to /etc/clamd.conf, /etc/freshclam.conf and files in
/etc/clamd.d. See <filter>.
*)
module Clamav =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
************************************************************************)
let word = /[A-Za-z][A-Za-z0-9]+/
let comment = Util.comment
let some_value = Sep.space . store Rx.space_in
(************************************************************************
* Group: Entry
************************************************************************)
let example_entry = [ key "Example" . Util.eol ]
let clamd_entry = [ key word . some_value . Util.eol ]
(******************************************************************
* Group: LENS AND FILTER
******************************************************************)
(************************************************************************
* View: Lns
************************************************************************)
let lns = (Util.empty | example_entry | clamd_entry | comment )*
(* Variable: filter *)
let filter = (incl "/etc/clamd.conf")
. (incl "/etc/freshclam.conf")
. (incl "/etc/clamd.d/*.conf")
. (incl "/etc/clamav/clamd.conf")
. (incl "/etc/clamav/freshclam.conf")
. (incl "/etc/clamav/clamd.d/*.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,21 @@
(*
Module: Cmdline
Parses /proc/cmdline and /etc/kernel/cmdline
Author: Thomas Weißschuh <thomas.weissschuh@amadeus.com>
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module Cmdline =
autoload xfm
let entry = [ key Rx.word . Util.del_str "=" . store Rx.no_spaces ] | [ key Rx.word ]
let lns = (Build.opt_list entry Sep.space)? . del /\n?/ ""
let filter = incl "/etc/kernel/cmdline"
. incl "/proc/cmdline"
let xfm = transform lns filter

View File

@ -0,0 +1,17 @@
module CobblerModules =
autoload xfm
let comment = IniFile.comment "#" "#"
let sep = IniFile.sep "=" "="
let entry = IniFile.entry IniFile.entry_re sep comment
let title = IniFile.indented_title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/cobbler/modules.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,72 @@
(*
Parse the /etc/cobbler/settings file which is in
YAML 1.0 format.
The lens can handle the following constructs
* key: value
* key: "value"
* key: 'value'
* key: [value1, value2]
* key:
- value1
- value2
* key:
key2: value1
key3: value2
Author: Bryan Kearney
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
*)
module CobblerSettings =
autoload xfm
let kw = /[a-zA-Z0-9_]+/
(* TODO Would be better if this stripped off the "" and '' characters *)
let kv = /([^]['", \t\n#:@-]+|"[^"\n]*"|'[^'\n]*')/
let lbr = del /\[/ "["
let rbr = del /\]/ "]"
let colon = del /[ \t]*:[ \t]*/ ": "
let dash = del /-[ \t]*/ "- "
(* let comma = del /,[ \t]*(\n[ \t]+)?/ ", " *)
let comma = del /[ \t]*,[ \t]*/ ", "
let eol_only = del /\n/ "\n"
(* TODO Would be better to make items a child of a document *)
let docmarker = /-{3}/
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let indent = del /[ \t]+/ "\t"
let ws = del /[ \t]*/ " "
let value_list = Build.opt_list [label "item" . store kv] comma
let setting = [key kw . colon . store kv] . eol
let simple_setting_suffix = store kv . eol
let setting_list_suffix = [label "sequence" . lbr . ws . (value_list . ws)? . rbr ] . eol
let indendented_setting_list_suffix = eol_only . (indent . setting)+
let indented_list_suffix = [label "list" . eol_only . ([ label "value" . indent . dash . store kv] . eol)+]
(* Break out setting because of a current bug in augeas *)
let nested_setting = [key kw . colon . (
(* simple_setting_suffix | *)
setting_list_suffix |
indendented_setting_list_suffix |
indented_list_suffix
)
]
let document = [label "---" . store docmarker] . eol
let lns = (document | comment | empty | setting | nested_setting )*
let xfm = transform lns (incl "/etc/cobbler/settings")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,36 @@
(*
Module: Collectd
Parses collectd configuration files
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 collectd.conf` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to collectd configuration files. See <filter>.
About: Examples
The <Test_Collectd> file contains various examples and tests.
*)
module Collectd =
autoload xfm
(* View: lns
Collectd is essentially Httpd-compliant configuration files *)
let lns = Httpd.lns
(* Variable: filter *)
let filter = incl "/etc/collectd.conf"
. incl "/etc/collectd/*.conf"
. incl "/usr/share/doc/collectd/examples/collection3/etc/collection.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,39 @@
(*
Module: CPanel
Parses cpanel.config
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens parses cpanel.config files
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to cpanel.config files. See <filter>.
About: Examples
The <Test_CPanel> file contains various examples and tests.
*)
module CPanel =
autoload xfm
(* View: kv
A key-value pair, supporting flags and empty values *)
let kv = [ key /[A-Za-z0-9:_.-]+/
. (Sep.equal . store (Rx.space_in?))?
. Util.eol ]
(* View: lns
The <CPanel> lens *)
let lns = (Util.comment | Util.empty | kv)*
(* View: filter *)
let filter = incl "/var/cpanel/cpanel.config"
let xfm = transform lns filter

View File

@ -0,0 +1,155 @@
(*
Module: Cron
Parses /etc/cron.d/*, /etc/crontab
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 crontab` where
possible.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* Get the entry that launches '/usr/bin/ls'
> match '/files/etc/crontab/entry[. = "/usr/bin/ls"]'
About: Configuration files
This lens applies to /etc/cron.d/* and /etc/crontab. See <filter>.
*)
module Cron =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Generic primitives *)
(* Variable: eol *)
let eol = Util.eol
(* Variable: indent *)
let indent = Util.indent
(* Variable: comment *)
let comment = Util.comment
(* Variable: empty *)
let empty = Util.empty
(* Variable: num *)
let num = /[0-9*][0-9\/,*-]*/
(* Variable: alpha *)
let alpha = /[A-Za-z]{3}/
(* Variable: alphanum *)
let alphanum = (num|alpha) . ("-" . (num|alpha))?
(* Variable: entry_prefix *)
let entry_prefix = /-/
(* Group: Separators *)
(* Variable: sep_spc *)
let sep_spc = Util.del_ws_spc
(* Variable: sep_eq *)
let sep_eq = Util.del_str "="
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(************************************************************************
* View: shellvar
* A shell variable in crontab
*************************************************************************)
let shellvar =
let key_re = /[A-Za-z1-9_-]+(\[[0-9]+\])?/ - "entry" in
let sto_to_eol = store /[^\n]*[^ \t\n]/ in
[ key key_re . sep_eq . sto_to_eol . eol ]
(* View: - prefix of an entry *)
let prefix = [ label "prefix" . store entry_prefix ]
(* View: minute *)
let minute = [ label "minute" . store num ]
(* View: hour *)
let hour = [ label "hour" . store num ]
(* View: dayofmonth *)
let dayofmonth = [ label "dayofmonth" . store num ]
(* View: month *)
let month = [ label "month" . store alphanum ]
(* View: dayofweek *)
let dayofweek = [ label "dayofweek" . store alphanum ]
(* View: user *)
let user = [ label "user" . store Rx.word ]
(************************************************************************
* View: time
* Time in the format "minute hour dayofmonth month dayofweek"
*************************************************************************)
let time = [ label "time" .
minute . sep_spc . hour . sep_spc . dayofmonth
. sep_spc . month . sep_spc . dayofweek ]
(* Variable: the valid values for schedules *)
let schedule_re = "reboot" | "yearly" | "annually" | "monthly"
| "weekly" | "daily" | "midnight" | "hourly"
(************************************************************************
* View: schedule
* Time in the format "@keyword"
*************************************************************************)
let schedule = [ label "schedule" . Util.del_str "@"
. store schedule_re ]
(************************************************************************
* View: entry
* A crontab entry
*************************************************************************)
let entry = [ label "entry" . indent
. prefix?
. ( time | schedule )
. sep_spc . user
. sep_spc . store Rx.space_in . eol ]
(*
* View: lns
* The cron lens
*)
let lns = ( empty | comment | shellvar | entry )*
(* Variable: filter *)
let filter =
incl "/etc/cron.d/*" .
incl "/etc/crontab" .
incl "/etc/crontabs/*" .
excl "/etc/cron.d/at.allow" .
excl "/etc/cron.d/at.deny" .
excl "/etc/cron.d/cron.allow" .
excl "/etc/cron.d/cron.deny" .
Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,46 @@
(*
Module: Cron_User
Parses /var/spool/cron/*
Author: David Lutterkort <lutter@watzmann.net>
About: Reference
This lens parses the user crontab files in /var/spool/cron. It produces
almost the same tree as the Cron.lns, except that it never contains a user
field.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* Get the entry that launches '/usr/bin/ls'
> match '/files/var/spool/cron/foo/entry[. = "/usr/bin/ls"]'
About: Configuration files
This lens applies to /var/spool/cron*. See <filter>.
*)
module Cron_User =
autoload xfm
(************************************************************************
* View: entry
* A crontab entry for a user's crontab
*************************************************************************)
let entry = [ label "entry" . Cron.indent
. Cron.prefix?
. ( Cron.time | Cron.schedule )
. Cron.sep_spc . store Rx.space_in . Cron.eol ]
(*
* View: lns
* The cron_user lens. Almost identical to Cron.lns
*)
let lns = ( Cron.empty | Cron.comment | Cron.shellvar | entry )*
let filter =
incl "/var/spool/cron/*" .
Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,108 @@
(*
Module: Crypttab
Parses /etc/crypttab from the cryptsetup package.
Author: Frédéric Lespez <frederic.lespez@free.fr>
About: Reference
This lens tries to keep as close as possible to `man crypttab` where possible.
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
Sample usage of this lens in augtool
* Create a new entry for an encrypted block devices
> ins 01 after /files/etc/crypttab/*[last()]
> set /files/etc/crypttab/01/target crypt_sda2
> set /files/etc/crypttab/01/device /dev/sda2
> set /files/etc/crypttab/01/password /dev/random
> set /files/etc/crypttab/01/opt swap
* Print the entry applying to the "/dev/sda2" device
> print /files/etc/crypttab/01
* Remove the entry applying to the "/dev/sda2" device
> rm /files/etc/crypttab/*[device="/dev/sda2"]
About: Configuration files
This lens applies to /etc/crypttab. See <filter>.
*)
module Crypttab =
autoload xfm
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Separators *)
(* Variable: sep_tab *)
let sep_tab = Sep.tab
(* Variable: comma *)
let comma = Sep.comma
(* Group: Generic primitives *)
(* Variable: eol *)
let eol = Util.eol
(* Variable: comment *)
let comment = Util.comment
(* Variable: empty *)
let empty = Util.empty
(* Variable: word *)
let word = Rx.word
(* Variable: optval *)
let optval = /[A-Za-z0-9\/_.:-]+/
(* Variable: target *)
let target = Rx.device_name
(* Variable: fspath *)
let fspath = Rx.fspath
(* Variable: uuid *)
let uuid = /UUID=[0-9a-f-]+/
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(************************************************************************
* View: comma_sep_list
* A comma separated list of options (opt=value or opt)
*************************************************************************)
let comma_sep_list (l:string) =
let value = [ label "value" . Util.del_str "=" . store optval ] in
let lns = [ label l . store word . value? ] in
Build.opt_list lns comma
(************************************************************************
* View: record
* A crypttab record
*************************************************************************)
let record = [ seq "entry" .
[ label "target" . store target ] . sep_tab .
[ label "device" . store (fspath|uuid) ] .
(sep_tab . [ label "password" . store fspath ] .
( sep_tab . comma_sep_list "opt")? )?
. eol ]
(*
* View: lns
* The crypttab lens
*)
let lns = ( empty | comment | record ) *
(* Variable: filter *)
let filter = (incl "/etc/crypttab")
let xfm = transform lns filter
(* coding: utf-8 *)

View File

@ -0,0 +1,51 @@
(*
Module: CSV
Generic CSV lens collection
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
About: Reference
https://tools.ietf.org/html/rfc4180
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
About: Examples
The <Test_CSV> file contains various examples and tests.
Caveats:
No support for files without an ending CRLF
*)
module CSV =
(* View: eol *)
let eol = Util.del_str "\n"
(* View: comment *)
let comment = Util.comment
| [ del /#[ \t]*\r?\n/ "#\n" ]
(* View: entry
An entry of fields, quoted or not *)
let entry (sep_str:string) =
let field = [ seq "field" . store (/[^"#\r\n]/ - sep_str)* ]
| [ seq "field" . store /("[^"#]*")+/ ]
in let sep = Util.del_str sep_str
in [ seq "entry" . counter "field" . Build.opt_list field sep . eol ]
(* View: lns
The generic lens, taking the separator as a parameter *)
let lns_generic (sep:string) = (comment | entry sep)*
(* View: lns
The comma-separated value lens *)
let lns = lns_generic ","
(* View: lns_semicol
A semicolon-separated value lens *)
let lns_semicol = lns_generic ";"

View File

@ -0,0 +1,27 @@
(*
Module: Cups
Parses cups configuration files
Author: Raphael Pinson <raphink@gmail.com>
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Examples
The <Test_Cups> file contains various examples and tests.
*)
module Cups =
autoload xfm
(* View: lns *)
let lns = Httpd.lns
(* Variable: filter *)
let filter = incl "/etc/cups/*.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,49 @@
(*
Cyrus_Imapd module for Augeas
Author: Free Ekanayaka <free@64studio.com>
*)
module Cyrus_Imapd =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let indent = del /[ \t]*(\n[ \t]+)?/ " "
let comment = Util.comment
let empty = Util.empty
let eq = del /[ \t]*:/ ":"
let word = /[A-Za-z0-9_.-]+/
(* The value of a parameter, after the '=' sign. Postfix allows that
* lines are continued by starting continuation lines with spaces.
* The definition needs to make sure we don't add indented comment lines
* into values *)
let value =
let chr = /[^# \t\n]/ in
let any = /.*/ in
let line = (chr . any* . chr | chr) in
let lines = line . (/\n[ \t]+/ . line)* in
store lines
(************************************************************************
* ENTRIES
*************************************************************************)
let entry = [ key word . eq . (indent . value)? . eol ]
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|entry) *
let filter = (incl "/etc/imapd.conf")
. (incl "/etc/imap/*.conf")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,29 @@
(* Darkice module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man 5 darkice.cfg
*)
module Darkice =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
let entry_re = ( /[A-Za-z0-9][A-Za-z0-9._-]*/ )
let entry = IniFile.entry entry_re sep comment
let title = IniFile.title_label "target" IniFile.record_label_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/darkice.cfg")
let xfm = transform lns filter

View File

@ -0,0 +1,131 @@
(*
Module: debctrl
Parses ./debian/control
Author:
Dominique Dumont domi.dumont@free.fr or dominique.dumont@hp.com
About: Reference
http://augeas.net/page/Create_a_lens_from_bottom_to_top
http://www.debian.org/doc/debian-policy/ch-controlfields.html
About: License
This file is licensed under the LGPL v2+.
About: Lens Usage
Since control file is not a system configuration file, you will have
to use augtool -r option to point to 'debian' directory.
Run augtool:
$ augtool -r debian
Sample usage of this lens in augtool:
* Get the value stored in control file
> print /files/control
...
Saving your file:
> save
*)
module Debctrl =
autoload xfm
let eol = Util.eol
let del_ws_spc = del /[\t ]*/ " "
let hardeol = del /\n/ "\n"
let del_opt_ws = del /[\t ]*/ ""
let colon = del /:[ \t]*/ ": "
let simple_entry (k:regexp) =
let value = store /[^ \t][^\n]+/ in
[ key k . colon . value . hardeol ]
let cont_line = del /\n[ \t]+/ "\n "
let comma = del /,[ \t]*/ ", "
let sep_comma_with_nl = del /[ \t\n]*,[ \t\n]*/ ",\n "
(*= del_opt_ws . cont_line* . comma . cont_line**)
let email = store ( /([A-Za-z]+ )+<[^\n>]+>/ | /[^\n,\t<> ]+/ )
let multi_line_array_entry (k:regexp) (v:lens) =
[ key k . colon . [ counter "array" . seq "array" . v ] .
[ seq "array" . sep_comma_with_nl . v ]* . hardeol ]
(* dependency stuff *)
let version_depends =
[ label "version"
. [ del / *\( */ " ( " . label "relation" . store /[<>=]+/ ]
. [ del_ws_spc . label "number"
. store ( /[a-zA-Z0-9_.-]+/ | /\$\{[a-zA-Z0-9:]+\}/ )
. del / *\)/ " )" ]
]
let arch_depends =
[ label "arch"
. [ del / *\[ */ " [ " . label "prefix" . store /!?/ ]
. [ label "name" . store /[a-zA-Z0-9_.-]+/ . del / *\]/ " ]" ] ]
let package_depends
= [ key ( /[a-zA-Z0-9_-]+/ | /\$\{[a-zA-Z0-9:]+\}/ )
. ( version_depends | arch_depends ) * ]
let dependency = [ label "or" . package_depends ]
. [ label "or" . del / *\| */ " | "
. package_depends ] *
let dependency_list (field:regexp) =
[ key field . colon . [ label "and" . dependency ]
. [ label "and" . sep_comma_with_nl . dependency ]*
. eol ]
(* source package *)
let uploaders =
multi_line_array_entry /Uploaders/ email
let simple_src_keyword = "Source" | "Section" | "Priority"
| "Standards\-Version" | "Homepage" | /Vcs\-Svn/ | /Vcs\-Browser/
| "Maintainer" | "DM-Upload-Allowed" | /XS?-Python-Version/
let depend_src_keywords = /Build\-Depends/ | /Build\-Depends\-Indep/
let src_entries = ( simple_entry simple_src_keyword
| uploaders
| dependency_list depend_src_keywords ) *
(* package paragraph *)
let multi_line_entry (k:string) =
let line = /.*[^ \t\n].*/ in
[ label k . del / / " " . store line . hardeol ] *
let description
= [ key "Description" . colon
. [ label "summary" . store /[a-zA-Z][^\n]+/ . hardeol ]
. multi_line_entry "text" ]
(* binary package *)
let simple_bin_keywords = "Package" | "Architecture" | "Section"
| "Priority" | "Essential" | "Homepage" | "XB-Python-Version"
let depend_bin_keywords = "Depends" | "Recommends" | "Suggests" | "Provides"
let bin_entries = ( simple_entry simple_bin_keywords
| dependency_list depend_bin_keywords
) + . description
(* The whole stuff *)
let lns = [ label "srcpkg" . src_entries ]
. [ label "binpkg" . hardeol+ . bin_entries ]+
. eol*
(* lens must be used with AUG_ROOT set to debian package source directory *)
let xfm = transform lns (incl "/control")

View File

@ -0,0 +1,53 @@
(*
Module: Desktop
Desktop module for Augeas (.desktop files)
Author: Raphael Pinson <raphink@gmail.com>
About: Lens Usage
This lens is made to provide a lens for .desktop files for augeas
Reference: Freedesktop.org
http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
*)
module Desktop =
(* We don't load this lens by default
Since a lot of desktop files contain unicode characters
which we can't parse *)
(* autoload xfm *)
(* Comments can be only of # type *)
let comment = IniFile.comment "#" "#"
(* TITLE
* These represents sections of a desktop file
* Example : [DesktopEntry]
*)
let title = IniFile.title IniFile.record_re
let sep = IniFile.sep "=" "="
let setting = /[A-Za-z0-9_.-]+([][@A-Za-z0-9_.-]+)?/
(* Variable: sto_to_comment
Store until comment *)
let sto_to_comment = Sep.opt_space . store /[^# \t\r\n][^#\r\n]*[^# \t\r\n]|[^# \t\r\n]/
(* Entries can have comments at their end and so they are modified to represent as such *)
let entry = [ key setting . sep . sto_to_comment? . (comment|IniFile.eol) ] | comment
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = ( incl "/usr/share/applications/*.desktop"
. incl "/usr/share/applications/screensavers/*.desktop" )
let xfm = transform lns filter

View File

@ -0,0 +1,24 @@
module DevfsRules =
autoload xfm
let comment = IniFile.comment IniFile.comment_re "#"
let eol = Util.eol
let line_re = /[^][#; \t\n][^#;\n]*[^#; \t\n]/
let entry = [ seq "entry" . store line_re . (eol | comment) ]
let title = Util.del_str "["
. key Rx.word . [ label "id" . Sep.equal . store Rx.integer ]
. Util.del_str "]" . eol
. counter "entry"
let record = IniFile.record title (entry | comment)
let lns = IniFile.lns record comment
let filter = incl "/etc/defaults/devfs.rules"
. incl "/etc/devfs.rules"
let xfm = transform lns filter

View File

@ -0,0 +1,28 @@
(* Parsing grub's device.map *)
module Device_map =
autoload xfm
let sep_tab = Sep.tab
let eol = Util.eol
let fspath = Rx.fspath
let del_str = Util.del_str
let comment = Util.comment
let empty = Util.empty
let dev_name = /(h|f|c)d[0-9]+(,[0-9a-zA-Z]+){0,2}/
let dev_hex = Rx.hex
let dev_dec = /[0-9]+/
let device = del_str "(" . key ( dev_name | dev_hex | dev_dec ) . del_str ")"
let map = [ device . sep_tab . store fspath . eol ]
let lns = ( empty | comment | map ) *
let xfm = transform lns (incl "/boot/*/device.map")
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,184 @@
(* Intefraces module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man dhclient.conf
The only difference with the reference syntax is that this lens assumes
that statements end with a new line, while the reference syntax allows
new statements to be started right after the trailing ";" of the
previous statement. This should not be a problem in real-life
configuration files as statements get usually split across several
lines, rather than merged in a single one.
*)
module Dhclient =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let comment = Util.comment
let comment_or_eol = Util.comment_or_eol
let empty = Util.empty
(* Define separators *)
let sep_spc = del /[ \t\n]+/ " "
let sep_scl = del /[ \t]*;/ ";"
let sep_obr = del /[ \t\n]*\{\n]*/ " {\n"
let sep_cbr = del /[ \t\n]*\}/ " }"
let sep_com = del /[ \t\n]*,[ \t\n]*/ ","
let sep_slh = del "\/" "/"
let sep_col = del ":" ":"
let sep_eq = del /[ \t]*=[ \t]*/ "="
(* Define basic types *)
let word = /[A-Za-z0-9_.-]+(\[[0-9]+\])?/
(* Define fields *)
(* TODO: there could be a " " in the middle of a value ... *)
let sto_to_spc = store /[^\\#,;{}" \t\n]+|"[^\\#"\n]+"/
let sto_to_spc_noeval = store /[^=\\#,;{}" \t\n]|[^=\\#,;{}" \t\n][^\\#,;{}" \t\n]*|"[^\\#"\n]+"/
let sto_to_scl = store /[^ \t\n][^;\n]+[^ \t]|[^ \t;\n]+/
let rfc_code = [ key "code" . sep_spc . store word ]
. sep_eq
. [ label "value" . sto_to_scl ]
let eval = [ label "#eval" . Sep.equal . sep_spc . sto_to_scl ]
let sto_number = store /[0-9][0-9]*/
(************************************************************************
* SIMPLE STATEMENTS
*************************************************************************)
let stmt_simple_re = "timeout"
| "retry"
| "select-timeout"
| "reboot"
| "backoff-cutoff"
| "initial-interval"
| "do-forward-updates"
| "reject"
let stmt_simple = [ key stmt_simple_re
. sep_spc
. sto_to_spc
. sep_scl
. comment_or_eol ]
(************************************************************************
* ARRAY STATEMENTS
*************************************************************************)
(* TODO: the array could also be empty, like in the request statement *)
let stmt_array_re = "media"
| "request"
| "require"
let stmt_array = [ key stmt_array_re
. sep_spc
. counter "stmt_array"
. [ seq "stmt_array" . sto_to_spc ]
. [ sep_com . seq "stmt_array" . sto_to_spc ]*
. sep_scl . comment_or_eol ]
(************************************************************************
* HASH STATEMENTS
*************************************************************************)
let stmt_hash_re = "send"
| "option"
let stmt_args = ( [ key word . sep_spc . sto_to_spc_noeval ]
| [ key word . sep_spc . (rfc_code|eval) ] )
. sep_scl
. comment_or_eol
let stmt_hash = [ key stmt_hash_re
. sep_spc
. stmt_args ]
let stmt_opt_mod_re = "append"
| "prepend"
| "default"
| "supersede"
let stmt_opt_mod = [ key stmt_opt_mod_re
. sep_spc
. stmt_args ]
(************************************************************************
* BLOCK STATEMENTS
*************************************************************************)
let stmt_block_re = "interface"
| "lease"
| "alias"
let stmt_block_opt_re = "interface"
| "script"
| "bootp"
| "fixed-address"
| "filename"
| "server-name"
| "medium"
| "vendor option space"
(* TODO: some options could take no argument like bootp *)
let stmt_block_opt = [ key stmt_block_opt_re
. sep_spc
. sto_to_spc
. sep_scl
. comment_or_eol ]
let stmt_block_date_re
= "renew"
| "rebind"
| "expire"
let stmt_block_date = [ key stmt_block_date_re
. [ sep_spc . label "weekday" . sto_number ]
. [ sep_spc . label "year" . sto_number ]
. [ sep_slh . label "month" . sto_number ]
. [ sep_slh . label "day" . sto_number ]
. [ sep_spc . label "hour" . sto_number ]
. [ sep_col . label "minute" . sto_number ]
. [ sep_col . label "second" . sto_number ]
. sep_scl
. comment_or_eol ]
let stmt_block_arg = sep_spc . sto_to_spc
let stmt_block_entry = sep_spc
. ( stmt_array
| stmt_hash
| stmt_opt_mod
| stmt_block_opt
| stmt_block_date )
let stmt_block = [ key stmt_block_re
. stmt_block_arg?
. sep_obr
. stmt_block_entry+
. sep_cbr
. comment_or_eol ]
(************************************************************************
* LENS & FILTER
*************************************************************************)
let statement = (stmt_simple|stmt_opt_mod|stmt_array|stmt_hash|stmt_block)
let lns = ( empty
| comment
| statement )*
let filter = incl "/etc/dhcp3/dhclient.conf"
. incl "/etc/dhcp/dhclient.conf"
. incl "/etc/dhclient.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,518 @@
(*
Module: Dhcpd
BIND dhcp 3 server configuration module for Augeas
Author: Francis Giraldeau <francis.giraldeau@usherbrooke.ca>
About: Reference
Reference: manual of dhcpd.conf and dhcp-eval
Follow dhclient module for tree structure
About: License
This file is licensed under the GPL.
About: Lens Usage
Sample usage of this lens in augtool
Directive without argument.
Set this dhcpd server authoritative on the domain.
> clear /files/etc/dhcp3/dhcpd.conf/authoritative
Directives with integer or string argument.
Set max-lease-time to one hour:
> set /files/etc/dhcp3/dhcpd.conf/max-lease-time 3600
Options are declared as a list, even for single values.
Set the domain of the network:
> set /files/etc/dhcp3/dhcpd.conf/option/domain-name/arg example.org
Set two name server:
> set /files/etc/dhcp3/dhcpd.conf/option/domain-name-servers/arg[1] foo.example.org
> set /files/etc/dhcp3/dhcpd.conf/option/domain-name-servers/arg[2] bar.example.org
Create the subnet 172.16.0.1 with 10 addresses:
> clear /files/etc/dhcp3/dhcpd.conf/subnet[last() + 1]
> set /files/etc/dhcp3/dhcpd.conf/subnet[last()]/network 172.16.0.0
> set /files/etc/dhcp3/dhcpd.conf/subnet[last()]/netmask 255.255.255.0
> set /files/etc/dhcp3/dhcpd.conf/subnet[last()]/range/from 172.16.0.10
> set /files/etc/dhcp3/dhcpd.conf/subnet[last()]/range/to 172.16.0.20
Create a new group "foo" with one static host. Nodes type and address are ordered.
> ins group after /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/*[last()]
> set /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/group[last()]/host foo
> set /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/group[host='foo']/host/hardware/type "ethernet"
> set /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/group[host='foo']/host/hardware/address "00:00:00:aa:bb:cc"
> set /files/etc/dhcp3/dhcpd.conf/subnet[network='172.16.0.0']/group[host='foo']/host/fixed-address 172.16.0.100
About: Configuration files
This lens applies to /etc/dhcpd3/dhcpd.conf. See <filter>.
*)
module Dhcpd =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let dels (s:string) = del s s
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let indent = Util.indent
let eos = comment?
(* Define separators *)
let sep_spc = del /[ \t]+/ " "
let sep_osp = del /[ \t]*/ ""
let sep_scl = del /[ \t]*;([ \t]*\n)*/ ";\n"
let sep_obr = del /[ \t\n]*\{([ \t]*\n)*/ " {\n"
let sep_cbr = del /[ \t]*\}([ \t]*\n)*/ "}\n"
let sep_com = del /[ \t\n]*,[ \t\n]*/ ", "
let sep_slh = del "\/" "/"
let sep_col = del ":" ":"
let sep_eq = del /[ \t\n]*=[ \t\n]*/ "="
let scl = del ";" ";"
(* Define basic types *)
let word = /[A-Za-z0-9_.-]+(\[[0-9]+\])?/
let ip = Rx.ipv4
(* Define fields *)
(* adapted from sysconfig.aug *)
(* Chars allowed in a bare string *)
let bchar = /[^ \t\n"'\\{}#,()\/]|\\\\./
let qchar = /["']/ (* " *)
(* We split the handling of right hand sides into a few cases:
* bare - strings that contain no spaces, optionally enclosed in
* single or double quotes
* dquot - strings that contain at least one space, apostrophe or slash
* which must be enclosed in double quotes
* squot - strings that contain an unescaped double quote
*)
let bare = del qchar? "" . store (bchar+) . del qchar? ""
let quote = Quote.do_quote (store (bchar* . /[ \t'\/]/ . bchar*)+)
let dquote = Quote.do_dquote (store (bchar+))
(* these two are for special cases. bare_to_scl is for any bareword that is
* space or semicolon terminated. dquote_any allows almost any character in
* between the quotes. *)
let bare_to_scl = Quote.do_dquote_opt (store /[^" \t\n;]+/)
let dquote_any = Quote.do_dquote (store /[^"\n]*[ \t]+[^"\n]*/)
let sto_to_spc = store /[^\\#,;\{\}" \t\n]+|"[^\\#"\n]+"/
let sto_to_scl = store /[^ \t;][^;\n=]+[^ \t;]|[^ \t;=]+/
let sto_number = store /[0-9][0-9]*/
(************************************************************************
* NO ARG STATEMENTS
*************************************************************************)
let stmt_noarg_re = "authoritative"
| "primary"
| "secondary"
let stmt_noarg = [ indent
. key stmt_noarg_re
. sep_scl
. eos ]
(************************************************************************
* INT ARG STATEMENTS
*************************************************************************)
let stmt_integer_re = "default-lease-time"
| "max-lease-time"
| "min-lease-time"
| /lease[ ]+limit/
| "port"
| /peer[ ]+port/
| "max-response-delay"
| "max-unacked-updates"
| "mclt"
| "split"
| /load[ ]+balance[ ]+max[ ]+seconds/
| "max-lease-misbalance"
| "max-lease-ownership"
| "min-balance"
| "max-balance"
| "adaptive-lease-time-threshold"
| "dynamic-bootp-lease-length"
| "local-port"
| "min-sec"
| "omapi-port"
| "ping-timeout"
| "remote-port"
let stmt_integer = [ indent
. key stmt_integer_re
. sep_spc
. sto_number
. sep_scl
. eos ]
(************************************************************************
* STRING ARG STATEMENTS
*************************************************************************)
let stmt_string_re = "ddns-update-style"
| "ddns-updates"
| "ddns-hostname"
| "ddns-domainname"
| "ddns-rev-domainname"
| "log-facility"
| "server-name"
| "fixed-address"
| /failover[ ]+peer/
| "use-host-decl-names"
| "next-server"
| "address"
| /peer[ ]+address/
| "type"
| "file"
| "algorithm"
| "secret"
| "key"
| "include"
| "hba"
| "boot-unknown-clients"
| "db-time-format"
| "do-forward-updates"
| "dynamic-bootp-lease-cutoff"
| "get-lease-hostnames"
| "infinite-is-reserved"
| "lease-file-name"
| "local-address"
| "one-lease-per-client"
| "pid-file-name"
| "ping-check"
| "server-identifier"
| "site-option-space"
| "stash-agent-options"
| "update-conflict-detection"
| "update-optimization"
| "update-static-leases"
| "use-host-decl-names"
| "use-lease-addr-for-default-route"
| "vendor-option-space"
| "primary"
| "omapi-key"
let stmt_string_tpl (kw:regexp) (l:lens) = [ indent
. key kw
. sep_spc
. l
. sep_scl
. eos ]
let stmt_string = stmt_string_tpl stmt_string_re bare
| stmt_string_tpl stmt_string_re quote
| stmt_string_tpl "filename" dquote
(************************************************************************
* RANGE STATEMENTS
*************************************************************************)
let stmt_range = [ indent
. key "range"
. sep_spc
. [ label "flag" . store /dynamic-bootp/ . sep_spc ]?
. [ label "from" . store ip . sep_spc ]?
. [ label "to" . store ip ]
. sep_scl
. eos ]
(************************************************************************
* HARDWARE STATEMENTS
*************************************************************************)
let stmt_hardware = [ indent
. key "hardware"
. sep_spc
. [ label "type" . store /ethernet|tokenring|fddi/ ]
. sep_spc
. [ label "address" . store /[a-fA-F0-9:-]+/ ]
. sep_scl
. eos ]
(************************************************************************
* SET STATEMENTS
*************************************************************************)
let stmt_set = [ indent
. key "set"
. sep_spc
. store word
. sep_spc
. Sep.equal
. sep_spc
. [ label "value" . sto_to_scl ]
. sep_scl
. eos ]
(************************************************************************
* OPTION STATEMENTS
*************************************************************************)
(* The general case is considering options as a list *)
let stmt_option_value = /((array of[ \t]+)?(((un)?signed[ \t]+)?integer (8|16|32)|string|ip6?-address|boolean|domain-list|text)|encapsulate [A-Za-z0-9_.-]+)/
let stmt_option_list = ([ label "arg" . bare ] | [ label "arg" . quote ])
. ( sep_com . ([ label "arg" . bare ] | [ label "arg" . quote ]))*
let del_trail_spc = del /[ \t\n]*/ ""
let stmt_record = counter "record" . Util.del_str "{"
. sep_spc
. ([seq "record" . store stmt_option_value . sep_com]*
. [seq "record" . store stmt_option_value . del_trail_spc])?
. Util.del_str "}"
let stmt_option_code = [ label "label" . store word . sep_spc ]
. [ key "code" . sep_spc . store word ]
. sep_eq
. ([ label "type" . store stmt_option_value ]
|[ label "record" . stmt_record ])
let stmt_option_basic = [ key word . sep_spc . stmt_option_list ]
let stmt_option_extra = [ key word . sep_spc . store /true|false/ . sep_spc . stmt_option_list ]
let stmt_option_body = stmt_option_basic | stmt_option_extra
let stmt_option1 = [ indent
. key "option"
. sep_spc
. stmt_option_body
. sep_scl
. eos ]
let stmt_option2 = [ indent
. dels "option" . label "rfc-code"
. sep_spc
. stmt_option_code
. sep_scl
. eos ]
let stmt_option = stmt_option1 | stmt_option2
(************************************************************************
* SUBCLASS STATEMENTS
*************************************************************************)
(* this statement is not well documented in the manual dhcpd.conf
we support basic use case *)
let stmt_subclass = [ indent . key "subclass" . sep_spc
. ( [ label "name" . bare_to_scl ]|[ label "name" . dquote_any ] )
. sep_spc
. ( [ label "value" . bare_to_scl ]|[ label "value" . dquote_any ] )
. sep_scl
. eos ]
(************************************************************************
* ALLOW/DENY STATEMENTS
*************************************************************************)
(* We have to use special key for allow/deny members of
to avoid ambiguity in the put direction *)
let allow_deny_re = /unknown(-|[ ]+)clients/
| /known(-|[ ]+)clients/
| /all[ ]+clients/
| /dynamic[ ]+bootp[ ]+clients/
| /authenticated[ ]+clients/
| /unauthenticated[ ]+clients/
| "bootp"
| "booting"
| "duplicates"
| "declines"
| "client-updates"
| "leasequery"
let stmt_secu_re = "allow"
| "deny"
let del_allow = del /allow[ ]+members[ ]+of/ "allow members of"
let del_deny = del /deny[ \t]+members[ \t]+of/ "deny members of"
(* bare is anything but whitespace, quote marks or semicolon.
* technically this should be locked down to mostly alphanumerics, but the
* idea right now is just to make things work. Also ideally I would use
* dquote_space but I had a whale of a time with it. It doesn't like
* semicolon termination and my attempts to fix that led me to 3 hours of
* frustration and back to this :)
*)
let stmt_secu_tpl (l:lens) (s:string) =
[ indent . l . sep_spc . label s . bare_to_scl . sep_scl . eos ] |
[ indent . l . sep_spc . label s . dquote_any . sep_scl . eos ]
let stmt_secu = [ indent . key stmt_secu_re . sep_spc .
store allow_deny_re . sep_scl . eos ] |
stmt_secu_tpl del_allow "allow-members-of" |
stmt_secu_tpl del_deny "deny-members-of"
(************************************************************************
* MATCH STATEMENTS
*************************************************************************)
let sto_com = /[^ \t\n,\(\)][^,\(\)]*[^ \t\n,\(\)]|[^ \t\n,\(\)]+/ | word . /[ \t]*\([^)]*\)/
(* this is already the most complicated part of this module and it's about to
* get worse. match statements can be way more complicated than this
*
* examples:
* using or:
* match if ((option vendor-class-identifier="Banana Bready") or (option vendor-class-identifier="Cherry Sunfire"));
* unneeded parenthesis:
* match if (option vendor-class-identifier="Hello");
*
* and of course the fact that the above two rules used one of infinately
* many potential options instead of a builtin function.
*)
(* sto_com doesn't support quoted strings as arguments. It also doesn't
support single arguments (needs to match a comma) It will need to be
updated for lcase, ucase and log to be workable.
it also doesn't support no arguments, so gethostbyname() doesn't work.
option and config-option are considered operators. They should be matched
in stmt_entry but also available under "match if" and "if" conditionals
leased-address, host-decl-name, both take no args and return a value. We
might need to treat them as variable names in the parser.
things like this may be near-impossible to parse even with recursion
because we have no way of knowing when or if a subfunction takes arguments
set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
even if we could parse it, they could get arbitrarily complicated like:
binary-to-ascii(16, 8, ":", substring(hardware, 1, 6) and substring(hardware, 2, 3));
so at some point we may need to programmatically knock it off and tell
people to put weird stuff in an include file that augeas doesn't parse.
the other option is to change the API to not parse the if statement at all,
just pull in the conditional as a string.
*)
let fct_re = "substring" | "binary-to-ascii" | "suffix" | "lcase" | "ucase"
| "gethostbyname" | "packet"
| "concat" | "reverse" | "encode-int"
| "extract-int" | "lease-time" | "client-state" | "exists" | "known" | "static"
| "pick-first-value" | "log" | "execute"
(* not needs to be different because it's a negation of whatever happens next *)
let op_re = "~="|"="|"~~"|"and"|"or"
let fct_args = [ label "args" . dels "(" . sep_osp .
([ label "arg" . store sto_com ] . [ label "arg" . sep_com . store sto_com ]+) .
sep_osp . dels ")" ]
let stmt_match_ifopt = [ dels "if" . sep_spc . key "option" . sep_spc . store word .
sep_eq . ([ label "value" . bare_to_scl ]|[ label "value" . dquote_any ]) ]
let stmt_match_func = [ store fct_re . sep_osp . label "function" . fct_args ] .
sep_eq . ([ label "value" . bare_to_scl ]|[ label "value" . dquote_any ])
let stmt_match_pfv = [ label "function" . store "pick-first-value" . sep_spc .
dels "(" . sep_osp .
[ label "args" .
[ label "arg" . store sto_com ] .
[ sep_com . label "arg" . store sto_com ]+ ] .
dels ")" ]
let stmt_match_tpl (l:lens) = [ indent . key "match" . sep_spc . l . sep_scl . eos ]
let stmt_match = stmt_match_tpl (dels "if" . sep_spc . stmt_match_func | stmt_match_pfv | stmt_match_ifopt)
(************************************************************************
* BLOCK STATEMENTS
*************************************************************************)
(* Blocks doesn't support comments at the end of the closing bracket *)
let stmt_entry = stmt_secu
| stmt_option
| stmt_hardware
| stmt_range
| stmt_string
| stmt_integer
| stmt_noarg
| stmt_match
| stmt_subclass
| stmt_set
| empty
| comment
let stmt_block_noarg_re = "pool" | "group"
let stmt_block_noarg (body:lens)
= [ indent
. key stmt_block_noarg_re
. sep_obr
. body*
. sep_cbr ]
let stmt_block_arg_re = "host"
| "class"
| "shared-network"
| /failover[ ]+peer/
| "zone"
| "group"
| "on"
let stmt_block_arg (body:lens)
= ([ indent . key stmt_block_arg_re . sep_spc . dquote_any . sep_obr . body* . sep_cbr ]
|[ indent . key stmt_block_arg_re . sep_spc . bare_to_scl . sep_obr . body* . sep_cbr ]
|[ indent . del /key/ "key" . label "key_block" . sep_spc . dquote_any . sep_obr . body* . sep_cbr . del /(;([ \t]*\n)*)?/ "" ]
|[ indent . del /key/ "key" . label "key_block" . sep_spc . bare_to_scl . sep_obr . body* . sep_cbr . del /(;([ \t]*\n)*)?/ "" ])
let stmt_block_subnet (body:lens)
= [ indent
. key "subnet"
. sep_spc
. [ label "network" . store ip ]
. sep_spc
. [ key "netmask" . sep_spc . store ip ]
. sep_obr
. body*
. sep_cbr ]
let conditional (body:lens) =
let condition = /[^{ \r\t\n][^{\n]*[^{ \r\t\n]|[^{ \t\n\r]/
in let elsif = [ indent
. Build.xchgs "elsif" "@elsif"
. sep_spc
. store condition
. sep_obr
. body*
. sep_cbr ]
in let else = [ indent
. Build.xchgs "else" "@else"
. sep_obr
. body*
. sep_cbr ]
in [ indent
. Build.xchgs "if" "@if"
. sep_spc
. store condition
. sep_obr
. body*
. sep_cbr
. elsif*
. else? ]
let all_block (body:lens) =
let lns1 = stmt_block_subnet body in
let lns2 = stmt_block_arg body in
let lns3 = stmt_block_noarg body in
let lns4 = conditional body in
(lns1 | lns2 | lns3 | lns4 | stmt_entry)
let rec lns_staging = stmt_entry|all_block lns_staging
let lns = (lns_staging)*
let filter = incl "/etc/dhcp3/dhcpd.conf"
. incl "/etc/dhcp/dhcpd.conf"
. incl "/etc/dhcpd.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,113 @@
(*
Module: Dns_Zone
Lens for parsing DNS zone files
Authors:
Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
About: Reference
RFC 1035, RFC 2782, RFC 3403
About: License
This file is licensed under the LGPL v2+
*)
module Dns_Zone =
autoload xfm
let eol = del /([ \t\n]*(;[^\n]*)?\n)+/ "\n"
let opt_eol = del /([ \t\n]*(;[^\n]*)?\n)*/ ""
let ws = del /[ \t]+|(([ \t\n]*;[^\n]*)?\n)+[ \t]*/ " "
let opt_ws = del /(([ \t\n]*;[^\n]*)?\n)*[ \t]*/ ""
let token = /([^ \t\n";()\\]|\\\\.)+|"([^"\\]|\\\\.)*"/
let control = [ key /\$[^ \t\n\/]+/
. Util.del_ws_tab
. store token
. eol ]
let labeled_token (lbl:string) (re:regexp) (sep:lens) =
[ label lbl . store re . sep ]
let regexp_token (lbl:string) (re:regexp) =
labeled_token lbl re Util.del_ws_tab
let type_token (re:regexp) = regexp_token "type" re
let simple_token (lbl:string) = regexp_token lbl token
let enclosed_token (lbl:string) = labeled_token lbl token ws
let last_token (lbl:string) = labeled_token lbl token eol
let class_re = /IN/
let ttl = regexp_token "ttl" /[0-9]+[DHMWdhmw]?/
let class = regexp_token "class" class_re
let rr =
let simple_type = /[A-Z]+/ - class_re - /MX|NAPTR|SOA|SRV/
in type_token simple_type . last_token "rdata"
let mx = type_token "MX"
. simple_token "priority"
. last_token "exchange"
let naptr = type_token "NAPTR"
. simple_token "order"
. simple_token "preference"
. simple_token "flags"
. simple_token "service"
. simple_token "regexp"
. last_token "replacement"
let soa = type_token "SOA"
. simple_token "mname"
. simple_token "rname"
. Util.del_str "("
. opt_ws
. enclosed_token "serial"
. enclosed_token "refresh"
. enclosed_token "retry"
. enclosed_token "expiry"
. labeled_token "minimum" token opt_ws
. Util.del_str ")"
. eol
let srv = type_token "SRV"
. simple_token "priority"
. simple_token "weight"
. simple_token "port"
. last_token "target"
let record = seq "owner"
. ((ttl? . class?) | (class . ttl))
. (rr|mx|naptr|soa|srv)
let ws_record = [ Util.del_ws_tab . record ]
let records (k:regexp) = [ key k . counter "owner" . ws_record+ ]
let any_record_block = records /[^ \t\n;\/$][^ \t\n;\/]*/
let non_root_records = records /@[^ \t\n;\/]+|[^ \t\n;\/$@][^ \t\n;\/]*/
let root_records = [ del /@?/ "@"
. Util.del_ws_tab
. label "@"
. counter "owner"
. [ record ]
. ws_record* ]
let lns = opt_eol
. control*
. ( (root_records|non_root_records)
. (control|any_record_block)* )?
let filter = incl "/var/bind/pri/*.zone"
let xfm = transform Dns_Zone.lns filter

View File

@ -0,0 +1,62 @@
(* Dnsmasq module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man dnsmasq (8)
"Format is one option per line, legal options are the same
as the long options legal on the command line. See
"/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details."
*)
module Dnsmasq =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let spc = Util.del_ws_spc
let comment = Util.comment
let empty = Util.empty
let sep_eq = Sep.equal
let sto_to_eol = store /([^ \t\n].*[^ \t\n]|[^ \t\n])/
let slash = Util.del_str "/"
let sto_no_slash = store /([^\/ \t\n]+)/
let domains = slash . [ label "domain" . sto_no_slash . slash ]+
(************************************************************************
* SIMPLE ENTRIES
*************************************************************************)
let entry_re = Rx.word - /(address|server)/
let entry = [ key entry_re . (sep_eq . sto_to_eol)? . eol ]
(************************************************************************
* STRUCTURED ENTRIES
*************************************************************************)
let address = [ key "address" . sep_eq . domains . sto_no_slash . eol ]
let server =
let port = [ Build.xchgs "#" "port" . store Rx.integer ]
in let source = [ Build.xchgs "@" "source" . store /[^#\/ \t\n]+/ . port? ]
in let srv_spec = store /(#|([^#@\/ \t\n]+))/ . port? . source?
in [ key "server" . sep_eq . domains? . srv_spec? . eol ]
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|address|server|entry) *
let filter = incl "/etc/dnsmasq.conf"
. incl "/etc/dnsmasq.d/*"
. excl ".*"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,135 @@
(*
Module: Dovecot
Parses dovecot configuration files.
Author: Serge Smetana <serge.smetana@gmail.com>
Acunote http://www.acunote.com
Pluron, Inc. http://pluron.com
About: License
This file is licensed under the LGPL v2+.
About: Configuration files
This lens applies to /etc/dovecot/dovecot.conf and files in
/etc/dovecot/conf.d/. See <filter>.
About: Examples
The <Test_Dovecot> file contains various examples and tests.
About: TODO
Support for multiline values like queries in dict-sql.conf
*)
module Dovecot =
autoload xfm
(******************************************************************
* Group: USEFUL PRIMITIVES
******************************************************************)
(* View: indent *)
let indent = Util.indent
(* View: eol *)
let eol = Util.eol
(* View: empty
Map empty lines. *)
let empty = Util.empty
(* View: comment
Map comments in "#comment" nodes. *)
let comment = Util.comment
(* View: eq *)
let eq = del /[ \t]*=/ " ="
(* Variable: any *)
let any = Rx.no_spaces
(* Variable: value
Match any value after " =".
Should not start and end with spaces. May contain spaces inside *)
let value = any . (Rx.space . any)*
(* View: command_start *)
let command_start = Util.del_str "!"
(******************************************************************
* Group: ENTRIES
******************************************************************)
(* Variable: commands *)
let commands = /include|include_try/
(* Variable: block_names *)
let block_names = /dict|userdb|passdb|protocol|service|plugin|namespace|map|fields|unix_listener|fifo_listener|inet_listener/
(* Variable: keys
Match any possible key except commands and block names. *)
let keys = Rx.word - (commands | block_names)
(* View: entry
Map simple "key = value" entries including "key =" entries with empty value. *)
let entry = [ indent . key keys. eq . (Sep.opt_space . store value)? . eol ]
(* View: command
Map commands started with "!". *)
let command = [ command_start . key commands . Sep.space . store Rx.fspath . eol ]
(*
View: dquote_spaces
Make double quotes mandatory if value contains spaces,
and optional if value doesn't contain spaces.
Based off Quote.dquote_spaces
Parameters:
lns1:lens - the lens before
lns2:lens - the lens after
*)
let dquote_spaces (lns1:lens) (lns2:lens) =
(* bare has no spaces, and is optionally quoted *)
let bare = Quote.do_dquote_opt (store /[^" \t\n]+/)
(* quoted has at least one space, and must be quoted *)
in let quoted = Quote.do_dquote (store /[^"\n]*[ \t]+[^"\n]*/)
in [ lns1 . bare . lns2 ] | [ lns1 . quoted . lns2 ]
let mailbox = indent
. dquote_spaces
(key /mailbox/ . Sep.space)
(Build.block_newlines_spc entry comment . eol)
let block_ldelim_newlines_re = /[ \t]+\{([ \t\n]*\n)?/
let block_newlines (entry:lens) (comment:lens) =
let indent = del Rx.opt_space "\t"
in del block_ldelim_newlines_re Build.block_ldelim_default
. ((entry | comment) . (Util.empty | entry | comment)*)?
. del Build.block_rdelim_newlines_re Build.block_rdelim_newlines_default
(* View: block
Map block enclosed in brackets recursively.
Block may be indented and have optional argument.
Block body may have entries, comments, empty lines, and nested blocks recursively. *)
let rec block = [ indent . key block_names . (Sep.space . Quote.do_dquote_opt (store /!?[\/A-Za-z0-9_-]+/))? . block_newlines (entry|block|mailbox) comment . eol ]
(******************************************************************
* Group: LENS AND FILTER
******************************************************************)
(* View: lns
The Dovecot lens *)
let lns = (comment|empty|entry|command|block)*
(* Variable: filter *)
let filter = incl "/etc/dovecot/dovecot.conf"
. (incl "/etc/dovecot/conf.d/*.conf")
. incl "/usr/local/etc/dovecot/dovecot.conf"
. (incl "/usr/local/etc/dovecot/conf.d/*.conf")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,91 @@
(*
Module: Dpkg
Parses /etc/dpkg/dpkg.cfg
Author: Robin Lee Powell <rlpowell@digitalkingdom.org>
About: License
This file, and the attendant test_dpgk.aug, are explicitly
placed in the public domain.
About: Description
dpkg.cfg is a simple list of options, the same ones as the
command line options, with or without a value.
The tree is a list of either comments or option/value pairs by
name. Use "set" to set an option with a value, and "clear" for a
bare option.
About: Usage Example
(start code)
$ augtool -n
augtool> ls /files/etc/dpkg/dpkg.cfg
#comment[1] = dpkg configuration file
#comment[2] = This file can contain default options for dpkg. All command-line
#comment[3] = options are allowed. Values can be specified by putting them after
#comment[4] = the option, separated by whitespace and/or an `=' sign.
#comment[5] = Do not enable debsig-verify by default; since the distribution is not using
#comment[6] = embedded signatures, debsig-verify would reject all packages.
no-debsig = (none)
#comment[7] = Log status changes and actions to a file.
log = /var/log/dpkg.log
augtool> get /files/etc/dpkg/dpkg.cfg/no-debsig
/files/etc/dpkg/dpkg.cfg/no-debsig (none)
augtool> get /files/etc/dpkg/dpkg.cfg/log
/files/etc/dpkg/dpkg.cfg/log = /var/log/dpkg.log
augtool> clear /files/etc/dpkg/dpkg.cfg/testopt
augtool> set /files/etc/dpkg/dpkg.cfg/testopt2 test
augtool> save
Saved 1 file(s)
augtool>
$ cat /etc/dpkg/dpkg.cfg.augnew
# dpkg configuration file
#
# This file can contain default options for dpkg. All command-line
# options are allowed. Values can be specified by putting them after
# the option, separated by whitespace and/or an `=' sign.
#
# Do not enable debsig-verify by default; since the distribution is not using
# embedded signatures, debsig-verify would reject all packages.
no-debsig
# Log status changes and actions to a file.
log /var/log/dpkg.log
testopt
testopt2 test
(end code)
*)
module Dpkg =
autoload xfm
let sep_tab = Util.del_ws_tab
let sep_spc = Util.del_ws_spc
let eol = del /[ \t]*\n/ "\n"
let comment = Util.comment
let empty = Util.empty
let word = /[^,# \n\t]+/
let keyword = /[^,# \n\t\/]+/
(* View: record
Keyword, followed by optional whitespace and value, followed
by EOL.
The actual file specification doesn't require EOL, but the
likelihood of the file not having one is pretty slim, and
this way things we add have EOL.
*)
let record = [ key keyword . (sep_spc . store word)? . eol ]
(* View: lns
Any number of empty lines, comments, and records.
*)
let lns = ( empty | comment | record ) *
let xfm = transform lns (incl "/etc/dpkg/dpkg.cfg")

View File

@ -0,0 +1,68 @@
(* Dput module for Augeas
Author: Raphael Pinson <raphink@gmail.com>
Reference: dput uses Python's ConfigParser:
http://docs.python.org/lib/module-ConfigParser.html
*)
module Dput =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
let setting = "allow_dcut"
| "allow_non-us_software"
| "allow_unsigned_uploads"
| "check_version"
| "default_host_main"
| "default_host_non-us"
| "fqdn"
| "hash"
| "incoming"
| "login"
| "method"
| "passive_ftp"
| "post_upload_command"
| "pre_upload_command"
| "progress_indicator"
| "run_dinstall"
| "run_lintian"
| "scp_compress"
| "ssh_config_options"
| "allowed_distributions"
(************************************************************************
* "name: value" entries, with continuations in the style of RFC 822;
* "name=value" is also accepted
* leading whitespace is removed from values
*************************************************************************)
let entry = IniFile.entry setting sep comment
(************************************************************************
* sections, led by a "[section]" header
* We can't use titles as node names here since they could contain "/"
* We remove #comment from possible keys
* since it is used as label for comments
* We also remove / as first character
* because augeas doesn't like '/' keys (although it is legal in INI Files)
*************************************************************************)
let title = IniFile.title_label "target" IniFile.record_label_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/dput.cf")
. (incl (Sys.getenv("HOME") . "/.dput.cf"))
let xfm = transform lns filter

View File

@ -0,0 +1,196 @@
(*
Module: Erlang
Parses Erlang configuration files
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
About: Reference
This lens tries to keep as close as possible to `http://www.erlang.org/doc/man/config.html` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to Erlang configuration files. See <filter>.
About: Examples
The <Test_Erlang> file contains various examples and tests.
*)
module Erlang =
(* Group: Spacing Functions *)
(* View: space *)
let space = del /[ \t\n]*/ ""
(* View: lspace
Add spaces to the left of char *)
let lspace (char:string) = del (/[ \t\n]*/ . char) char
(* View: rspace
Add spaces to the right of char *)
let rspace (char:string) = del (char . /[ \t\n]*/ ) char
(* View: lrspace
Add spaces to the left or right of char *)
let lrspace (char:string) = del (/[ \t\n]*/ . char . /[ \t\n]*/ ) char
(* Group: Separators *)
(* Variable: lbrace
Left square bracket *)
let lbrace = "{"
(* Variable: rbrace
Right square bracket *)
let rbrace = "}"
(* Variable: lbrack
Left curly brackets *)
let lbrack = "["
(* Variable: rbrack
Right curly brackets *)
let rbrack = "]"
(* Variable: lglob
Left glob separator *)
let lglob = "<<\""
(* Variable: rglob
Right glob separator *)
let rglob = "\">>"
(* Variable: comma *)
let comma = ","
(* Group: Value types *)
(* View: opt_list
An optional list of elements, in square brackets *)
let opt_list (lns:lens) = rspace lbrack
. (Build.opt_list lns (lrspace comma) . space)?
. Util.del_str rbrack
(* View: integer
Store a <Rx.integer> *)
let integer = store Rx.integer
(* View: decimal
Store a decimal value *)
let decimal = store /[0-9]+(.[0-9]+)?/
(* View: quoted
Store a quoted value *)
let quoted = Quote.do_quote (store /[^,\n}{]+/)
(* View: bare
Store a bare <Rx.word> *)
let bare = store Rx.word
(* View: boolean
Store a boolean value *)
let boolean = store /true|false/
(* View: path
Store a path (<quoted>) *)
let path = quoted
(* View: glob
Store a glob *)
let glob = Util.del_str lglob . store /[^\n"]+/ . Util.del_str rglob
(* View: make_value
Make a "value" subnode for arrays/tuples *)
let make_value (lns:lens) = [ label "value" . lns ]
(* Group: Store types *)
(* View: value
A single value *)
let value (kw:regexp) (sto:lens) =
[ rspace lbrace
. key kw
. lrspace comma
. sto
. lspace rbrace ]
(* View: tuple
A tuple of values *)
let tuple (one:lens) (two:lens) =
[ rspace lbrace
. label "tuple"
. [ label "value" . one ]
. lrspace comma
. [ label "value" . two ]
. lspace rbrace ]
(* View: tuple3
A tuple of 3 values *)
let tuple3 (one:lens) (two:lens) (three:lens) =
[ rspace lbrace
. label "tuple"
. [ label "value" . one ]
. lrspace comma
. [ label "value" . two ]
. lrspace comma
. [ label "value" . three ]
. lspace rbrace ]
(* View: list
A list of lenses *)
let list (kw:regexp) (lns:lens) =
[ rspace lbrace
. key kw
. lrspace comma
. opt_list lns
. lspace rbrace ]
(* View: value_list
A <list> of seq entries *)
let value_list (kw:regexp) (sto:lens) =
list kw (make_value sto)
(* View: application *)
let application (name:regexp) (parameter:lens) =
list name parameter
(* View: kernel_parameters
Config parameters accepted for kernel app *)
let kernel_parameters =
value "browser_cmd" path
| value "dist_auto_connect" (store /never|once/)
| value "error_logger" (store /tty|false|silent/)
| value "net_setuptime" integer
| value "net_ticktime" integer
| value "shutdown_timeout" integer
| value "sync_nodes_timeout" integer
| value "start_dist_ac" boolean
| value "start_boot_server" boolean
| value "start_disk_log" boolean
| value "start_pg2" boolean
| value "start_timer" boolean
(* View: kernel
Core Erlang kernel app configuration *)
let kernel = application "kernel" kernel_parameters
(* View: comment *)
let comment = Util.comment_generic /%[ \t]*/ "% "
(* View: config
A top-level config *)
let config (app:lens) =
(Util.empty | comment)*
. rspace lbrack
. Build.opt_list (kernel | app) (lrspace comma)
. lrspace rbrack
. Util.del_str "." . Util.eol
. (Util.empty | comment)*

View File

@ -0,0 +1,25 @@
(* Parsing /etc/ethers *)
module Ethers =
autoload xfm
let sep_tab = Util.del_ws_tab
let eol = del /[ \t]*\n/ "\n"
let indent = del /[ \t]*/ ""
let comment = Util.comment
let empty = [ del /[ \t]*#?[ \t]*\n/ "\n" ]
let word = /[^# \n\t]+/
let address =
let hex = /[0-9a-fA-F][0-9a-fA-F]?/ in
hex . ":" . hex . ":" . hex . ":" . hex . ":" . hex . ":" . hex
let record = [ seq "ether" . indent .
[ label "mac" . store address ] . sep_tab .
[ label "ip" . store word ] . eol ]
let lns = ( empty | comment | record ) *
let xfm = transform lns (incl "/etc/ethers")

View File

@ -0,0 +1,98 @@
(* Lens for Linux syntax of NFS exports(5) *)
(*
Module: Exports
Parses /etc/exports
Author: David Lutterkort <lutter@redhat.com>
About: Description
/etc/exports contains lines associating a directory with one or
more hosts, and NFS options for each host.
About: Usage Example
(start code)
$ augtool
augtool> ls /files/etc/exports/
comment[1] = /etc/exports: the access control list for filesystems which may be exported
comment[2] = to NFS clients. See exports(5).
comment[3] = sample /etc/exports file
dir[1]/ = /
dir[2]/ = /projects
dir[3]/ = /usr
dir[4]/ = /home/joe
augtool> ls /files/etc/exports/dir[1]
client[1]/ = master
client[2]/ = trusty
(end code)
The corresponding line in the file is:
(start code)
/ master(rw) trusty(rw,no_root_squash)
(end code)
Digging further:
(start code)
augtool> ls /files/etc/exports/dir[1]/client[1]
option = rw
To add a new entry, you'd do something like this:
(end code)
(start code)
augtool> set /files/etc/exports/dir[10000] /foo
augtool> set /files/etc/exports/dir[last()]/client[1] weeble
augtool> set /files/etc/exports/dir[last()]/client[1]/option[1] ro
augtool> set /files/etc/exports/dir[last()]/client[1]/option[2] all_squash
augtool> save
Saved 1 file(s)
(end code)
Which creates the line:
(start code)
/foo weeble(ro,all_squash)
(end code)
About: Limitations
This lens cannot handle options without a host, as with the last
example line in "man 5 exports":
/pub (ro,insecure,all_squash)
In this case, though, you can just do:
/pub *(ro,insecure,all_squash)
It also can't handle whitespace before the directory name.
*)
module Exports =
autoload xfm
let client_re = /[][a-zA-Z0-9.@*?\/:-]+/
let eol = Util.eol
let lbracket = Util.del_str "("
let rbracket = Util.del_str ")"
let sep_com = Sep.comma
let sep_spc = Sep.space
let option = [ label "option" . store /[^,)]*/ ]
let client = [ label "client" . store client_re .
( Build.brackets lbracket rbracket
( Build.opt_list option sep_com ) )? ]
let entry = [ label "dir" . store /[^ \t\n#]*/
. sep_spc . Build.opt_list client sep_spc . eol ]
let lns = (Util.empty | Util.comment | entry)*
let xfm = transform lns (incl "/etc/exports")

View File

@ -0,0 +1,286 @@
(*
Module: FAI_DiskConfig
Parses disk_config files for FAI
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to the FAI wiki where possible:
http://wiki.fai-project.org/wiki/Setup-storage#New_configuration_file_syntax
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About: Examples
The <Test_FAI_DiskConfig> file contains various examples and tests.
*)
module FAI_DiskConfig =
(* autoload xfm *)
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* Group: Generic primitives *)
(* Variable: eol *)
let eol = Util.eol
(* Variable: space *)
let space = Sep.space
(* Variable: empty *)
let empty = Util.empty
(* Variable: comment *)
let comment = Util.comment
(* Variable: tag
A generic tag beginning with a colon *)
let tag (re:regexp) = [ Util.del_str ":" . key re ]
(* Variable: generic_opt
A generic key/value option *)
let generic_opt (type:string) (kw:regexp) =
[ key type . Util.del_str ":" . store kw ]
(* Variable: generic_opt_list
A generic key/list option *)
let generic_opt_list (type:string) (kw:regexp) =
[ key type . Util.del_str ":" . counter "locallist"
. Build.opt_list [seq "locallist" . store kw] Sep.comma ]
(************************************************************************
* Group: RECORDS
*************************************************************************)
(* Group: volume *)
(* Variable: mountpoint_kw *)
let mountpoint_kw = "-" (* do not mount *)
| "swap" (* swap space *)
(* fully qualified path; if :encrypt is given, the partition
* will be encrypted, the key is generated automatically *)
| /\/[^: \t\n]*/
(* Variable: encrypt
encrypt tag *)
let encrypt = tag "encrypt"
(* Variable: mountpoint *)
let mountpoint = [ label "mountpoint" . store mountpoint_kw
(* encrypt is only for the fspath, but we parse it anyway *)
. encrypt?]
(* Variable: resize
resize tag *)
let resize = tag "resize"
(* Variable: size_kw
Regexps for size *)
let size_kw = /[0-9]+[kMGTP%]?(-([0-9]+[kMGTP%]?)?)?/
| /-[0-9]+[kMGTP%]?/
(* Variable: size *)
let size = [ label "size" . store size_kw . resize? ]
(* Variable: filesystem_kw
Regexps for filesystem *)
let filesystem_kw = "-"
| "swap"
(* NOTE: Restraining this regexp would improve perfs *)
| (Rx.no_spaces - ("-" | "swap")) (* mkfs.xxx must exist *)
(* Variable: filesystem *)
let filesystem = [ label "filesystem" . store filesystem_kw ]
(* Variable: mount_option_value *)
let mount_option_value = [ label "value" . Util.del_str "="
. store /[^,= \t\n]+/ ]
(* Variable: mount_option
Counting options *)
let mount_option = [ seq "mount_option"
. store /[^,= \t\n]+/
. mount_option_value? ]
(* Variable: mount_options
An array of <mount_option>s *)
let mount_options = [ label "mount_options"
. counter "mount_option"
. Build.opt_list mount_option Sep.comma ]
(* Variable: fs_option *)
let fs_option =
[ key /createopts|tuneopts/
. Util.del_str "=\"" . store /[^"\n]*/ . Util.del_str "\"" ]
(* Variable: fs_options
An array of <fs_option>s *)
let fs_options =
(* options to append to mkfs.xxx and to the filesystem-specific
* tuning tool *)
[ label "fs_options" . Build.opt_list fs_option Sep.space ]
(* Variable: volume_full *)
let volume_full (type:lens) (third_field:lens) =
[ type . space
. mountpoint .space
(* The third field changes depending on types *)
. third_field . space
. filesystem . space
. mount_options
. (space . fs_options)?
. eol ]
(* Variable: name
LVM volume group name *)
let name = [ label "name" . store /[^\/ \t\n]+/ ]
(* Variable: partition
An optional partition number for <disk> *)
let partition = [ label "partition" . Util.del_str "." . store /[0-9]+/ ]
(* Variable: disk *)
let disk = [ label "disk" . store /[^., \t\n]+/ . partition? ]
(* Variable: vg_option
An option for <volume_vg> *)
let vg_option =
[ key "pvcreateopts"
. Util.del_str "=\"" . store /[^"\n]*/ . Util.del_str "\"" ]
(* Variable: volume_vg *)
let volume_vg = [ key "vg"
. space . name
. space . disk
. (space . vg_option)?
. eol ]
(* Variable: spare_missing *)
let spare_missing = tag /spare|missing/
(* Variable: disk_with_opt
A <disk> with a spare/missing option for raids *)
let disk_with_opt = [ label "disk" . store /[^:., \t\n]+/ . partition?
. spare_missing* ]
(* Variable: disk_list
A list of <disk_with_opt>s *)
let disk_list = Build.opt_list disk_with_opt Sep.comma
(* Variable: type_label_lv *)
let type_label_lv = label "lv"
. [ label "vg" . store (/[^# \t\n-]+/ - "raw") ]
. Util.del_str "-"
. [ label "name" . store /[^ \t\n]+/ ]
(* Variable: volume_tmpfs *)
let volume_tmpfs =
[ key "tmpfs" . space
. mountpoint .space
. size . space
. mount_options
. (space . fs_options)?
. eol ]
(* Variable: volume_lvm *)
let volume_lvm = volume_full type_label_lv size (* lvm logical volume: vg name and lv name *)
| volume_vg
(* Variable: volume_raid *)
let volume_raid = volume_full (key /raid[0156]/) disk_list (* raid level *)
(* Variable: device *)
let device = [ label "device" . store Rx.fspath ]
(* Variable: volume_cryptsetup *)
let volume_cryptsetup = volume_full (key ("swap"|"tmp"|"luks")) device
(* Variable: volume *)
let volume = volume_full (key "primary") size (* for physical disks only *)
| volume_full (key "logical") size (* for physical disks only *)
| volume_full (key "raw-disk") size
(* Variable: volume_or_comment
A succesion of <volume>s and <comment>s *)
let volume_or_comment (vol:lens) =
(vol|empty|comment)* . vol
(* Variable: disk_config_entry *)
let disk_config_entry (kw:regexp) (opt:lens) (vol:lens) =
[ key "disk_config" . space . store kw
. (space . opt)* . eol
. (volume_or_comment vol)? ]
(* Variable: lvmoption *)
let lvmoption =
(* preserve partitions -- always *)
generic_opt "preserve_always" /[^\/, \t\n-]+-[^\/, \t\n-]+(,[^\/, \t\n-]+-[^\/, \t\n-]+)*/
(* preserve partitions -- unless the system is installed
* for the first time *)
| generic_opt "preserve_reinstall" /[^\/, \t\n-]+-[^\/, \t\n-]+(,[^\/, \t\n-]+-[^\/, \t\n-]+)*/
(* attempt to resize partitions *)
| generic_opt "resize" /[^\/, \t\n-]+-[^\/, \t\n-]+(,[^\/, \t\n-]+-[^\/, \t\n-]+)*/
(* when creating the fstab, the key used for defining the device
* may be the device (/dev/xxx), a label given using -L, or the uuid *)
| generic_opt "fstabkey" /device|label|uuid/
(* Variable: raidoption *)
let raidoption =
(* preserve partitions -- always *)
generic_opt_list "preserve_always" (Rx.integer | "all")
(* preserve partitions -- unless the system is installed
* for the first time *)
| generic_opt_list "preserve_reinstall" Rx.integer
(* when creating the fstab, the key used for defining the device
* may be the device (/dev/xxx), a label given using -L, or the uuid *)
| generic_opt "fstabkey" /device|label|uuid/
(* Variable: option *)
let option =
(* preserve partitions -- always *)
generic_opt_list "preserve_always" (Rx.integer | "all")
(* preserve partitions -- unless the system is installed
for the first time *)
| generic_opt_list "preserve_reinstall" Rx.integer
(* attempt to resize partitions *)
| generic_opt_list "resize" Rx.integer
(* write a disklabel - default is msdos *)
| generic_opt "disklabel" /msdos|gpt/
(* mark a partition bootable, default is / *)
| generic_opt "bootable" Rx.integer
(* do not assume the disk to be a physical device, use with xen *)
| [ key "virtual" ]
(* when creating the fstab, the key used for defining the device
* may be the device (/dev/xxx), a label given using -L, or the uuid *)
| generic_opt "fstabkey" /device|label|uuid/
| generic_opt_list "always_format" Rx.integer
| generic_opt "sameas" Rx.fspath
let cryptoption =
[ key "randinit" ]
(* Variable: disk_config *)
let disk_config =
let excludes = "lvm" | "raid" | "end" | /disk[0-9]+/
| "cryptsetup" | "tmpfs" in
let other_label = Rx.fspath - excludes in
disk_config_entry "lvm" lvmoption volume_lvm
| disk_config_entry "raid" raidoption volume_raid
| disk_config_entry "tmpfs" option volume_tmpfs
| disk_config_entry "end" option volume (* there shouldn't be an option here *)
| disk_config_entry /disk[0-9]+/ option volume
| disk_config_entry "cryptsetup" cryptoption volume_cryptsetup
| disk_config_entry other_label option volume
(* Variable: lns
The disk_config lens *)
let lns = (disk_config|comment|empty)*
(* let xfm = transform lns Util.stdexcl *)

View File

@ -0,0 +1,47 @@
(* Fail2ban module for Augeas *)
(* Author: Nicolas Gif <ngf18490@pm.me> *)
(* Heavily based on DPUT module by Raphael Pinson *)
(* <raphink@gmail.com> *)
(* *)
module Fail2ban =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
(************************************************************************
* "name: value" entries, with continuations in the style of RFC 822;
* "name=value" is also accepted
* leading whitespace is removed from values
*************************************************************************)
let entry = IniFile.entry IniFile.entry_re sep comment
(************************************************************************
* sections, led by a "[section]" header
* We can't use titles as node names here since they could contain "/"
* We remove #comment from possible keys
* since it is used as label for comments
* We also remove / as first character
* because augeas doesn't like '/' keys (although it is legal in INI Files)
*************************************************************************)
let title = IniFile.title IniFile.record_re
let record = IniFile.record title entry
let lns = IniFile.lns record comment
let filter = (incl "/etc/fail2ban/fail2ban.conf")
. (incl "/etc/fail2ban/jail.conf")
. (incl "/etc/fail2ban/jail.local")
. (incl "/etc/fail2ban/fail2ban.d/*.conf")
. (incl "/etc/fail2ban/jail.d/*.conf")
let xfm = transform lns filter

View File

@ -0,0 +1,37 @@
(*
Module: Fonts
Parses the /etc/fonts directory
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 fonts-conf` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to files in the /etc/fonts directory. See <filter>.
About: Examples
The <Test_Fonts> file contains various examples and tests.
*)
module Fonts =
autoload xfm
(* View: lns *)
let lns = Xml.lns
(* Variable: filter *)
let filter = incl "/etc/fonts/fonts.conf"
. incl "/etc/fonts/conf.avail/*"
. incl "/etc/fonts/conf.d/*"
. excl "/etc/fonts/*/README"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,43 @@
(* Parsing /etc/fstab *)
module Fstab =
autoload xfm
let sep_tab = Sep.tab
let sep_spc = Sep.space
let comma = Sep.comma
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let file = /[^# \t\n]+/
(* An option label can't contain comma, comment, equals, or space *)
let optlabel = /[^,#= \n\t]+/
let spec = /[^,# \n\t][^ \n\t]*/
let comma_sep_list (l:string) =
let value = [ label "value" . Util.del_str "=" . ( store Rx.neg1 )? ] in
let lns = [ label l . store optlabel . value? ] in
Build.opt_list lns comma
let record = [ seq "mntent" .
Util.indent .
[ label "spec" . store spec ] . sep_tab .
[ label "file" . store file ] . sep_tab .
comma_sep_list "vfstype" .
(sep_tab . comma_sep_list "opt" .
(sep_tab . [ label "dump" . store /[0-9]+/ ] .
( sep_spc . [ label "passno" . store /[0-9]+/ ])? )? )?
. Util.comment_or_eol ]
let lns = ( empty | comment | record ) *
let filter = incl "/etc/fstab"
. incl "/etc/mtab"
let xfm = transform lns filter
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,45 @@
(*
Module: Fuse
Parses /etc/fuse.conf
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to /etc/fuse.conf. See <filter>.
About: Examples
The <Test_Fuse> file contains various examples and tests.
*)
module Fuse =
autoload xfm
(* Variable: equal *)
let equal = del /[ \t]*=[ \t]*/ " = "
(* View: mount_max *)
let mount_max = Build.key_value_line "mount_max" equal (store Rx.integer)
(* View: user_allow_other *)
let user_allow_other = Build.flag_line "user_allow_other"
(* View: lns
The fuse.conf lens
*)
let lns = ( Util.empty | Util.comment | mount_max | user_allow_other )*
(* Variable: filter *)
let filter = incl "/etc/fuse.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,48 @@
(* Gdm module for Augeas *)
(* Author: Free Ekanayaka <freek@64studio.com> *)
(* *)
module Gdm =
autoload xfm
(************************************************************************
* INI File settings
*************************************************************************)
let comment = IniFile.comment IniFile.comment_re IniFile.comment_default
let sep = IniFile.sep IniFile.sep_re IniFile.sep_default
let empty = IniFile.empty
(************************************************************************
* ENTRY
* Entry keywords can be bare digits as well (the [server] section)
*************************************************************************)
let entry_re = ( /[A-Za-z0-9][A-Za-z0-9._-]*/ )
let entry = IniFile.entry entry_re sep comment
(************************************************************************
* TITLE
*
* We use IniFile.title_label because there can be entries
* outside of sections whose labels would conflict with section names
*************************************************************************)
let title = IniFile.title ( IniFile.record_re - ".anon" )
let record = IniFile.record title entry
let record_anon = [ label ".anon" . ( entry | empty )+ ]
(************************************************************************
* LENS & FILTER
* There can be entries before any section
* IniFile.entry includes comment management, so we just pass entry to lns
*************************************************************************)
let lns = record_anon? . record*
let filter = (incl "/etc/gdm/gdm.conf*")
. (incl "/etc/gdm/custom.conf")
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,49 @@
(*
Module: Getcap
Parses generic termcap-style capability databases
Author: Matt Dainty <matt@bodgit-n-scarper.com>
About: Reference
- man 3 getcap
- man 5 login.conf
- man 5 printcap
Each line represents a record consisting of a number of ':'-separated fields
the first of which is the name or identifier for the record. The name can
optionally be split by '|' and each subsequent value is considered an alias
of the first. Records can be split across multiple lines with '\'.
See also the Rtadvd and Termcap modules which contain slightly more specific
grammars.
*)
module Getcap =
autoload xfm
(* Comments cannot have any leading characters *)
let comment = Util.comment_generic /#[ \t]*/ "# "
let nfield = /[^#:\\\\\t\n|][^:\\\\\t\n|]*/
(* field must not contain ':' *)
let cfield = /[a-zA-Z0-9-]+([%^$#\\]?@|[%^$#\\=]([^:\\\\^]|\\\\[0-7]{1,3}|\\\\[bBcCeEfFnNrRtT\\^]|\^.)*)?/
let csep = del /:([ \t]*\\\\\n[ \t]*:)?/ ":\\\n\t:"
let nsep = Util.del_str "|"
let name = [ label "name" . store nfield ]
let capability (re:regexp) = [ label "capability" . store re ]
let record (re:regexp) = [ label "record" . name . ( nsep . name )* . ( csep . capability re )* . Sep.colon . Util.eol ]
let lns = ( Util.empty | comment | record cfield )*
let filter = incl "/etc/login.conf"
. incl "/etc/printcap"
. Util.stdexcl
let xfm = transform lns filter
(* Local Variables: *)
(* mode: caml *)
(* End: *)

View File

@ -0,0 +1,59 @@
(* Group module for Augeas
Author: Free Ekanayaka <free@64studio.com>
Reference: man 5 group
*)
module Group =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let dels = Util.del_str
let colon = Sep.colon
let comma = Sep.comma
let sto_to_spc = store Rx.space_in
let sto_to_col = Passwd.sto_to_col
let word = Rx.word
let password = /[A-Za-z0-9_.!*-]*/
let integer = Rx.integer
(************************************************************************
* ENTRIES
*************************************************************************)
let user = [ label "user" . store word ]
let user_list = Build.opt_list user comma
let params = [ label "password" . store password . colon ]
. [ label "gid" . store integer . colon ]
. user_list?
let entry = Build.key_value_line word colon params
let nisdefault =
let overrides =
colon
. [ label "password" . store password? . colon ]
. [ label "gid" . store integer? . colon ]
. user_list? in
[ dels "+" . label "@nisdefault" . overrides? . eol ]
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|entry|nisdefault) *
let filter = incl "/etc/group"
let xfm = transform lns filter

View File

@ -0,0 +1,337 @@
(*
Module: Grub
Parses grub configuration
Author: David Lutterkort <lutter@redhat.com>
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
*)
module Grub =
autoload xfm
(* This only covers the most basic grub directives. Needs to be *)
(* expanded to cover more (and more esoteric) directives *)
(* It is good enough to handle the grub.conf on my Fedora 8 box *)
(************************************************************************
* Group: USEFUL PRIMITIVES
*************************************************************************)
(* View: value_to_eol *)
let value_to_eol = store /[^= \t\n][^\n]*[^= \t\n]|[^= \t\n]/
(* View: eol *)
let eol = Util.eol
(* View: spc *)
let spc = Util.del_ws_spc
(* View: opt_ws *)
let opt_ws = Util.del_opt_ws ""
(* View: dels *)
let dels (s:string) = Util.del_str s
(* View: eq *)
let eq = dels "="
(* View: switch *)
let switch (n:regexp) = dels "--" . key n
(* View: switch_arg *)
let switch_arg (n:regexp) = switch n . eq . store Rx.no_spaces
(* View: value_sep *)
let value_sep (dflt:string) = del /[ \t]*[ \t=][ \t]*/ dflt
(* View: comment_re *)
let comment_re = /([^ \t\n].*[^ \t\n]|[^ \t\n])/
- /# ## (Start|End) Default Options ##/
(* View: comment *)
let comment =
[ Util.indent . label "#comment" . del /#[ \t]*/ "# "
. store comment_re . eol ]
(* View: empty *)
let empty = Util.empty
(************************************************************************
* Group: USEFUL FUNCTIONS
*************************************************************************)
(* View: command *)
let command (kw:regexp) (indent:string) =
Util.del_opt_ws indent . key kw
(* View: kw_arg *)
let kw_arg (kw:regexp) (indent:string) (dflt_sep:string) =
[ command kw indent . value_sep dflt_sep . value_to_eol . eol ]
(* View: kw_boot_arg *)
let kw_boot_arg (kw:regexp) = kw_arg kw "\t" " "
(* View: kw_menu_arg *)
let kw_menu_arg (kw:regexp) = kw_arg kw "" " "
(* View: password_arg *)
let password_arg = [ command "password" "" .
(spc . [ switch "md5" ])? .
(spc . [ switch "encrypted" ])? .
spc . store (/[^ \t\n]+/ - /--[^ \t\n]+/) .
(spc . [ label "file" . store /[^ \t\n]+/ ])? .
eol ]
(* View: kw_pres *)
let kw_pres (kw:string) = [ opt_ws . key kw . eol ]
(* View: error
* Parse a line that looks almost like a valid setting, but isn't,
* into an '#error' node. Any line that starts with letters, but not
* anything matching kw, is considered an error line.
*
* Parameters:
* kw:regexp - the valid keywords that are _not_ considered an
* error
*)
let error (kw:regexp) =
let not_kw = /[a-zA-Z]+/ - kw in
[ label "#error" . Util.del_opt_ws "\t"
. store (not_kw . /([^a-zA-Z\n].*[^ \t\n])?/) . eol ]
(************************************************************************
* Group: BOOT ENTRIES
*************************************************************************)
(* View: device
* This is a shell-only directive in upstream grub; the grub versions
* in at least Fedora/RHEL use this to find devices for UEFI boot *)
let device =
[ command "device" "" . Sep.space . store /\([A-Za-z0-9_.-]+\)/ . spc .
[ label "file" . value_to_eol ] . Util.eol ]
(* View: color *)
let color =
(* Should we nail it down to exactly the color names that *)
(* grub supports ? *)
let color_name = store /[A-Za-z-]+/ in
let color_spec =
[ label "foreground" . color_name] .
dels "/" .
[ label "background" . color_name ] in
[ opt_ws . key "color" .
spc . [ label "normal" . color_spec ] .
(spc . [ label "highlight" . color_spec ])? .
eol ]
(* View: serial *)
let serial =
[ command "serial" "" .
[ spc . switch_arg /unit|port|speed|word|parity|stop|device/ ]* .
eol ]
(* View: terminal *)
let terminal =
[ command "terminal" "" .
([ spc . switch /dumb|no-echo|no-edit|silent/ ]
|[ spc . switch_arg /timeout|lines/ ])* .
[ spc . key /console|serial|hercules/ ]* . eol ]
(* View: setkey *)
let setkey = [ command "setkey" "" .
( spc . [ label "to" . store Rx.no_spaces ] .
spc . [ label "from" . store Rx.no_spaces ] )? .
eol ]
(* View: menu_entry *)
let menu_entry = kw_menu_arg "default"
| kw_menu_arg "fallback"
| kw_pres "hiddenmenu"
| kw_menu_arg "timeout"
| kw_menu_arg "splashimage"
| kw_menu_arg "gfxmenu"
| kw_menu_arg "foreground"
| kw_menu_arg "background"
| kw_menu_arg "verbose"
| kw_menu_arg "boot" (* only for CLI, ignored in conf *)
| serial
| terminal
| password_arg
| color
| device
| setkey
(* View: menu_error
* Accept lines not matching menu_entry and stuff them into
* '#error' nodes
*)
let menu_error =
let kw = /default|fallback|hiddenmenu|timeout|splashimage|gfxmenu/
|/foreground|background|verbose|boot|password|title/
|/serial|setkey|terminal|color|device/ in
error kw
(* View: menu_setting
* a valid menu setting or a line that looks like one but is an #error
*)
let menu_setting = menu_entry | menu_error
(* View: title *)
let title = del /title[ \t=]+/ "title " . value_to_eol . eol
(* View: multiboot_arg
* Permits a second form for Solaris multiboot kernels that
* take a path (with a slash) as their first arg, e.g.
* /boot/multiboot kernel/unix another=arg *)
let multiboot_arg = [ label "@path" .
store (Rx.word . "/" . Rx.no_spaces) ]
(* View: kernel_args
Parse the file name and args on a kernel or module line. *)
let kernel_args =
let arg = /[A-Za-z0-9_.$\+-]+/ - /type|no-mem-option/ in
store /(\([a-z0-9,]+\))?\/[^ \t\n]*/ .
(spc . multiboot_arg)? .
(spc . [ key arg . (eq. store /([^ \t\n])*/)?])* . eol
(* View: module_line
Solaris extension adds module$ and kernel$ for variable interpolation *)
let module_line =
[ command /module\$?/ "\t" . spc . kernel_args ]
(* View: map_line *)
let map_line =
[ command "map" "\t" . spc .
[ label "from" . store /[()A-za-z0-9]+/ ] . spc .
[ label "to" . store /[()A-za-z0-9]+/ ] . eol ]
(* View: kernel *)
let kernel =
[ command /kernel\$?/ "\t" .
(spc .
([switch "type" . eq . store /[a-z]+/]
|[switch "no-mem-option"]))* .
spc . kernel_args ]
(* View: chainloader *)
let chainloader =
[ command "chainloader" "\t" .
[ spc . switch "force" ]? . spc . store Rx.no_spaces . eol ]
(* View: savedefault *)
let savedefault =
[ command "savedefault" "\t" . (spc . store Rx.integer)? . eol ]
(* View: configfile *)
let configfile =
[ command "configfile" "\t" . spc . store Rx.no_spaces . eol ]
(* View: boot_entry
<boot> entries *)
let boot_entry =
let boot_arg_re = "root" | "initrd" | "rootnoverify" | "uuid"
| "findroot" | "bootfs" (* Solaris extensions *)
in kw_boot_arg boot_arg_re
| kernel
| chainloader
| kw_pres "quiet" (* Seems to be a Ubuntu extension *)
| savedefault
| configfile
| module_line
| map_line
| kw_pres "lock"
| kw_pres "makeactive"
| password_arg
(* View: boot_error
* Accept lines not matching boot_entry and stuff them into
* '#error' nodes
*)
let boot_error =
let kw = /lock|uuid|password|root|initrd|rootnoverify|findroot|bootfs/
|/configfile|chainloader|title|boot|quiet|kernel|module/
|/makeactive|savedefault|map/ in
error kw
(* View: boot_setting
* a valid boot setting or a line that looks like one but is an #error
*)
let boot_setting = boot_entry | boot_error
(* View: boot *)
let boot =
let line = ((boot_setting|comment)* . boot_setting)? in
[ label "title" . title . line ]
(************************************************************************
* Group: DEBIAN-SPECIFIC SECTIONS
*************************************************************************)
(* View: debian_header
Header for a <debian>-specific section *)
let debian_header = "## ## Start Default Options ##\n"
(* View: debian_footer
Footer for a <debian>-specific section *)
let debian_footer = "## ## End Default Options ##\n"
(* View: debian_comment_re *)
let debian_comment_re = /([^ \t\n].*[^ \t\n]|[^ \t\n])/
- "## End Default Options ##"
(* View: debian_comment
A comment entry inside a <debian>-specific section *)
let debian_comment =
[ Util.indent . label "#comment" . del /##[ \t]*/ "## "
. store debian_comment_re . eol ]
(* View: debian_setting_re *)
let debian_setting_re = "kopt"
| "groot"
| "alternative"
| "lockalternative"
| "defoptions"
| "lockold"
| "xenhopt"
| "xenkopt"
| "altoptions"
| "howmany"
| "memtest86"
| "updatedefaultentry"
| "savedefault"
| "indomU"
(* View: debian_entry *)
let debian_entry = [ Util.del_str "#" . Util.indent
. key debian_setting_re . del /[ \t]*=/ "="
. value_to_eol? . eol ]
(* View: debian
A debian-specific section, made of <debian_entry> lines *)
let debian = [ label "debian"
. del debian_header debian_header
. (debian_comment|empty|debian_entry)*
. del debian_footer debian_footer ]
(************************************************************************
* Group: LENS AND FILTER
*************************************************************************)
(* View: lns *)
let lns = (comment | empty | menu_setting | debian)*
. (boot . (comment | empty | boot)*)?
(* View: filter *)
let filter = incl "/boot/grub/grub.conf"
. incl "/boot/grub/menu.lst"
. incl "/etc/grub.conf"
. incl "/boot/efi/EFI/*/grub.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,19 @@
(* Parsing /boot/grub/grubenv *)
module GrubEnv =
autoload xfm
let eol = Util.del_str "\n"
let comment = Util.comment
let eq = Util.del_str "="
let value = /[^\\\n]*(\\\\(\\\\|\n)[^\\\n]*)*/
let word = /[A-Za-z_][A-Za-z0-9_]*/
let record = [ seq "target" .
[ label "name" . store word ] . eq .
[ label "value" . store value ] . eol ]
let lns = ( comment | record ) *
let xfm = transform lns (incl "/boot/grub/grubenv" . incl "/boot/grub2/grubenv")

View File

@ -0,0 +1,80 @@
(*
Module: Gshadow
Parses /etc/gshadow
Author: Lorenzo M. Catucci <catucci@ccd.uniroma2.it>
Original Author: Free Ekanayaka <free@64studio.com>
About: Reference
- man 5 gshadow
About: License
This file is licensed under the LGPL v2+, like the rest of Augeas.
About:
Each line in the gshadow files represents the additional shadow-defined
attributes for the corresponding group, as defined in the group file.
*)
module Gshadow =
autoload xfm
(************************************************************************
* USEFUL PRIMITIVES
*************************************************************************)
let eol = Util.eol
let comment = Util.comment
let empty = Util.empty
let colon = Sep.colon
let comma = Sep.comma
let sto_to_spc = store Rx.space_in
let word = Rx.word
let password = /[A-Za-z0-9_.!*-]*/
let integer = Rx.integer
(************************************************************************
* Group: ENTRIES
*************************************************************************)
(* View: member *)
let member = [ label "member" . store word ]
(* View: member_list
the member list is a comma separated list of
users allowed to chgrp to the group without
being prompted for the group's password *)
let member_list = Build.opt_list member comma
(* View: admin *)
let admin = [ label "admin" . store word ]
(* View: admin_list
the admin_list is a comma separated list of
users allowed to change the group's password
and the member_list *)
let admin_list = Build.opt_list admin comma
(* View: params *)
let params = [ label "password" . store password . colon ]
. admin_list? . colon
. member_list?
let entry = Build.key_value_line word colon params
(************************************************************************
* LENS
*************************************************************************)
let lns = (comment|empty|entry) *
let filter
= incl "/etc/gshadow"
. Util.stdexcl
let xfm = transform lns filter

View File

@ -0,0 +1,36 @@
(*
Module: GtkBookmarks
Parses $HOME/.gtk-bookmarks
Author: Raphael Pinson <raphael.pinson@camptocamp.com>
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to $HOME/.gtk-bookmarks. See <filter>.
About: Examples
The <Test_GtkBookmarks> file contains various examples and tests.
*)
module GtkBookmarks =
autoload xfm
(* View: empty
Comment are not allowed, even empty comments *)
let empty = Util.empty_generic Rx.opt_space
(* View: entry *)
let entry = [ label "bookmark" . store Rx.no_spaces
. (Sep.space . [ label "label" . store Rx.space_in ])?
. Util.eol ]
(* View: lns *)
let lns = (empty | entry)*
(* View: xfm *)
let xfm = transform lns (incl (Sys.getenv("HOME") . "/.gtk-bookmarks"))

View File

@ -0,0 +1,71 @@
(*
Module: Host_Conf
Parses /etc/host.conf
Author: Raphael Pinson <raphink@gmail.com>
About: Reference
This lens tries to keep as close as possible to `man 5 host.conf` where possible.
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
About: Lens Usage
To be documented
About: Configuration files
This lens applies to /etc/host.conf. See <filter>.
*)
module Host_Conf =
autoload xfm
(************************************************************************
* Group: ENTRY TYPES
*************************************************************************)
(* View: sto_bool
Store a boolean value *)
let sto_bool = store ("on"|"off")
(* View: sto_bool_warn
Store a boolean value *)
let sto_bool_warn = store ("on"|"off"|"warn"|"nowarn")
(* View: bool
A boolean switch *)
let bool (kw:regexp) = Build.key_value_line kw Sep.space sto_bool
(* View: bool_warn
A boolean switch with extended values *)
let bool_warn (kw:regexp) = Build.key_value_line kw Sep.space sto_bool_warn
(* View: list
A list of items *)
let list (kw:regexp) (elem:string) =
let list_elems = Build.opt_list [seq elem . store Rx.word] (Sep.comma . Sep.opt_space) in
Build.key_value_line kw Sep.space list_elems
(* View: trim *)
let trim =
let trim_list = Build.opt_list [seq "trim" . store Rx.word] (del /[:;,]/ ":") in
Build.key_value_line "trim" Sep.space trim_list
(* View: entry *)
let entry = bool ("multi"|"nospoof"|"spoofalert"|"reorder")
| bool_warn "spoof"
| list "order" "order"
| trim
(************************************************************************
* Group: LENS AND FILTER
*************************************************************************)
(* View: lns *)
let lns = ( Util.empty | Util.comment | entry )*
(* View: filter *)
let filter = incl "/etc/host.conf"
let xfm = transform lns filter

View File

@ -0,0 +1,22 @@
(*
Module: Hostname
Parses /etc/hostname and /etc/mailname
Author: Raphael Pinson <raphink@gmail.com>
About: License
This file is licenced under the LGPL v2+, like the rest of Augeas.
*)
module Hostname =
autoload xfm
(* View: lns *)
let lns = [ label "hostname" . store Rx.word . Util.eol ] | Util.empty
(* View: filter *)
let filter = incl "/etc/hostname"
. incl "/etc/mailname"
let xfm = transform lns filter

View File

@ -0,0 +1,15 @@
(* Parsing /etc/hosts *)
module Hosts =
autoload xfm
let word = /[^# \n\t]+/
let record = [ seq "host" . Util.indent .
[ label "ipaddr" . store word ] . Sep.tab .
[ label "canonical" . store word ] .
[ label "alias" . Sep.space . store word ]*
. Util.comment_or_eol ]
let lns = ( Util.empty | Util.comment | record ) *
let xfm = transform lns (incl "/etc/hosts")

Some files were not shown because too many files have changed in this diff Show More