Revision 4b97f902
b/Makefile.am | ||
---|---|---|
712 | 712 |
echo "XEN_INITRD = '$(XEN_INITRD)'"; \ |
713 | 713 |
echo "FILE_STORAGE_DIR = '$(FILE_STORAGE_DIR)'"; \ |
714 | 714 |
echo "ENABLE_FILE_STORAGE = $(ENABLE_FILE_STORAGE)"; \ |
715 |
echo "SHARED_FILE_STORAGE_DIR = '$(SHARED_FILE_STORAGE_DIR)'"; \ |
|
716 |
echo "ENABLE_SHARED_FILE_STORAGE = $(ENABLE_SHARED_FILE_STORAGE)"; \ |
|
715 | 717 |
echo "IALLOCATOR_SEARCH_PATH = [$(IALLOCATOR_SEARCH_PATH)]"; \ |
716 | 718 |
echo "KVM_PATH = '$(KVM_PATH)'"; \ |
717 | 719 |
echo "SOCAT_PATH = '$(SOCAT)'"; \ |
b/configure.ac | ||
---|---|---|
115 | 115 |
AC_SUBST(FILE_STORAGE_DIR, $file_storage_dir) |
116 | 116 |
AC_SUBST(ENABLE_FILE_STORAGE, $enable_file_storage) |
117 | 117 |
|
118 |
# --with-shared-file-storage-dir=... |
|
119 |
AC_ARG_WITH([shared-file-storage-dir], |
|
120 |
[AS_HELP_STRING([--with-shared-file-storage-dir=PATH], |
|
121 |
[directory to store files for shared file-based backend] |
|
122 |
[ (default is /srv/ganeti/shared-file-storage)] |
|
123 |
)], |
|
124 |
[[shared_file_storage_dir="$withval"; |
|
125 |
if test "$withval" != no; then |
|
126 |
enable_shared_file_storage=True |
|
127 |
else |
|
128 |
enable_shared_file_storage=False |
|
129 |
fi |
|
130 |
]], |
|
131 |
[[shared_file_storage_dir="/srv/ganeti/shared-file-storage"; enable_shared_file_storage="True"]]) |
|
132 |
AC_SUBST(SHARED_FILE_STORAGE_DIR, $shared_file_storage_dir) |
|
133 |
AC_SUBST(ENABLE_SHARED_FILE_STORAGE, $enable_shared_file_storage) |
|
134 |
|
|
118 | 135 |
# --with-kvm-path=... |
119 | 136 |
AC_ARG_WITH([kvm-path], |
120 | 137 |
[AS_HELP_STRING([--with-kvm-path=PATH], |
b/lib/backend.py | ||
---|---|---|
2404 | 2404 |
_Fail("; ".join(msgs)) |
2405 | 2405 |
|
2406 | 2406 |
|
2407 |
def _TransformFileStorageDir(file_storage_dir):
|
|
2407 |
def _TransformFileStorageDir(fs_dir):
|
|
2408 | 2408 |
"""Checks whether given file_storage_dir is valid. |
2409 | 2409 |
|
2410 |
Checks wheter the given file_storage_dir is within the cluster-wide
|
|
2411 |
default file_storage_dir stored in SimpleStore. Only paths under that
|
|
2412 |
directory are allowed.
|
|
2410 |
Checks wheter the given fs_dir is within the cluster-wide default
|
|
2411 |
file_storage_dir or the shared_file_storage_dir, which are stored in
|
|
2412 |
SimpleStore. Only paths under those directories are allowed.
|
|
2413 | 2413 |
|
2414 |
@type file_storage_dir: str
|
|
2415 |
@param file_storage_dir: the path to check
|
|
2414 |
@type fs_dir: str
|
|
2415 |
@param fs_dir: the path to check
|
|
2416 | 2416 |
|
2417 | 2417 |
@return: the normalized path if valid, None otherwise |
2418 | 2418 |
|
... | ... | |
2420 | 2420 |
if not constants.ENABLE_FILE_STORAGE: |
2421 | 2421 |
_Fail("File storage disabled at configure time") |
2422 | 2422 |
cfg = _GetConfig() |
2423 |
file_storage_dir = os.path.normpath(file_storage_dir) |
|
2424 |
base_file_storage_dir = cfg.GetFileStorageDir() |
|
2425 |
if (os.path.commonprefix([file_storage_dir, base_file_storage_dir]) != |
|
2426 |
base_file_storage_dir): |
|
2423 |
fs_dir = os.path.normpath(fs_dir) |
|
2424 |
base_fstore = cfg.GetFileStorageDir() |
|
2425 |
base_shared = cfg.GetSharedFileStorageDir() |
|
2426 |
if ((os.path.commonprefix([fs_dir, base_fstore]) != base_fstore) and |
|
2427 |
(os.path.commonprefix([fs_dir, base_shared]) != base_shared)): |
|
2427 | 2428 |
_Fail("File storage directory '%s' is not under base file" |
2428 |
" storage directory '%s'", file_storage_dir, base_file_storage_dir) |
|
2429 |
return file_storage_dir |
|
2429 |
" storage directory '%s' or shared storage directory '%s'", |
|
2430 |
fs_dir, base_fstore, base_shared) |
|
2431 |
return fs_dir |
|
2430 | 2432 |
|
2431 | 2433 |
|
2432 | 2434 |
def CreateFileStorageDir(file_storage_dir): |
b/lib/bdev.py | ||
---|---|---|
1 | 1 |
# |
2 | 2 |
# |
3 | 3 |
|
4 |
# Copyright (C) 2006, 2007, 2010 Google Inc. |
|
4 |
# Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
|
|
5 | 5 |
# |
6 | 6 |
# This program is free software; you can redistribute it and/or modify |
7 | 7 |
# it under the terms of the GNU General Public License as published by |
... | ... | |
2074 | 2074 |
constants.LD_DRBD8: DRBD8, |
2075 | 2075 |
} |
2076 | 2076 |
|
2077 |
if constants.ENABLE_FILE_STORAGE: |
|
2077 |
if constants.ENABLE_FILE_STORAGE or constants.ENABLE_SHARED_FILE_STORAGE:
|
|
2078 | 2078 |
DEV_MAP[constants.LD_FILE] = FileStorage |
2079 | 2079 |
|
2080 | 2080 |
|
b/lib/bootstrap.py | ||
---|---|---|
410 | 410 |
master_netdev=master_netdev, |
411 | 411 |
cluster_name=clustername.name, |
412 | 412 |
file_storage_dir=file_storage_dir, |
413 |
shared_file_storage_dir=shared_file_storage_dir, |
|
413 | 414 |
enabled_hypervisors=enabled_hypervisors, |
414 | 415 |
beparams={constants.PP_DEFAULT: beparams}, |
415 | 416 |
nicparams={constants.PP_DEFAULT: nicparams}, |
b/lib/cli.py | ||
---|---|---|
79 | 79 |
"FORCE_VARIANT_OPT", |
80 | 80 |
"GLOBAL_FILEDIR_OPT", |
81 | 81 |
"HID_OS_OPT", |
82 |
"GLOBAL_SHARED_FILEDIR_OPT", |
|
82 | 83 |
"HVLIST_OPT", |
83 | 84 |
"HVOPTS_OPT", |
84 | 85 |
"HYPERVISOR_OPT", |
... | ... | |
972 | 973 |
metavar="DIR", |
973 | 974 |
default=constants.DEFAULT_FILE_STORAGE_DIR) |
974 | 975 |
|
976 |
GLOBAL_SHARED_FILEDIR_OPT = cli_option("--shared-file-storage-dir", |
|
977 |
dest="shared_file_storage_dir", |
|
978 |
help="Specify the default directory (cluster-" |
|
979 |
"wide) for storing the shared file-based" |
|
980 |
" disks [%s]" % |
|
981 |
constants.DEFAULT_SHARED_FILE_STORAGE_DIR, |
|
982 |
metavar="SHAREDDIR", |
|
983 |
default=constants.DEFAULT_SHARED_FILE_STORAGE_DIR) |
|
984 |
|
|
975 | 985 |
NOMODIFY_ETCHOSTS_OPT = cli_option("--no-etc-hosts", dest="modify_etc_hosts", |
976 | 986 |
help="Don't modify /etc/hosts", |
977 | 987 |
action="store_false", default=True) |
b/lib/client/gnt_cluster.py | ||
---|---|---|
352 | 352 |
ToStdout(" - lvm reserved volumes: %s", reserved_lvs) |
353 | 353 |
ToStdout(" - drbd usermode helper: %s", result["drbd_usermode_helper"]) |
354 | 354 |
ToStdout(" - file storage path: %s", result["file_storage_dir"]) |
355 |
ToStdout(" - shared file storage path: %s", |
|
356 |
result["shared_file_storage_dir"]) |
|
355 | 357 |
ToStdout(" - maintenance of node health: %s", |
356 | 358 |
result["maintain_node_health"]) |
357 | 359 |
ToStdout(" - uid pool: %s", |
b/lib/cmdlib.py | ||
---|---|---|
1036 | 1036 |
# Special case for file storage |
1037 | 1037 |
if storage_type == constants.ST_FILE: |
1038 | 1038 |
# storage.FileStorage wants a list of storage directories |
1039 |
return [[cfg.GetFileStorageDir()]] |
|
1039 |
return [[cfg.GetFileStorageDir(), cfg.GetSharedFileStorageDir()]]
|
|
1040 | 1040 |
|
1041 | 1041 |
return [] |
1042 | 1042 |
|
... | ... | |
4696 | 4696 |
"volume_group_name": cluster.volume_group_name, |
4697 | 4697 |
"drbd_usermode_helper": cluster.drbd_usermode_helper, |
4698 | 4698 |
"file_storage_dir": cluster.file_storage_dir, |
4699 |
"shared_file_storage_dir": cluster.shared_file_storage_dir, |
|
4699 | 4700 |
"maintain_node_health": cluster.maintain_node_health, |
4700 | 4701 |
"ctime": cluster.ctime, |
4701 | 4702 |
"mtime": cluster.mtime, |
... | ... | |
5542 | 5543 |
old_name = inst.name |
5543 | 5544 |
|
5544 | 5545 |
rename_file_storage = False |
5545 |
if (inst.disk_template == constants.DT_FILE and
|
|
5546 |
if (inst.disk_template in (constants.DT_FILE, constants.DT_SHARED_FILE) and
|
|
5546 | 5547 |
self.op.new_name != inst.name): |
5547 | 5548 |
old_file_storage_dir = os.path.dirname(inst.disks[0].logical_id[1]) |
5548 | 5549 |
rename_file_storage = True |
... | ... | |
6635 | 6636 |
disk_index)), |
6636 | 6637 |
mode=disk["mode"]) |
6637 | 6638 |
disks.append(disk_dev) |
6639 |
elif template_name == constants.DT_SHARED_FILE: |
|
6640 |
if len(secondary_nodes) != 0: |
|
6641 |
raise errors.ProgrammerError("Wrong template configuration") |
|
6642 |
|
|
6643 |
opcodes.RequireSharedFileStorage() |
|
6644 |
|
|
6645 |
for idx, disk in enumerate(disk_info): |
|
6646 |
disk_index = idx + base_index |
|
6647 |
disk_dev = objects.Disk(dev_type=constants.LD_FILE, size=disk["size"], |
|
6648 |
iv_name="disk/%d" % disk_index, |
|
6649 |
logical_id=(file_driver, |
|
6650 |
"%s/disk%d" % (file_storage_dir, |
|
6651 |
disk_index)), |
|
6652 |
mode=disk["mode"]) |
|
6653 |
disks.append(disk_dev) |
|
6638 | 6654 |
else: |
6639 | 6655 |
raise errors.ProgrammerError("Invalid disk template '%s'" % template_name) |
6640 | 6656 |
return disks |
... | ... | |
6744 | 6760 |
pnode = target_node |
6745 | 6761 |
all_nodes = [pnode] |
6746 | 6762 |
|
6747 |
if instance.disk_template == constants.DT_FILE:
|
|
6763 |
if instance.disk_template in (constants.DT_FILE, constants.DT_SHARED_FILE):
|
|
6748 | 6764 |
file_storage_dir = os.path.dirname(instance.disks[0].logical_id[1]) |
6749 | 6765 |
result = lu.rpc.call_file_storage_dir_create(pnode, file_storage_dir) |
6750 | 6766 |
|
... | ... | |
6834 | 6850 |
# 128 MB are added for drbd metadata for each disk |
6835 | 6851 |
constants.DT_DRBD8: _compute(disks, 128), |
6836 | 6852 |
constants.DT_FILE: {}, |
6853 |
constants.DT_SHARED_FILE: {}, |
|
6837 | 6854 |
} |
6838 | 6855 |
|
6839 | 6856 |
if disk_template not in req_size_dict: |
... | ... | |
6854 | 6871 |
# 128 MB are added for drbd metadata for each disk |
6855 | 6872 |
constants.DT_DRBD8: sum(d["size"] + 128 for d in disks), |
6856 | 6873 |
constants.DT_FILE: None, |
6874 |
constants.DT_SHARED_FILE: 0, |
|
6857 | 6875 |
} |
6858 | 6876 |
|
6859 | 6877 |
if disk_template not in req_size_dict: |
... | ... | |
7657 | 7675 |
else: |
7658 | 7676 |
network_port = None |
7659 | 7677 |
|
7660 |
if constants.ENABLE_FILE_STORAGE: |
|
7678 |
if constants.ENABLE_FILE_STORAGE or constants.ENABLE_SHARED_FILE_STORAGE:
|
|
7661 | 7679 |
# this is needed because os.path.join does not accept None arguments |
7662 | 7680 |
if self.op.file_storage_dir is None: |
7663 | 7681 |
string_file_storage_dir = "" |
... | ... | |
7665 | 7683 |
string_file_storage_dir = self.op.file_storage_dir |
7666 | 7684 |
|
7667 | 7685 |
# build the full file storage dir path |
7668 |
file_storage_dir = utils.PathJoin(self.cfg.GetFileStorageDir(), |
|
7686 |
if self.op.disk_template == constants.DT_SHARED_FILE: |
|
7687 |
get_fsd_fn = self.cfg.GetSharedFileStorageDir |
|
7688 |
else: |
|
7689 |
get_fsd_fn = self.cfg.GetFileStorageDir |
|
7690 |
|
|
7691 |
file_storage_dir = utils.PathJoin(get_fsd_fn(), |
|
7669 | 7692 |
string_file_storage_dir, instance) |
7670 | 7693 |
else: |
7671 | 7694 |
file_storage_dir = "" |
... | ... | |
8811 | 8834 |
|
8812 | 8835 |
self.disk = instance.FindDisk(self.op.disk) |
8813 | 8836 |
|
8814 |
if instance.disk_template != constants.DT_FILE: |
|
8815 |
# TODO: check the free disk space for file, when that feature |
|
8816 |
# will be supported |
|
8837 |
if instance.disk_template not in (constants.DT_FILE, |
|
8838 |
constants.DT_SHARED_FILE): |
|
8839 |
# TODO: check the free disk space for file, when that feature will be |
|
8840 |
# supported |
|
8817 | 8841 |
_CheckNodesFreeDiskPerVG(self, nodenames, |
8818 | 8842 |
self.disk.ComputeGrowth(self.op.amount)) |
8819 | 8843 |
|
... | ... | |
9554 | 9578 |
result.append(("disk/%d" % device_idx, "remove")) |
9555 | 9579 |
elif disk_op == constants.DDM_ADD: |
9556 | 9580 |
# add a new disk |
9557 |
if instance.disk_template == constants.DT_FILE: |
|
9581 |
if instance.disk_template in (constants.DT_FILE, |
|
9582 |
constants.DT_SHARED_FILE): |
|
9558 | 9583 |
file_driver, file_path = instance.disks[0].logical_id |
9559 | 9584 |
file_path = os.path.dirname(file_path) |
9560 | 9585 |
else: |
b/lib/config.py | ||
---|---|---|
878 | 878 |
return self._config_data.cluster.file_storage_dir |
879 | 879 |
|
880 | 880 |
@locking.ssynchronized(_config_lock, shared=1) |
881 |
def GetSharedFileStorageDir(self): |
|
882 |
"""Get the shared file storage dir for this cluster. |
|
883 |
|
|
884 |
""" |
|
885 |
return self._config_data.cluster.shared_file_storage_dir |
|
886 |
|
|
887 |
@locking.ssynchronized(_config_lock, shared=1) |
|
881 | 888 |
def GetHypervisorType(self): |
882 | 889 |
"""Get the hypervisor type for this cluster. |
883 | 890 |
|
... | ... | |
1738 | 1745 |
constants.SS_CLUSTER_NAME: cluster.cluster_name, |
1739 | 1746 |
constants.SS_CLUSTER_TAGS: cluster_tags, |
1740 | 1747 |
constants.SS_FILE_STORAGE_DIR: cluster.file_storage_dir, |
1748 |
constants.SS_SHARED_FILE_STORAGE_DIR: cluster.shared_file_storage_dir, |
|
1741 | 1749 |
constants.SS_MASTER_CANDIDATES: mc_data, |
1742 | 1750 |
constants.SS_MASTER_CANDIDATES_IPS: mc_ips_data, |
1743 | 1751 |
constants.SS_MASTER_IP: cluster.master_ip, |
b/lib/constants.py | ||
---|---|---|
144 | 144 |
KVM_IFUP = _autoconf.PKGLIBDIR + "/kvm-ifup" |
145 | 145 |
ETC_HOSTS = "/etc/hosts" |
146 | 146 |
DEFAULT_FILE_STORAGE_DIR = _autoconf.FILE_STORAGE_DIR |
147 |
DEFAULT_SHARED_FILE_STORAGE_DIR = _autoconf.SHARED_FILE_STORAGE_DIR |
|
147 | 148 |
ENABLE_FILE_STORAGE = _autoconf.ENABLE_FILE_STORAGE |
149 |
ENABLE_SHARED_FILE_STORAGE = _autoconf.ENABLE_SHARED_FILE_STORAGE |
|
148 | 150 |
SYSCONFDIR = _autoconf.SYSCONFDIR |
149 | 151 |
TOOLSDIR = _autoconf.TOOLSDIR |
150 | 152 |
CONF_DIR = SYSCONFDIR + "/ganeti" |
... | ... | |
360 | 362 |
DT_PLAIN = "plain" |
361 | 363 |
DT_DRBD8 = "drbd" |
362 | 364 |
DT_FILE = "file" |
365 |
DT_SHARED_FILE = "sharedfile" |
|
363 | 366 |
|
364 | 367 |
# the set of network-mirrored disk templates |
365 | 368 |
DTS_NET_MIRROR = frozenset([DT_DRBD8]) |
366 | 369 |
|
370 |
# the set of externally mirrored disk templates |
|
371 |
DTS_EXT_MIRROR = frozenset([DT_SHARED_FILE]) |
|
372 |
|
|
367 | 373 |
# the set of non-lvm-based disk templates |
368 |
DTS_NOT_LVM = frozenset([DT_DISKLESS, DT_FILE]) |
|
374 |
DTS_NOT_LVM = frozenset([DT_DISKLESS, DT_FILE, DT_SHARED_FILE])
|
|
369 | 375 |
|
370 | 376 |
# the set of disk templates which can be grown |
371 |
DTS_GROWABLE = frozenset([DT_PLAIN, DT_DRBD8, DT_FILE]) |
|
377 |
DTS_GROWABLE = frozenset([DT_PLAIN, DT_DRBD8, DT_FILE, DT_SHARED_FILE])
|
|
372 | 378 |
|
373 | 379 |
# the set of disk templates that allow adoption |
374 | 380 |
DTS_MAY_ADOPT = frozenset([DT_PLAIN]) |
... | ... | |
449 | 455 |
#: Give child process up to 5 seconds to exit after sending a signal |
450 | 456 |
CHILD_LINGER_TIMEOUT = 5.0 |
451 | 457 |
|
452 |
DISK_TEMPLATES = frozenset([DT_DISKLESS, DT_PLAIN, |
|
453 |
DT_DRBD8, DT_FILE])
|
|
458 |
DISK_TEMPLATES = frozenset([DT_DISKLESS, DT_PLAIN, DT_DRBD8,
|
|
459 |
DT_FILE, DT_SHARED_FILE])
|
|
454 | 460 |
|
455 | 461 |
FILE_DRIVER = frozenset([FD_LOOP, FD_BLKTAP]) |
456 | 462 |
|
... | ... | |
1077 | 1083 |
SS_CLUSTER_NAME = "cluster_name" |
1078 | 1084 |
SS_CLUSTER_TAGS = "cluster_tags" |
1079 | 1085 |
SS_FILE_STORAGE_DIR = "file_storage_dir" |
1086 |
SS_SHARED_FILE_STORAGE_DIR = "shared_file_storage_dir" |
|
1080 | 1087 |
SS_MASTER_CANDIDATES = "master_candidates" |
1081 | 1088 |
SS_MASTER_CANDIDATES_IPS = "master_candidates_ips" |
1082 | 1089 |
SS_MASTER_IP = "master_ip" |
b/lib/objects.py | ||
---|---|---|
558 | 558 |
actual algorithms from bdev. |
559 | 559 |
|
560 | 560 |
""" |
561 |
if self.dev_type == constants.LD_LV or self.dev_type == constants.LD_FILE:
|
|
561 |
if self.dev_type in (constants.LD_LV, constants.LD_FILE):
|
|
562 | 562 |
self.size += amount |
563 | 563 |
elif self.dev_type == constants.LD_DRBD8: |
564 | 564 |
if self.children: |
... | ... | |
1066 | 1066 |
"master_netdev", |
1067 | 1067 |
"cluster_name", |
1068 | 1068 |
"file_storage_dir", |
1069 |
"shared_file_storage_dir", |
|
1069 | 1070 |
"enabled_hypervisors", |
1070 | 1071 |
"hvparams", |
1071 | 1072 |
"os_hvp", |
b/lib/opcodes.py | ||
---|---|---|
162 | 162 |
errors.ECODE_INVAL) |
163 | 163 |
|
164 | 164 |
|
165 |
def RequireSharedFileStorage(): |
|
166 |
"""Checks that shared file storage is enabled. |
|
167 |
|
|
168 |
While it doesn't really fit into this module, L{utils} was deemed too large |
|
169 |
of a dependency to be imported for just one or two functions. |
|
170 |
|
|
171 |
@raise errors.OpPrereqError: when shared file storage is disabled |
|
172 |
|
|
173 |
""" |
|
174 |
if not constants.ENABLE_SHARED_FILE_STORAGE: |
|
175 |
raise errors.OpPrereqError("Shared file storage disabled at" |
|
176 |
" configure time", errors.ECODE_INVAL) |
|
177 |
|
|
178 |
|
|
165 | 179 |
@ht.WithDesc("CheckFileStorage") |
166 | 180 |
def _CheckFileStorage(value): |
167 | 181 |
"""Ensures file storage is enabled if used. |
... | ... | |
169 | 183 |
""" |
170 | 184 |
if value == constants.DT_FILE: |
171 | 185 |
RequireFileStorage() |
186 |
elif value == constants.DT_SHARED_FILE: |
|
187 |
RequireSharedFileStorage() |
|
172 | 188 |
return True |
173 | 189 |
|
174 | 190 |
|
b/lib/ssconf.py | ||
---|---|---|
155 | 155 |
def GetFileStorageDir(self): |
156 | 156 |
return self._config_data["cluster"]["file_storage_dir"] |
157 | 157 |
|
158 |
def GetSharedFileStorageDir(self): |
|
159 |
return self._config_data["cluster"]["shared_file_storage_dir"] |
|
160 |
|
|
158 | 161 |
def GetNodeList(self): |
159 | 162 |
return self._config_data["nodes"].keys() |
160 | 163 |
|
... | ... | |
272 | 275 |
constants.SS_CLUSTER_NAME, |
273 | 276 |
constants.SS_CLUSTER_TAGS, |
274 | 277 |
constants.SS_FILE_STORAGE_DIR, |
278 |
constants.SS_SHARED_FILE_STORAGE_DIR, |
|
275 | 279 |
constants.SS_MASTER_CANDIDATES, |
276 | 280 |
constants.SS_MASTER_CANDIDATES_IPS, |
277 | 281 |
constants.SS_MASTER_IP, |
... | ... | |
369 | 373 |
""" |
370 | 374 |
return self._ReadFile(constants.SS_FILE_STORAGE_DIR) |
371 | 375 |
|
376 |
def GetSharedFileStorageDir(self): |
|
377 |
"""Get the shared file storage dir. |
|
378 |
|
|
379 |
""" |
|
380 |
return self._ReadFile(constants.SS_SHARED_FILE_STORAGE_DIR) |
|
381 |
|
|
372 | 382 |
def GetMasterCandidates(self): |
373 | 383 |
"""Return the list of master candidates. |
374 | 384 |
|
Also available in: Unified diff