Skip to content

Commit d4e2d8c

Browse files
committed
Feat: allow user to define custom template for share name
1 parent 857bd9b commit d4e2d8c

File tree

9 files changed

+115
-3
lines changed

9 files changed

+115
-3
lines changed

usr/lib/python3/dist-packages/linuxmusterLinuxclient7/config.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ def network():
1919

2020
return True, networkConfig
2121

22+
def shares():
23+
"""
24+
Get the shares configuration in `/etc/linuxmuster-linuxclient7/config.yml`
25+
26+
:return: Tuple (success, dict of keys)
27+
:rtype: tuple
28+
"""
29+
config = _readConfig()
30+
sharesConfig = {}
31+
if config is not None and "shares" in config:
32+
sharesConfig = config["shares"]
33+
34+
if not "nameTemplate" in sharesConfig:
35+
sharesConfig["nameTemplate"] = constants.defaultShareNameTemplate
36+
37+
return sharesConfig
38+
2239
def writeNetworkConfig(newNetworkConfig):
2340
"""
2441
Write the network configuration in `/etc/linuxmuster-linuxclient7/config.yml`.

usr/lib/python3/dist-packages/linuxmusterLinuxclient7/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
shareMountBasepath = "/home/{}/media"
1111
hiddenShareMountBasepath = "/srv/samba/{}"
1212
machineAccountSysvolMountPath = "/var/lib/samba/sysvol"
13+
defaultShareNameTemplate = "{label} ({letter}:)"
1314

1415
etcBaseDir = "/etc/linuxmuster-linuxclient7"
1516
shareBaseDir = "/usr/share/linuxmuster-linuxclient7"

usr/lib/python3/dist-packages/linuxmusterLinuxclient7/gpo.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ def _processDrivesPolicy(policyBasepath):
239239

240240
for drive in shareList:
241241
if drive["useLetter"] == "1":
242-
shareName = f"{drive['label']} ({drive['letter']}:)"
242+
nameTemplate = config.shares()["nameTemplate"]
243+
shareName = nameTemplate.format(label=drive['label'], letter=drive['letter'])
243244
else:
244245
shareName = drive["label"]
245246

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
network:
2+
serverHostname: server.linuxmuster.lan
3+
domain: linuxmuster.lan
4+
realm: LINUXMUSTER.LAN

usr/lib/python3/dist-packages/linuxmusterLinuxclient7/tests/files/config/config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
shares:
2+
nameTemplate: "{label}_{letter}"
3+
14
network:
25
serverHostname: server.linuxmuster.lan
36
domain: linuxmuster.lan

usr/lib/python3/dist-packages/linuxmusterLinuxclient7/tests/test_config.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,27 @@ def test_network_invalid():
4444
assert not rc
4545
assert networkConfig is None
4646

47+
@mock.patch("linuxmusterLinuxclient7.config.constants.legacyNetworkConfigFilePath", f"/does/not/exist/network.conf")
48+
@mock.patch("linuxmusterLinuxclient7.config.constants.configFilePath", f"{os.path.dirname(os.path.realpath(__file__))}/files/config/config.yml")
49+
def test_shares():
50+
sharesConfig = config.shares()
51+
assert "nameTemplate" in sharesConfig
52+
assert sharesConfig["nameTemplate"] == "{label}_{letter}"
53+
54+
@mock.patch("linuxmusterLinuxclient7.config.constants.legacyNetworkConfigFilePath", f"/does/not/exist/network.conf")
55+
@mock.patch("linuxmusterLinuxclient7.config.constants.configFilePath", f"/does/not/exist/config.yml")
56+
def test_shares_none():
57+
sharesConfig = config.shares()
58+
assert "nameTemplate" in sharesConfig
59+
assert sharesConfig["nameTemplate"] == config.constants.defaultShareNameTemplate
60+
61+
@mock.patch("linuxmusterLinuxclient7.config.constants.legacyNetworkConfigFilePath", f"/does/not/exist/network.conf")
62+
@mock.patch("linuxmusterLinuxclient7.config.constants.configFilePath", f"{os.path.dirname(os.path.realpath(__file__))}/files/config/config.no-shares.yml")
63+
def test_shares_missing():
64+
sharesConfig = config.shares()
65+
assert "nameTemplate" in sharesConfig
66+
assert sharesConfig["nameTemplate"] == config.constants.defaultShareNameTemplate
67+
4768
@mock.patch("linuxmusterLinuxclient7.config.constants.legacyNetworkConfigFilePath", f"/does/not/exist/network.conf")
4869
@mock.patch("linuxmusterLinuxclient7.config.constants.configFilePath", f"{os.path.dirname(os.path.realpath(__file__))}/files/config/config.invalid-syntax.yml")
4970
def test_syntax_invalid():

usr/lib/python3/dist-packages/linuxmusterLinuxclient7/tests/test_gpo.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,47 @@ def test_allOkAllTrue(mockUserSchool, mockLdapHelperSearchOne, mockSharesGetMoun
4646
assert len(mockPrintersInstallPrinter.call_args_list) == 1
4747
assert mockPrintersInstallPrinter.call_args_list[0] == mock.call('ipp://SERVER/printers/PRINTER1', 'PRINTER1')
4848

49+
@mock.patch("linuxmusterLinuxclient7.gpo.config.shares")
50+
@mock.patch("linuxmusterLinuxclient7.gpo.computer.isInGroup")
51+
@mock.patch("linuxmusterLinuxclient7.gpo.user.isInGroup")
52+
@mock.patch("linuxmusterLinuxclient7.gpo.printers.installPrinter")
53+
@mock.patch("linuxmusterLinuxclient7.gpo.shares.mountShare")
54+
@mock.patch("linuxmusterLinuxclient7.gpo.shares.getMountpointOfRemotePath")
55+
@mock.patch("linuxmusterLinuxclient7.gpo.ldapHelper.searchOne")
56+
@mock.patch("linuxmusterLinuxclient7.gpo.user.school")
57+
def test_customShareNameTemplate(mockUserSchool, mockLdapHelperSearchOne, mockSharesGetMountpointOfRemotePath, mockSharesmMountShare, mockPrintersInstallPrinter, mockUserIsInGroup, mockComputerIsInGroup, mockConfigShares):
58+
mockUserSchool.return_value = (True, "school1")
59+
mockLdapHelperSearchOne.return_value = (True, {
60+
"distinguishedName": "policy1",
61+
"gPCFileSysPath": "\\\\linuxmuster.lan\\sysvol\\linuxmuster.lan\\Policies\\policy1"
62+
})
63+
mockSharesGetMountpointOfRemotePath.return_value = (True, f"{os.path.dirname(os.path.realpath(__file__))}/files/policy1")
64+
mockSharesmMountShare.return_value = (True, "")
65+
mockPrintersInstallPrinter.return_value = True
66+
mockUserIsInGroup.return_value = True
67+
mockComputerIsInGroup.return_value = True
68+
mockConfigShares.return_value = {
69+
"nameTemplate": "{label}_{letter}"
70+
}
71+
72+
assert gpo.processAllPolicies()
73+
assert len(mockSharesmMountShare.call_args_list) == 3
74+
assert mockSharesmMountShare.call_args_list[0] == mock.call('\\\\server\\default-school\\program', shareName='Programs_K')
75+
# Projects (P:) is disabled and should not be mounted
76+
assert mockSharesmMountShare.call_args_list[1] == mock.call('\\\\server\\default-school\\students', shareName='Students-Home_S')
77+
assert mockSharesmMountShare.call_args_list[2] == mock.call('\\\\server\\default-school\\share', shareName='Shares')
78+
79+
# Test without letter
80+
mockConfigShares.return_value = {
81+
"nameTemplate": "{label}"
82+
}
83+
assert gpo.processAllPolicies()
84+
assert len(mockSharesmMountShare.call_args_list) == 6
85+
assert mockSharesmMountShare.call_args_list[3] == mock.call('\\\\server\\default-school\\program', shareName='Programs')
86+
# Projects (P:) is disabled and should not be mounted
87+
assert mockSharesmMountShare.call_args_list[4] == mock.call('\\\\server\\default-school\\students', shareName='Students-Home')
88+
assert mockSharesmMountShare.call_args_list[5] == mock.call('\\\\server\\default-school\\share', shareName='Shares')
89+
4990
@mock.patch("linuxmusterLinuxclient7.gpo.computer.isInGroup")
5091
@mock.patch("linuxmusterLinuxclient7.gpo.user.isInGroup")
5192
@mock.patch("linuxmusterLinuxclient7.gpo.printers.installPrinter")

usr/lib/python3/dist-packages/linuxmusterLinuxclient7/tests/test_user.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,29 @@ def test_getHomeShareMountpoint(mockUsername, mockReadAttributes):
135135
rc, homeShareMountpoint = user.getHomeShareMountpoint()
136136
assert rc
137137
assert homeShareMountpoint == "/home/user1/media/user1 (H:)"
138+
139+
140+
@mock.patch("linuxmusterLinuxclient7.gpo.config.shares")
141+
@mock.patch("linuxmusterLinuxclient7.user.readAttributes")
142+
@mock.patch("linuxmusterLinuxclient7.user.username")
143+
def test_getHomeShareMountpointCustomShareNameTemplate(mockUsername, mockReadAttributes, mockConfigShares):
144+
mockUsername.return_value = "user1"
145+
mockReadAttributes.return_value = (True, {"homeDrive": "H:"})
146+
mockConfigShares.return_value = {
147+
"nameTemplate": "{label}_{letter}"
148+
}
149+
150+
rc, homeShareMountpoint = user.getHomeShareMountpoint()
151+
assert rc
152+
assert homeShareMountpoint == "/home/user1/media/user1_H"
153+
154+
# Test without letter
155+
mockConfigShares.return_value = {
156+
"nameTemplate": "{label}"
157+
}
158+
rc, homeShareMountpoint = user.getHomeShareMountpoint()
159+
assert rc
160+
assert homeShareMountpoint == "/home/user1/media/user1"
138161

139162
@mock.patch("linuxmusterLinuxclient7.user.shares.mountShare")
140163
@mock.patch("linuxmusterLinuxclient7.user.readAttributes")

usr/lib/python3/dist-packages/linuxmusterLinuxclient7/user.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,9 @@ def _getHomeShareName(userAttributes=None):
146146

147147
if rc:
148148
try:
149-
usernameString = username()
150-
shareName = f"{usernameString} ({userAttributes['homeDrive']})"
149+
nameTemplate = config.shares()["nameTemplate"]
150+
letter = userAttributes['homeDrive'].replace(':', '')
151+
shareName = nameTemplate.format(label=username(), letter=letter)
151152
return True, shareName
152153

153154
except Exception as e:

0 commit comments

Comments
 (0)