hardlink.py revision 583
1516N/A#!/usr/bin/python2.4
49N/A#
49N/A# CDDL HEADER START
49N/A#
49N/A# The contents of this file are subject to the terms of the
49N/A# Common Development and Distribution License (the "License").
49N/A# You may not use this file except in compliance with the License.
49N/A#
49N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
49N/A# or http://www.opensolaris.org/os/licensing.
49N/A# See the License for the specific language governing permissions
49N/A# and limitations under the License.
49N/A#
49N/A# When distributing Covered Code, include this CDDL HEADER in each
49N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
49N/A# If applicable, add the following below this CDDL HEADER, with the
49N/A# fields enclosed by brackets "[]" replaced with your own identifying
49N/A# information: Portions Copyright [yyyy] [name of copyright owner]
49N/A#
49N/A# CDDL HEADER END
49N/A#
49N/A
49N/A#
1908N/A# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
49N/A# Use is subject to license terms.
49N/A#
49N/A
49N/A"""module describing a (hard) link packaging object
49N/A
49N/AThis module contains the HardLinkAction class, which represents a hardlink-type
49N/Apackaging object."""
49N/A
49N/Aimport os
49N/Afrom stat import *
51N/Aimport link
51N/A
51N/Aclass HardLinkAction(link.LinkAction):
51N/A """Class representing a hardlink-type packaging object."""
51N/A
49N/A name = "hardlink"
49N/A
49N/A def __init__(self, data=None, **attrs):
49N/A link.LinkAction.__init__(self, data, **attrs)
49N/A
49N/A def get_target_path(self):
49N/A """ return a path for target that is relative to image"""
49N/A
49N/A target = self.attrs["target"]
49N/A
49N/A # paths are either relative to path or absolute;
49N/A # both need to be passed through os.path.normpath to ensure
49N/A # that all ".." are removed to constrain target to image
49N/A
49N/A if target[0] != "/":
49N/A path = self.attrs["path"]
49N/A target = os.path.normpath(
49N/A os.path.join(os.path.split(path)[0], target))
49N/A else:
49N/A target = os.path.normpath(target)[1:]
49N/A
49N/A return target
49N/A
49N/A def install(self, pkgplan, orig):
49N/A """Client-side method that installs a hard link."""
49N/A
49N/A path = self.attrs["path"]
49N/A target = self.get_target_path()
49N/A
49N/A path = os.path.normpath(os.path.sep.join(
51N/A (pkgplan.image.get_root(), path)))
49N/A
49N/A if not os.path.exists(os.path.dirname(path)):
49N/A self.makedirs(os.path.dirname(path), mode=0755)
51N/A elif os.path.exists(path):
1846N/A os.unlink(path)
591N/A
873N/A target = os.path.normpath(os.path.sep.join(
873N/A (pkgplan.image.get_root(), target)))
1540N/A
1540N/A os.link(target, path)
1540N/A
1540N/A def verify(self, img, **args):
1540N/A path = self.attrs["path"]
1540N/A target = self.get_target_path()
873N/A
873N/A errors = []
591N/A path = os.path.normpath(os.path.sep.join(
591N/A (img.get_root(), path)))
591N/A
1755N/A if not os.path.exists(path):
591N/A errors.append("No such path %s" % self.attrs["path"])
591N/A
591N/A target = os.path.normpath(os.path.sep.join(
591N/A (img.get_root(), target)))
591N/A
873N/A if not os.path.exists(target):
873N/A errors.append("Target %s doesn't exist" % \
873N/A self.attrs["target"])
873N/A
873N/A # No point in continuing if we have errors already
873N/A if errors:
873N/A return errors
591N/A
591N/A try:
591N/A if os.stat(path)[ST_INO] != os.stat(target)[ST_INO]:
1755N/A errors.append("Path and Target (%s) inodes not the same" % \
591N/A self.get_target_path())
591N/A
591N/A except OSError, e:
591N/A errors.append("Unexpected exception: %s" % e)
591N/A
591N/A return errors
591N/A