Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
lvm-snapshots
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
infra
lvm-snapshots
Commits
b17feee7
Commit
b17feee7
authored
8 years ago
by
Administrator
Browse files
Options
Downloads
Patches
Plain Diff
Create, mount, remove, umount works
parent
7ba866d8
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
lvmsnapshot.py
+36
-16
36 additions, 16 deletions
lvmsnapshot.py
with
36 additions
and
16 deletions
lvmsnapshot.py
+
36
−
16
View file @
b17feee7
...
@@ -42,9 +42,9 @@ PERIOD_KEYS = OrderedDict([
...
@@ -42,9 +42,9 @@ PERIOD_KEYS = OrderedDict([
@contextmanager
@contextmanager
def
xfs_freeze
(
mountpoint
):
def
xfs_freeze
(
mountpoint
):
freeze_xfs
(
True
)
#
freeze_xfs(
mountpoint,
True)
yield
yield
freeze_xfs
(
False
)
#
freeze_xfs(
mountpoint,
False)
def
freeze_xfs
(
mountpoint
,
freeze
):
def
freeze_xfs
(
mountpoint
,
freeze
):
command
=
[
command
=
[
...
@@ -113,19 +113,24 @@ class Snapshot:
...
@@ -113,19 +113,24 @@ class Snapshot:
return
parent_name
,
timestamp
return
parent_name
,
timestamp
def
get_full_volume
(
self
):
def
get_full_volume
(
self
):
return
"
{}/{}
"
.
format
(
self
.
volume_group
,
self
.
get_name
())
return
"
{}/{}
"
.
format
(
self
.
parent_volume
.
volume_group
,
self
.
get_name
())
def
get_mountpoint
(
self
):
def
get_mountpoint
(
self
):
return
os
.
path
.
join
(
[
return
os
.
path
.
join
(
SNAPSHOT_BASE_DIR
,
self
.
parent_volume
.
name
,
self
.
get_timestamp_str
()
SNAPSHOT_BASE_DIR
,
self
.
parent_volume
.
name
,
self
.
get_timestamp_str
()
])
)
def
create_mountpoint
(
self
):
os
.
makedirs
(
self
.
get_mountpoint
(),
mode
=
0o755
,
exist_ok
=
True
)
def
get_mapper_device
(
self
):
def
get_mapper_device
(
self
):
return
"
/dev/mapper/{}-{}
"
.
format
(
self
.
volume_group
,
self
.
get_name
())
return
"
/dev/mapper/{}-{}
"
.
format
(
self
.
parent_volume
.
volume_group
,
self
.
get_name
().
replace
(
"
-
"
,
"
--
"
))
def
create
(
self
):
def
create
(
self
):
parent_mountpoint
=
self
.
parent_volume
.
get_mountpoint
()
parent_mountpoint
=
self
.
parent_volume
.
get_mountpoint
()
with
xfs_freeze
(
mountpoint
):
with
xfs_freeze
(
parent_
mountpoint
):
create_command
=
[
create_command
=
[
"
/sbin/lvcreate
"
,
"
/sbin/lvcreate
"
,
"
--snapshot
"
,
"
--snapshot
"
,
...
@@ -145,11 +150,12 @@ class Snapshot:
...
@@ -145,11 +150,12 @@ class Snapshot:
]
]
sp
.
run
(
activate_command
,
check
=
True
)
sp
.
run
(
activate_command
,
check
=
True
)
self
.
active
=
True
self
.
active
=
True
self
.
create_mountpoint
()
mount_command
=
[
mount_command
=
[
"
/bin/mount
"
,
"
/bin/mount
"
,
self
.
get_mapper_device
(),
self
.
get_mapper_device
(),
self
.
get_mountpoint
(),
self
.
get_mountpoint
(),
"
-onouuid,ro
"
# nouuid is necessary for xfs snapshots
"
-onouuid,ro
,norecovery
"
# nouuid is necessary for xfs snapshots
]
]
sp
.
run
(
mount_command
,
check
=
True
)
sp
.
run
(
mount_command
,
check
=
True
)
...
@@ -175,6 +181,7 @@ class Snapshot:
...
@@ -175,6 +181,7 @@ class Snapshot:
]
]
sp
.
run
(
deactivate_command
,
check
=
True
)
sp
.
run
(
deactivate_command
,
check
=
True
)
self
.
active
=
False
self
.
active
=
False
os
.
rmdir
(
self
.
get_mountpoint
())
@staticmethod
@staticmethod
def
list_snapshots
():
def
list_snapshots
():
...
@@ -267,6 +274,7 @@ def load_config():
...
@@ -267,6 +274,7 @@ def load_config():
def
parse_config
(
config
):
def
parse_config
(
config
):
periods
=
{}
periods
=
{}
min_interval
=
None
for
volume_conf
in
config
[
"
volume
"
]:
for
volume_conf
in
config
[
"
volume
"
]:
name
=
volume_conf
[
"
name
"
]
name
=
volume_conf
[
"
name
"
]
volume_group
=
volume_conf
[
"
volume_group
"
]
volume_group
=
volume_conf
[
"
volume_group
"
]
...
@@ -274,20 +282,27 @@ def parse_config(config):
...
@@ -274,20 +282,27 @@ def parse_config(config):
periods
[
volume
]
=
[]
periods
[
volume
]
=
[]
for
raw_period
in
volume_conf
[
"
keep
"
]:
for
raw_period
in
volume_conf
[
"
keep
"
]:
interval
=
Period
.
parse_interval
(
raw_period
[
"
interval
"
])
interval
=
Period
.
parse_interval
(
raw_period
[
"
interval
"
])
if
min_interval
is
None
or
interval
<
min_interval
:
min_interval
=
interval
number
=
int
(
raw_period
[
"
number
"
])
number
=
int
(
raw_period
[
"
number
"
])
periods
[
volume
].
append
(
periods
[
volume
].
append
(
Period
(
target_number
=
number
,
interval
=
interval
))
Period
(
target_number
=
number
,
interval
=
interval
))
return
periods
return
periods
,
min_interval
def
mark_snapshots
(
snapshots
,
periods
):
def
mark_snapshots
(
snapshots
,
periods
,
min_interval
):
all_snapshots
=
set
(
snapshots
)
all_snapshots
=
set
(
snapshots
)
marked_snapshots
=
set
()
marked_snapshots
=
set
()
budgets
=
{
period
:
period
.
target_number
for
period
in
periods
}
budgets
=
{
period
:
period
.
target_number
for
period
in
periods
}
last_snapshot
=
{
period
:
None
for
period
in
periods
}
for
snapshot
in
sorted
(
snapshots
,
key
=
lambda
s
:
s
.
timestamp
):
for
snapshot
in
sorted
(
snapshots
,
key
=
lambda
s
:
s
.
timestamp
):
for
period
in
sorted
(
periods
,
key
=
Period
.
interval
):
for
period
in
sorted
(
periods
,
key
=
lambda
p
:
p
.
interval
):
required_distance
=
period
.
interval
-
min_interval
/
2
if
(
budgets
[
period
]
>
0
if
(
budgets
[
period
]
>
0
and
period
.
get_start
()
<
snapshot
.
timestamp
):
and
period
.
get_start
()
<
snapshot
.
timestamp
):
if
(
last_snapshot
[
period
]
is
None
or
abs
(
snapshot
.
timestamp
-
last_snapshot
[
period
].
timestamp
)
>
required_distance
):
marked_snapshots
.
add
(
snapshot
)
marked_snapshots
.
add
(
snapshot
)
last_snapshot
[
period
]
=
snapshot
budgets
[
period
]
-=
1
budgets
[
period
]
-=
1
unmarked_snapshots
=
all_snapshots
-
marked_snapshots
unmarked_snapshots
=
all_snapshots
-
marked_snapshots
return
unmarked_snapshots
return
unmarked_snapshots
...
@@ -295,15 +310,20 @@ def mark_snapshots(snapshots, periods):
...
@@ -295,15 +310,20 @@ def mark_snapshots(snapshots, periods):
def
main
():
def
main
():
config
=
load_config
()
config
=
load_config
()
snapshots
=
Snapshot
.
list_snapshots
()
snapshots
=
Snapshot
.
list_snapshots
()
periods
=
parse_config
(
config
)
periods
,
min_interval
=
parse_config
(
config
)
for
volume
in
set
(
periods
.
keys
())
-
set
(
snapshots
.
keys
()):
for
volume
in
set
(
periods
.
keys
())
-
set
(
snapshots
.
keys
()):
print
(
"
Warning: Volume {} is configured but does not exist or has no snapshots.
"
.
format
(
volume
))
print
(
"
Warning: Volume {} is configured but does not exist or has no snapshots.
"
.
format
(
volume
))
for
volume
in
set
(
snapshots
.
keys
())
-
set
(
periods
.
keys
()):
for
volume
in
set
(
snapshots
.
keys
())
-
set
(
periods
.
keys
()):
print
(
"
Warning: Volume {} does exist but is not configured.
"
.
format
(
volume
))
print
(
"
Warning: Volume {} does exist but is not configured.
"
.
format
(
volume
))
snapshots
.
pop
(
volume
)
snapshots
.
pop
(
volume
)
for
volume
in
snapshots
:
for
volume
in
snapshots
:
unmarked_snapshots
=
mark_snapshots
(
snapshots
[
volume
],
periods
[
volume
])
unmarked_snapshots
=
mark_snapshots
(
snapshots
[
volume
],
periods
[
volume
],
min_interval
)
print
(
unmarked_snapshots
)
print
(
"
removing
"
,
unmarked_snapshots
)
for
snapshot
in
unmarked_snapshots
:
snapshot
.
remove
()
new_snapshot
=
Snapshot
(
volume
,
datetime
.
now
())
new_snapshot
.
create
()
if
__name__
==
"
__main__
"
:
if
__name__
==
"
__main__
"
:
main
()
main
()
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment