Skip to content

Releases: FOGProject/fog-plugins

v1.6.11

Choose a tag to compare

@mastacontrola mastacontrola released this 19 Aug 18:32
c0edd09

Notifications: name the image, and tell a capture from a deploy (#21).

The six imaging listeners registered for HOST_IMAGEUP_COMPLETE and HOST_IMAGE_FAIL and then ignored which event had arrived, so a finished capture announced itself identically to a deploy and a failure said This host has failed to image with no hint as to why.

before after
deploy Host lab01 completed imaging. Host lab01 finished deploying image Win11-Lab.
capture Host lab01 completed imaging. Host lab01 finished capturing image Win11-Lab.
failure Host lab01 imaging failed. Host lab01 failed imaging Win11-Lab: fog.download: failed to restore partition 2 …

The failure case is the one worth updating for. The FOS reporting work (FOGProject/fogproject#1206, #1211, #1217, #1223) gives a failed task a stored, multi-line report of what FOS actually said — and until this release none of it reached a notification. Verified live before the release: a report whose stored row read fog.download: failed to restore partition 2 / partclone.ntfs: /dev/sda2 is busy / … pushed only Failed / This host has failed to image.

Every added key is read defensively, with a translated placeholder for a missing one, so all six keep working against a server whose core still sends nothing but HostName — they just say more on one that has taken FOGProject/fogproject#1205.

fog_min is unchanged for that reason.

Requires core with FOGProject/fogproject#1205 to carry the image name and the failure reason. The 1.5 equivalent is FOGProject/fogproject#1226.

v1.6.10

Choose a tag to compare

@mastacontrola mastacontrola released this 18 Aug 12:34
f82114e

OIDC: after a successful single logout, land on FOG's ordinary login page (#20).

With Single Logout and Redirect Login To This Provider both on, signing out left you on the break-glass page (management/login.php) instead of the normal login page. Single logout is precisely the case where the provider session has been ended, so returning to the redirecting page is correct — the provider then asks who you are, and signing out and back in as somebody else is one continuous journey.

⚠️ If you enabled Single Logout on v1.6.9, re-register the post-logout redirect URI at your provider. It changes from …/management/login.php to …/management/index.php. Providers that follow the spec refuse an unregistered value and show their own error page instead of returning to FOG. The value is printed on the provider's page in FOG.

Unchanged: a failed sign-in, and logging out with Single Logout off while the redirect is on, both still land on management/login.php — in those cases the provider session is untouched, so returning to it would loop or silently sign you back in.

Requires core with FOGProject/fogproject#1174 and #1175.

v1.6.9

Choose a tag to compare

@mastacontrola mastacontrola released this 18 Aug 12:12
d259151

OIDC: the account is refreshed on every sign-in, signing out can end the provider session, and the login page can be sent straight to the provider.

  • Refresh the account from the provider on every sign-in (#16). The display name was written once, at first sign-in, and never again — renaming somebody in the directory left FOG showing their original name forever.
  • Single logout (#15). Signing out of FOG left the provider's SSO session intact, so clicking the provider button again silently signed the same person back into the same account. New per-provider setting, off by default; register the printed post-logout redirect URI at your provider if you turn it on.
  • Send the login page straight to the provider (#17). New per-provider setting, off by default. Two flagged providers refuse to redirect rather than silently picking one.

The local login form is always available at https://<fog>/fog/management/login.php — one URL that never routes to an identity provider, whatever the settings above say. Tick the redirect setting only once you know that URL exists.

Requires core with FOGProject/fogproject#1174 and #1175 (the USER_LOGGING_OUT redirect return value, the LOGIN_PAGE_REDIRECT seam, and management/login.php).

v1.6.8

Choose a tag to compare

@mastacontrola mastacontrola released this 18 Aug 00:06
02dd5c9

Read routed query parameters through Route::queryParam() (#14).

Fixes the OIDC plugin refusing a configured, enabled provider with "Unknown identity provider" on every nginx install. Pairs with FOGProject/fogproject#1163.

Requires core with #1163 (Route::queryParam() public).

v1.6.7

Choose a tag to compare

@mastacontrola mastacontrola released this 17 Aug 19:59
6d7ee5b

A one-line fix that turns the OIDC plugin from unusable back into usable.

clientId ends in "id", and FOGController::save() read any key ending
that way as an integer foreign key. Because clientId is required, the
mismatch did not degrade provider rows — it made creating one impossible,
reported as Required database field is empty: clientId about a field the
admin had filled in, and shown in the UI as the generic "Add provider
failed!". No provider meant no provider group, which meant the Role and User
Group provider-group tabs added in v1.6.6 had nothing to associate.

The model now declares clientId a string, and the base class stops
inferring a column's type from its name.

Requires fogproject working-1.6 with FOGProject/fogproject#1153. Without
it the declaration is simply unread, so this release is safe to install
either way. Pair with the FOG_PLUGINS_VERSION bump to v1.6.7.

v1.6.6

Choose a tag to compare

@mastacontrola mastacontrola released this 17 Aug 18:21
87176fd

Adds the OIDC provider-group tabs to the Role and User Group pages (#10), so a
provider group can be associated from either end rather than only from the
OIDC Groups page.

The tabs mirror the LDAP ones, including their permission rule: rendering
takes oidcgroup.view and saving takes oidcgroup.edit, not role.edit
or usergroup.edit. Granting a provider group to a role widens what every
holder of that role gets at sign-in, so being able to edit roles is not by
itself enough to hand that out. A refusal answers 403 rather than silently
doing nothing. Both tabs also offer create-and-associate, so a group can be
created without leaving the page.

Also in this release:

  • the plugin test suite now runs on every pull request (#11), on PHP 7.4 and
    8.3, via fog-workflows/.github/workflows/fog-plugins-tests.yml;
  • tests/group-tab-permissions.test.php covers the LDAP and OIDC group tabs
    together, so the two cannot drift apart;
  • .github/ is excluded from this tarball (#12) — the installer untars this
    straight into lib/plugins, which the web server serves.

Requires fogproject working-1.6 with the OIDC plugin's own prerequisites.
Pair with the FOG_PLUGINS_VERSION bump to v1.6.6.

v1.6.5

Choose a tag to compare

@mastacontrola mastacontrola released this 16 Aug 17:15
3d33d4e

Retires the site plugin. Core owns sites now.

Schema step 332 (fogproject working-1.6) reconstructs the plugin's data into the core sites tables and then drops the plugin's own, so every file in the plugin read tables that stop existing the moment an admin runs the schema updater.

Leaving it installed was not the safe option. Four of its hooks enforced the site boundary by asking the dropped tables which sites a user belonged to — and Route::getIds() returns an empty array rather than raising when its table is gone, so the answer came back "no sites" and the plugin denied every host, user, group and usergroup to every non-* user. Silent: no error, no log line, just an empty host list, on exactly the installs that had site data to migrate.

Core replaced all four surfaces first:

Removed hook Core replacement
sitescopecheck Authorization::objectInScope() (#1069)
listsitehosts the AJAX list path in FOGPage::index() (#1071)
filtersitemassdata Route::_applySiteScope() (#1071)
sitedeletemassitems the site membership map in Route::deletemass() (#1071)

The management half is removed with them — its pages, tabs and reports read the same dropped tables, so keeping them would trade a lockout for broken pages. Core's site management UI is still being built; until it lands this leaves an install with sites enforced correctly and no page to administer them from. A visible gap, chosen over an invisible lockout.

Requires fogproject with schema >= 333 and #1067, #1069, #1071. Pair with the FOG_PLUGINS_VERSION bump to v1.6.5.

v1.6.4

Choose a tag to compare

@mastacontrola mastacontrola released this 16 Aug 14:49
a86e2c2

Pairs with fogproject #1054–#1058 (ADR 0011).

25 call sites across 19 plugins move off Route::listem(...); json_decode(Route::getData()) and onto getList() / getItem() / asValue(). A router failure inside a plugin hook now raises instead of reaching breakHead()'s exit, so it can no longer end a page render half-written.

The 12 raw sites that remain are HTTP response boundaries and stay as they are: the nine report endpoints, location's two storage lookups, and listsitehosts's AJAX_DATA_DISPLAY_CHANGE payload. There the paginated envelope is the response.

Requires a core carrying the wrappers. FOG_PLUGINS_VERSION and route.class.php both live in the core tree, so the pin and the wrappers always upgrade together — an install cannot end up with this release on a core that lacks them.

fog-plugins v1.6.3

Choose a tag to compare

@mastacontrola mastacontrola released this 14 Aug 11:10

Adds the first worked example of a plugin background task.

FOG 1.6.0-beta.3349 introduces FOGPluginRunner, a core-owned daemon that runs work a plugin declares at <plugin>/tasks/*.task.php — see ADR 0010. Until now everything a plugin could register ran inside a request, so a plugin could react to an event but could not poll, reconcile, expire or retry.

helloworld/tasks/helloworldheartbeat.task.php is the worked example: it counts the plugin's rows on a schedule and logs the total. Deliberately read-only, and deliberately without a try/catch, since the runner catches Throwable and names the plugin and task in the log.

Its comments carry the three rules the runner imposes, none of which are guessable from the class:

  • it runs as the web user, not root — installing a plugin grants exactly what installing a plugin already granted;
  • every plugin's tasks share one process and run one at a time, so bound your network and database calls;
  • run() must be idempotent — next-run times live in memory, so a restart makes every task immediately due.

Plus the naming trap: a task class shares one global namespace with every class in FOG, so tasks/host.task.php would collide with the core Host model. Prefix with your plugin name.

Requires FOG 1.6.0-beta.3350 or newer. The runner itself landed in beta.3349, but PluginTask::log() — which the example calls — landed one build later; on beta.3349 the task is discovered and then fails with an undefined method, which the runner catches and logs rather than crashing on. On anything older the runner does not exist, the .task.php extension is not autoloaded, and the file is simply inert — nothing breaks, the task just never runs.

Also corrects the persistentgroups line in the README: it does not keep group membership across re-registration; its trigger copies image, AD, printer and location settings onto a joining host from a template host whose name matches the group's.

Only helloworld/tasks/ and README.md differ from v1.6.2.

fog-plugins v1.6.2

Choose a tag to compare

@mastacontrola mastacontrola released this 13 Aug 17:16

The LDAP plugin declares its own bind password as an API secret, through the API_SENSITIVE_FIELDS hook.

Pairs with FOGProject/fogproject#1025 and must not be skipped. That PR removes the hardcoded 'ldap' => 'bindPwd' entry from Route::$sensitiveAlwaysFields — core naming a plugin is what the plugin architecture exists to end. Without this release present, core dropping that entry means the LDAP bind password, a directory service account credential stored in cleartext, stops being stripped from API payloads.

#1025 bumps FOG_PLUGINS_VERSION to v1.6.2 in the same PR, so an installer run applies both halves together.

Only ldap/hooks/addldapapi.hook.php differs from v1.6.1.