maintenance_scripts.md #1

  • //
  • guest/
  • russell_jackson/
  • sdp/
  • doc/
  • maintenance_scripts.md
  • Markdown
  • View
  • Commits
  • Open Download .zip Download (12 KB)

SDP Maintenance Scripts Reference

This document describes all the maintenance scripts included in the Server Deployment Package (SDP). These scripts are located in the $SDP/Maintenance directory and provide tools for routine Perforce server administration tasks.


Table of Contents

  • Configuration
  • User Management Scripts
  • Group Management Scripts
  • Client Management Scripts
  • Label Management Scripts
  • Email and Notification Scripts
  • Protection Table Scripts
  • Reporting Scripts
  • File and Archive Operations
  • Utility Scripts

Configuration

Most maintenance scripts read their configuration from maintenance.cfg in the Maintenance directory. Key configuration parameters include:

Parameter Description
weeks Default inactivity threshold in weeks
deleteweeks Threshold for permanent deletion
userweeks Inactivity threshold for user accounts
weeks1warn First warning threshold
weeks2warn Second warning threshold
administrator Email from address
mailhost SMTP server hostname
mailport SMTP server port
mailsecure Use TLS (1 or 0)
mailuser SMTP username
mailpass SMTP password
default_user_password Default password for new users

User Management Scripts

accessdates.py

Generate lists of inactive Perforce specs (branches, clients, labels, users) that haven't been accessed within a specified number of weeks.

python accessdates.py [instance]

Output Files:

  • branches.txt
  • clients.txt
  • labels.txt
  • users.txt

createusers.py

Create Perforce users in bulk from a CSV file.

python createusers.py <userlist.csv> [instance]

CSV Format:

user,email,fullname
jsmith,jsmith@company.com,John Smith

delusers.py

Remove users that haven't accessed Perforce within the configured threshold.

python delusers.py [instance]

Uses the weeks threshold from maintenance.cfg.


p4deleteuser.py

Remove Perforce users and their associated metadata (clients, shelves).

python p4deleteuser.py [instance] <user_or_file> [--simulate]

Arguments:

  • instance: SDP instance identifier (default: '1')
  • user_or_file: Username or file containing usernames (one per line)
  • --simulate: Print actions without executing

Features:

  • Protects service accounts (p4admin, perforce, swarm) from deletion
  • Supports batch deletion from files
  • Uses p4 user -FDy command

setpass.py

Set a user's password to the default password configured in maintenance.cfg.

python setpass.py [instance] <username>

checkusers.py

Find group members without corresponding user accounts (orphaned members).

python checkusers.py [instance]

Output: removeusersfromgroups.txt


checkusers_not_in_group.py

Find users that are not members of any Perforce group.

python checkusers_not_in_group.py [instance]

maintain_user_from_groups.py

Sync users based on group membership - creates missing users and removes users not in any group.

python maintain_user_from_groups.py [instance]

email_pending_user_deletes.py

Send warning emails to users whose accounts are scheduled for deletion due to inactivity.

python email_pending_user_deletes.py [instance]

Uses userweeks threshold from maintenance.cfg.


totalusers.py

Generate a CSV report of Perforce users across multiple servers.

python totalusers.py [cfgfile] [--output <outfile>] [--verbose]

Configuration File (totalusers.cfg):

case_sensitive=1
ROBOT,p4robot
ROBOT,jenkins
SERVER,server1.example.com:1666,p4admin,1
SERVER,server2.example.com:1666,p4admin,2

Group Management Scripts

creategroups.py

Create Perforce groups from a configuration file.

python creategroups.py [instance]

Input File Format (groups.txt):

group,groupname1
username1
username2
group,groupname2
username3

addusertogroup.py

Add user(s) to a Perforce group.

python addusertogroup.py [instance] <user_or_file> <group>

Examples:

python addusertogroup.py jsmith developers
python addusertogroup.py 2 userlist.txt developers

removeuserfromgroups.py

Remove user(s) from all their Perforce groups.

python removeuserfromgroups.py [instance] <user_or_file>

removeuserfromgroups_file.py

Remove users from a specific list of groups.

python removeuserfromgroups_file.py <instance> <user_or_file> <groups_file>

removeusersfromgroup.py

Remove users from a specific group.

python removeusersfromgroup.py [instance] <user_or_file> <groupname>

mirroraccess.py

Mirror user access from one user to others (add target users to all groups the source user belongs to).

python mirroraccess.py <instance> <source_user> <target_user> [<user3> ... <userN>]

group_audit.py

Send quarterly audit reminders to group owners asking them to validate group membership.

python group_audit.py [instance]

Client Management Scripts

unload_clients.py

Unload inactive Perforce clients to the unload depot.

python unload_clients.py [instance]

Uses weeks threshold from maintenance.cfg. Skips Swarm clients.


unload_clients_with_delete.py

Unload inactive clients, but forcibly delete those with exclusive file locks (which can't be unloaded).

python unload_clients_with_delete.py [instance]

delete_unload_clients.py

Delete inactive unloaded clients from the unload depot.

python delete_unload_clients.py [instance]

Uses deleteweeks threshold from maintenance.cfg.


unloadaccessdates.py

Generate lists of inactive unloaded clients and labels.

python unloadaccessdates.py [instance]

Output Files:

  • unload_clients.txt
  • unload_labels.txt

email_pending_client_deletes.py

Send warning emails for inactive clients scheduled for unload.

python email_pending_client_deletes.py [instance]

Sends two-tier warnings using weeks1warn and weeks2warn thresholds.


del_shelve.py

Delete shelves and inactive clients.

python del_shelve.py [instance]

Label Management Scripts

unload_labels.py

Unload labels that haven't been accessed within the configured threshold.

python unload_labels.py [instance]

convert_label_to_autoreload.py

Convert Perforce labels from noautoreload to autoreload mode.

python convert_label_to_autoreload.py [instance] <label_or_file>

isitalabel.py

Check if a label exists in Perforce.

python isitalabel.py [instance] <labelname>

Exit Codes:

  • 0: Label exists
  • 1: Label not found

p4lock.py

Lock a Perforce label.

python p4lock.py [instance] <labelname>

p4unlock.py

Unlock a Perforce label.

python p4unlock.py [instance] <labelname>

Note: Saves owner info to owner.txt for restoration by p4lock.py.


Email and Notification Scripts

email.sh

Send email to all Perforce users.

./email.sh "Subject line"

Prerequisites:

  • message.txt must exist containing the email body
  • pymail.py must be available

pymail.py

Send email from command line using SMTP.

python pymail.py -t <to-address or file> -s <subject> -i <input-file> [instance]

Arguments:

  • -t: Recipient email address or path to file with addresses
  • -s: Email subject
  • -i: Path to file containing email body

Examples:

python pymail.py -t admin@example.com -s "Test" -i message.txt
python pymail.py -t recipients.txt -s "Announcement" -i body.txt 2

Protection Table Scripts

protect_groups.py

Find groups in the protection table that don't exist on the server.

# First, extract groups from protect table
p4 protect -o | grep group | cut -d " " -f 3 | sort | uniq > protect_groups.txt

# Then find non-existent groups
python protect_groups.py [instance] protect_groups.txt > remove_groups.txt

clean_protect.py

Remove groups from the Perforce protection table.

# Generate protection table
p4 protect -o > p4.protect

# Clean up invalid groups
python clean_protect.py remove_groups.txt p4.protect

# Review and apply
p4 protect -i < new.p4.protect

Reporting Scripts

countrevs.py

Count total files and revisions from a Perforce files list.

p4 files //... > files.txt
python countrevs.py files.txt

proxysearch.py

Find proxy servers in Perforce server log.

python proxysearch.py <logfile>

Output: Unique proxy IP addresses (one per line)


File and Archive Operations

create_p4_filelist.sh

Generate a combined file list from all Perforce depots.

./create_p4_filelist.sh

Output: p4_file_list.txt

Iterates through depots one directory level deep to avoid memory spikes.


lowercp.py

Copy a directory tree to a target with lowercase names.

cd /p4/1/depots
python lowercp.py depot

Note: Configure TARGETDEPOTPATH variable at top of script.


lowertree.py

Rename a directory tree to all lowercase (in place).

python lowertree.py <directory>

Useful for converting from case-sensitive to case-insensitive Perforce servers.


remove_empty_pending_changes.py

Delete all empty pending changelists.

python remove_empty_pending_changes.py [instance]

Note: Changelists with #do-not-delete in description are protected.


remove_jobs.py

Remove Perforce jobs and their associated fixes.

p4 jobs > jobs.txt
python remove_jobs.py [instance] jobs.txt

update-changes.py

Force update on changelists (useful with form triggers).

p4 changes | cut -d " " -f 2 > changes.txt
python update-changes.py [instance] changes.txt

Utility Scripts

sdputils.py

Core utility module used by most other maintenance scripts. Provides:

  • SDPUtils class for Perforce interactions
  • Configuration loading from maintenance.cfg
  • Safe p4 command execution via run_p4()
  • Secure password management
  • Common Perforce operations (get users, groups, etc.)

Example Usage:

from sdputils import SDPUtils

utils = SDPUtils("1")
utils.login()
users = utils.get_all_users()

Summary

Category Script Count
User Management 10
Group Management 7
Client Management 6
Label Management 5
Email/Notification 3
Protection Table 2
Reporting 2
File/Archive Operations 5
Utility 1
Total 41

Common Workflows

Remove Inactive Users

# 1. Generate list of inactive users
python accessdates.py 1

# 2. Review users.txt, then delete
python p4deleteuser.py 1 users.txt --simulate  # Review first
python p4deleteuser.py 1 users.txt             # Execute

Clean Up Inactive Clients

# 1. Send warnings to users
python email_pending_client_deletes.py 1

# 2. Unload inactive clients
python unload_clients.py 1

# 3. Later, delete unloaded clients
python delete_unload_clients.py 1

Clean Up Protection Table

# 1. Extract groups from protect table
p4 protect -o | grep group | cut -d " " -f 3 | sort | uniq > protect_groups.txt

# 2. Find non-existent groups
python protect_groups.py 1 protect_groups.txt > remove_groups.txt

# 3. Export current protect table
p4 protect -o > p4.protect

# 4. Remove invalid groups
python clean_protect.py remove_groups.txt p4.protect

# 5. Review and apply
diff p4.protect new.p4.protect
p4 protect -i < new.p4.protect

Audit Group Membership

# Find users in groups that don't exist
python checkusers.py 1

# Review and remove orphaned entries
python removeuserfromgroups.py 1 removeusersfromgroups.txt
# SDP Maintenance Scripts Reference

This document describes all the maintenance scripts included in the Server Deployment Package (SDP). These scripts are located in the `$SDP/Maintenance` directory and provide tools for routine Perforce server administration tasks.

---

## Table of Contents

- [Configuration](#configuration)
- [User Management Scripts](#user-management-scripts)
- [Group Management Scripts](#group-management-scripts)
- [Client Management Scripts](#client-management-scripts)
- [Label Management Scripts](#label-management-scripts)
- [Email and Notification Scripts](#email-and-notification-scripts)
- [Protection Table Scripts](#protection-table-scripts)
- [Reporting Scripts](#reporting-scripts)
- [File and Archive Operations](#file-and-archive-operations)
- [Utility Scripts](#utility-scripts)

---

## Configuration

Most maintenance scripts read their configuration from `maintenance.cfg` in the Maintenance directory. Key configuration parameters include:

| Parameter | Description |
|-----------|-------------|
| `weeks` | Default inactivity threshold in weeks |
| `deleteweeks` | Threshold for permanent deletion |
| `userweeks` | Inactivity threshold for user accounts |
| `weeks1warn` | First warning threshold |
| `weeks2warn` | Second warning threshold |
| `administrator` | Email from address |
| `mailhost` | SMTP server hostname |
| `mailport` | SMTP server port |
| `mailsecure` | Use TLS (1 or 0) |
| `mailuser` | SMTP username |
| `mailpass` | SMTP password |
| `default_user_password` | Default password for new users |

---

## User Management Scripts

### accessdates.py

Generate lists of inactive Perforce specs (branches, clients, labels, users) that haven't been accessed within a specified number of weeks.

```bash
python accessdates.py [instance]
```

**Output Files:**
- `branches.txt`
- `clients.txt`
- `labels.txt`
- `users.txt`

---

### createusers.py

Create Perforce users in bulk from a CSV file.

```bash
python createusers.py <userlist.csv> [instance]
```

**CSV Format:**
```csv
user,email,fullname
jsmith,jsmith@company.com,John Smith
```

---

### delusers.py

Remove users that haven't accessed Perforce within the configured threshold.

```bash
python delusers.py [instance]
```

Uses the `weeks` threshold from `maintenance.cfg`.

---

### p4deleteuser.py

Remove Perforce users and their associated metadata (clients, shelves).

```bash
python p4deleteuser.py [instance] <user_or_file> [--simulate]
```

**Arguments:**
- `instance`: SDP instance identifier (default: '1')
- `user_or_file`: Username or file containing usernames (one per line)
- `--simulate`: Print actions without executing

**Features:**
- Protects service accounts (p4admin, perforce, swarm) from deletion
- Supports batch deletion from files
- Uses `p4 user -FDy` command

---

### setpass.py

Set a user's password to the default password configured in `maintenance.cfg`.

```bash
python setpass.py [instance] <username>
```

---

### checkusers.py

Find group members without corresponding user accounts (orphaned members).

```bash
python checkusers.py [instance]
```

**Output:** `removeusersfromgroups.txt`

---

### checkusers_not_in_group.py

Find users that are not members of any Perforce group.

```bash
python checkusers_not_in_group.py [instance]
```

---

### maintain_user_from_groups.py

Sync users based on group membership - creates missing users and removes users not in any group.

```bash
python maintain_user_from_groups.py [instance]
```

---

### email_pending_user_deletes.py

Send warning emails to users whose accounts are scheduled for deletion due to inactivity.

```bash
python email_pending_user_deletes.py [instance]
```

Uses `userweeks` threshold from `maintenance.cfg`.

---

### totalusers.py

Generate a CSV report of Perforce users across multiple servers.

```bash
python totalusers.py [cfgfile] [--output <outfile>] [--verbose]
```

**Configuration File (totalusers.cfg):**
```
case_sensitive=1
ROBOT,p4robot
ROBOT,jenkins
SERVER,server1.example.com:1666,p4admin,1
SERVER,server2.example.com:1666,p4admin,2
```

---

## Group Management Scripts

### creategroups.py

Create Perforce groups from a configuration file.

```bash
python creategroups.py [instance]
```

**Input File Format (groups.txt):**
```
group,groupname1
username1
username2
group,groupname2
username3
```

---

### addusertogroup.py

Add user(s) to a Perforce group.

```bash
python addusertogroup.py [instance] <user_or_file> <group>
```

**Examples:**
```bash
python addusertogroup.py jsmith developers
python addusertogroup.py 2 userlist.txt developers
```

---

### removeuserfromgroups.py

Remove user(s) from all their Perforce groups.

```bash
python removeuserfromgroups.py [instance] <user_or_file>
```

---

### removeuserfromgroups_file.py

Remove users from a specific list of groups.

```bash
python removeuserfromgroups_file.py <instance> <user_or_file> <groups_file>
```

---

### removeusersfromgroup.py

Remove users from a specific group.

```bash
python removeusersfromgroup.py [instance] <user_or_file> <groupname>
```

---

### mirroraccess.py

Mirror user access from one user to others (add target users to all groups the source user belongs to).

```bash
python mirroraccess.py <instance> <source_user> <target_user> [<user3> ... <userN>]
```

---

### group_audit.py

Send quarterly audit reminders to group owners asking them to validate group membership.

```bash
python group_audit.py [instance]
```

---

## Client Management Scripts

### unload_clients.py

Unload inactive Perforce clients to the unload depot.

```bash
python unload_clients.py [instance]
```

Uses `weeks` threshold from `maintenance.cfg`. Skips Swarm clients.

---

### unload_clients_with_delete.py

Unload inactive clients, but forcibly delete those with exclusive file locks (which can't be unloaded).

```bash
python unload_clients_with_delete.py [instance]
```

---

### delete_unload_clients.py

Delete inactive unloaded clients from the unload depot.

```bash
python delete_unload_clients.py [instance]
```

Uses `deleteweeks` threshold from `maintenance.cfg`.

---

### unloadaccessdates.py

Generate lists of inactive unloaded clients and labels.

```bash
python unloadaccessdates.py [instance]
```

**Output Files:**
- `unload_clients.txt`
- `unload_labels.txt`

---

### email_pending_client_deletes.py

Send warning emails for inactive clients scheduled for unload.

```bash
python email_pending_client_deletes.py [instance]
```

Sends two-tier warnings using `weeks1warn` and `weeks2warn` thresholds.

---

### del_shelve.py

Delete shelves and inactive clients.

```bash
python del_shelve.py [instance]
```

---

## Label Management Scripts

### unload_labels.py

Unload labels that haven't been accessed within the configured threshold.

```bash
python unload_labels.py [instance]
```

---

### convert_label_to_autoreload.py

Convert Perforce labels from `noautoreload` to `autoreload` mode.

```bash
python convert_label_to_autoreload.py [instance] <label_or_file>
```

---

### isitalabel.py

Check if a label exists in Perforce.

```bash
python isitalabel.py [instance] <labelname>
```

**Exit Codes:**
- `0`: Label exists
- `1`: Label not found

---

### p4lock.py

Lock a Perforce label.

```bash
python p4lock.py [instance] <labelname>
```

---

### p4unlock.py

Unlock a Perforce label.

```bash
python p4unlock.py [instance] <labelname>
```

> **Note:** Saves owner info to `owner.txt` for restoration by `p4lock.py`.

---

## Email and Notification Scripts

### email.sh

Send email to all Perforce users.

```bash
./email.sh "Subject line"
```

**Prerequisites:**
- `message.txt` must exist containing the email body
- `pymail.py` must be available

---

### pymail.py

Send email from command line using SMTP.

```bash
python pymail.py -t <to-address or file> -s <subject> -i <input-file> [instance]
```

**Arguments:**
- `-t`: Recipient email address or path to file with addresses
- `-s`: Email subject
- `-i`: Path to file containing email body

**Examples:**
```bash
python pymail.py -t admin@example.com -s "Test" -i message.txt
python pymail.py -t recipients.txt -s "Announcement" -i body.txt 2
```

---

## Protection Table Scripts

### protect_groups.py

Find groups in the protection table that don't exist on the server.

```bash
# First, extract groups from protect table
p4 protect -o | grep group | cut -d " " -f 3 | sort | uniq > protect_groups.txt

# Then find non-existent groups
python protect_groups.py [instance] protect_groups.txt > remove_groups.txt
```

---

### clean_protect.py

Remove groups from the Perforce protection table.

```bash
# Generate protection table
p4 protect -o > p4.protect

# Clean up invalid groups
python clean_protect.py remove_groups.txt p4.protect

# Review and apply
p4 protect -i < new.p4.protect
```

---

## Reporting Scripts

### countrevs.py

Count total files and revisions from a Perforce files list.

```bash
p4 files //... > files.txt
python countrevs.py files.txt
```

---

### proxysearch.py

Find proxy servers in Perforce server log.

```bash
python proxysearch.py <logfile>
```

**Output:** Unique proxy IP addresses (one per line)

---

## File and Archive Operations

### create_p4_filelist.sh

Generate a combined file list from all Perforce depots.

```bash
./create_p4_filelist.sh
```

**Output:** `p4_file_list.txt`

Iterates through depots one directory level deep to avoid memory spikes.

---

### lowercp.py

Copy a directory tree to a target with lowercase names.

```bash
cd /p4/1/depots
python lowercp.py depot
```

> **Note:** Configure `TARGETDEPOTPATH` variable at top of script.

---

### lowertree.py

Rename a directory tree to all lowercase (in place).

```bash
python lowertree.py <directory>
```

Useful for converting from case-sensitive to case-insensitive Perforce servers.

---

### remove_empty_pending_changes.py

Delete all empty pending changelists.

```bash
python remove_empty_pending_changes.py [instance]
```

> **Note:** Changelists with `#do-not-delete` in description are protected.

---

### remove_jobs.py

Remove Perforce jobs and their associated fixes.

```bash
p4 jobs > jobs.txt
python remove_jobs.py [instance] jobs.txt
```

---

### update-changes.py

Force update on changelists (useful with form triggers).

```bash
p4 changes | cut -d " " -f 2 > changes.txt
python update-changes.py [instance] changes.txt
```

---

## Utility Scripts

### sdputils.py

Core utility module used by most other maintenance scripts. Provides:

- `SDPUtils` class for Perforce interactions
- Configuration loading from `maintenance.cfg`
- Safe `p4` command execution via `run_p4()`
- Secure password management
- Common Perforce operations (get users, groups, etc.)

**Example Usage:**
```python
from sdputils import SDPUtils

utils = SDPUtils("1")
utils.login()
users = utils.get_all_users()
```

---

# Summary

| Category | Script Count |
|----------|--------------|
| User Management | 10 |
| Group Management | 7 |
| Client Management | 6 |
| Label Management | 5 |
| Email/Notification | 3 |
| Protection Table | 2 |
| Reporting | 2 |
| File/Archive Operations | 5 |
| Utility | 1 |
| **Total** | **41** |

---

# Common Workflows

## Remove Inactive Users

```bash
# 1. Generate list of inactive users
python accessdates.py 1

# 2. Review users.txt, then delete
python p4deleteuser.py 1 users.txt --simulate  # Review first
python p4deleteuser.py 1 users.txt             # Execute
```

## Clean Up Inactive Clients

```bash
# 1. Send warnings to users
python email_pending_client_deletes.py 1

# 2. Unload inactive clients
python unload_clients.py 1

# 3. Later, delete unloaded clients
python delete_unload_clients.py 1
```

## Clean Up Protection Table

```bash
# 1. Extract groups from protect table
p4 protect -o | grep group | cut -d " " -f 3 | sort | uniq > protect_groups.txt

# 2. Find non-existent groups
python protect_groups.py 1 protect_groups.txt > remove_groups.txt

# 3. Export current protect table
p4 protect -o > p4.protect

# 4. Remove invalid groups
python clean_protect.py remove_groups.txt p4.protect

# 5. Review and apply
diff p4.protect new.p4.protect
p4 protect -i < new.p4.protect
```

## Audit Group Membership

```bash
# Find users in groups that don't exist
python checkusers.py 1

# Review and remove orphaned entries
python removeuserfromgroups.py 1 removeusersfromgroups.txt
```
# Change User Description Committed
#1 32388 Russell C. Jackson (Rusty) Updates using Claude.ai to clean up the code, reduce duplication, enhanace security, and use current standards.