Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
elphel-apps-camogm
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
elphel-apps-camogm
Commits
2f0a2331
Commit
2f0a2331
authored
Jan 13, 2017
by
Mikhail Karpenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add script for disk partitioning
parent
456ea2b8
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
259 additions
and
1 deletion
+259
-1
Makefile
src/Makefile
+4
-1
format_disk.py
src/format_disk/format_disk.py
+255
-0
No files found.
src/Makefile
View file @
2f0a2331
GUIDIR
=
camogmgui
PROGS
=
camogm
TEST_PROG
=
camogm_test
EXESCRIPTS
=
format_disk/format_disk.py
PHPSCRIPTS
=
camogmstate.php
$(GUIDIR)
/camogmgui.php
$(GUIDIR)
/camogmgui.css
$(GUIDIR)
/camogmgui.js
$(GUIDIR)
/camogm_interface.php
\
$(GUIDIR)
/SpryTabbedPanels.css
$(GUIDIR)
/SpryTabbedPanels.js
$(GUIDIR)
/xml_simple.php
$(GUIDIR)
/SpryCollapsiblePanel.css
\
$(GUIDIR)
/SpryCollapsiblePanel.js
...
...
@@ -22,6 +23,7 @@ INSTALL = install
INSTMODE
=
0755
INSTDOCS
=
0644
OWN
=
-o
root
-g
root
LN
=
ln
-sf
SYSCONFDIR
=
/etc/
BINDIR
=
/usr/bin/
...
...
@@ -35,10 +37,11 @@ $(PROGS): $(OBJS)
$(TEST_PROG)
:
$(TEST_SRC:.c=.o)
install
:
$(PROGS) $(PHPSCRIPTS) $(CONFIGS)
install
:
$(PROGS) $(PHPSCRIPTS) $(CONFIGS)
$(EXESCRIPTS)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-m
$(INSTMODE)
$(PROGS)
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-m
$(INSTMODE)
$(TEST_PROG)
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-m
$(INSTMODE)
$(EXESCRIPTS)
$(DESTDIR)$(BINDIR)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(SYSCONFDIR)
$(INSTALL)
$(OWN)
-m
$(INSTDOCS)
$(CONFIGS)
$(DESTDIR)$(SYSCONFDIR)
$(INSTALL)
$(OWN)
-d
$(DESTDIR)$(WWW_PAGES)
...
...
src/format_disk/format_disk.py
0 → 100644
View file @
2f0a2331
#!/usr/bin/env python
# encoding: utf-8
from
__future__
import
print_function
from
__future__
import
division
from
subprocess
import
CalledProcessError
'''
# Copyright (C) 2017, Elphel.inc.
# Prepare and partition new disk for fast recording.
# This script creates two partitions on a disk: one is formatted to ext4 and the other
# is left unformatted for fast recording from camogm.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
__author__
=
"Elphel"
__copyright__
=
"Copyright 2017, Elphel, Inc."
__license__
=
"GPL"
__version__
=
"3.0+"
__maintainer__
=
"Mikhail Karpenko"
__email__
=
"mikhail@elphel.com"
__status__
=
"Development"
import
os
import
re
import
sys
import
stat
import
argparse
import
subprocess
# use this % of total disk space for system partition
SYS_PARTITION_RATIO
=
5
class
ErrCodes
(
object
):
OK
=
0
WRONG_DISK
=
1
WRONG_PATH
=
2
NOT_DISK
=
3
NO_TOOLS
=
4
NO_PERMISSIONS
=
5
PART_FAILURE
=
6
def
__init__
(
self
,
code
=
OK
):
"""
Prepare strings with error code description.
"""
# the length of this list must match the number of error code defined as clas attributes
self
.
err_str
=
[
"Operation finished successfully"
,
"The disk specified is already partitioned"
,
"Path to disk provided on the command line is invalid"
,
"The path provided is a partition, not a disk"
,
"One of the command-line utilities required for this script is not found"
,
"This scrip requires root permissions"
,
"Partitioning finished unsuccessfully"
]
self
.
_err_code
=
code
def
err2str
(
self
):
"""
Convert error code to string description.
Return: string containing error description
"""
if
self
.
_err_code
<
len
(
self
.
err_str
):
ret
=
self
.
err_str
[
self
.
_err_code
]
else
:
ret
=
"No description for this error code"
return
ret
@
property
def
err_code
(
self
):
return
self
.
_err_code
@
err_code
.
setter
def
err_code
(
self
,
val
):
if
val
<
len
(
self
.
err_str
):
self
.
_err_code
=
val
def
check_prerequisites
():
"""
Check all tools required for disk partitioning.
Return: emtry string if all tools are found and the name of a missing program otherwise
"""
ret_str
=
""
check_tools
=
[[
'parted'
,
'-v'
],
[
'mkfs.ext4'
,
'-V'
]]
# make it silent
with
open
(
'/dev/null'
,
'w'
)
as
devnull
:
for
tool
in
check_tools
:
try
:
subprocess
.
check_call
(
tool
,
stdout
=
devnull
,
stderr
=
devnull
)
except
:
ret_str
=
tool
[
0
]
return
ret_str
def
find_disks
():
"""
Find all attached and unpartitioned SCSI disks.
Return: a list containing paths to disks
"""
dlist
=
[]
try
:
partitions
=
subprocess
.
check_output
([
'cat'
,
'/proc/partitions'
])
# the first two elemets of the list are table header and empty line delimiter, skip them
for
partition
in
partitions
.
splitlines
()[
2
:]:
dev
=
re
.
search
(
' +(sd[a-z]$)'
,
partition
)
if
dev
:
dev_path
=
'/dev/{0}'
.
format
(
dev
.
group
(
1
))
plist
=
find_partitions
(
dev_path
)
if
not
plist
:
dlist
.
append
(
dev_path
)
except
:
# something went wrong, clear list to prevent accidental data loss
del
dlist
[:]
return
dlist
def
find_partitions
(
dev_path
):
"""
Find all partitions (if any) on a disk.
@param dev_path: path to device
Return: a list of full paths to partitions or empty list in case no partitions found on disk
"""
plist
=
[]
try
:
partitions
=
subprocess
.
check_output
([
'cat'
,
'/proc/partitions'
])
search_str
=
' +({0}[0-9]+$)'
.
format
(
dev_path
.
rpartition
(
'/'
)[
-
1
])
# the first two elemets of the list are table header and empty line delimiter, skip them
for
partition
in
partitions
.
splitlines
()[
2
:]:
dev
=
re
.
search
(
search_str
,
partition
)
if
dev
:
plist
.
append
(
'/dev/{0}'
.
format
(
dev
.
group
(
1
)))
except
:
# something went wrong, clear list to prevent accidental data loss
del
plist
[:]
return
plist
def
is_partition
(
dev_path
):
"""
Check if the path specified corresponds to partition and not to disk.
@param dev_path: path to device
Return: boolean value indicating if the path provided is a partition.
"""
# disk path should end with a character only
disk
=
re
.
search
(
'sd[a-z]$'
,
dev_path
)
if
disk
:
ret
=
False
else
:
ret
=
True
return
ret
def
get_disk_size
(
dev_path
):
"""
Get the size of disk specified.
@param dev_path: path to device
Return: disk size in GB
"""
try
:
parted_print
=
subprocess
.
check_output
([
'parted'
,
'-m'
,
dev_path
,
'unit'
,
'GB'
,
'print'
])
fields
=
parted_print
.
split
(
':'
)
sz
=
fields
[
1
]
disk_size
=
int
(
sz
[:
-
2
])
except
:
disk_size
=
0
return
disk_size
def
partition_disk
(
dev_path
,
sys_size
,
disk_size
,
dry_run
=
True
):
"""
Create partitions on disk and format system partition.
@param dev_path: path to device
@param sys_size: the size of system partition in GB
@param disk_size: total disk size in GB
Return: empty string in case of success or error message indicating the result of partitioning
"""
try
:
if
not
dry_run
:
# create system partition
start
=
0
end
=
sys_size
subprocess
.
check_call
([
'parted'
,
dev_path
,
'unit'
,
'GB'
,
'mkpart'
,
'primary'
,
str
(
start
),
str
(
end
)])
# create raw partition
start
=
sys_size
end
=
disk_size
subprocess
.
check_call
([
'parted'
,
dev_path
,
'unit'
,
'GB'
,
'mkpart'
,
'primary'
,
str
(
start
),
str
(
end
)])
# make file system of first partition
partition
=
dev_path
+
'1'
subprocess
.
check_call
([
'mkfs.ext4'
,
partition
])
ret_str
=
""
except
subprocess
.
CalledProcessError
as
e
:
ret_str
=
str
(
e
.
returncode
)
except
OSError
as
e
:
ret_str
=
e
.
strerror
return
ret_str
if
__name__
==
"__main__"
:
ret_str
=
check_prerequisites
()
if
ret_str
!=
""
:
ret_code
=
ErrCodes
(
ErrCodes
.
NO_TOOLS
)
print
(
"{0}: {1}"
.
format
(
ret_code
.
err2str
(),
ret_str
))
sys
.
exit
(
ret_code
.
err_code
)
if
os
.
geteuid
()
!=
0
:
ret_code
=
ErrCodes
(
ErrCodes
.
NO_PERMISSIONS
)
print
(
ret_code
.
err2str
())
sys
.
exit
(
ret_code
.
err_code
)
parser
=
argparse
.
ArgumentParser
(
description
=
"Prepare and partition new disk for fast recording from camogm"
)
parser
.
add_argument
(
'disk_path'
,
nargs
=
'?'
,
help
=
"path to a disk which should be partitioned, e.g /dev/sda"
)
parser
.
add_argument
(
'-l'
,
'--list'
,
action
=
'store_true'
,
help
=
"list attached disk(s) suitable for partitioning"
)
parser
.
add_argument
(
'-e'
,
'--errno'
,
nargs
=
1
,
type
=
int
,
help
=
"convert error number returned by the script to error message"
)
parser
.
add_argument
(
'-d'
,
'--dry_run'
,
action
=
'store_true'
,
help
=
"execute the script but do not actually create partitions"
)
args
=
parser
.
parse_args
()
if
args
.
list
:
disks
=
find_disks
()
for
disk
in
disks
:
print
(
disk
)
elif
args
.
errno
:
ret
=
ErrCodes
(
args
.
errno
[
0
])
print
(
ret
.
err2str
())
elif
args
.
disk_path
:
disk_path
=
""
ret_code
=
ErrCodes
()
if
os
.
path
.
exists
(
args
.
disk_path
):
mode
=
os
.
stat
(
args
.
disk_path
)
.
st_mode
if
stat
.
S_ISBLK
(
mode
):
if
not
is_partition
(
args
.
disk_path
):
disk_path
=
args
.
disk_path
plist
=
find_partitions
(
disk_path
)
if
not
plist
:
# OK, disk is not partitioned and we can proceed
ret_code
.
err_code
=
ErrCodes
.
OK
else
:
# stop, disk is already partitioned
ret_code
.
err_code
=
ErrCodes
.
WRONG_DISK
else
:
ret_code
.
err_code
=
ErrCodes
.
NOT_DISK
else
:
ret_code
.
err_code
=
ErrCodes
.
WRONG_PATH
else
:
ret_code
.
err_code
=
ErrCodes
.
WRONG_PATH
if
ret_code
.
err_code
!=
ErrCodes
.
OK
:
print
(
ret_code
.
err2str
())
sys
.
exit
(
ret_code
.
err_code
)
total_size
=
get_disk_size
(
disk_path
)
if
total_size
>
0
:
sys_size
=
total_size
*
(
SYS_PARTITION_RATIO
/
100
)
ret_str
=
partition_disk
(
disk_path
,
sys_size
,
total_size
,
args
.
dry_run
)
if
ret_str
:
ret_code
=
ErrCodes
(
ErrCodes
.
PART_FAILURE
)
print
(
ret_code
.
err2str
())
sys
.
exit
(
ret_code
.
err_code
)
else
:
parser
.
print_help
()
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment