client/tools
by Partha Aji
client/tools/rhncfg/config_client/rhncfgcli_diff.py | 18 +++++++++++-------
client/tools/rhncfg/config_client/rhncfgcli_list.py | 2 +-
client/tools/rhncfg/config_common/file_utils.py | 7 ++++---
3 files changed, 16 insertions(+), 11 deletions(-)
New commits:
commit 145edafbeb6da83bbfbc612da1c6a406712af34a
Author: Partha Aji <paji(a)redhat.com>
Date: Thu Jul 29 19:07:55 2010 -0400
Made the diff in operation rhncfg client work with symlinks
diff --git a/client/tools/rhncfg/config_client/rhncfgcli_diff.py b/client/tools/rhncfg/config_client/rhncfgcli_diff.py
index 4d1d29d..10c928a 100644
--- a/client/tools/rhncfg/config_client/rhncfgcli_diff.py
+++ b/client/tools/rhncfg/config_client/rhncfgcli_diff.py
@@ -15,7 +15,7 @@
import sys
import os
-
+import os.path
from config_common import utils
from config_common.rhn_log import log_debug
@@ -24,9 +24,8 @@ import handler_base
class Handler(handler_base.HandlerBase):
_usage_options = handler_base.HandlerBase._usage_options + " [ files ... ]"
def _process_file(self, *args):
- src, dst = args[:2]
- type = args[3]
-
+ src, dst= args [:2]
+ type = args[3]
# label for diff output. this lets 'patch -R' properly apply
# a patch to update to known version and have proper lsdiff
# output. also gets rid of /tmp/@blah in diff output.
@@ -35,11 +34,16 @@ class Handler(handler_base.HandlerBase):
if type == 'directory':
#dst is a directory, so just tell the user we're skipping the entry
print "Entry \'%s\' is a directory, skipping" % dst
- return
elif type == 'symlink':
#dst is a symlink, so just tell the user we're skipping the entry
- print "Entry \'%s\' is a symbolic link, skipping" % dst
- return
+ srclink = os.path.abspath(os.readlink(src))
+ destlink = os.path.abspath(os.readlink(dst))
+ if srclink == destlink:
+ print "No change between the symbolic links '%s' " % dst
+ else:
+ print "Symbolic link targets are different."
+ print "Channel: '%s' -> '%s' System: '%s' -> '%s' " % (dst,srclink, dst, destlink)
+
else:
# if file isn't present, compare to /dev/null so we see the
# whole thing in the diff
diff --git a/client/tools/rhncfg/config_client/rhncfgcli_list.py b/client/tools/rhncfg/config_client/rhncfgcli_list.py
index ae597b2..a79501f 100644
--- a/client/tools/rhncfg/config_client/rhncfgcli_list.py
+++ b/client/tools/rhncfg/config_client/rhncfgcli_list.py
@@ -32,7 +32,7 @@ class Handler(handler_base.HandlerBase):
maxlen = max(map(lambda s: len(s[0]), files))
maxlen = max(maxlen, len(label)) + 2
- print "DoF %*s %s" % (maxlen, label, "File")
+ print "DoFoS %*s %s" % (maxlen, label, "File")
for file in files:
# checking to see if the filetype is in the 'file' entry,
# and if it is and that type is '1', it is a file
diff --git a/client/tools/rhncfg/config_common/file_utils.py b/client/tools/rhncfg/config_common/file_utils.py
index 971224e..6325c39 100644
--- a/client/tools/rhncfg/config_common/file_utils.py
+++ b/client/tools/rhncfg/config_common/file_utils.py
@@ -14,6 +14,7 @@
#
import os
+import os.path
import time
import tempfile
import base64
@@ -103,12 +104,12 @@ class FileProcessor:
if file_struct['filetype'] == 'symlink':
try:
- curlink = os.readlink(path)
- newlink = os.readlink(temp_file)
+ curlink = os.path.abspath(os.readlink(path))
+ newlink = os.path.abspath(os.readlink(temp_file))
if curlink == newlink:
result = ''
else:
- result = "Link targets differ: actual: [%s], expected: [%s]\n" % (curlink, newlink)
+ result = "Link targets differ for [%s]: actual: [%s], expected: [%s]\n" % (path, curlink, newlink)
except OSError, e:
if e.errno == 22:
result = "Deployed symlink is no longer a symlink!"
13 years, 9 months
scripts/update_symlinks.py
by Partha Aji
scripts/update_symlinks.py | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
New commits:
commit 3a9f2ffa99a55c5c368d12fad1b2149ec790c30d
Author: Partha Aji <paji(a)redhat.com>
Date: Thu Jul 29 18:08:49 2010 -0400
Improved the output of update_symlinks script
diff --git a/scripts/update_symlinks.py b/scripts/update_symlinks.py
old mode 100644
new mode 100755
index bc49e2d..be906f4
--- a/scripts/update_symlinks.py
+++ b/scripts/update_symlinks.py
@@ -19,13 +19,16 @@
# $Id$
"""
-Test module for blob updates.
-To create the table for this test run:
+This script is meant to be used by spacewalk users upgrading from 1.0 to 1.1.
+The schema storing the symlinks target path was updated between spacewalk 1.0 to 1.1
+from a blob in rhnConfigContent to symlink_target_filename_id in rhnConfigInfo.
-drop table test_blob_update;
+This script extracts symlink paths that were previously stored as blobs in rhnConfigContent
+and then creates an entry in rhnConfigFileName with that path and sets the
+rhnConfigInfo.symlink_target_filename_id.
+
+It acquires the database information from rhn.conf
-create table test_blob_update
- (id1 int not null, id2 int, val1 blob, val2 blob, nval int not null);
"""
import sys
@@ -37,7 +40,7 @@ from server.importlib.backendLib import Table, DBblob, DBint, TableUpdate, \
from pprint import pprint
from os.path import isabs
-def setupDb():
+def setup_db():
initCFG('server.satellite')
db_backend = CFG.DB_BACKEND
db_host = CFG.DB_HOST
@@ -49,7 +52,9 @@ def setupDb():
username=db_user, password=db_password, database=database)
def main():
- setupDb()
+ setup_db()
+ print "================="
+ print "Updating Symbolic Links"
q = """select cr.id as rev_id,
ccon.id as content_id,
ccon.contents,
@@ -74,6 +79,8 @@ def main():
h.execute()
results = h.fetchall_dict()
if not results:
+ print "Update completed."
+ print "================="
return
contents = []
for row in results:
@@ -98,6 +105,13 @@ def main():
update_cr = """ update rhnConfigRevision set config_content_id = null where id = :revision_id"""
delete_content = """ delete from rhnConfigContent where id = :content_id"""
+ format = """
+ Path: [%(path)s]
+ Symbolic link:[%(symlink_target)s]
+ Update URL: https://<FQDN>/rhn/configuration/file/FileDetails.do?cfid=%(file_id)d&crid=%(revision_id)d
+ Organization Id : [%(org_id)d]
+ Organization Name : [%(org_name)s]
+ """
bad_items = list()
for item in contents:
if item['symlink_target'] is None:
@@ -110,23 +124,20 @@ def main():
rhnSQL.prepare(update_query).execute(**item)
rhnSQL.prepare(update_cr).execute(**item)
rhnSQL.prepare(delete_content).execute(**item)
+ print format % item
rhnSQL.commit()
rhnSQL.closeDB()
-
+ print "%d rows updated." % len(contents)
+ print "Update completed"
+ print "================="
msg = """
The following symbolic link paths are either null or not absolute or above 1024 characters in length.
While entries have been added in the DB, the values have to be updated for them in the Web UI.
Please go to the provided url, logging in as a user with config admin/org admin role in the specified organization
and update the target path value accordingly.
"""
- format = """
- Path: [%(path)s]
- Symbolic link:[%(symlink_target)s]
- Update URL: https://<FQDN>/rhn/configuration/file/FileDetails.do?cfid=%(file_id)d&crid=%(revision_id)d
- Organization Id : [%(org_id)d]
- Organization Name : [%(org_name)s]
- """
+
if bad_items:
print msg
for item in bad_items:
13 years, 9 months
schema/spacewalk scripts/update_symlinks.py
by Justin Sherrill
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql | 2 +-
scripts/update_symlinks.py | 8 +++++---
2 files changed, 6 insertions(+), 4 deletions(-)
New commits:
commit 26151497cef7820cdbbd7e96b5727c55b1c7ea28
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Thu Jul 29 17:44:47 2010 -0400
fixing a few things with the new config changes for symlinks
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql
index 5ab5e92..03b4e8d 100644
--- a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql
@@ -43,7 +43,7 @@ BEGIN
END LOOP;
commit;
END;
-
+/
alter table rhnConfigContent modify delim_start not null;
alter table rhnConfigContent modify delim_end not null;
diff --git a/scripts/update_symlinks.py b/scripts/update_symlinks.py
index 872257b..bc49e2d 100644
--- a/scripts/update_symlinks.py
+++ b/scripts/update_symlinks.py
@@ -71,10 +71,12 @@ def main():
where
cr.CONFIG_FILE_TYPE_ID in (select id from rhnConfigFileType where label='symlink')"""
h = rhnSQL.prepare(q)
- if h.execute() == 0:
- return
+ h.execute()
+ results = h.fetchall_dict()
+ if not results:
+ return
contents = []
- for row in h.fetchall_dict():
+ for row in results:
contents.append( dict(revision_id = row["rev_id"],
file_id = row ["file_id"],
info_id = row ["info_id"],
13 years, 9 months
schema/spacewalk
by Partha Aji
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config-pks.sql | 98 +++
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config.pks | 98 ---
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config-pkb.sql | 288 ++++++++++
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config.pkb | 288 ----------
4 files changed, 386 insertions(+), 386 deletions(-)
New commits:
commit 69abf120f633cd3def192ab101b802481d167eb9
Author: Partha Aji <paji(a)redhat.com>
Date: Thu Jul 29 17:00:53 2010 -0400
renamed a couple of upgrade files ..
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config-pks.sql b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config-pks.sql
new file mode 100644
index 0000000..37f5899
--- /dev/null
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config-pks.sql
@@ -0,0 +1,98 @@
+--
+-- Copyright (c) 2008 Red Hat, Inc.
+--
+-- This software is licensed to you under the GNU General Public License,
+-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
+-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
+-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+-- along with this software; if not, see
+-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+--
+-- Red Hat trademarks are not licensed under GPLv2. No permission is
+-- granted to use or replicate Red Hat trademarks that are incorporated
+-- in this software or its documentation.
+--
+--
+--
+--
+
+create or replace package
+rhn_config
+is
+ procedure prune_org_configs (
+ org_id_in in number,
+ total_in in number
+ );
+
+ function insert_revision (
+ revision_in in number,
+ config_file_id_in in number,
+ config_content_id_in in number,
+ config_info_id_in in number,
+ config_file_type_id_in number := 1
+ ) return number;
+
+ procedure delete_revision (
+ config_revision_id_in in number,
+ org_id_in in number := -1
+ );
+
+ function get_latest_revision (
+ config_file_id_in in number
+ ) return number;
+
+ function insert_file (
+ config_channel_id_in in number,
+ name_in in varchar2
+ ) return number;
+
+ procedure delete_file (
+ config_file_id_in in number
+ );
+
+ function insert_channel (
+ org_id_in in number,
+ type_in in varchar2,
+ name_in in varchar2,
+ label_in in varchar2,
+ description_in in varchar2
+ ) return number;
+
+ procedure delete_channel (
+ config_channel_id_in in number
+ );
+end rhn_config;
+/
+show errors
+
+--
+--
+-- Revision 1.8 2005/02/16 14:03:35 jslagle
+-- bz #148844
+-- Changed insert_revision function to take a config_file_type_id instead of label
+--
+-- Revision 1.7 2005/02/15 02:42:59 jslagle
+-- bz #147860
+-- insert_revision function now takes a rhnConfigFileType label as a parameter instead of an id
+--
+-- Revision 1.6 2005/02/14 22:45:23 jslagle
+-- bz#147860
+-- Update rhn_config package body and specification for additional column to rhnConfigRevision
+--
+-- Revision 1.5 2004/01/09 17:39:45 pjones
+-- bugzilla: 113029 -- need to do functions for deleting rhnConfigChannel,
+-- too, or we can't prune rhnConfigFile when we do.
+--
+-- Revision 1.4 2004/01/08 19:46:31 pjones
+-- bugzilla: 113029 -- insert/delete for rhnConfigFile and rhnConfigRevision
+--
+-- Revision 1.3 2004/01/08 00:30:10 pjones
+-- bugzilla: 113029 -- more deletion of config files and revisions
+--
+-- Revision 1.2 2004/01/08 00:03:37 pjones
+-- bugzilla: 113029 -- rhn_config.delete_revision() and delete trigger on
+-- rhnConfigFile
+--
+-- Revision 1.1 2003/12/19 22:07:30 pjones
+-- bugzilla: 112392 -- quota support for config files
+--
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config.pks b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config.pks
deleted file mode 100644
index 37f5899..0000000
--- a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config.pks
+++ /dev/null
@@ -1,98 +0,0 @@
---
--- Copyright (c) 2008 Red Hat, Inc.
---
--- This software is licensed to you under the GNU General Public License,
--- version 2 (GPLv2). There is NO WARRANTY for this software, express or
--- implied, including the implied warranties of MERCHANTABILITY or FITNESS
--- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
--- along with this software; if not, see
--- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
---
--- Red Hat trademarks are not licensed under GPLv2. No permission is
--- granted to use or replicate Red Hat trademarks that are incorporated
--- in this software or its documentation.
---
---
---
---
-
-create or replace package
-rhn_config
-is
- procedure prune_org_configs (
- org_id_in in number,
- total_in in number
- );
-
- function insert_revision (
- revision_in in number,
- config_file_id_in in number,
- config_content_id_in in number,
- config_info_id_in in number,
- config_file_type_id_in number := 1
- ) return number;
-
- procedure delete_revision (
- config_revision_id_in in number,
- org_id_in in number := -1
- );
-
- function get_latest_revision (
- config_file_id_in in number
- ) return number;
-
- function insert_file (
- config_channel_id_in in number,
- name_in in varchar2
- ) return number;
-
- procedure delete_file (
- config_file_id_in in number
- );
-
- function insert_channel (
- org_id_in in number,
- type_in in varchar2,
- name_in in varchar2,
- label_in in varchar2,
- description_in in varchar2
- ) return number;
-
- procedure delete_channel (
- config_channel_id_in in number
- );
-end rhn_config;
-/
-show errors
-
---
---
--- Revision 1.8 2005/02/16 14:03:35 jslagle
--- bz #148844
--- Changed insert_revision function to take a config_file_type_id instead of label
---
--- Revision 1.7 2005/02/15 02:42:59 jslagle
--- bz #147860
--- insert_revision function now takes a rhnConfigFileType label as a parameter instead of an id
---
--- Revision 1.6 2005/02/14 22:45:23 jslagle
--- bz#147860
--- Update rhn_config package body and specification for additional column to rhnConfigRevision
---
--- Revision 1.5 2004/01/09 17:39:45 pjones
--- bugzilla: 113029 -- need to do functions for deleting rhnConfigChannel,
--- too, or we can't prune rhnConfigFile when we do.
---
--- Revision 1.4 2004/01/08 19:46:31 pjones
--- bugzilla: 113029 -- insert/delete for rhnConfigFile and rhnConfigRevision
---
--- Revision 1.3 2004/01/08 00:30:10 pjones
--- bugzilla: 113029 -- more deletion of config files and revisions
---
--- Revision 1.2 2004/01/08 00:03:37 pjones
--- bugzilla: 113029 -- rhn_config.delete_revision() and delete trigger on
--- rhnConfigFile
---
--- Revision 1.1 2003/12/19 22:07:30 pjones
--- bugzilla: 112392 -- quota support for config files
---
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config-pkb.sql b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config-pkb.sql
new file mode 100644
index 0000000..e51ca85
--- /dev/null
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config-pkb.sql
@@ -0,0 +1,288 @@
+--
+-- Copyright (c) 2008 Red Hat, Inc.
+--
+-- This software is licensed to you under the GNU General Public License,
+-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
+-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
+-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+-- along with this software; if not, see
+-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+--
+-- Red Hat trademarks are not licensed under GPLv2. No permission is
+-- granted to use or replicate Red Hat trademarks that are incorporated
+-- in this software or its documentation.
+--
+--
+--
+--
+
+create or replace package body
+rhn_config
+is
+ -- just a stub for now
+ procedure prune_org_configs (
+ org_id_in in number,
+ total_in in number
+ ) is
+ begin
+ null;
+ end prune_org_configs;
+
+ function insert_revision (
+ revision_in in number,
+ config_file_id_in in number,
+ config_content_id_in in number,
+ config_info_id_in in number,
+ config_file_type_id_in in number := 1
+ ) return number is
+ retval number;
+ cursor affected_orgs is
+ select cc.org_id id
+ from rhnConfigChannel cc,
+ rhnConfigFile cf
+ where cf.id = config_file_id_in
+ and cf.config_channel_id = cc.id;
+ begin
+
+ insert into rhnConfigRevision(id, revision, config_file_id,
+ config_content_id, config_info_id, config_file_type_id
+ ) values (
+ rhn_confrevision_id_seq.nextval, revision_in, config_file_id_in,
+ config_content_id_in, config_info_id_in, config_file_type_id_in
+ )
+ returning id into retval;
+
+ for org in affected_orgs loop
+ rhn_quota.update_org_quota(org.id);
+ end loop;
+
+ return retval;
+ end insert_revision;
+
+ procedure delete_revision (
+ config_revision_id_in in number,
+ org_id_in in number := -1
+ ) is
+ cfid number;
+ ccid number;
+ oid number;
+ latest_crid number;
+ others number := 0;
+ cursor snapshots is
+ select scr.snapshot_id id
+ from rhnSnapshot s,
+ rhnSnapshotConfigRevision scr
+ where scr.config_revision_id = config_revision_id_in
+ and scr.snapshot_id = s.id
+ and s.invalid is null;
+ cursor other_revisions(config_content_id_in in number) is
+ select 1
+ from rhnConfigRevision
+ where config_content_id = config_content_id_in;
+ begin
+ for snapshot in snapshots loop
+ update rhnSnapshot s
+ set s.invalid =
+ lookup_snapshot_invalid_reason('cr_removed')
+ where s.id = snapshot.id;
+ end loop;
+
+ if org_id_in < 0 then
+ select cr.config_content_id, cc.org_id
+ into ccid, oid
+ from rhnConfigChannel cc,
+ rhnConfigFile cf,
+ rhnConfigRevision cr
+ where cr.id = config_revision_id_in
+ and cr.config_file_id = cf.id
+ and cf.config_channel_id = cc.id;
+ else
+ select cr.config_content_id, org_id_in
+ into ccid, oid
+ from rhnConfigRevision cr
+ where cr.id = config_revision_id_in;
+ end if;
+
+ -- right now this will set rhnActionConfigFileName.config_revision_id
+ -- to null, and will remove an entry from rhnActionConfigRevision.
+ -- might we want to prune and/or kill the action in some way? maybe
+ -- mark it failed or something?
+ delete from rhnConfigRevision where id = config_revision_id_in;
+
+ -- now prune away content if there aren't any other revisions pointing
+ -- at it
+ for other_revision in other_revisions(ccid) loop
+ others := 1;
+ exit;
+ end loop;
+ if others = 0 then
+ delete from rhnConfigContent where id = ccid;
+ end if;
+
+ -- now make sure rhnConfigFile points at a valid revision;
+ -- if there isn't one, we're deleting it, _unless_ org_id_in is
+ -- >= 0, in which case we're in the delete trigger anyway
+ if org_id_in < 0 then
+ select cf.latest_config_revision_id,
+ cf.id
+ into latest_crid,
+ cfid
+ from rhnConfigFile cf,
+ rhnConfigRevision cr
+ where cr.id = config_revision_id_in
+ and cr.config_file_id = cf.id;
+
+ if latest_crid = config_revision_id_in then
+ latest_crid := rhn_config.get_latest_revision(cfid);
+ if latest_crid is not null then
+ update rhnConfigFile set latest_config_revision_id = latest_crid
+ where id = cfid;
+ else
+ delete from rhnConfigFile where id = cfid;
+ end if;
+ end if;
+
+ end if;
+ rhn_quota.update_org_quota(oid);
+ end delete_revision;
+
+ function get_latest_revision (
+ config_file_id_in in number
+ ) return number is
+ cursor revisions is
+ select cr.id
+ from rhnConfigRevision cr
+ where cr.config_file_id = config_file_id_in
+ order by revision desc;
+ begin
+ for revision in revisions loop
+ return revision.id;
+ end loop;
+ return null;
+ end get_latest_revision;
+
+ function insert_file (
+ config_channel_id_in in number,
+ name_in in varchar2
+ ) return number is
+ retval number;
+ begin
+ select rhn_conffile_id_seq.nextval
+ into retval
+ from dual;
+
+ insert into rhnConfigFile(id, config_channel_id, config_file_name_id,
+ state_id
+ ) (
+ select retval,
+ config_channel_id_in,
+ lookup_config_filename(name_in),
+ id
+ from rhnConfigFileState
+ where label = 'alive'
+ );
+
+ return retval;
+ end insert_file;
+
+ procedure delete_file (
+ config_file_id_in in number
+ ) is
+ cursor revisions is
+ select cr.id, cc.org_id
+ from rhnConfigChannel cc,
+ rhnConfigRevision cr,
+ rhnConfigFile cf
+ where cf.id = config_file_id_in
+ and cf.config_channel_id = cc.id
+ and cr.config_file_id = cf.id;
+ org_id number;
+ begin
+ for revision in revisions loop
+ rhn_config.delete_revision(revision.id, revision.org_id);
+ org_id := revision.org_id;
+ end loop;
+ rhn_quota.update_org_quota(org_id);
+ delete from rhnConfigFile where id = config_file_id_in;
+ end delete_file;
+
+ function insert_channel (
+ org_id_in in number,
+ type_in in varchar2,
+ name_in in varchar2,
+ label_in in varchar2,
+ description_in in varchar2
+ ) return number is
+ retval number;
+ begin
+ select rhn_confchan_id_seq.nextval
+ into retval
+ from dual;
+
+ insert into rhnConfigChannel(id, org_id, confchan_type_id,
+ name, label, description
+ ) (
+ select retval,
+ org_id_in,
+ cct.id,
+ name_in,
+ label_in,
+ description_in
+ from rhnConfigChannelType cct
+ where label = type_in
+ );
+ return retval;
+ end insert_channel;
+
+ procedure delete_channel (
+ config_channel_id_in in number
+ ) is
+ cursor config_files is
+ select id
+ from rhnConfigFile
+ where config_channel_id = config_channel_id_in;
+ begin
+ for config_file in config_files loop
+ rhn_config.delete_file(config_file.id);
+ end loop;
+ delete from rhnConfigChannel where id = config_channel_id_in;
+ end delete_channel;
+end rhn_config;
+/
+show errors
+
+--
+--
+-- Revision 1.9 2005/02/16 14:03:35 jslagle
+-- bz #148844
+-- Changed insert_revision function to take a config_file_type_id instead of label
+--
+-- Revision 1.8 2005/02/15 02:42:59 jslagle
+-- bz #147860
+-- insert_revision function now takes a rhnConfigFileType label as a parameter instead of an id
+--
+-- Revision 1.7 2005/02/14 22:45:23 jslagle
+-- bz#147860
+-- Update rhn_config package body and specification for additional column to rhnConfigRevision
+--
+-- Revision 1.6 2004/10/11 14:02:53 pjones
+-- bugzilla: 133169 -- somehow, we just never update the quota in this case.
+-- Amazingly, I thought this worked _and_ QA passed it...
+--
+-- Revision 1.5 2004/01/09 17:39:45 pjones
+-- bugzilla: 113029 -- need to do functions for deleting rhnConfigChannel,
+-- too, or we can't prune rhnConfigFile when we do.
+--
+-- Revision 1.4 2004/01/08 19:46:31 pjones
+-- bugzilla: 113029 -- insert/delete for rhnConfigFile and rhnConfigRevision
+--
+-- Revision 1.3 2004/01/08 00:30:10 pjones
+-- bugzilla: 113029 -- more deletion of config files and revisions
+--
+-- Revision 1.2 2004/01/08 00:03:37 pjones
+-- bugzilla: 113029 -- rhn_config.delete_revision() and delete trigger on
+-- rhnConfigFile
+--
+-- Revision 1.1 2003/12/19 22:07:30 pjones
+-- bugzilla: 112392 -- quota support for config files
+--
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config.pkb b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config.pkb
deleted file mode 100644
index e51ca85..0000000
--- a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config.pkb
+++ /dev/null
@@ -1,288 +0,0 @@
---
--- Copyright (c) 2008 Red Hat, Inc.
---
--- This software is licensed to you under the GNU General Public License,
--- version 2 (GPLv2). There is NO WARRANTY for this software, express or
--- implied, including the implied warranties of MERCHANTABILITY or FITNESS
--- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
--- along with this software; if not, see
--- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
---
--- Red Hat trademarks are not licensed under GPLv2. No permission is
--- granted to use or replicate Red Hat trademarks that are incorporated
--- in this software or its documentation.
---
---
---
---
-
-create or replace package body
-rhn_config
-is
- -- just a stub for now
- procedure prune_org_configs (
- org_id_in in number,
- total_in in number
- ) is
- begin
- null;
- end prune_org_configs;
-
- function insert_revision (
- revision_in in number,
- config_file_id_in in number,
- config_content_id_in in number,
- config_info_id_in in number,
- config_file_type_id_in in number := 1
- ) return number is
- retval number;
- cursor affected_orgs is
- select cc.org_id id
- from rhnConfigChannel cc,
- rhnConfigFile cf
- where cf.id = config_file_id_in
- and cf.config_channel_id = cc.id;
- begin
-
- insert into rhnConfigRevision(id, revision, config_file_id,
- config_content_id, config_info_id, config_file_type_id
- ) values (
- rhn_confrevision_id_seq.nextval, revision_in, config_file_id_in,
- config_content_id_in, config_info_id_in, config_file_type_id_in
- )
- returning id into retval;
-
- for org in affected_orgs loop
- rhn_quota.update_org_quota(org.id);
- end loop;
-
- return retval;
- end insert_revision;
-
- procedure delete_revision (
- config_revision_id_in in number,
- org_id_in in number := -1
- ) is
- cfid number;
- ccid number;
- oid number;
- latest_crid number;
- others number := 0;
- cursor snapshots is
- select scr.snapshot_id id
- from rhnSnapshot s,
- rhnSnapshotConfigRevision scr
- where scr.config_revision_id = config_revision_id_in
- and scr.snapshot_id = s.id
- and s.invalid is null;
- cursor other_revisions(config_content_id_in in number) is
- select 1
- from rhnConfigRevision
- where config_content_id = config_content_id_in;
- begin
- for snapshot in snapshots loop
- update rhnSnapshot s
- set s.invalid =
- lookup_snapshot_invalid_reason('cr_removed')
- where s.id = snapshot.id;
- end loop;
-
- if org_id_in < 0 then
- select cr.config_content_id, cc.org_id
- into ccid, oid
- from rhnConfigChannel cc,
- rhnConfigFile cf,
- rhnConfigRevision cr
- where cr.id = config_revision_id_in
- and cr.config_file_id = cf.id
- and cf.config_channel_id = cc.id;
- else
- select cr.config_content_id, org_id_in
- into ccid, oid
- from rhnConfigRevision cr
- where cr.id = config_revision_id_in;
- end if;
-
- -- right now this will set rhnActionConfigFileName.config_revision_id
- -- to null, and will remove an entry from rhnActionConfigRevision.
- -- might we want to prune and/or kill the action in some way? maybe
- -- mark it failed or something?
- delete from rhnConfigRevision where id = config_revision_id_in;
-
- -- now prune away content if there aren't any other revisions pointing
- -- at it
- for other_revision in other_revisions(ccid) loop
- others := 1;
- exit;
- end loop;
- if others = 0 then
- delete from rhnConfigContent where id = ccid;
- end if;
-
- -- now make sure rhnConfigFile points at a valid revision;
- -- if there isn't one, we're deleting it, _unless_ org_id_in is
- -- >= 0, in which case we're in the delete trigger anyway
- if org_id_in < 0 then
- select cf.latest_config_revision_id,
- cf.id
- into latest_crid,
- cfid
- from rhnConfigFile cf,
- rhnConfigRevision cr
- where cr.id = config_revision_id_in
- and cr.config_file_id = cf.id;
-
- if latest_crid = config_revision_id_in then
- latest_crid := rhn_config.get_latest_revision(cfid);
- if latest_crid is not null then
- update rhnConfigFile set latest_config_revision_id = latest_crid
- where id = cfid;
- else
- delete from rhnConfigFile where id = cfid;
- end if;
- end if;
-
- end if;
- rhn_quota.update_org_quota(oid);
- end delete_revision;
-
- function get_latest_revision (
- config_file_id_in in number
- ) return number is
- cursor revisions is
- select cr.id
- from rhnConfigRevision cr
- where cr.config_file_id = config_file_id_in
- order by revision desc;
- begin
- for revision in revisions loop
- return revision.id;
- end loop;
- return null;
- end get_latest_revision;
-
- function insert_file (
- config_channel_id_in in number,
- name_in in varchar2
- ) return number is
- retval number;
- begin
- select rhn_conffile_id_seq.nextval
- into retval
- from dual;
-
- insert into rhnConfigFile(id, config_channel_id, config_file_name_id,
- state_id
- ) (
- select retval,
- config_channel_id_in,
- lookup_config_filename(name_in),
- id
- from rhnConfigFileState
- where label = 'alive'
- );
-
- return retval;
- end insert_file;
-
- procedure delete_file (
- config_file_id_in in number
- ) is
- cursor revisions is
- select cr.id, cc.org_id
- from rhnConfigChannel cc,
- rhnConfigRevision cr,
- rhnConfigFile cf
- where cf.id = config_file_id_in
- and cf.config_channel_id = cc.id
- and cr.config_file_id = cf.id;
- org_id number;
- begin
- for revision in revisions loop
- rhn_config.delete_revision(revision.id, revision.org_id);
- org_id := revision.org_id;
- end loop;
- rhn_quota.update_org_quota(org_id);
- delete from rhnConfigFile where id = config_file_id_in;
- end delete_file;
-
- function insert_channel (
- org_id_in in number,
- type_in in varchar2,
- name_in in varchar2,
- label_in in varchar2,
- description_in in varchar2
- ) return number is
- retval number;
- begin
- select rhn_confchan_id_seq.nextval
- into retval
- from dual;
-
- insert into rhnConfigChannel(id, org_id, confchan_type_id,
- name, label, description
- ) (
- select retval,
- org_id_in,
- cct.id,
- name_in,
- label_in,
- description_in
- from rhnConfigChannelType cct
- where label = type_in
- );
- return retval;
- end insert_channel;
-
- procedure delete_channel (
- config_channel_id_in in number
- ) is
- cursor config_files is
- select id
- from rhnConfigFile
- where config_channel_id = config_channel_id_in;
- begin
- for config_file in config_files loop
- rhn_config.delete_file(config_file.id);
- end loop;
- delete from rhnConfigChannel where id = config_channel_id_in;
- end delete_channel;
-end rhn_config;
-/
-show errors
-
---
---
--- Revision 1.9 2005/02/16 14:03:35 jslagle
--- bz #148844
--- Changed insert_revision function to take a config_file_type_id instead of label
---
--- Revision 1.8 2005/02/15 02:42:59 jslagle
--- bz #147860
--- insert_revision function now takes a rhnConfigFileType label as a parameter instead of an id
---
--- Revision 1.7 2005/02/14 22:45:23 jslagle
--- bz#147860
--- Update rhn_config package body and specification for additional column to rhnConfigRevision
---
--- Revision 1.6 2004/10/11 14:02:53 pjones
--- bugzilla: 133169 -- somehow, we just never update the quota in this case.
--- Amazingly, I thought this worked _and_ QA passed it...
---
--- Revision 1.5 2004/01/09 17:39:45 pjones
--- bugzilla: 113029 -- need to do functions for deleting rhnConfigChannel,
--- too, or we can't prune rhnConfigFile when we do.
---
--- Revision 1.4 2004/01/08 19:46:31 pjones
--- bugzilla: 113029 -- insert/delete for rhnConfigFile and rhnConfigRevision
---
--- Revision 1.3 2004/01/08 00:30:10 pjones
--- bugzilla: 113029 -- more deletion of config files and revisions
---
--- Revision 1.2 2004/01/08 00:03:37 pjones
--- bugzilla: 113029 -- rhn_config.delete_revision() and delete trigger on
--- rhnConfigFile
---
--- Revision 1.1 2003/12/19 22:07:30 pjones
--- bugzilla: 112392 -- quota support for config files
---
13 years, 9 months
schema/spacewalk
by Partha Aji
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql | 25 ++++++++--
1 file changed, 22 insertions(+), 3 deletions(-)
New commits:
commit 921c54b6e87b30f37bcd610b2602ce2a296d4c6a
Author: Partha Aji <paji(a)redhat.com>
Date: Thu Jul 29 16:51:21 2010 -0400
Fixed a small glitch in the upgrade script.. The column name had an extra _
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql
index 5c2d431..5ab5e92 100644
--- a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql
@@ -1,8 +1,27 @@
-alter table rhnConfigInfo add SYMLINK_TARGET_FILE_NAME_ID NUMBER
+--
+-- Copyright (c) 2008 Red Hat, Inc.
+--
+-- This software is licensed to you under the GNU General Public License,
+-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
+-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
+-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+-- along with this software; if not, see
+-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+--
+-- Red Hat trademarks are not licensed under GPLv2. No permission is
+-- granted to use or replicate Red Hat trademarks that are incorporated
+-- in this software or its documentation.
+--
+
+alter table rhnConfigInfo add SYMLINK_TARGET_FILENAME_ID NUMBER
CONSTRAINT rhn_confinfo_symlink_fk
REFERENCES rhnConfigFileName (id);
-
-
+alter table rhnConfigInfo modify username NULL;
+alter table rhnConfigInfo modify groupname NULL;
+alter table rhnConfigInfo modify filemode NULL;
+drop index rhn_confinfo_ugf_uq;
+CREATE UNIQUE INDEX rhn_confinfo_ugf_uq
+ ON rhnConfigInfo (username, groupname, filemode, selinux_ctx, symlink_target_filename_id);
alter table rhnConfigContent add delim_start VARCHAR2(16);
13 years, 9 months
backend/server client/tools java/code schema/spacewalk scripts/update_symlinks.py
by Partha Aji
backend/server/action/configfiles.py | 17
backend/server/configFilesHandler.py | 99 ++-
backend/server/handlers/config/rhn_config_management.py | 12
backend/server/handlers/config_mgmt/rhn_config_management.py | 28
client/tools/rhncfg/actions/configfiles.py | 3
client/tools/rhncfg/config_client/rhncfgcli_diff.py | 25
client/tools/rhncfg/config_common/file_utils.py | 50 -
client/tools/rhncfg/config_common/repository.py | 3
client/tools/rhncfg/config_common/transactions.py | 57 +
java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml | 42 -
java/code/src/com/redhat/rhn/domain/config/ConfigContent.hbm.xml | 10
java/code/src/com/redhat/rhn/domain/config/ConfigContent.java | 33 +
java/code/src/com/redhat/rhn/domain/config/ConfigFileType.java | 16
java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml | 16
java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java | 15
java/code/src/com/redhat/rhn/domain/config/ConfigRevision.hbm.xml | 4
java/code/src/com/redhat/rhn/domain/config/ConfigRevision.java | 37 -
java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java | 66 +-
java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java | 9
java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java | 43 +
java/code/src/com/redhat/rhn/frontend/action/configuration/files/DiffAction.java | 60 +-
java/code/src/com/redhat/rhn/frontend/action/configuration/files/FileDetailsAction.java | 53 -
java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileFormForSymlink.xsd | 10
java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml | 6
java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml | 20
java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/test/ConfigChannelHandlerTest.java | 9
java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java | 8
java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/test/ServerConfigHandlerTest.java | 10
java/code/src/com/redhat/rhn/manager/configuration/ConfigFileBuilder.java | 82 +-
java/code/src/com/redhat/rhn/manager/configuration/file/BinaryFileData.java | 4
java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java | 89 +--
java/code/src/com/redhat/rhn/manager/configuration/file/DirectoryData.java | 2
java/code/src/com/redhat/rhn/manager/configuration/file/SymlinkData.java | 111 +++
java/code/src/com/redhat/rhn/manager/configuration/file/TextFileData.java | 5
java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java | 10
java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf | 93 ++-
java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/add_details.jspf | 16
java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/details.jspf | 2
java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/file_info.jsp | 14
java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf | 11
java/code/webapp/WEB-INF/pages/configuration/files/filedetails.jsp | 4
java/code/webapp/WEB-INF/struts-config.xml | 1
schema/spacewalk/common/tables/rhnConfigContent.sql | 2
schema/spacewalk/common/tables/rhnConfigInfo.sql | 11
schema/spacewalk/common/tables/rhnConfigRevision.sql | 4
schema/spacewalk/oracle/packages/rhn_config.pkb | 8
schema/spacewalk/oracle/packages/rhn_config.pks | 2
schema/spacewalk/oracle/procs/lookup_config_info.sql | 17
schema/spacewalk/oracle/triggers/rhnConfigRevision.sql | 12
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql | 44 +
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config.pks | 98 +++
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config.pkb | 288 ++++++++++
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/104-rhnconfigrevision-trigger.sql | 102 +++
schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/105-lookup_config_info.sql | 64 ++
scripts/update_symlinks.py | 134 ++++
55 files changed, 1549 insertions(+), 442 deletions(-)
New commits:
commit 592b5c8619abd9094fd7cd9f8b7b10e5ceca608a
Author: Partha Aji <paji(a)redhat.com>
Date: Thu Jul 29 16:04:30 2010 -0400
Config Management schema update + ui + symlinks
1) Updates symlinks to be used as real paths as opposed to blobs. So the
symlink path is now stored as "SYMLINK_TARGET_FILENAME_ID" in the
rhnConfigInfo table instead of a blob in rhnConfigContent
2) Changed the config management schema slightly, delim_start and
delim_end, and configContent blobs are no longer needed for
directories/symlinks. Delim_start and Delim_end moved from
rhnConfigRevision to rhnConfigContent since they are related to content.
Also made config_content_id nullable in rhnConfigRevision since we are
not going to be storing those for directories and sym links
3) Made filemode/groupmode and dir permissions nullable since we don;t
want to store those for symbolic links. Symbolic link will inherit
automatically those properties from the target it points to.
4) Cleaned up the create and File Details UI to handle symlinks vs
directories vs files more appropriately including greying
out/disabling and displaying the right stuff. Also updated the
"compare" ui to show different target paths/
5) Cleaned up the backend and client rhncfg packages to handle these
schema changes appropriately. Client will be getting a "symlink" entry to show
the symlink path or null if that doesn't exist.
6) Added a git/scripts/update_symlinks.py script to help people using
spacewalk 1.0 to update their schema. This script reads from the blobs
and updates the symlink path appropriately.
diff --git a/backend/server/action/configfiles.py b/backend/server/action/configfiles.py
index e6ae6a6..30920c4 100644
--- a/backend/server/action/configfiles.py
+++ b/backend/server/action/configfiles.py
@@ -117,14 +117,18 @@ _query_get_files = rhnSQL.Statement("""
ccont.is_binary is_binary,
c.checksum_type,
c.checksum,
- cr.delim_start,
- cr.delim_end,
+ ccont.delim_start,
+ ccont.delim_end,
cr.revision,
ci.username,
ci.groupname,
ci.filemode,
- cft.label,
- ci.selinux_ctx
+ cft.label,
+ ci.selinux_ctx,
+ case
+ when cft.label='symlink' then (select path from rhnConfigFileName where id = ci.SYMLINK_TARGET_FILENAME_ID)
+ else ''
+ end as symlink
from
rhnConfigFileState cfs,
rhnConfigContent ccont,
@@ -145,15 +149,14 @@ _query_get_files = rhnSQL.Statement("""
and cf.config_channel_id = cc.id
and cf.state_id = cfs.id
and cfs.label = 'alive'
- and cr.config_content_id = ccont.id
+ and cr.config_content_id = ccont.id (+)
and cr.config_file_type_id = cft.id
- and ccont.checksum_id = c.id
+ and ccont.checksum_id = c.id(+)
""")
def _get_files(server_id, action_id):
h = rhnSQL.prepare(_query_get_files)
h.execute(action_id=action_id, server_id=server_id)
-
server = rhnServer.search(server_id)
server = var_interp_prep(server)
diff --git a/backend/server/configFilesHandler.py b/backend/server/configFilesHandler.py
index c805223..f13ae7d 100644
--- a/backend/server/configFilesHandler.py
+++ b/backend/server/configFilesHandler.py
@@ -134,36 +134,48 @@ class ConfigFilesHandler(rhnHandler):
def _check_user_role(self):
pass
+ def _is_file(self, file):
+ return str(file['config_file_type_id']) == '1'
+
+ def _is_link(self, file):
+ return str(file['config_file_type_id']) == '3'
+
def _push_file(self, config_channel_id, file):
if not file:
# Nothing to do
return {}
- # Check for full path on the file
- path = file.get('path')
- if not (path[0] == os.sep):
- raise ConfigFilePathIncomplete(file)
+ # Check for full path on the file
+ path = file.get('path')
+ if not (path[0] == os.sep):
+ raise ConfigFilePathIncomplete(file)
+ if not file.has_key('config_file_type_id'):
+ log_debug(4, "Client does not support config directories, so set file_type_id to 1")
+ file['config_file_type_id'] = '1'
# Check if delimiters are present
- if not (file.get('delim_start') and file.get('delim_end')):
+ if self._is_file(file) and \
+ not (file.get('delim_start') and file.get('delim_end')):
# Need delimiters
raise ConfigFileMissingDelimError(file)
if not (file.get('user') and file.get('group') and
- file.get('mode')):
+ file.get('mode')) and not self._is_link(file) :
raise ConfigFileMissingInfoError(file)
# Oracle doesn't like certain binding variables
- file['username'] = file['user']
- file['groupname'] = file['group']
- file['file_mode'] = file['mode']
- if not file.has_key('selinux_ctx'):
- file['selinux_ctx'] = ''
-
+ file['username'] = file.get('user','')
+ file['groupname'] = file.get('group','')
+ file['file_mode'] = file.get('mode','')
+ file['selinux_ctx'] = file.get('selinux_ctx','')
result = {}
try:
- self._push_contents(file)
+
+ if self._is_file(file):
+ self._push_contents(file)
+ elif self._is_link(file):
+ file['symlink'] = file.get('symlink') or ''
except ConfigFileTooLargeError:
result['file_too_large'] = 1
@@ -221,7 +233,7 @@ class ConfigFilesHandler(rhnHandler):
return result
_query_content_lookup = rhnSQL.Statement("""
- select cc.id, cv.checksum_type, cv.checksum, file_size, contents, is_binary
+ select cc.id, cv.checksum_type, cv.checksum, file_size, contents, is_binary, delim_start, delim_end
from rhnConfigContent cc, rhnChecksumView cv
where cv.checksum = :checksum
and cv.checksum_type = :checksum_type
@@ -231,16 +243,16 @@ class ConfigFilesHandler(rhnHandler):
_query_insert_content = rhnSQL.Statement("""
insert into rhnConfigContent
- (id, checksum_id, file_size, contents, is_binary)
+ (id, checksum_id, file_size, contents, is_binary, delim_start, delim_end)
values (:config_content_id, lookup_checksum(:checksum_type, :checksum),
- :file_size, empty_blob(), :is_binary)
+ :file_size, empty_blob(), :is_binary, :delim_start, :delim_end)
""")
_query_insert_null_content = rhnSQL.Statement("""
insert into rhnConfigContent
- (id, checksum_id, file_size, contents, is_binary)
+ (id, checksum_id, file_size, contents, is_binary, delim_start, delim_end)
values (:config_content_id, lookup_checksum(:checksum_type, :checksum),
- :file_size, NULL, :is_binary)
+ :file_size, NULL, :is_binary, :delim_start, :delim_end)
""")
_query_get_content_row = rhnSQL.Statement("""
@@ -325,8 +337,13 @@ class ConfigFilesHandler(rhnHandler):
lob = row['contents']
lob.write(file_contents)
- _query_lookup_config_info = rhnSQL.Statement("""
- select lookup_config_info(:username, :groupname, :file_mode, :selinux_ctx) id
+ _query_lookup_symlink_config_info = rhnSQL.Statement("""
+ select lookup_config_info(null, null, null, :selinux_ctx, lookup_config_filename(:symlink)) id
+ from dual
+ """)
+
+ _query_lookup_non_symlink_config_info = rhnSQL.Statement("""
+ select lookup_config_info(:username, :groupname, :file_mode, :selinux_ctx, null) id
from dual
""")
@@ -338,8 +355,12 @@ class ConfigFilesHandler(rhnHandler):
""")
def _push_config_file(self, file):
+ config_info_query = self._query_lookup_non_symlink_config_info
+ if self._is_link(file) and file.get("symlink"):
+ config_info_query = self._query_lookup_symlink_config_info
+
# Look up the config info first
- h = rhnSQL.prepare(self._query_lookup_config_info)
+ h = rhnSQL.prepare(config_info_query)
apply(h.execute, (), file)
row = h.fetchone_dict()
if not row:
@@ -368,7 +389,7 @@ class ConfigFilesHandler(rhnHandler):
_query_lookup_revision = rhnSQL.Statement("""
select id, revision, config_content_id, config_info_id,
- delim_start, delim_end, config_file_type_id
+ config_file_type_id
from rhnConfigRevision
where config_file_id = :config_file_id
order by revision desc
@@ -383,15 +404,14 @@ class ConfigFilesHandler(rhnHandler):
if row:
# Is it the same revision as this one?
- fields = ['config_content_id', 'config_info_id', 'delim_start',
- 'delim_end', 'config_file_type_id']
+ fields = ['config_content_id', 'config_info_id', 'config_file_type_id']
if not file.has_key('config_file_type_id'):
log_debug(4, "Client does not support config directories, so set file_type_id to 1")
file['config_file_type_id'] = '1'
for f in fields:
- if file[f] != row[f]:
+ if file.get(f) != row.get(f):
break
else: # for
# All fields are equal
@@ -430,10 +450,8 @@ class ConfigFilesHandler(rhnHandler):
rhnSQL.types.NUMBER())
file['config_revision_id'] = insert_call(file['revision'],
file['config_file_id'],
- file['config_content_id'],
+ file.get('config_content_id',''),
file['config_info_id'],
- file['delim_start'],
- file['delim_end'],
file['config_file_type_id'])
_query_update_revision_add_author = rhnSQL.Statement("""
@@ -473,9 +491,9 @@ class ConfigFilesHandler(rhnHandler):
return rhnSQL.Sequence('rhn_confchan_id_seq').next()
def format_file_results(row, server=None):
-
encoding = ''
- contents = rhnSQL.read_lob(row['file_contents'])
+ contents = None
+ contents = rhnSQL.read_lob(row['file_contents']) or ''
if server and (row['is_binary'] == 'N') and contents:
@@ -494,16 +512,17 @@ def format_file_results(row, server=None):
return {
'path' : row['path'],
'config_channel': row['config_channel'],
- 'file_contents' : contents or '',
- 'checksum_type' : row['checksum_type'],
- 'checksum' : row['checksum'],
- 'delim_start' : row['delim_start'],
- 'delim_end' : row['delim_end'],
- 'revision' : row['revision'],
- 'username' : row['username'],
- 'groupname' : row['groupname'],
- 'filemode' : row['filemode'],
- 'encoding' : encoding,
+ 'file_contents' : contents,
+ 'symlink' : row['symlink'] or '',
+ 'checksum_type' : row['checksum_type'] or '',
+ 'checksum' : row['checksum'] or '',
+ 'delim_start' : row['delim_start'] or '',
+ 'delim_end' : row['delim_end'] or '',
+ 'revision' : row['revision'] or '',
+ 'username' : row['username'] or '',
+ 'groupname' : row['groupname'] or '',
+ 'filemode' : row['filemode'] or '',
+ 'encoding' : encoding or '',
'filetype' : row['label'],
'selinux_ctx' : row['selinux_ctx'] or '',
}
diff --git a/backend/server/handlers/config/rhn_config_management.py b/backend/server/handlers/config/rhn_config_management.py
index f2f2498..04fd9f0 100644
--- a/backend/server/handlers/config/rhn_config_management.py
+++ b/backend/server/handlers/config/rhn_config_management.py
@@ -172,7 +172,7 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
ccont.is_binary is_binary,
c.checksum_type,
c.checksum,
- cr.delim_start, cr.delim_end,
+ ccont.delim_start, ccont.delim_end,
cr.revision,
cf.modified,
ci.username,
@@ -180,7 +180,11 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
ci.filemode,
cft.label,
cct.priority,
- ci.selinux_ctx
+ ci.selinux_ctx,
+ case
+ when cft.label='symlink' then (select path from rhnConfigFileName where id = ci.SYMLINK_TARGET_FILENAME_ID)
+ else ''
+ end as symlink
from rhnConfigChannel cc,
rhnConfigInfo ci,
rhnConfigRevision cr,
@@ -197,10 +201,10 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
and cr.config_file_id = cf.id
and cr.config_info_id = ci.id
and cf.latest_config_revision_id = cr.id
- and cr.config_content_id = ccont.id
+ and cr.config_content_id = ccont.id (+)
and cr.config_file_type_id = cft.id
and cct.id = cc.confchan_type_id
- and ccont.checksum_id = c.id
+ and ccont.checksum_id = c.id (+)
order by cct.priority, scc.position
""")
diff --git a/backend/server/handlers/config_mgmt/rhn_config_management.py b/backend/server/handlers/config_mgmt/rhn_config_management.py
index c7ec9f5..41bce45 100644
--- a/backend/server/handlers/config_mgmt/rhn_config_management.py
+++ b/backend/server/handlers/config_mgmt/rhn_config_management.py
@@ -253,14 +253,18 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
ccont.is_binary,
c.checksum_type,
c.checksum,
- cr.delim_start, cr.delim_end,
+ ccont.delim_start, ccont.delim_end,
cr.revision,
cf.modified,
ci.username,
ci.groupname,
ci.filemode,
cft.label,
- ci.selinux_ctx
+ ci.selinux_ctx,
+ case
+ when cft.label='symlink' then (select path from rhnConfigFileName where id = ci.SYMLINK_TARGET_FILENAME_ID)
+ else ''
+ end as symlink
from rhnConfigChannel cc,
rhnConfigInfo ci,
rhnConfigRevision cr,
@@ -275,9 +279,9 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
and cr.config_file_id = cf.id
and cr.config_info_id = ci.id
and cf.latest_config_revision_id = cr.id
- and cr.config_content_id = ccont.id
+ and cr.config_content_id = ccont.id(+)
and cr.config_file_type_id = cft.id
- and ccont.checksum_id = c.id
+ and ccont.checksum_id = c.id(+)
""")
_query_get_file_revision = rhnSQL.Statement("""
select :path path,
@@ -286,14 +290,18 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
ccont.is_binary,
c.checksum_type,
c.checksum,
- cr.delim_start, cr.delim_end,
+ ccont.delim_start, ccont.delim_end,
cr.revision,
cf.modified,
ci.username,
ci.groupname,
ci.filemode,
cft.label,
- ci.selinux_ctx
+ ci.selinux_ctx,
+ case
+ when cft.label='symlink' then (select path from rhnConfigFileName where id = ci.SYMLINK_TARGET_FILENAME_ID)
+ else ''
+ end as symlink
from rhnConfigChannel cc,
rhnConfigInfo ci,
rhnConfigRevision cr,
@@ -308,9 +316,9 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
and cr.config_file_id = cf.id
and cr.config_info_id = ci.id
and cr.revision = :revision
- and cr.config_content_id = ccont.id
+ and cr.config_content_id = ccont.id(+)
and cr.config_file_type_id = cft.id
- and ccont.checksum_id = c.id
+ and ccont.checksum_id = c.id(+)
""")
@@ -462,7 +470,7 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
raise rhnFault(4011, "File %s (revision %s) does not exist "
"in channel %s" % (path, revision_src, config_channel_src),
explain=0)
- if fsrc['is_binary'] == 'Y':
+ if fsrc['label'] == 'file' and fsrc['is_binary'] == 'Y':
raise rhnFault(4004, "File %s (revision %s) seems to contain "
"binary data" % (path, revision_src),
explain=0)
@@ -488,7 +496,7 @@ class ConfigManagement(configFilesHandler.ConfigFilesHandler):
raise rhnFault(4011, "File %s (revision %s) does not exist "
"in channel %s" % (path, revision_dst, config_channel_dst),
explain=0)
- if fdst['is_binary'] == 'Y':
+ if fdst['label'] == 'file' and fdst['is_binary'] == 'Y':
raise rhnFault(4004, "File %s (revision %s) seems to contain "
"binary data" % (path, revision_dst),
explain=0)
diff --git a/client/tools/rhncfg/actions/configfiles.py b/client/tools/rhncfg/actions/configfiles.py
index 5a5626a..e0b706c 100755
--- a/client/tools/rhncfg/actions/configfiles.py
+++ b/client/tools/rhncfg/actions/configfiles.py
@@ -317,9 +317,10 @@ def diff(params, cache_only=None):
fp = file_utils.FileProcessor()
missing_files = []
diffs = {}
+ exists = hasattr(os.path, 'lexists') and os.path.lexists or os.path.exists
for file in files:
path = file['path']
- if not os.path.exists(path):
+ if not exists(path):
missing_files.append(path)
continue
if os.path.isdir(path):
diff --git a/client/tools/rhncfg/config_client/rhncfgcli_diff.py b/client/tools/rhncfg/config_client/rhncfgcli_diff.py
index cda6c14..4d1d29d 100644
--- a/client/tools/rhncfg/config_client/rhncfgcli_diff.py
+++ b/client/tools/rhncfg/config_client/rhncfgcli_diff.py
@@ -25,25 +25,28 @@ class Handler(handler_base.HandlerBase):
_usage_options = handler_base.HandlerBase._usage_options + " [ files ... ]"
def _process_file(self, *args):
src, dst = args[:2]
- type = args[3]
-
+ type = args[3]
+
# label for diff output. this lets 'patch -R' properly apply
# a patch to update to known version and have proper lsdiff
# output. also gets rid of /tmp/@blah in diff output.
label = dst
-
- if type == 'directory':
- #dst is a directory, so just tell the user we're skipping the entry
+
+ if type == 'directory':
+ #dst is a directory, so just tell the user we're skipping the entry
print "Entry \'%s\' is a directory, skipping" % dst
-
- return
- else:
+ return
+ elif type == 'symlink':
+ #dst is a symlink, so just tell the user we're skipping the entry
+ print "Entry \'%s\' is a symbolic link, skipping" % dst
+ return
+ else:
# if file isn't present, compare to /dev/null so we see the
# whole thing in the diff
if not os.access(dst, os.R_OK):
dst = "/dev/null"
-
- # Test -L and -u options to diff
+
+ # Test -L and -u options to diff
diffcmd = "/usr/bin/diff -L %s -u" % (label,)
dst = '"' + dst + '"'
pipe = os.popen("%s %s %s 2>/dev/null" % (diffcmd, src, dst))
@@ -53,6 +56,6 @@ class Handler(handler_base.HandlerBase):
ret = ret/256 # Return code in upper byte
if ret == 2: # error in diff call
diffcmd = "/usr/bin/diff -c"
-
+
pipe = os.popen("%s %s %s" % (diffcmd, src, dst))
sys.stdout.write(pipe.read())
diff --git a/client/tools/rhncfg/config_common/file_utils.py b/client/tools/rhncfg/config_common/file_utils.py
index d9c69b4..971224e 100644
--- a/client/tools/rhncfg/config_common/file_utils.py
+++ b/client/tools/rhncfg/config_common/file_utils.py
@@ -37,6 +37,20 @@ class FileProcessor:
pass
def process(self, file_struct, directory=None, strict_ownership=1):
+ # Older servers will not return directories; if filetype is missing,
+ # assume file
+ if file_struct.get('filetype') == 'directory':
+ return directory, []
+
+ if file_struct.get('filetype') == 'symlink':
+ if not file_struct.has_key('symlink'):
+ raise Exception, "Missing key symlink"
+
+ (dirname, filename) = os.path.split(file_struct['path'])
+ temppath = ".rhn-cfg-tmp_%s_%s_%.8f" % (filename, os.getpid(), time.time())
+ os.symlink(file_struct['symlink'], temppath)
+ return temppath, []
+
for k in self.file_struct_fields.keys():
if not file_struct.has_key(k):
# XXX
@@ -56,30 +70,20 @@ class FileProcessor:
delim_end = file_struct['delim_end']
fh = None
- # Older servers will not return directories; if filetype is missing,
- # assume file
- if file_struct.get('filetype') == 'directory':
- return directory, []
- if file_struct.get('filetype') == 'symlink':
- (dirname, filename) = os.path.split(file_struct['path'])
- temppath = ".rhn-cfg-tmp_%s_%s_%.8f" % (filename, os.getpid(), time.time())
- os.symlink(contents, temppath)
- return temppath, []
- else:
- (fullpath, dirs_created, fh) = maketemp(prefix=".rhn-cfg-tmp",
- directory=directory)
+ (fullpath, dirs_created, fh) = maketemp(prefix=".rhn-cfg-tmp",
+ directory=directory)
- try:
- fh.write(contents)
- except Exception:
- if fh:
- fh.close() # don't leak fds...
- raise
- else:
- fh.close()
+ try:
+ fh.write(contents)
+ except Exception:
+ if fh:
+ fh.close() # don't leak fds...
+ raise
+ else:
+ fh.close()
- return fullpath, dirs_created
+ return fullpath, dirs_created
def diff(self, file_struct):
@@ -95,7 +99,7 @@ class FileProcessor:
cur_sectx = ''
if file_struct.has_key('selinux_ctx'):
if cur_sectx != file_struct['selinux_ctx']:
- sectx_result = "SELinux contexts differ! Current: %s, expected: %s\n" % (cur_sectx, file_struct['selinux_ctx'])
+ sectx_result = "SELinux contexts differ: actual: [%s], expected: [%s]\n" % (cur_sectx, file_struct['selinux_ctx'])
if file_struct['filetype'] == 'symlink':
try:
@@ -104,7 +108,7 @@ class FileProcessor:
if curlink == newlink:
result = ''
else:
- result = "Link targets differ"
+ result = "Link targets differ: actual: [%s], expected: [%s]\n" % (curlink, newlink)
except OSError, e:
if e.errno == 22:
result = "Deployed symlink is no longer a symlink!"
diff --git a/client/tools/rhncfg/config_common/repository.py b/client/tools/rhncfg/config_common/repository.py
index fc938d7..7712d61 100644
--- a/client/tools/rhncfg/config_common/repository.py
+++ b/client/tools/rhncfg/config_common/repository.py
@@ -169,9 +169,8 @@ class Repository:
file_contents = None
if os.path.islink(local_path):
params['config_file_type_id'] = 3
+ params['symlink'] = os.readlink(local_path)
load_contents = 0
- file_contents = os.readlink(local_path)
- self._add_content(file_contents, params)
elif os.path.isdir(local_path):
params['config_file_type_id'] = 2
load_contents = 0
diff --git a/client/tools/rhncfg/config_common/transactions.py b/client/tools/rhncfg/config_common/transactions.py
index cc1ca01..ae0ea25 100644
--- a/client/tools/rhncfg/config_common/transactions.py
+++ b/client/tools/rhncfg/config_common/transactions.py
@@ -104,34 +104,35 @@ class DeployTransaction:
self.deployment_cb = cb
def _chown_chmod_chcon(self, temp_file_path, dest_path, file_info, strict_ownership=1):
- uid = file_info.get('uid')
- if uid is None:
- if file_info.has_key('username'):
- # determine uid
-
- try:
- user_record = pwd.getpwnam(file_info['username'])
- except Exception, e:
- raise cfg_exceptions.UserNotFound(file_info['username'])
-
- uid = user_record[2]
- else:
- #default to root (3.2 sats)
- uid = 0
-
- gid = file_info.get('gid')
- if gid is None:
- if file_info.has_key('groupname'):
- # determine gid
- try:
- group_record = grp.getgrnam(file_info['groupname'])
- except Exception, e:
- raise cfg_exceptions.GroupNotFound(file_info['groupname'])
-
- gid = group_record[2]
- else:
- #default to root (3.2 sats)
- gid = 0
+ if file_info['filetype'] != 'symlink':
+ uid = file_info.get('uid')
+ if uid is None:
+ if file_info.has_key('username'):
+ # determine uid
+
+ try:
+ user_record = pwd.getpwnam(file_info['username'])
+ except Exception, e:
+ raise cfg_exceptions.UserNotFound(file_info['username'])
+
+ uid = user_record[2]
+ else:
+ #default to root (3.2 sats)
+ uid = 0
+
+ gid = file_info.get('gid')
+ if gid is None:
+ if file_info.has_key('groupname'):
+ # determine gid
+ try:
+ group_record = grp.getgrnam(file_info['groupname'])
+ except Exception, e:
+ raise cfg_exceptions.GroupNotFound(file_info['groupname'])
+
+ gid = group_record[2]
+ else:
+ #default to root (3.2 sats)
+ gid = 0
try:
if file_info['filetype'] != 'symlink':
diff --git a/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml b/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
index 1258710..c007ac1 100644
--- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
+++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
@@ -495,7 +495,7 @@ SELECT CF.id,
CF.latest_config_revision_id,
CFN.path,
CR.revision AS latest_config_revision,
- CCon.modified,
+ coalesce(CCon.modified, CR.modified) as modified,
CFT.label as type
FROM rhnConfigContent CCon,
rhnConfigFileName CFN,
@@ -506,7 +506,7 @@ SELECT CF.id,
AND CF.config_channel_id = :ccid
AND CFN.id = CF.config_file_name_id
AND CR.config_file_id = CF.id
- AND CR.config_content_id = CCon.id
+ AND CR.config_content_id = CCon.id (+)
AND CF.latest_config_revision_id = CR.id
AND CR.config_file_type_id = CFT.id
ORDER BY CFN.path
@@ -518,10 +518,10 @@ ORDER BY CFN.path
SELECT CF.id,
CF.latest_config_revision_id,
CFN.path,
- CR.revision AS latest_config_revision,
- CCon.modified,
+ CR.revision AS latest_config_revision,
+ coalesce(CCon.modified, CR.modified) as modified,
CFT.label as type
- FROM rhnConfigContent CCon,
+ FROM rhnConfigContent CCon,
rhnConfigFileName CFN,
rhnConfigFile CF,
rhnConfigRevision CR,
@@ -534,7 +534,7 @@ SELECT CF.id,
AND CF.config_channel_id = :ccid
AND CFN.id = CF.config_file_name_id
AND CR.config_file_id = CF.id
- AND CR.config_content_id = CCon.id
+ AND CR.config_content_id = CCon.id (+)
AND CF.latest_config_revision_id = CR.id
AND CFT.id = CR.config_file_type_id
ORDER BY CFN.path
@@ -546,24 +546,24 @@ ORDER BY CFN.path
SELECT CR.id,
CR.created,
CR.revision AS revision_number,
- CCon.file_size
+ coalesce(CCon.file_size,0) as file_size
FROM rhnConfigContent CCon,
rhnConfigRevision CR
WHERE rhn_config_channel.get_user_file_access(:cfid, :user_id) = 1
AND CR.config_file_id = :cfid
- AND CR.config_content_id = CCon.id
+ AND CR.config_content_id = CCon.id(+)
ORDER BY CR.revision DESC
</query>
</mode>
<mode name="configfile_revisions_size">
<query params="cfid, user_id">
-SELECT SUM(CCon.file_size) AS total_file_size
+SELECT SUM(coalesce(CCon.file_size, 0)) AS total_file_size
FROM rhnConfigContent CCon,
rhnConfigRevision CR
WHERE rhn_config_channel.get_user_file_access(:cfid, :user_id) = 1
AND CR.config_file_id = :cfid
- AND CR.config_content_id = CCon.id
+ AND CR.config_content_id = CCon.id(+)
</query>
</mode>
@@ -726,7 +726,7 @@ SELECT DISTINCT CF.id AS id,
CFT.label AS type,
CCT.label AS config_channel_type,
CC.name AS CONFIG_CHANNEL_NAME,
- SUM(CCon.file_size) AS total_file_size
+ SUM(Coalesce(CCon.file_size,0)) AS total_file_size
FROM rhnConfigContent CCon,
rhnConfigChannelType CCT,
rhnConfigRevision CR,
@@ -742,7 +742,7 @@ SELECT DISTINCT CF.id AS id,
AND LCR.id = CF.latest_config_revision_id
AND LCR.config_file_type_id = CFT.id
AND CR.config_file_id = CF.id
- AND CCon.id = CR.config_content_id
+ AND CCon.id = CR.config_content_id(+)
AND CC.confchan_type_id = CCT.id
GROUP BY CF.id, CFN.path, CC.name, CC.label, CFT.label, CCT.label, CC.id, CF.latest_config_revision_id, LCR.revision
ORDER BY total_file_size DESC
@@ -942,7 +942,7 @@ SELECT COUNT(CF.id) AS num_files
<mode name="files_by_date" class="com.redhat.rhn.frontend.dto.ConfigFileDto">
<query params="ccid, user_id">
-SELECT CR.id, CFN.path, CCon.modified
+SELECT CR.id, CFN.path, coalesce(CCon.modified, CR.modified) as modified
FROM rhnConfigContent CCon,
rhnConfigFileName CFN,
rhnConfigFile CF,
@@ -952,16 +952,16 @@ SELECT CR.id, CFN.path, CCon.modified
AND CF.config_channel_id = CC.id
AND CFN.id = CF.config_file_name_id
AND CR.config_file_id = CF.id
- AND CR.config_content_id = CCon.id
+ AND CR.config_content_id = CCon.id(+)
AND CF.latest_config_revision_id = CR.id
AND rhn_config_channel.get_user_file_access(CF.id, :user_id) = 1
-ORDER BY CCon.modified DESC
+ORDER BY modified DESC
</query>
</mode>
<callable-mode name="lookup_config_info">
- <query params="username_in, groupname_in, filemode_in, selinuxCtx_in">
- {:info_id = call lookup_config_info( :username_in, :groupname_in, :filemode_in, :selinuxCtx_in )}
+ <query params="username_in, groupname_in, filemode_in, selinuxCtx_in, symlink_target_file_in">
+ {:info_id = call lookup_config_info( :username_in, :groupname_in, :filemode_in, :selinuxCtx_in, :symlink_target_file_in)}
</query>
</callable-mode>
@@ -1050,7 +1050,7 @@ ORDER BY CFN.path
SELECT CF.id, CR.modified,
CR.revision AS latest_config_revision,
CR.id AS latest_config_revision_id,
- CCon.file_size AS latest_revision_size,
+ coalesce(CCon.file_size,0) AS latest_revision_size,
CFT.label AS type
FROM rhnConfigFile CF, rhnConfigRevision CR,
rhnConfigContent CCon, rhnConfigFileName CFN,
@@ -1058,7 +1058,7 @@ SELECT CF.id, CR.modified,
WHERE CF.id IN (%s)
AND CF.config_file_name_id = CFN.id
AND CF.latest_config_revision_id = CR.id
- AND CR.config_content_id = CCon.id
+ AND CR.config_content_id = CCon.id(+)
AND CR.config_file_type_id = CFT.id
</elaborator>
</mode>
@@ -2260,8 +2260,8 @@ ORDER BY UPPER(CFN.path)
</callable-mode>
<callable-mode name="create_new_config_revision">
- <query params="revision_in, config_file_id_in, config_content_id_in, config_info_id_in, delim_start_in, delim_end_in, config_file_type_id">
- {:configRevisionId = call rhn_config.insert_revision( :revision_in, :config_file_id_in, :config_content_id_in, :config_info_id_in, :delim_start_in, :delim_end_in, :config_file_type_id)}
+ <query params="revision_in, config_file_id_in, config_content_id_in, config_info_id_in, config_file_type_id">
+ {:configRevisionId = call rhn_config.insert_revision( :revision_in, :config_file_id_in, :config_content_id_in, :config_info_id_in, :config_file_type_id)}
</query>
</callable-mode>
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigContent.hbm.xml b/java/code/src/com/redhat/rhn/domain/config/ConfigContent.hbm.xml
index 46e09ed..97cccd1 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigContent.hbm.xml
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigContent.hbm.xml
@@ -14,8 +14,14 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
<property name="contents" column="contents" type="binary" />
<property name="fileSize" column="file_size" type="long" />
<property name="binary" column="is_binary" type="yes_no" />
- <property name="created" column="created" type="timestamp" />
- <property name="modified" column="modified" type="timestamp" />
+ <property name="created" column="created" type="timestamp"
+ insert="false" update="false"/>
+ <property name="modified" column="modified" type="timestamp"
+ insert="false" update="false"/>
+ <property name="delimStart" column="delim_start" type="string"
+ length="16" />
+ <property name="delimEnd" column="delim_end" type="string" length="16"
+ />
<many-to-one name="checksum" class="com.redhat.rhn.domain.common.Checksum"
column="checksum_id" />
</class>
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigContent.java b/java/code/src/com/redhat/rhn/domain/config/ConfigContent.java
index 7df22a1..12dd796 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigContent.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigContent.java
@@ -28,6 +28,8 @@ public class ConfigContent extends BaseDomainHelper {
private Checksum checksum;
private boolean isBinary;
private byte[] contents;
+ private String delimStart;
+ private String delimEnd;
/**
* protected constructor.
* Use the ConfigurationFactory to get new ConfigContents
@@ -127,4 +129,35 @@ public class ConfigContent extends BaseDomainHelper {
this.isBinary = isBinaryIn;
}
+ /**
+ * Getter for delimStart
+ * @return String to get
+ */
+ public String getDelimStart() {
+ return this.delimStart;
+ }
+
+ /**
+ * Setter for delimStart
+ * @param delimStartIn to set
+ */
+ public void setDelimStart(String delimStartIn) {
+ this.delimStart = delimStartIn;
+ }
+
+ /**
+ * Getter for delimEnd
+ * @return String to get
+ */
+ public String getDelimEnd() {
+ return this.delimEnd;
+ }
+
+ /**
+ * Setter for delimEnd
+ * @param delimEndIn to set
+ */
+ public void setDelimEnd(String delimEndIn) {
+ this.delimEnd = delimEndIn;
+ }
}
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigFileType.java b/java/code/src/com/redhat/rhn/domain/config/ConfigFileType.java
index d7d0820..9d7aab6 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigFileType.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigFileType.java
@@ -213,6 +213,7 @@ public class ConfigFileType implements Serializable {
/**
* {@inheritDoc}
*/
+ @Override
public String toString() {
return new ToStringBuilder(this).append("id", getId()).toString();
}
@@ -220,6 +221,7 @@ public class ConfigFileType implements Serializable {
/**
* {@inheritDoc}
*/
+ @Override
public boolean equals(Object other) {
if (!(other instanceof ConfigFileType)) {
return false;
@@ -231,8 +233,22 @@ public class ConfigFileType implements Serializable {
/**
* {@inheritDoc}
*/
+ @Override
public int hashCode() {
return new HashCodeBuilder().append(getId()).toHashCode();
}
+ /**
+ * @return The i18n message key for the type
+ */
+ public String getMessageKey() {
+ if (dir().equals(this)) {
+ return "addfiles.jsp.type.directory";
+ }
+ else if (symlink().equals(this)) {
+ return "addfiles.jsp.type.symlink";
+ }
+ return "addfiles.jsp.type.text";
+ }
+
}
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
index 04c4e85..94382df 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
@@ -15,15 +15,13 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
<property name="groupname" column="groupname" type="string" length="32"
/>
<property name="filemode" column="filemode" type="long" />
- <property name="created" column="created" type="timestamp" />
- <property name="modified" column="modified" type="timestamp" />
+ <property name="created" column="created" type="timestamp"
+ insert="false" update="false"/>
+ <property name="modified" column="modified" type="timestamp"
+ insert="false" update="false"/>
<property name="selinuxCtx" column="selinux_ctx" type="string" length="64" />
+ <many-to-one name="targetFileName"
+ class="com.redhat.rhn.domain.config.ConfigFileName"
+ column="SYMLINK_TARGET_FILENAME_ID" cascade="none" />
</class>
-
- <query name="ConfigInfo.findWithoutId">
- <![CDATA[from com.redhat.rhn.domain.config.ConfigInfo as c
- where c.username = :username
- and c.groupname = :groupname
- and c.filemode = :filemode]]>
- </query>
</hibernate-mapping>
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
index 8db7184..3c7e891 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
@@ -27,6 +27,7 @@ public class ConfigInfo extends BaseDomainHelper {
private String groupname;
private Long filemode;
private String selinuxCtx;
+ private ConfigFileName targetFileName;
/**
* protected constructor
@@ -115,4 +116,18 @@ public class ConfigInfo extends BaseDomainHelper {
public void setSelinuxCtx(String ctxIn) {
this.selinuxCtx = ctxIn;
}
+
+ /**
+ * @param targetFileNameIn The targetFileName to set.
+ */
+ public void setTargetFileName(ConfigFileName targetFileNameIn) {
+ this.targetFileName = targetFileNameIn;
+ }
+
+ /**
+ * @return Returns the targetFileName.
+ */
+ public ConfigFileName getTargetFileName() {
+ return targetFileName;
+ }
}
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigRevision.hbm.xml b/java/code/src/com/redhat/rhn/domain/config/ConfigRevision.hbm.xml
index c227782..685ee3c 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigRevision.hbm.xml
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigRevision.hbm.xml
@@ -9,10 +9,6 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
<generator class="assigned" />
</id>
<property name="revision" column="revision" type="long" />
- <property name="delimStart" column="delim_start" type="string"
- length="16" />
- <property name="delimEnd" column="delim_end" type="string" length="16"
- />
<property name="created" column="created" type="timestamp" />
<property name="modified" column="modified" type="timestamp" />
<property name="changedById" column="changed_by_id" type="long" />
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigRevision.java b/java/code/src/com/redhat/rhn/domain/config/ConfigRevision.java
index 7a3a888..4007259 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigRevision.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigRevision.java
@@ -28,9 +28,6 @@ public class ConfigRevision extends BaseDomainHelper {
private Long id;
private Long revision;
- private String delimStart;
- private String delimEnd;
-
private ConfigFile configFile;
private ConfigContent configContent;
private ConfigInfo configInfo;
@@ -80,38 +77,6 @@ public class ConfigRevision extends BaseDomainHelper {
}
/**
- * Getter for delimStart
- * @return String to get
- */
- public String getDelimStart() {
- return this.delimStart;
- }
-
- /**
- * Setter for delimStart
- * @param delimStartIn to set
- */
- public void setDelimStart(String delimStartIn) {
- this.delimStart = delimStartIn;
- }
-
- /**
- * Getter for delimEnd
- * @return String to get
- */
- public String getDelimEnd() {
- return this.delimEnd;
- }
-
- /**
- * Setter for delimEnd
- * @param delimEndIn to set
- */
- public void setDelimEnd(String delimEndIn) {
- this.delimEnd = delimEndIn;
- }
-
- /**
* @return Returns the configContent.
*/
public ConfigContent getConfigContent() {
@@ -188,8 +153,6 @@ public class ConfigRevision extends BaseDomainHelper {
retval.setConfigFile(getConfigFile());
retval.setConfigInfo(getConfigInfo());
retval.setConfigFileType(getConfigFileType());
- retval.setDelimEnd(getDelimEnd());
- retval.setDelimStart(getDelimStart());
retval.setCreated(new Date());
retval.setModified(new Date());
retval.setRevision(getRevision());
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java b/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
index 03d6494..31a6842 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
@@ -27,6 +27,7 @@ import com.redhat.rhn.domain.org.Org;
import com.redhat.rhn.domain.server.Server;
import com.redhat.rhn.domain.user.User;
+import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
@@ -54,6 +55,7 @@ public class ConfigurationFactory extends HibernateFactory {
super();
}
+ @Override
protected Logger getLogger() {
return log;
}
@@ -207,9 +209,12 @@ public class ConfigurationFactory extends HibernateFactory {
CallableMode m = ModeFactory.getCallableMode("config_queries",
"create_new_config_revision");
- //We need to save the content first so that we have an id for
- // the stored procedure.
- singleton.saveObject(revision.getConfigContent());
+
+ if (revision.isFile()) {
+ //We need to save the content first so that we have an id for
+ // the stored procedure.
+ singleton.saveObject(revision.getConfigContent());
+ }
//We do not have to save the ConfigInfo, because the info should always already be
// in the database. If this is not the case, please read the documentation for
// lookupOrInsertConfigInfo(String, String, Long) and correct the problem.
@@ -219,10 +224,13 @@ public class ConfigurationFactory extends HibernateFactory {
inParams.put("revision_in", revision.getRevision());
inParams.put("config_file_id_in", revision.getConfigFile().getId());
- inParams.put("config_content_id_in", revision.getConfigContent().getId());
+ if (revision.isFile()) {
+ inParams.put("config_content_id_in", revision.getConfigContent().getId());
+ }
+ else {
+ inParams.put("config_content_id_in", null);
+ }
inParams.put("config_info_id_in", revision.getConfigInfo().getId());
- inParams.put("delim_start_in", revision.getDelimStart());
- inParams.put("delim_end_in", revision.getDelimEnd());
inParams.put("config_file_type_id", new Long(
revision.getConfigFileType().getId()));
@@ -299,11 +307,17 @@ public class ConfigurationFactory extends HibernateFactory {
//ConfigInfos have a unique constraint for their four data fields.
//The config info object associated with this revision may have been
//changed, so we need to carefully not update the database record.
+
+ String targetPath = revision.getConfigInfo().getTargetFileName() == null ?
+ null :
+ revision.getConfigInfo().getTargetFileName().getPath();
+
ConfigInfo info = lookupOrInsertConfigInfo(
revision.getConfigInfo().getUsername(),
revision.getConfigInfo().getGroupname(),
revision.getConfigInfo().getFilemode(),
- revision.getConfigInfo().getSelinuxCtx());
+ revision.getConfigInfo().getSelinuxCtx(),
+ targetPath);
//if the object did not change, we now have two hibernate objects
//with the same identifier. Evict one so that hibernate doesn't get mad.
getSession().evict(revision.getConfigInfo());
@@ -479,11 +493,14 @@ public class ConfigurationFactory extends HibernateFactory {
* @param groupname The linux groupname associated with a file
* @param filemode The three digit file mode (ex: 655)
* @param selinuxCtx The SELinux context
+ * @param symlinkTargetPath a target path for symlink or null for a non symlink path
* @return The ConfigInfo found or inserted.
*/
public static ConfigInfo lookupOrInsertConfigInfo(String username,
- String groupname, Long filemode, String selinuxCtx) {
- Long id = lookupConfigInfo(username, groupname, filemode, selinuxCtx);
+ String groupname, Long filemode, String selinuxCtx,
+ String symlinkTargetPath) {
+ Long id = lookupConfigInfo(username, groupname,
+ filemode, selinuxCtx, symlinkTargetPath);
return lookupConfigInfoById(id);
}
@@ -497,7 +514,8 @@ public class ConfigurationFactory extends HibernateFactory {
* @return The id of the found config info
*/
private static Long lookupConfigInfo(String user, String group,
- Long filemode, String selinuxCtx) {
+ Long filemode, String selinuxCtx,
+ String symlinkTargetPath) {
CallableMode m = ModeFactory.getCallableMode("config_queries",
"lookup_config_info");
@@ -508,6 +526,14 @@ public class ConfigurationFactory extends HibernateFactory {
inParams.put("groupname_in", group);
inParams.put("filemode_in", filemode);
inParams.put("selinuxCtx_in", selinuxCtx);
+ if (!StringUtils.isBlank(symlinkTargetPath)) {
+ ConfigFileName fn = lookupOrInsertConfigFileName(symlinkTargetPath);
+ inParams.put("symlink_target_file_in", fn.getId());
+ }
+ else {
+ inParams.put("symlink_target_file_in", null);
+ }
+
outParams.put("info_id", new Integer(Types.NUMERIC));
Map out = m.execute(inParams, outParams);
@@ -706,10 +732,17 @@ public class ConfigurationFactory extends HibernateFactory {
revision.setChangedById(usr.getId());
//Steps 2-4
- if (!revision.isDirectory()) {
+ if (revision.isFile()) {
+ String delimStart = null;
+ String delimEnd = null;
+ if (!revision.getConfigContent().isBinary()) {
+ delimStart = revision.getConfigContent().getDelimStart();
+ delimEnd = revision.getConfigContent().getDelimEnd();
+ }
revision.setConfigContent(
createNewContentFromStream(stream, size,
- revision.getConfigContent().isBinary()));
+ revision.getConfigContent().isBinary(),
+ delimStart, delimEnd));
}
//Step 5
@@ -729,10 +762,13 @@ public class ConfigurationFactory extends HibernateFactory {
* @param size number of bytes to read
* @param isBinary true if the content is to be treated as binary (which means we
* won't expand macros, morph EOL, or let you edit it from the web UI)
+ * @param delimStart start delimeter or null for binary
+ * @param delimEnd end delimeter or null for binary
* @return filled-in ConfigContent
*/
public static ConfigContent createNewContentFromStream(
- InputStream stream, Long size, boolean isBinary) {
+ InputStream stream, Long size, boolean isBinary,
+ String delimStart, String delimEnd) {
ConfigContent content = ConfigurationFactory.newConfigContent();
content.setCreated(new Date());
content.setModified(new Date());
@@ -761,6 +797,10 @@ public class ConfigurationFactory extends HibernateFactory {
Checksum newChecksum = ChecksumFactory.safeCreate(MD5Crypt.md5Hex(foo), "md5");
content.setChecksum(newChecksum);
content.setBinary(isBinary);
+ if (!isBinary) {
+ content.setDelimEnd(delimEnd);
+ content.setDelimStart(delimStart);
+ }
return content;
}
diff --git a/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java b/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
index 7c1ec39..d4b5a7b 100644
--- a/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
+++ b/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
@@ -40,11 +40,13 @@ public class ConfigurationFactoryTest extends RhnBaseTestCase {
private User user;
+ @Override
protected void setUp() throws Exception {
super.setUp();
user = UserTestUtils.findNewUser("testyman", "testyorg");
}
+ @Override
protected void tearDown() throws Exception {
user = null;
super.tearDown();
@@ -140,9 +142,6 @@ public class ConfigurationFactoryTest extends RhnBaseTestCase {
ConfigurationFactory.lookupConfigRevisionById(revision.getId());
assertNotNull(revision2);
assertEquals(revision.getRevision(), revision2.getRevision());
-
- //now change something and hopefully avoid database problem
- revision2.setDelimEnd("\n");
ConfigurationFactory.commit(revision2);
}
@@ -151,9 +150,9 @@ public class ConfigurationFactoryTest extends RhnBaseTestCase {
//one problem is that looking up the same thing must be done in such a way that
//hibernate doesn't yell about it.
ConfigInfo info1 = ConfigurationFactory.lookupOrInsertConfigInfo("testman",
- "testgroup", new Long(665), "");
+ "testgroup", new Long(665), "", null);
ConfigInfo info2 = ConfigurationFactory.lookupOrInsertConfigInfo("testman",
- "testgroup", new Long(665), "");
+ "testgroup", new Long(665), "", null);
assertNotNull(info1.getId());
assertNotNull(info2.getId());
assertEquals(info1.getId(), info2.getId());
diff --git a/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java b/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
index afc6391..7c351d9 100644
--- a/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
+++ b/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
@@ -32,6 +32,7 @@ import com.redhat.rhn.manager.configuration.ConfigurationValidation;
import com.redhat.rhn.manager.configuration.file.BinaryFileData;
import com.redhat.rhn.manager.configuration.file.ConfigFileData;
import com.redhat.rhn.manager.configuration.file.DirectoryData;
+import com.redhat.rhn.manager.configuration.file.SymlinkData;
import com.redhat.rhn.manager.configuration.file.TextFileData;
import org.apache.struts.upload.FormFile;
@@ -54,6 +55,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm {
private static final long serialVersionUID = -2162768922109257186L;
// configFileForm elements
public static final String REV_PATH = "cffPath";
+ public static final String REV_SYMLINK_TARGET_PATH = "targetPath";
public static final String REV_UID = "cffUid";
public static final String REV_GID = "cffGid";
public static final String REV_PERMS = "cffPermissions";
@@ -159,27 +161,38 @@ public class ConfigFileForm extends ScrubbingDynaActionForm {
User u = requestContext.getLoggedInUser();
set(ConfigFileForm.REV_PATH, cr.getConfigFile().getConfigFileName().getPath());
+ if (cr.isSymlink() && cr.getConfigInfo().getTargetFileName() != null) {
+ set(ConfigFileForm.REV_SYMLINK_TARGET_PATH,
+ cr.getConfigInfo().getTargetFileName().getPath());
+ }
+
+ set(REV_NUMBER, String.valueOf(
+ cr.getConfigFile().getLatestConfigRevision().getRevision() + 1));
+
Long mode = cr.getConfigInfo().getFilemode();
- String modeStr = new DecimalFormat("000").format(mode.longValue());
+
+ String modeStr = mode == null ? "" :
+ new DecimalFormat("000").format(mode.longValue());
set(ConfigFileForm.REV_PERMS, modeStr);
set(ConfigFileForm.REV_SELINUX_CTX, cr.getConfigInfo().getSelinuxCtx());
set(ConfigFileForm.REV_UID, cr.getConfigInfo().getUsername());
set(ConfigFileForm.REV_GID, cr.getConfigInfo().getGroupname());
- set(ConfigFileForm.REV_BINARY, new Boolean(cr.getConfigContent().isBinary()));
set("submitted", Boolean.TRUE);
-
- if (!cr.getConfigContent().isBinary() && !cr.isDirectory()) {
- set(ConfigFileForm.REV_CONTENTS, cr.getConfigContent().getContentsString());
+ if (cr.isFile()) {
+ set(ConfigFileForm.REV_BINARY, cr.getConfigContent().isBinary());
+ if (!cr.getConfigContent().isBinary() && !cr.isDirectory()) {
+ set(ConfigFileForm.REV_CONTENTS, cr.getConfigContent().getContentsString());
+ }
+ Boolean toolarge = cr.getConfigContent().getFileSize().
+ longValue() > MAX_EDITABLE_SIZE;
+ request.setAttribute(REV_TOOLARGE, toolarge);
}
-
ConfigActionHelper.setupRequestAttributes(requestContext, cr.getConfigFile(), cr);
- request.setAttribute(REV_DISPLAYABLE, new Boolean(canDisplayContent(cr)));
- request.setAttribute(REV_EDITABLE, new Boolean(canEditContent(u, cr)));
+ request.setAttribute(REV_DISPLAYABLE, canDisplayContent(cr));
+ request.setAttribute(REV_EDITABLE, canEditContent(u, cr));
+
- Boolean toolarge = new Boolean(
- cr.getConfigContent().getFileSize().longValue() > MAX_EDITABLE_SIZE);
- request.setAttribute(REV_TOOLARGE, toolarge);
}
/**
@@ -191,7 +204,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm {
* @return true IFF the above conditions are true
*/
protected boolean canDisplayContent(ConfigRevision cr) {
- return (!cr.isDirectory() &&
+ return (cr.isFile() &&
!cr.getConfigContent().isBinary() &&
cr.getConfigContent().getFileSize().longValue() < MAX_EDITABLE_SIZE);
}
@@ -221,6 +234,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm {
* but the rest MUST be scrubbed
* {@inheritDoc}
*/
+ @Override
protected boolean isScrubbable(String name, Object value) {
if (REV_CONTENTS.equals(name) ||
REV_MACROSTART.equals(name) ||
@@ -283,6 +297,9 @@ public class ConfigFileForm extends ScrubbingDynaActionForm {
if (isDirectory()) {
data = new DirectoryData();
}
+ else if (ConfigFileType.symlink().equals(extractFileType())) {
+ data = new SymlinkData(getString(REV_SYMLINK_TARGET_PATH));
+ }
else if (isBinary()) {
if (isUpload()) {
FormFile file = (FormFile) get(REV_UPLOAD);
@@ -333,7 +350,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm {
public ConfigFileData toRevisedData(ConfigRevision rev) {
ConfigFileData data = toData();
boolean toBeBinary = (Boolean)get(REV_BINARY) == null ?
- rev.getConfigContent().isBinary() :
+ rev.isFile() && rev.getConfigContent().isBinary() :
isBinary();
if (!canDisplayContent(rev) || toBeBinary) {
data.processRevisedContentFrom(rev);
diff --git a/java/code/src/com/redhat/rhn/frontend/action/configuration/files/DiffAction.java b/java/code/src/com/redhat/rhn/frontend/action/configuration/files/DiffAction.java
index 103f6cc..e6ec2d7 100644
--- a/java/code/src/com/redhat/rhn/frontend/action/configuration/files/DiffAction.java
+++ b/java/code/src/com/redhat/rhn/frontend/action/configuration/files/DiffAction.java
@@ -15,7 +15,9 @@
package com.redhat.rhn.frontend.action.configuration.files;
import com.redhat.rhn.common.filediff.Diff;
+import com.redhat.rhn.domain.config.ConfigContent;
import com.redhat.rhn.domain.config.ConfigFile;
+import com.redhat.rhn.domain.config.ConfigFileName;
import com.redhat.rhn.domain.config.ConfigInfo;
import com.redhat.rhn.domain.config.ConfigRevision;
import com.redhat.rhn.domain.user.User;
@@ -25,6 +27,7 @@ import com.redhat.rhn.frontend.struts.RhnAction;
import com.redhat.rhn.frontend.struts.RhnHelper;
import com.redhat.rhn.manager.configuration.ConfigurationManager;
+import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
@@ -41,6 +44,7 @@ public class DiffAction extends RhnAction {
/**
* {@inheritDoc}
*/
+ @Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws Exception {
@@ -60,11 +64,17 @@ public class DiffAction extends RhnAction {
.lookupConfigRevision(user, ocrid);
//Only do the diff if both files are text files.
- if (!revision.isDirectory() && !revision.getConfigContent().isBinary() &&
- !other.isDirectory() && !other.getConfigContent().isBinary()) {
+ if (revision.isFile() && !revision.getConfigContent().isBinary() &&
+ other.isFile() && !other.getConfigContent().isBinary()) {
request.setAttribute("showdiff", "true");
request.setAttribute("diff",
performFileDiff(revision, other, view.equals("changed")));
+ ConfigContent revContent = revision.getConfigContent();
+ ConfigContent otherContent = other.getConfigContent();
+ if (!revContent.getDelimStart().equals(otherContent.getDelimStart()) ||
+ !revContent.getDelimEnd().equals(otherContent.getDelimEnd())) {
+ request.setAttribute("diffdelim", "true");
+ }
}
//Set attributes so we can display basic file information.
@@ -94,28 +104,42 @@ public class DiffAction extends RhnAction {
HttpServletRequest request) {
ConfigInfo info = revision.getConfigInfo();
ConfigInfo oinfo = other.getConfigInfo();
-
- //The following pieces are differences between revisions that are
- //not in the file content. We only show these if they are different.
- if (!info.getFilemode().equals(oinfo.getFilemode())) {
- request.setAttribute("diffmode", "true");
- }
- if (!info.getUsername().equals(oinfo.getUsername())) {
- request.setAttribute("diffuser", "true");
+ if (!revision.isSymlink()) {
+ //The following pieces are differences between revisions that are
+ //not in the file content. We only show these if they are different.
+ if (!info.getFilemode().equals(oinfo.getFilemode())) {
+ request.setAttribute("diffmode", "true");
+ }
+ if (!info.getUsername().equals(oinfo.getUsername())) {
+ request.setAttribute("diffuser", "true");
+ }
+ if (!info.getGroupname().equals(oinfo.getGroupname())) {
+ request.setAttribute("diffgroup", "true");
+ }
}
- if (!info.getGroupname().equals(oinfo.getGroupname())) {
- request.setAttribute("diffgroup", "true");
- }
- if (!revision.getDelimStart().equals(other.getDelimStart()) ||
- !revision.getDelimEnd().equals(other.getDelimEnd())) {
- request.setAttribute("diffdelim", "true");
+ else if (other.isSymlink()) {
+ ConfigFileName target = info.getTargetFileName();
+ ConfigFileName otarget = oinfo.getTargetFileName();
+ if ((target == null && otarget != null) ||
+ (target != null && otarget == null) ||
+ !otarget.equals(target)) {
+ request.setAttribute("difftargetpath", "true");
+ }
}
+
if (!revision.getConfigFileType().getLabel()
.equals(other.getConfigFileType().getLabel()) ||
- revision.getConfigContent().isBinary() !=
- other.getConfigContent().isBinary()) {
+ (revision.isFile() && revision.getConfigContent().isBinary() !=
+ other.getConfigContent().isBinary())) {
request.setAttribute("difftype", "true");
}
+
+ String selinux = StringUtils.defaultString(info.getSelinuxCtx());
+ String otherSelinux = StringUtils.defaultString(oinfo.getSelinuxCtx());
+ if (!selinux.equals(otherSelinux)) {
+ request.setAttribute("diffselinux", "true");
+ }
+
}
}
diff --git a/java/code/src/com/redhat/rhn/frontend/action/configuration/files/FileDetailsAction.java b/java/code/src/com/redhat/rhn/frontend/action/configuration/files/FileDetailsAction.java
index 71f036b..bdafd59 100644
--- a/java/code/src/com/redhat/rhn/frontend/action/configuration/files/FileDetailsAction.java
+++ b/java/code/src/com/redhat/rhn/frontend/action/configuration/files/FileDetailsAction.java
@@ -54,12 +54,13 @@ public class FileDetailsAction extends RhnAction {
public static final String LAST_USER = "lastUser";
public static final String LAST_USER_ID = "lastUserId";
public static final String TOOLARGE = "toolarge";
- public static final String REV_NUM = "revnum";
+
public static final String VALIDATION_XSD =
"/com/redhat/rhn/frontend/action/configuration/validation/configFileForm.xsd";
/** {@inheritDoc} */
+ @Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
@@ -74,26 +75,6 @@ public class FileDetailsAction extends RhnAction {
if (cr != null) {
if (isSubmitted(cff)) {
-
- // Shameful code ahead
- //
- // If this is a DIRECTORY, we've carefully arranged for the user to
- // only ever fill in uid/gid/mode, because that's all that makes
- // sense. Unfortunately, the DB schema REQUIRES macro start and
- // end. That means that updating a directory currently throws
- // struts-validation errors "Start/End Macro Required" - and if you
- // relax that constraint, then the DB throws a nasty SQLException on update.
- //
- // The right fix involves schema-changes, which is NOT an option. So,
- // here, we check for isDir - and if you are, we give you the default
- // macro-tags, willy-nilly.
- //
- // Ew.
- if (cr.isDirectory() || cr.getConfigContent().isBinary()) {
- cff.set(ConfigFileForm.REV_MACROSTART, "{@");
- cff.set(ConfigFileForm.REV_MACROEND, "@}");
- }
-
ConfigFileBuilder builder = ConfigFileBuilder.getInstance();
try {
cr = builder.update(cff.toRevisedData(cr),
@@ -104,6 +85,7 @@ public class FileDetailsAction extends RhnAction {
getStrutsDelegate().saveMessages(request, ve.getResult());
RhnValidationHelper.setFailedValidation(request);
cff.updateFromRevision(request, cr);
+ setupRequestParams(context, cr);
return getStrutsDelegate().forwardParams(
mapping.findForward("error"), params);
}
@@ -133,20 +115,27 @@ public class FileDetailsAction extends RhnAction {
ConfigDefaults.DEFAULT_CONFIG_REVISION_MAX_SIZE)));
request.setAttribute(MAX_EDIT_SIZE,
StringUtil.displayFileSize(ConfigFileForm.MAX_EDITABLE_SIZE));
-
- request.setAttribute(REV_TOTAL_SIZE, StringUtil.displayFileSize(totalBytes));
- request.setAttribute(REV_SIZE,
- StringUtil.displayFileSize(
- cr.getConfigContent().getFileSize().longValue()));
+ if (cr.isFile()) {
+ request.setAttribute(REV_TOTAL_SIZE, StringUtil.displayFileSize(totalBytes));
+ request.setAttribute(REV_SIZE,
+ StringUtil.displayFileSize(
+ cr.getConfigContent().getFileSize().longValue()));
+ }
request.setAttribute(REV_CREATED,
StringUtil.categorizeTime(cr.getConfigFile().getCreated().getTime(),
StringUtil.WEEKS_UNITS));
- request.setAttribute(REV_MODIFIED,
- StringUtil.categorizeTime(cr.getConfigContent().
- getModified().getTime(),
- StringUtil.WEEKS_UNITS));
- request.setAttribute(REV_NUM,
- cr.getConfigFile().getLatestConfigRevision().getRevision() + 1);
+
+ if (cr.getConfigContent() == null) {
+ request.setAttribute(REV_MODIFIED,
+ StringUtil.categorizeTime(cr.getModified().getTime(),
+ StringUtil.WEEKS_UNITS));
+ }
+ else {
+ request.setAttribute(REV_MODIFIED,
+ StringUtil.categorizeTime(cr.getConfigContent().getModified().getTime(),
+ StringUtil.WEEKS_UNITS));
+ }
+
User lastUser = cr.getChangedBy();
if (lastUser != null) {
diff --git a/java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileFormForSymlink.xsd b/java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileFormForSymlink.xsd
new file mode 100644
index 0000000..9f455ae
--- /dev/null
+++ b/java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileFormForSymlink.xsd
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+
+<schema targetNamespace="http://rhn.redhat.com"
+ xmlns="http://www.w3.org/1999/XMLSchema" xmlns:rhn="http://rhn.redhat.com">
+ <attribute name="cffSELinuxCtx">
+ <simpleType baseType="string">
+ <maxLength value="64" />
+ </simpleType>
+ </attribute>
+</schema>
diff --git a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml
index 6fba2c2..0bc0650 100644
--- a/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml
+++ b/java/code/src/com/redhat/rhn/frontend/strings/java/StringResource_en_US.xml
@@ -6712,6 +6712,12 @@ Follow this url to see the full list of inactive systems:
</context-group>
</trans-unit>
+ <trans-unit id="error.config-cannot-change-type">
+ <source>Error creating configuration file revision: ({0}) is a '{1}', but you are attempting to change it to a '{2}'. If you want to change its file type, you'll need to delete ({0}) and re-add it as a '{2}' rather than a '{1}'.</source>
+ <context-group name="ctx">
+ <context context-type="sourcefile">/rhn/configuration/file/ManageConfigRevision.do</context>
+ </context-group>
+ </trans-unit>
<trans-unit id="error.config-not-specified">
<source>Error creating Configuration File Revision: Upload file not found.</source>
diff --git a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
index 3cd7f72..7ee8a4c 100644
--- a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
+++ b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
@@ -14515,6 +14515,14 @@ centrally-managed configuration channel, {2}; below is a list of systems you may
<context context-type="sourcefile">/rhn/configuration/file/FileDetails.do</context>
</context-group>
</trans-unit>
+ <trans-unit id="config-file-form.error.selinux-invalid">
+<source>Invalid values set for SElinux Context.</source>
+ <context-group name="ctx">
+ <context context-type="sourcefile">/rhn/configuration/file/FileDetails.do</context>
+ </context-group>
+ </trans-unit>
+
+
<trans-unit id="config-file-form.error.start-delim-percent">
<source>Start delimiter may not contain the '%' character.</source>
<context-group name="ctx">
@@ -14828,6 +14836,12 @@ _Download /etc/sysconfig/rhn/up2date_ (Revision 7, 96 bytes)
<context context-type="sourcefile">/rhn/configuration/file/FileDetails.do</context>
</context-group>
</trans-unit>
+ <trans-unit id="filedetails.properties.jspf.targetpath">
+<source>Symbolic Link Target Filename/Path <span class=required-form-field>*</span>:</source>
+ <context-group name="ctx">
+ <context context-type="sourcefile">/rhn/configuration/file/FileDetails.do</context>
+ </context-group>
+ </trans-unit>
<trans-unit id="filedetails.properties.jspf.ownership">
<source>Ownership:</source>
<context-group name="ctx">
@@ -15685,6 +15699,12 @@ any of these revisions. Are you sure you want to do this?</source>
<trans-unit id="diff.jsp.groupname">
<source>Group:</source>
</trans-unit>
+ <trans-unit id="diff.jsp.selinux">
+ <source>SE Linux Context:</source>
+ </trans-unit>
+ <trans-unit id="diff.jsp.targetpath">
+ <source>Target Path:</source>
+ </trans-unit>
<trans-unit id="diff.jsp.startDelim">
<source>Start Delimiter:</source>
</trans-unit>
diff --git a/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/test/ConfigChannelHandlerTest.java b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/test/ConfigChannelHandlerTest.java
index 4be4958..c0ae8b3 100644
--- a/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/test/ConfigChannelHandlerTest.java
+++ b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/test/ConfigChannelHandlerTest.java
@@ -220,7 +220,6 @@ public class ConfigChannelHandlerTest extends BaseHandlerTestCase {
adminKey, cc.getLabel(), path, isDir, data);
assertEquals(path, rev.getConfigFile().getConfigFileName().getPath());
- assertEquals(contents, rev.getConfigContent().getContentsString());
assertEquals(group, rev.getConfigInfo().getGroupname());
assertEquals(owner, rev.getConfigInfo().getUsername());
assertEquals(perms, String.valueOf(rev.getConfigInfo().getFilemode()));
@@ -228,10 +227,10 @@ public class ConfigChannelHandlerTest extends BaseHandlerTestCase {
if (isDir) {
assertEquals(ConfigFileType.dir(), rev.getConfigFileType());
}
- else {
- assertEquals(ConfigFileType.file(), rev.getConfigFileType());
- assertEquals(start, rev.getDelimStart());
- assertEquals(end, rev.getDelimEnd());
+ else if (ConfigFileType.file().equals(rev.getConfigFileType())) {
+ assertEquals(contents, rev.getConfigContent().getContentsString());
+ assertEquals(start, rev.getConfigContent().getDelimStart());
+ assertEquals(end, rev.getConfigContent().getDelimEnd());
}
assertEquals(cc, rev.getConfigFile().getConfigChannel());
diff --git a/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java b/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
index 73ecdf4..55bccfa 100644
--- a/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
+++ b/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
@@ -51,9 +51,9 @@ import redstone.xmlrpc.XmlRpcSerializer;
* #prop_desc("boolean", "binary", "true/false , Present for files only.")
* #prop_desc("string", "md5", "File's md5 signature. Present for files only.")
* #prop_desc("string", "macro-start-delimiter",
- * "Macro start delimiter for a config file. Present for files only.")
+ * "Macro start delimiter for a config file. Present for text files only.")
* #prop_desc("string", "macro-end-delimiter",
- * "Macro end delimiter for a config file. Present for files only.")
+ * "Macro end delimiter for a config file. Present for text files only.")
* #struct_end()
*/
public class ConfigRevisionSerializer implements XmlRpcCustomSerializer {
@@ -108,10 +108,10 @@ public class ConfigRevisionSerializer implements XmlRpcCustomSerializer {
}
else {
helper.add(BINARY, Boolean.TRUE);
+ helper.add(MACRO_START, rev.getConfigContent().getDelimStart());
+ helper.add(MACRO_END, rev.getConfigContent().getDelimEnd());
}
helper.add("md5", rev.getConfigContent().getChecksum().getChecksum());
- helper.add(MACRO_START, rev.getDelimStart());
- helper.add(MACRO_END, rev.getDelimEnd());
}
else if (rev.isSymlink()) {
helper.add(CONTENTS, rev.getConfigContent().getContentsString());
diff --git a/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/test/ServerConfigHandlerTest.java b/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/test/ServerConfigHandlerTest.java
index 8be81a0..331b8e6 100644
--- a/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/test/ServerConfigHandlerTest.java
+++ b/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/test/ServerConfigHandlerTest.java
@@ -228,7 +228,7 @@ public class ServerConfigHandlerTest extends BaseHandlerTestCase {
String perms, boolean isDir, ConfigChannel cc,
String macroStart, String macroEnd, String selinuxCtx) {
assertEquals(path, rev.getConfigFile().getConfigFileName().getPath());
- assertEquals(contents, rev.getConfigContent().getContentsString());
+
assertEquals(group, rev.getConfigInfo().getGroupname());
assertEquals(owner, rev.getConfigInfo().getUsername());
assertEquals(perms, String.valueOf(rev.getConfigInfo().getFilemode()));
@@ -237,9 +237,11 @@ public class ServerConfigHandlerTest extends BaseHandlerTestCase {
assertEquals(ConfigFileType.dir(), rev.getConfigFileType());
}
else {
- assertEquals(ConfigFileType.file(), rev.getConfigFileType());
- assertEquals(macroStart, rev.getDelimStart());
- assertEquals(macroEnd, rev.getDelimEnd());
+ if (ConfigFileType.file().equals(rev.getConfigFileType())) {
+ assertEquals(contents, rev.getConfigContent().getContentsString());
+ assertEquals(macroStart, rev.getConfigContent().getDelimStart());
+ assertEquals(macroEnd, rev.getConfigContent().getDelimEnd());
+ }
}
assertEquals(cc,
rev.getConfigFile().getConfigChannel());
diff --git a/java/code/src/com/redhat/rhn/manager/configuration/ConfigFileBuilder.java b/java/code/src/com/redhat/rhn/manager/configuration/ConfigFileBuilder.java
index f877843..b734c21 100644
--- a/java/code/src/com/redhat/rhn/manager/configuration/ConfigFileBuilder.java
+++ b/java/code/src/com/redhat/rhn/manager/configuration/ConfigFileBuilder.java
@@ -14,6 +14,7 @@
*/
package com.redhat.rhn.manager.configuration;
+import com.redhat.rhn.common.localization.LocalizationService;
import com.redhat.rhn.common.validator.ValidatorError;
import com.redhat.rhn.common.validator.ValidatorException;
import com.redhat.rhn.common.validator.ValidatorResult;
@@ -21,6 +22,7 @@ import com.redhat.rhn.domain.config.ConfigChannel;
import com.redhat.rhn.domain.config.ConfigContent;
import com.redhat.rhn.domain.config.ConfigFile;
import com.redhat.rhn.domain.config.ConfigFileState;
+import com.redhat.rhn.domain.config.ConfigFileType;
import com.redhat.rhn.domain.config.ConfigRevision;
import com.redhat.rhn.domain.config.ConfigurationFactory;
import com.redhat.rhn.domain.user.User;
@@ -111,14 +113,6 @@ public class ConfigFileBuilder {
}
- private ConfigRevision makeNewRevision(User user, ConfigFileData form,
- ConfigFile cf, boolean onCreate, Long revNum) {
- ConfigRevision rev = makeNewRevision(user, form, cf, onCreate);
- rev.setRevision(revNum);
- ConfigurationFactory.saveNewConfigRevision(rev);
- return rev;
- }
-
/**
* Creates a new New config revision of a config file using the passed in data.
* @param user the logged in user
@@ -135,9 +129,19 @@ public class ConfigFileBuilder {
if (onCreate) {
revision = ConfigurationFactory.newConfigRevision();
- ConfigContent content = ConfigurationFactory
- .createNewContentFromStream(form.getContentStream(),
- form.getContentSize(), form.isBinary());
+ ConfigContent content = null;
+ if (ConfigFileType.file().equals(form.getType())) {
+ String delimStart = null;
+ String delimEnd = null;
+ if (!form.isBinary()) {
+ delimStart = form.getMacroStart();
+ delimEnd = form.getMacroEnd();
+ }
+ content = ConfigurationFactory.createNewContentFromStream(
+ form.getContentStream(),
+ form.getContentSize(), form.isBinary(),
+ delimStart, delimEnd);
+ }
revision.setConfigContent(content);
revision.setChangedById(user.getId());
}
@@ -145,13 +149,13 @@ public class ConfigFileBuilder {
revision = manager.createNewRevision(
user, form.getContentStream(), cf,
form.getContentSize());
- revision.getConfigContent().setBinary(form.isBinary());
+ if (revision.isFile()) {
+ revision.getConfigContent().setBinary(form.isBinary());
+ }
}
revision.setConfigInfo(form.extractInfo());
revision.setConfigFileType(form.getType());
revision.setConfigFile(cf);
- revision.setDelimStart(form.getMacroStart());
- revision.setDelimEnd(form.getMacroEnd());
if (!StringUtils.isEmpty(form.getRevNumber())) {
revision.setRevision(Long.parseLong(form.getRevNumber()));
}
@@ -176,40 +180,36 @@ public class ConfigFileBuilder {
public ConfigRevision update(ConfigFileData form,
User user, ConfigFile file)
throws ValidatorException {
+ form.validatePath();
ValidatorResult result;
- if (form.isDirectory() && !file.getLatestConfigRevision().isDirectory()) {
- result = new ValidatorResult();
- result.addError(new ValidatorError("error.config-cannot-change-file2dir",
- form.getPath()));
- throw new ValidatorException(result);
+ if (!form.getType().equals(file.getLatestConfigRevision().getConfigFileType())) {
+
+ LocalizationService ls = LocalizationService.getInstance();
+ String fromType = ls.getMessage(file.getLatestConfigRevision().
+ getConfigFileType().getMessageKey());
+ String toType = ls.getMessage(form.getType().getMessageKey());
+ ValidatorException.raiseException("error.config-cannot-change-type",
+ form.getPath(), fromType, toType);
}
- else if (!form.isDirectory() && file.getLatestConfigRevision().isDirectory()) {
+
+ try {
+ Long l = Long.parseLong(form.getRevNumber());
+ if (l.longValue() <= file.getLatestConfigRevision().getRevision()) {
+ result = new ValidatorResult();
+ result.addError(new ValidatorError("error.config.revnum.too-old",
+ form.getPath()));
+ throw new ValidatorException(result);
+ }
+ }
+ catch (NumberFormatException nfe) {
result = new ValidatorResult();
- result.addError(new ValidatorError("error.config-cannot-change-dir2file",
- form.getPath()));
+ result.addError(new ValidatorError("error.config.revnum.invalid",
+ form.getPath()));
throw new ValidatorException(result);
}
- else {
- try {
- Long l = Long.parseLong(form.getRevNumber());
- if (l.longValue() <= file.getLatestConfigRevision().getRevision()) {
- result = new ValidatorResult();
- result.addError(new ValidatorError("error.config.revnum.too-old",
- form.getPath()));
- throw new ValidatorException(result);
- }
- }
- catch (NumberFormatException nfe) {
- result = new ValidatorResult();
- result.addError(new ValidatorError("error.config.revnum.invalid",
- form.getPath()));
- throw new ValidatorException(result);
- }
-
- form.validate(false);
- }
+ form.validate(false);
return makeNewRevision(user, form, file, false);
}
diff --git a/java/code/src/com/redhat/rhn/manager/configuration/file/BinaryFileData.java b/java/code/src/com/redhat/rhn/manager/configuration/file/BinaryFileData.java
index 2a1ab8e..53cedc7 100644
--- a/java/code/src/com/redhat/rhn/manager/configuration/file/BinaryFileData.java
+++ b/java/code/src/com/redhat/rhn/manager/configuration/file/BinaryFileData.java
@@ -42,6 +42,8 @@ public class BinaryFileData extends ConfigFileData {
setType(ConfigFileType.file());
setContents(data);
setContentSize(size);
+ setMacroStart(null);
+ setMacroEnd(null);
}
/**
* @return the contents
@@ -110,7 +112,7 @@ public class BinaryFileData extends ConfigFileData {
* {@inheritDoc}
*/
@Override
- protected void copyRevisedContentFrom(ConfigRevision rev) {
+ public void processRevisedContentFrom(ConfigRevision rev) {
setContents(new ByteArrayInputStream(rev.
getConfigContent().getContents()));
setContentSize(rev.getConfigContent().getFileSize());
diff --git a/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java b/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
index cc283a8..f1bb310 100644
--- a/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
+++ b/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
@@ -45,6 +45,7 @@ public abstract class ConfigFileData {
private static long serialVersionUID = -2162768922109257186L;
private static final String VALIDATION_XSD =
"/com/redhat/rhn/frontend/action/configuration/validation/configFileForm.xsd";
+
private String path;
private String owner;
private String group;
@@ -206,7 +207,7 @@ public abstract class ConfigFileData {
ConfigInfo info = ConfigurationFactory.lookupOrInsertConfigInfo(
getOwner(), getGroup(),
Long.valueOf(getPermissions()),
- getSelinuxCtx());
+ getSelinuxCtx(), null);
return info;
}
@@ -233,7 +234,6 @@ public abstract class ConfigFileData {
private void validateData(boolean onCreate) throws ValidatorException {
ValidatorResult msgs = new ValidatorResult();
-
// Validate user/uid
if (!ConfigurationValidation.validateUserOrGroup(getOwner()) &&
!ConfigurationValidation.validateUGID(getOwner())) {
@@ -251,6 +251,40 @@ public abstract class ConfigFileData {
msgs.addError(error("mode-invalid"));
}
+ if (isFile()) {
+ if (!StringUtils.isBlank(getMacroStart())) {
+ // Validate macro-start
+ if (getMacroStart().indexOf('%') != -1) {
+ msgs.addError(error("start-delim-percent"));
+ }
+ }
+
+ // Validate macro-end
+ if (!StringUtils.isBlank(getMacroEnd())) {
+ if (getMacroEnd().indexOf('%') != -1) {
+ msgs.addError(error("end-delim-percent"));
+ }
+ }
+
+ if (getContentSize() > ConfigFile.getMaxFileSize()) {
+ msgs.addError("error.configtoolarge",
+ StringUtil.displayFileSize(ConfigFile.getMaxFileSize(), false));
+ }
+ validateContents(msgs, onCreate);
+ }
+
+ ValidatorError ve = validateSELinux();
+ if (ve != null) {
+ msgs.addError(ve);
+ }
+
+
+ if (!msgs.isEmpty()) {
+ throw new ValidatorException(msgs);
+ }
+ }
+
+ protected ValidatorError validateSELinux() {
String sens = "s\\d+";
String cats = "c\\d+(\\.c\\d+)?";
String mlsregex = sens + "(:" + cats + "(," + cats + ")*)?";
@@ -263,32 +297,9 @@ public abstract class ConfigFileData {
"(:" + mlsregex + // low
"(\\-" + mlsregex + // high
")?)?)?)?$")) {
- msgs.addError(new ValidatorError("Invalid SELinux context"));
- }
-
- if (!StringUtils.isBlank(getMacroStart())) {
- // Validate macro-start
- if (getMacroStart().indexOf('%') != -1) {
- msgs.addError(error("start-delim-percent"));
- }
- }
-
- // Validate macro-end
- if (!StringUtils.isBlank(getMacroEnd())) {
- if (getMacroEnd().indexOf('%') != -1) {
- msgs.addError(error("end-delim-percent"));
- }
- }
-
- if (getContentSize() > ConfigFile.getMaxFileSize()) {
- msgs.addError("error.configtoolarge",
- StringUtil.displayFileSize(ConfigFile.getMaxFileSize(), false));
- }
- validateContents(msgs, onCreate);
-
- if (!msgs.isEmpty()) {
- throw new ValidatorException(msgs);
+ return new ValidatorError("config-file-form.error.selinux-invalid");
}
+ return null;
}
protected abstract void validateContents(ValidatorResult result,
@@ -312,8 +323,8 @@ public abstract class ConfigFileData {
*
* @return true if the data in this Calass is a directory
*/
- public boolean isDirectory() {
- return ConfigFileType.dir().equals(getType());
+ public boolean isFile() {
+ return ConfigFileType.file().equals(getType());
}
/**
@@ -325,6 +336,7 @@ public abstract class ConfigFileData {
if (onCreate) {
validatePath();
}
+
// Struts-validation errors? Bug out if so
ValidatorResult result = RhnValidationHelper.validate(this.getClass(),
makeValidationMap(), null,
@@ -355,42 +367,31 @@ public abstract class ConfigFileData {
* while matching values against xsds..
* @return a map with key = ConfigFIleForms keys, & value = ConfigFIleData values..
*/
- private Map makeValidationMap() {
+ protected Map makeValidationMap() {
Map map = new HashMap();
map.put(ConfigFileForm.REV_UID, getOwner());
map.put(ConfigFileForm.REV_GID, getGroup());
map.put(ConfigFileForm.REV_PERMS, getPermissions());
map.put(ConfigFileForm.REV_SELINUX_CTX, getSelinuxCtx());
+ map.put(ConfigFileForm.REV_SYMLINK_TARGET_PATH, getSelinuxCtx());
map.put(ConfigFileForm.REV_MACROSTART, getMacroStart());
map.put(ConfigFileForm.REV_MACROEND, getMacroEnd());
return map;
}
/**
- * Basically hook point to update the relevant in this data file
- * with the content provided in the revision param. This is mainly
- * used to update things like BinaryFiles/Directories where we want
- * the contents of the previosu version copied over to the new content ...
- * @param rev thr revision to copy stuff from..
- */
- public void processRevisedContentFrom(ConfigRevision rev) {
- copyRevisedContentFrom(rev);
- setMacroStart(rev.getDelimStart());
- setMacroEnd(rev.getDelimEnd());
- }
-
- /**
* Basically Extension point to update the relevant in this data file
* with the content provided in the revision param. This is mainly
* used to update things like BinaryFiles/Directories where we want
* the contents of the previous version copied over to the new content ...
* @param rev the revision to copy stuff from..
*/
- protected abstract void copyRevisedContentFrom(ConfigRevision rev);
+ public abstract void processRevisedContentFrom(ConfigRevision rev);
/**
* {@inheritDoc}
*/
+ @Override
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this);
builder.append("Path", getPath()).
diff --git a/java/code/src/com/redhat/rhn/manager/configuration/file/DirectoryData.java b/java/code/src/com/redhat/rhn/manager/configuration/file/DirectoryData.java
index d46f158..27961b8 100644
--- a/java/code/src/com/redhat/rhn/manager/configuration/file/DirectoryData.java
+++ b/java/code/src/com/redhat/rhn/manager/configuration/file/DirectoryData.java
@@ -72,7 +72,7 @@ public class DirectoryData extends ConfigFileData {
* {@inheritDoc}
*/
@Override
- protected void copyRevisedContentFrom(ConfigRevision current) {
+ public void processRevisedContentFrom(ConfigRevision current) {
// NO -OP because directory has NO content!
}
}
diff --git a/java/code/src/com/redhat/rhn/manager/configuration/file/SymlinkData.java b/java/code/src/com/redhat/rhn/manager/configuration/file/SymlinkData.java
new file mode 100644
index 0000000..d7d8afd
--- /dev/null
+++ b/java/code/src/com/redhat/rhn/manager/configuration/file/SymlinkData.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2010 Red Hat, Inc.
+ *
+ * This software is licensed to you under the GNU General Public License,
+ * version 2 (GPLv2). There is NO WARRANTY for this software, express or
+ * implied, including the implied warranties of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+ * along with this software; if not, see
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * Red Hat trademarks are not licensed under GPLv2. No permission is
+ * granted to use or replicate Red Hat trademarks that are incorporated
+ * in this software or its documentation.
+ */
+package com.redhat.rhn.manager.configuration.file;
+
+import com.redhat.rhn.common.validator.ValidatorError;
+import com.redhat.rhn.common.validator.ValidatorException;
+import com.redhat.rhn.common.validator.ValidatorResult;
+import com.redhat.rhn.domain.config.ConfigFileType;
+import com.redhat.rhn.domain.config.ConfigInfo;
+import com.redhat.rhn.domain.config.ConfigurationFactory;
+import com.redhat.rhn.frontend.struts.RhnValidationHelper;
+import com.redhat.rhn.manager.configuration.ConfigurationValidation;
+
+
+/**
+ * SymlinkData
+ * @version $Rev$
+ */
+public class SymlinkData extends DirectoryData {
+ private static final String VALIDATION_XSD =
+ "/com/redhat/rhn/frontend/action/configuration/validation/" +
+ "configFileFormForSymlink.xsd";
+ private String targetPath;
+ /**
+ * Constructor
+ * @param path the target path of the symlink
+ */
+ public SymlinkData(String path) {
+ super();
+ setType(ConfigFileType.symlink());
+ targetPath = path;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public ConfigFileType getType() {
+ return ConfigFileType.symlink();
+ }
+
+ /**
+ * @return the targetPath
+ */
+ public String getTargetPath() {
+ return targetPath;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void validatePath() throws ValidatorException {
+ super.validatePath();
+ ValidatorResult result = ConfigurationValidation.validatePath(getTargetPath());
+ if (!result.isEmpty()) {
+ throw new ValidatorException(result);
+ }
+ }
+
+
+ /**
+ *
+ * @return info pertaining to this form.
+ */
+ @Override
+ public ConfigInfo extractInfo() {
+ ConfigInfo info = ConfigurationFactory.lookupOrInsertConfigInfo(
+ null, null,
+ null, getSelinuxCtx(), getTargetPath());
+ return info;
+ }
+
+ /**
+ * Entry point to validate the contents of this form..
+ * @param onCreate true if we're creating a config-file, false if we're only updating
+ * @throws ValidatorException if there are any validation errors.
+ */
+ @Override
+ public void validate(boolean onCreate) throws ValidatorException {
+ if (onCreate) {
+ validatePath();
+ }
+ // Struts-validation errors? Bug out if so
+ ValidatorResult result = RhnValidationHelper.validate(this.getClass(),
+ makeValidationMap(), null,
+ VALIDATION_XSD);
+ ValidatorError ve = validateSELinux();
+
+ if (ve != null) {
+ result.addError(ve);
+ }
+
+ if (!result.isEmpty()) {
+ throw new ValidatorException(result);
+ }
+ }
+}
diff --git a/java/code/src/com/redhat/rhn/manager/configuration/file/TextFileData.java b/java/code/src/com/redhat/rhn/manager/configuration/file/TextFileData.java
index 0f7db3e..ec3ee26 100644
--- a/java/code/src/com/redhat/rhn/manager/configuration/file/TextFileData.java
+++ b/java/code/src/com/redhat/rhn/manager/configuration/file/TextFileData.java
@@ -96,6 +96,7 @@ public class TextFileData extends ConfigFileData {
* {@inheritDoc}
*/
+ @Override
public boolean isBinary() {
return false;
}
@@ -125,8 +126,10 @@ public class TextFileData extends ConfigFileData {
* {@inheritDoc}
*/
@Override
- protected void copyRevisedContentFrom(ConfigRevision rev) {
+ public void processRevisedContentFrom(ConfigRevision rev) {
setContents(rev.getConfigContent().getContentsString());
+ setMacroStart(rev.getConfigContent().getDelimStart());
+ setMacroEnd(rev.getConfigContent().getDelimEnd());
}
/**
diff --git a/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java b/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
index 5999d8e..1ca764d 100644
--- a/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
+++ b/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
@@ -14,6 +14,7 @@
*/
package com.redhat.rhn.testing;
+import com.redhat.rhn.domain.common.ChecksumFactory;
import com.redhat.rhn.domain.config.ConfigChannel;
import com.redhat.rhn.domain.config.ConfigChannelType;
import com.redhat.rhn.domain.config.ConfigContent;
@@ -23,7 +24,6 @@ import com.redhat.rhn.domain.config.ConfigFileType;
import com.redhat.rhn.domain.config.ConfigInfo;
import com.redhat.rhn.domain.config.ConfigRevision;
import com.redhat.rhn.domain.config.ConfigurationFactory;
-import com.redhat.rhn.domain.common.ChecksumFactory;
import com.redhat.rhn.domain.org.Org;
import com.redhat.rhn.domain.server.Server;
import com.redhat.rhn.domain.server.ServerConstants;
@@ -205,8 +205,6 @@ public class ConfigTestUtils extends Assert {
cr.setCreated(new Date());
cr.setModified(new Date());
cr.setConfigContent(content);
- cr.setDelimStart("{@");
- cr.setDelimEnd("@}");
cr.setConfigFile(file);
cr.setConfigInfo(info);
cr.setConfigFileType(type);
@@ -286,6 +284,9 @@ public class ConfigTestUtils extends Assert {
cc.setBinary(isBinary);
cc.setCreated(new Date());
cc.setModified(new Date());
+ cc.setDelimStart("{@");
+ cc.setDelimEnd("@}");
+
return cc;
}
@@ -308,7 +309,8 @@ public class ConfigTestUtils extends Assert {
* @return The newly created ConfigInfo.
*/
public static ConfigInfo createConfigInfo(String user, String group, Long fileMode) {
- return ConfigurationFactory.lookupOrInsertConfigInfo(user, group, fileMode, "");
+ return ConfigurationFactory.lookupOrInsertConfigInfo(user, group,
+ fileMode, "", null);
}
/**
diff --git a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
index 912e105..829d6f1 100644
--- a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
+++ b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
@@ -2,6 +2,25 @@
<%@ include file="/WEB-INF/pages/common/fragments/editarea.jspf" %>
<html:hidden property="submitted" value="true"/>
<html:hidden property="binary"/>
+ <script type="text/javascript">
+ function toggleElement(row) {
+ if (row.style.display == '') {
+ row.style.display = 'none';
+ }
+ else {
+ row.style.display = '';
+ }
+ }
+
+
+ function pageToggleRows(linkId, ids){
+ for (var i = 0 ; i < ids.length; i++) {
+ toggleElement(document.getElementById(ids[i]));
+ }
+ toggleElement(document.getElementById(linkId + 'Show'));
+ toggleElement(document.getElementById(linkId + 'Hide'));
+ }
+ </script>
<table class="details">
<tr>
<th><bean:message key="addfiles.jsp.type-name" /></th>
@@ -14,23 +33,39 @@
<html:radio property="filetype" value="symlink" styleId="symlink_radio" /><bean:message
key="addfiles.jsp.type.symlink" /><br />
<script type="text/javascript">
- function enableAllInputs(event) {
- $('cffUid').readOnly = "";
- $('cffGid').readOnly = "";
- $('cffPermissions').readOnly = "";
- $('cffMacroStart').readOnly = "";
- $('cffMacroEnd').readOnly = "";
- }
+ Event.observe('symlink_radio', 'focus', function(event){
+ $('cffUid').disabled = true;
+ $('cffGid').disabled = true;
+ $('cffPermissions').disabled = true;
+ $('cffMacroStart').disabled = true;
+ $('cffMacroEnd').disabled = true;
+ $('targetPath').disabled = false;
+ $('contentsRow').style.display = 'none';
+ $('hiddenContentsRow').style.display = '';
+
+ });
- Event.observe('file_radio', 'focus', enableAllInputs);
- Event.observe('dir_radio', 'focus', enableAllInputs);
- Event.observe('symlink_radio', 'focus', function(event) {
- $('cffUid').readOnly = "readonly";
- $('cffGid').readOnly = "readonly";
- $('cffPermissions').readOnly = "readonly";
- $('cffMacroStart').readOnly = "readonly";
- $('cffMacroEnd').readOnly = "readonly";
+ Event.observe('file_radio', 'focus', function(event){
+ $('cffUid').disabled = false;
+ $('cffGid').disabled = false;
+ $('cffPermissions').disabled = false;
+ $('cffMacroStart').disabled = false;
+ $('cffMacroEnd').disabled = false;
+ $('targetPath').disabled = true;
+ $('contentsRow').style.display = '';
+ $('hiddenContentsRow').style.display = 'none';
});
+
+ Event.observe('dir_radio', 'focus', function(event){
+ $('cffUid').disabled = false;
+ $('cffGid').disabled = false;
+ $('cffPermissions').disabled = false;
+ $('cffMacroStart').disabled = false;
+ $('cffMacroEnd').disabled = false;
+ $('targetPath').disabled = true;
+ $('contentsRow').style.display = 'none';
+ $('hiddenContentsRow').style.display = '';
+ });
</script>
<span class="small-text"><bean:message key="filedetails.jsp.tip.symlink" /></span>
</td>
@@ -40,16 +75,20 @@
<td><html:text name="configFileForm" property="cffPath" size="30"/></td>
</tr>
<tr>
+ <th><bean:message key="filedetails.properties.jspf.targetpath" /></th>
+ <td><html:text name="configFileForm" property="targetPath" disabled = "${configFileForm.map.filetype != 'symlink'}" styleId="targetPath" size="30"/></td>
+ </tr>
+ <tr>
<th><bean:message key="filedetails.properties.jspf.ownership" /></th>
<td>
<table>
<tr>
<td><bean:message key="filedetails.properties.jspf.uid" /></td>
- <td><html:text property="cffUid" size="6" styleId="cffUid" /></td>
+ <td><html:text property="cffUid" size="6" styleId="cffUid" disabled = "${configFileForm.map.filetype == 'symlink'}"/></td>
</tr>
<tr>
<td><bean:message key="filedetails.properties.jspf.gid" /></td>
- <td><html:text property="cffGid" size="6" styleId="cffGid" /></td>
+ <td><html:text property="cffGid" size="6" styleId="cffGid" disabled = "${configFileForm.map.filetype == 'symlink'}"/></td>
</tr>
<tr>
<td colspan="2"><span class="small-text"><bean:message
@@ -60,7 +99,7 @@
</tr>
<tr>
<th><bean:message key="filedetails.properties.jspf.permissions" /></th>
- <td><html:text property="cffPermissions" maxlength="4" size="4" styleId="cffPermissions" /><br />
+ <td><html:text property="cffPermissions" maxlength="4" size="4" styleId="cffPermissions" disabled = "${configFileForm.map.filetype == 'symlink'}"/><br />
<span class="small-text"><bean:message
key="filedetails.jsp.tip.permissions" /></span></td>
</tr>
@@ -73,21 +112,33 @@
<th><bean:message key="filedetails.add_details.jspf.macro" /></th>
<td nowrap="nowrap">
<bean:message key="filedetails.add_details.jspf.macro.start" />
- <html:text property="cffMacroStart" size="3" styleId="cffMacroStart" />
+ <html:text property="cffMacroStart" size="3" styleId="cffMacroStart" disabled = "${configFileForm.map.filetype == 'symlink'}" />
<bean:message key="filedetails.add_details.jspf.macro.end" />
- <html:text property="cffMacroEnd" size="3" styleId="cffMacroEnd" /><br />
+ <html:text property="cffMacroEnd" size="3" styleId="cffMacroEnd" disabled = "${configFileForm.map.filetype == 'symlink'}" /><br />
<span class="small-text">
<bean:message key="filedetails.jsp.tip.macros" arg0="/rhn/help/reference/index.jsp" />
</span>
</td>
</tr>
- <tr>
+ <tr id = "contentsRow"
+ <c:if test="${configFileForm.map.filetype == 'symlink'}"> style="display:none"</c:if>
+ >
<th><bean:message key="addfiles.create.jspf.content-name" /></th>
<td>
<html:textarea property="contents" rows="20" cols="80" styleId="contents"/><br />
<span class="small-text"><bean:message key="filedetails.jsp.tip.edit"/></span>
</td>
</tr>
+ <tr id = "hiddenContentsRow"
+ <c:if test="${configFileForm.map.filetype != 'symlink'}"> style="display:none"</c:if>
+ >
+ <th><bean:message key="addfiles.create.jspf.content-name" /></th>
+ <td>
+ <textarea name="dumb" cols="80" rows="20" disabled="true"></textarea><br />
+ <span class="small-text"><bean:message key="filedetails.jsp.tip.edit"/></span>
+ </td>
+ </tr>
+
</table>
<hr />
<div align="right"><html:submit>
diff --git a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/add_details.jspf b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/add_details.jspf
index 1bd1ef3..7c07033 100644
--- a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/add_details.jspf
+++ b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/add_details.jspf
@@ -1,13 +1,11 @@
+<c:if test="${not empty revision.configContent}">
<h2><bean:message key="filedetails.add_details.jspf.header2" /></h2>
<table class="details">
<tr>
- <th><bean:message key="filedetails.add_details.jspf.size-name" /></th>
- <td><bean:message key="filedetails.add_details.jspf.size" arg0="${revbytes}" arg1="${totalbytes}" /></td>
-</tr>
-<tr>
<th><bean:message key="filedetails.add_details.jspf.md5" /></th>
<td>${revision.configContent.checksum}</td>
</tr>
+
<c:if test="${!revision.configContent.binary && !revision.directory}">
<tr>
<th><bean:message key="filedetails.add_details.jspf.macro" /></th>
@@ -15,22 +13,22 @@
<bean:message key="filedetails.add_details.jspf.macro.start" />
<rhn:require acl="config_channel_editable(${channel.id})"
mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
- <html:text property="cffMacroStart" value="${revision.delimStart}" size="3"/>
+ <html:text property="cffMacroStart" value="${revision.configContent.delimStart}" size="3"/>
</rhn:require>
<rhn:require acl="not config_channel_editable(${channel.id})"
mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
- <c:out value="${revision.delimStart}" />
+ <c:out value="${revision.configContent.delimStart}" />
</rhn:require>
<bean:message key="filedetails.add_details.jspf.macro.end" />
<rhn:require acl="config_channel_editable(${channel.id})"
mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
- <html:text property="cffMacroEnd" value="${revision.delimEnd}" size="3"/>
+ <html:text property="cffMacroEnd" value="${revision.configContent.delimEnd}" size="3"/>
</rhn:require>
<rhn:require acl="not config_channel_editable(${channel.id})"
mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
- <c:out value="${revision.delimEnd}" />
+ <c:out value="${revision.configContent.delimEnd}" />
</rhn:require>
<br />
@@ -38,3 +36,5 @@
</tr>
</c:if>
</table>
+</c:if>
+
diff --git a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/details.jspf b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/details.jspf
index da0c232..654879b 100644
--- a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/details.jspf
+++ b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/details.jspf
@@ -114,7 +114,7 @@
mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
<th> <bean:message key="filedetails.details.jspf.revnum"/> </th>
<td>
- <html:text property="revnum" size="4" value="${revnum}"/>
+ <html:text property="revnum" size="4"/>
</td>
</rhn:require>
</tr>
diff --git a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/file_info.jsp b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/file_info.jsp
index 7cc632b..b58f8d6 100644
--- a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/file_info.jsp
+++ b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/file_info.jsp
@@ -75,6 +75,20 @@
<td>${myrev.configInfo.groupname}</td>
</tr>
</c:if>
+ <c:if test="${diffselinux == 'true'}">
+ <tr>
+ <td><strong><bean:message key="diff.jsp.selinux" /></strong></td>
+ <td>${myrev.configInfo.selinuxCtx}</td>
+ </tr>
+ </c:if>
+
+ <c:if test="${difftargetpath== 'true'}">
+ <tr>
+ <td><strong><bean:message key="diff.jsp.targetpath" /></strong></td>
+ <td>${myrev.configInfo.targetFileName.path}</td>
+ </tr>
+ </c:if>
+
<c:if test="${diffdelim == 'true'}">
<tr>
<td><strong><bean:message key="diff.jsp.startDelim" /></strong></td>
diff --git a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
index cce3995..ed5b958 100644
--- a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
+++ b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
@@ -4,6 +4,14 @@
<th><bean:message key="filedetails.properties.jspf.path" /></th>
<td><bean:write name="configFileForm" property="cffPath"/></td>
</tr>
+<c:choose>
+<c:when test="${revision.symlink}">
+<tr>
+ <th><bean:message key="filedetails.properties.jspf.targetpath" /></th>
+ <td><html:text name="configFileForm" property="targetPath" size="30"/></td>
+</tr>
+</c:when>
+<c:otherwise>
<tr>
<th><bean:message key="filedetails.properties.jspf.ownership" /></th>
<td>
@@ -53,6 +61,9 @@
<span class="small-text"><bean:message key="filedetails.jsp.tip.permissions" /></span>
</td>
</tr>
+</c:otherwise>
+</c:choose>
+
<tr>
<th>SELinux context</th>
<td>
diff --git a/java/code/webapp/WEB-INF/pages/configuration/files/filedetails.jsp b/java/code/webapp/WEB-INF/pages/configuration/files/filedetails.jsp
index 328e4b2..e616963 100644
--- a/java/code/webapp/WEB-INF/pages/configuration/files/filedetails.jsp
+++ b/java/code/webapp/WEB-INF/pages/configuration/files/filedetails.jsp
@@ -23,7 +23,7 @@
<%@ include file="/WEB-INF/pages/common/fragments/configuration/files/properties.jspf"%>
</div>
- <c:if test="${!revision.directory}">
+ <c:if test="${revision.file}">
<div class="details-full">
<%@ include file="/WEB-INF/pages/common/fragments/configuration/files/add_details.jspf"%>
</div>
@@ -46,7 +46,7 @@
<rhn:require acl="config_channel_editable()"
mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
- <c:if test="${!revision.directory}">
+ <c:if test="${revision.file}">
<%@ include file="/WEB-INF/pages/common/fragments/configuration/files/upload.jspf" %>
</c:if>
</rhn:require>
diff --git a/java/code/webapp/WEB-INF/struts-config.xml b/java/code/webapp/WEB-INF/struts-config.xml
index e6002c8..79f713d 100644
--- a/java/code/webapp/WEB-INF/struts-config.xml
+++ b/java/code/webapp/WEB-INF/struts-config.xml
@@ -905,6 +905,7 @@
<form-property name="cffMacroEnd" type="java.lang.String"/>
<form-property name="cffUpload" type="org.apache.struts.upload.FormFile" />
<form-property name="contents" type="java.lang.String"/>
+ <form-property name="targetPath" type="java.lang.String"/>
<form-property name="filetype" type="java.lang.String" />
<form-property name="revnum" type="java.lang.String" />
<form-property name="binary" type="java.lang.Boolean" />
diff --git a/schema/spacewalk/common/tables/rhnConfigContent.sql b/schema/spacewalk/common/tables/rhnConfigContent.sql
index 57ed53e..b2c6e56 100644
--- a/schema/spacewalk/common/tables/rhnConfigContent.sql
+++ b/schema/spacewalk/common/tables/rhnConfigContent.sql
@@ -28,6 +28,8 @@ CREATE TABLE rhnConfigContent
DEFAULT ('N') NOT NULL
CONSTRAINT rhn_confcontent_isbin_ck
CHECK (is_binary in ( 'Y' , 'N' )),
+ delim_start VARCHAR2(16),
+ delim_end VARCHAR2(16),
created DATE
DEFAULT (sysdate) NOT NULL,
modified DATE
diff --git a/schema/spacewalk/common/tables/rhnConfigInfo.sql b/schema/spacewalk/common/tables/rhnConfigInfo.sql
index bb62b09..62761a8 100644
--- a/schema/spacewalk/common/tables/rhnConfigInfo.sql
+++ b/schema/spacewalk/common/tables/rhnConfigInfo.sql
@@ -19,9 +19,12 @@ CREATE TABLE rhnConfigInfo
id NUMBER NOT NULL
CONSTRAINT rhn_confinfo_id_pk PRIMARY KEY
USING INDEX TABLESPACE [[2m_tbs]],
- username VARCHAR2(32) NOT NULL,
- groupname VARCHAR2(32) NOT NULL,
- filemode NUMBER NOT NULL,
+ username VARCHAR2(32) NULL,
+ groupname VARCHAR2(32) NULL,
+ filemode NUMBER NULL,
+ symlink_target_filename_id NUMBER
+ CONSTRAINT rhn_confinfo_symlink_fk
+ REFERENCES rhnConfigFileName (id),
created DATE
DEFAULT (sysdate) NOT NULL,
modified DATE
@@ -32,7 +35,7 @@ ENABLE ROW MOVEMENT
;
CREATE UNIQUE INDEX rhn_confinfo_ugf_uq
- ON rhnConfigInfo (username, groupname, filemode, selinux_ctx)
+ ON rhnConfigInfo (username, groupname, filemode, selinux_ctx, symlink_target_filename_id)
TABLESPACE [[4m_tbs]];
CREATE SEQUENCE rhn_confinfo_id_seq;
diff --git a/schema/spacewalk/common/tables/rhnConfigRevision.sql b/schema/spacewalk/common/tables/rhnConfigRevision.sql
index 8c5c30c..eaa21f2 100644
--- a/schema/spacewalk/common/tables/rhnConfigRevision.sql
+++ b/schema/spacewalk/common/tables/rhnConfigRevision.sql
@@ -26,11 +26,9 @@ CREATE TABLE rhnConfigRevision
config_content_id NUMBER NOT NULL
CONSTRAINT rhn_confrevision_ccid_fk
REFERENCES rhnConfigContent (id),
- config_info_id NUMBER NOT NULL
+ config_info_id NUMBER
CONSTRAINT rhn_confrevision_ciid_fk
REFERENCES rhnConfigInfo (id),
- delim_start VARCHAR2(16) NOT NULL,
- delim_end VARCHAR2(16) NOT NULL,
created DATE
DEFAULT (sysdate) NOT NULL,
modified DATE
diff --git a/schema/spacewalk/oracle/packages/rhn_config.pkb b/schema/spacewalk/oracle/packages/rhn_config.pkb
index 46bfe7e..e51ca85 100644
--- a/schema/spacewalk/oracle/packages/rhn_config.pkb
+++ b/schema/spacewalk/oracle/packages/rhn_config.pkb
@@ -33,8 +33,6 @@ is
config_file_id_in in number,
config_content_id_in in number,
config_info_id_in in number,
- delim_start_in in varchar2 := '{@',
- delim_end_in in varchar2 := '@}',
config_file_type_id_in in number := 1
) return number is
retval number;
@@ -47,12 +45,10 @@ is
begin
insert into rhnConfigRevision(id, revision, config_file_id,
- config_content_id, config_info_id, delim_start, delim_end,
- config_file_type_id
+ config_content_id, config_info_id, config_file_type_id
) values (
rhn_confrevision_id_seq.nextval, revision_in, config_file_id_in,
- config_content_id_in, config_info_id_in, delim_start_in,
- delim_end_in, config_file_type_id_in
+ config_content_id_in, config_info_id_in, config_file_type_id_in
)
returning id into retval;
diff --git a/schema/spacewalk/oracle/packages/rhn_config.pks b/schema/spacewalk/oracle/packages/rhn_config.pks
index f7d9acd..37f5899 100644
--- a/schema/spacewalk/oracle/packages/rhn_config.pks
+++ b/schema/spacewalk/oracle/packages/rhn_config.pks
@@ -29,8 +29,6 @@ is
config_file_id_in in number,
config_content_id_in in number,
config_info_id_in in number,
- delim_start_in in varchar2 := '{@',
- delim_end_in in varchar2 := '@}',
config_file_type_id_in number := 1
) return number;
diff --git a/schema/spacewalk/oracle/procs/lookup_config_info.sql b/schema/spacewalk/oracle/procs/lookup_config_info.sql
index 71a968e..5121f04 100644
--- a/schema/spacewalk/oracle/procs/lookup_config_info.sql
+++ b/schema/spacewalk/oracle/procs/lookup_config_info.sql
@@ -21,7 +21,8 @@ lookup_config_info (
username_in in varchar2,
groupname_in in varchar2,
filemode_in in varchar2,
- selinux_ctx_in in varchar2
+ selinux_ctx_in in varchar2,
+ symlink_target_id in number
) return number
deterministic
is
@@ -31,10 +32,12 @@ is
select id
from rhnConfigInfo
where 1=1
- and username = username_in
- and groupname = groupname_in
- and filemode = filemode_in
- and nvl(selinux_ctx, ' ') = nvl(selinux_ctx_in, ' ');
+ and nvl(username, ' ') = nvl(username_in, ' ')
+ and nvl(groupname,' ') = nvl(groupname_in, ' ')
+ and nvl(filemode, -1) = nvl(filemode_in, -1)
+ and nvl(selinux_ctx, ' ') = nvl(selinux_ctx_in, ' ')
+ and nvl(symlink_target_filename_id, -1) = nvl(symlink_target_id, -1)
+ ;
begin
for r in lookup_cursor loop
return r.id;
@@ -43,8 +46,8 @@ begin
select rhn_confinfo_id_seq.nextval
into v_id
from dual;
- insert into rhnConfigInfo (id, username, groupname, filemode, selinux_ctx)
- values (v_id, username_in, groupname_in, filemode_in, selinux_ctx_in);
+ insert into rhnConfigInfo (id, username, groupname, filemode, selinux_ctx, symlink_target_filename_id)
+ values (v_id, username_in, groupname_in, filemode_in, selinux_ctx_in, symlink_target_id);
commit;
return v_id;
end lookup_config_info;
diff --git a/schema/spacewalk/oracle/triggers/rhnConfigRevision.sql b/schema/spacewalk/oracle/triggers/rhnConfigRevision.sql
index e5042ef..939f3bf 100644
--- a/schema/spacewalk/oracle/triggers/rhnConfigRevision.sql
+++ b/schema/spacewalk/oracle/triggers/rhnConfigRevision.sql
@@ -34,10 +34,11 @@ after insert on rhnConfigRevision
for each row
declare
org_id number;
- available number;
- added number;
+ available number := 0;
+ added number := 0;
begin
-- find the current amount of quota available
+ begin
select cc.org_id id,
oq.total + oq.bonus - oq.used available,
content.file_size added
@@ -49,8 +50,13 @@ begin
where cf.id = :new.config_file_id
and cf.config_channel_id = cc.id
and cc.org_id = oq.org_id
+ and :new.config_file_type_id = (select id from rhnConfigFileType where label='file')
and :new.config_content_id = content.id;
-
+ exception
+ when no_data_found then
+ added := 0;
+ available := 0;
+ end;
if added > available then
rhn_exception.raise_exception('not_enough_quota');
end if;
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql
new file mode 100644
index 0000000..5c2d431
--- /dev/null
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/101-update-config-schema.sql
@@ -0,0 +1,44 @@
+alter table rhnConfigInfo add SYMLINK_TARGET_FILE_NAME_ID NUMBER
+ CONSTRAINT rhn_confinfo_symlink_fk
+ REFERENCES rhnConfigFileName (id);
+
+
+
+
+alter table rhnConfigContent add delim_start VARCHAR2(16);
+alter table rhnConfigContent add delim_end VARCHAR2(16);
+
+DECLARE
+ CURSOR config_content_delimeters is
+ select CONFIG_CONTENT_ID, DELIM_START, DELIM_END
+ from rhnConfigRevision;
+BEGIN
+ FOR content IN config_content_delimeters
+ LOOP
+ update rhnConfigContent set DELIM_START = content.DELIM_START
+ where id = content.CONFIG_CONTENT_ID;
+
+ update rhnConfigContent set DELIM_END = content.DELIM_END
+ where id = content.CONFIG_CONTENT_ID;
+
+ END LOOP;
+ commit;
+END;
+
+
+alter table rhnConfigContent modify delim_start not null;
+alter table rhnConfigContent modify delim_end not null;
+
+alter table rhnConfigRevision modify config_content_id NULL;
+alter table rhnConfigRevision drop column delim_start;
+alter table rhnConfigRevision drop column delim_end;
+
+update rhnConfigRevision set CONFIG_CONTENT_ID = null
+ where CONFIG_CONTENT_ID in
+ (select cr.CONFIG_CONTENT_ID
+ from rhnConfigRevision cr
+ inner join rhnConfigFileType cft on cft.id = cr.config_file_type_id and cft.label ='directory');
+
+delete from rhnConfigContent where id not in
+ (select CONFIG_CONTENT_ID from rhnConfigRevision cr where CONFIG_CONTENT_ID is not null);
+
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config.pks b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config.pks
new file mode 100644
index 0000000..37f5899
--- /dev/null
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/102-rhn_config.pks
@@ -0,0 +1,98 @@
+--
+-- Copyright (c) 2008 Red Hat, Inc.
+--
+-- This software is licensed to you under the GNU General Public License,
+-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
+-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
+-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+-- along with this software; if not, see
+-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+--
+-- Red Hat trademarks are not licensed under GPLv2. No permission is
+-- granted to use or replicate Red Hat trademarks that are incorporated
+-- in this software or its documentation.
+--
+--
+--
+--
+
+create or replace package
+rhn_config
+is
+ procedure prune_org_configs (
+ org_id_in in number,
+ total_in in number
+ );
+
+ function insert_revision (
+ revision_in in number,
+ config_file_id_in in number,
+ config_content_id_in in number,
+ config_info_id_in in number,
+ config_file_type_id_in number := 1
+ ) return number;
+
+ procedure delete_revision (
+ config_revision_id_in in number,
+ org_id_in in number := -1
+ );
+
+ function get_latest_revision (
+ config_file_id_in in number
+ ) return number;
+
+ function insert_file (
+ config_channel_id_in in number,
+ name_in in varchar2
+ ) return number;
+
+ procedure delete_file (
+ config_file_id_in in number
+ );
+
+ function insert_channel (
+ org_id_in in number,
+ type_in in varchar2,
+ name_in in varchar2,
+ label_in in varchar2,
+ description_in in varchar2
+ ) return number;
+
+ procedure delete_channel (
+ config_channel_id_in in number
+ );
+end rhn_config;
+/
+show errors
+
+--
+--
+-- Revision 1.8 2005/02/16 14:03:35 jslagle
+-- bz #148844
+-- Changed insert_revision function to take a config_file_type_id instead of label
+--
+-- Revision 1.7 2005/02/15 02:42:59 jslagle
+-- bz #147860
+-- insert_revision function now takes a rhnConfigFileType label as a parameter instead of an id
+--
+-- Revision 1.6 2005/02/14 22:45:23 jslagle
+-- bz#147860
+-- Update rhn_config package body and specification for additional column to rhnConfigRevision
+--
+-- Revision 1.5 2004/01/09 17:39:45 pjones
+-- bugzilla: 113029 -- need to do functions for deleting rhnConfigChannel,
+-- too, or we can't prune rhnConfigFile when we do.
+--
+-- Revision 1.4 2004/01/08 19:46:31 pjones
+-- bugzilla: 113029 -- insert/delete for rhnConfigFile and rhnConfigRevision
+--
+-- Revision 1.3 2004/01/08 00:30:10 pjones
+-- bugzilla: 113029 -- more deletion of config files and revisions
+--
+-- Revision 1.2 2004/01/08 00:03:37 pjones
+-- bugzilla: 113029 -- rhn_config.delete_revision() and delete trigger on
+-- rhnConfigFile
+--
+-- Revision 1.1 2003/12/19 22:07:30 pjones
+-- bugzilla: 112392 -- quota support for config files
+--
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config.pkb b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config.pkb
new file mode 100644
index 0000000..e51ca85
--- /dev/null
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/103-rhn_config.pkb
@@ -0,0 +1,288 @@
+--
+-- Copyright (c) 2008 Red Hat, Inc.
+--
+-- This software is licensed to you under the GNU General Public License,
+-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
+-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
+-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+-- along with this software; if not, see
+-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+--
+-- Red Hat trademarks are not licensed under GPLv2. No permission is
+-- granted to use or replicate Red Hat trademarks that are incorporated
+-- in this software or its documentation.
+--
+--
+--
+--
+
+create or replace package body
+rhn_config
+is
+ -- just a stub for now
+ procedure prune_org_configs (
+ org_id_in in number,
+ total_in in number
+ ) is
+ begin
+ null;
+ end prune_org_configs;
+
+ function insert_revision (
+ revision_in in number,
+ config_file_id_in in number,
+ config_content_id_in in number,
+ config_info_id_in in number,
+ config_file_type_id_in in number := 1
+ ) return number is
+ retval number;
+ cursor affected_orgs is
+ select cc.org_id id
+ from rhnConfigChannel cc,
+ rhnConfigFile cf
+ where cf.id = config_file_id_in
+ and cf.config_channel_id = cc.id;
+ begin
+
+ insert into rhnConfigRevision(id, revision, config_file_id,
+ config_content_id, config_info_id, config_file_type_id
+ ) values (
+ rhn_confrevision_id_seq.nextval, revision_in, config_file_id_in,
+ config_content_id_in, config_info_id_in, config_file_type_id_in
+ )
+ returning id into retval;
+
+ for org in affected_orgs loop
+ rhn_quota.update_org_quota(org.id);
+ end loop;
+
+ return retval;
+ end insert_revision;
+
+ procedure delete_revision (
+ config_revision_id_in in number,
+ org_id_in in number := -1
+ ) is
+ cfid number;
+ ccid number;
+ oid number;
+ latest_crid number;
+ others number := 0;
+ cursor snapshots is
+ select scr.snapshot_id id
+ from rhnSnapshot s,
+ rhnSnapshotConfigRevision scr
+ where scr.config_revision_id = config_revision_id_in
+ and scr.snapshot_id = s.id
+ and s.invalid is null;
+ cursor other_revisions(config_content_id_in in number) is
+ select 1
+ from rhnConfigRevision
+ where config_content_id = config_content_id_in;
+ begin
+ for snapshot in snapshots loop
+ update rhnSnapshot s
+ set s.invalid =
+ lookup_snapshot_invalid_reason('cr_removed')
+ where s.id = snapshot.id;
+ end loop;
+
+ if org_id_in < 0 then
+ select cr.config_content_id, cc.org_id
+ into ccid, oid
+ from rhnConfigChannel cc,
+ rhnConfigFile cf,
+ rhnConfigRevision cr
+ where cr.id = config_revision_id_in
+ and cr.config_file_id = cf.id
+ and cf.config_channel_id = cc.id;
+ else
+ select cr.config_content_id, org_id_in
+ into ccid, oid
+ from rhnConfigRevision cr
+ where cr.id = config_revision_id_in;
+ end if;
+
+ -- right now this will set rhnActionConfigFileName.config_revision_id
+ -- to null, and will remove an entry from rhnActionConfigRevision.
+ -- might we want to prune and/or kill the action in some way? maybe
+ -- mark it failed or something?
+ delete from rhnConfigRevision where id = config_revision_id_in;
+
+ -- now prune away content if there aren't any other revisions pointing
+ -- at it
+ for other_revision in other_revisions(ccid) loop
+ others := 1;
+ exit;
+ end loop;
+ if others = 0 then
+ delete from rhnConfigContent where id = ccid;
+ end if;
+
+ -- now make sure rhnConfigFile points at a valid revision;
+ -- if there isn't one, we're deleting it, _unless_ org_id_in is
+ -- >= 0, in which case we're in the delete trigger anyway
+ if org_id_in < 0 then
+ select cf.latest_config_revision_id,
+ cf.id
+ into latest_crid,
+ cfid
+ from rhnConfigFile cf,
+ rhnConfigRevision cr
+ where cr.id = config_revision_id_in
+ and cr.config_file_id = cf.id;
+
+ if latest_crid = config_revision_id_in then
+ latest_crid := rhn_config.get_latest_revision(cfid);
+ if latest_crid is not null then
+ update rhnConfigFile set latest_config_revision_id = latest_crid
+ where id = cfid;
+ else
+ delete from rhnConfigFile where id = cfid;
+ end if;
+ end if;
+
+ end if;
+ rhn_quota.update_org_quota(oid);
+ end delete_revision;
+
+ function get_latest_revision (
+ config_file_id_in in number
+ ) return number is
+ cursor revisions is
+ select cr.id
+ from rhnConfigRevision cr
+ where cr.config_file_id = config_file_id_in
+ order by revision desc;
+ begin
+ for revision in revisions loop
+ return revision.id;
+ end loop;
+ return null;
+ end get_latest_revision;
+
+ function insert_file (
+ config_channel_id_in in number,
+ name_in in varchar2
+ ) return number is
+ retval number;
+ begin
+ select rhn_conffile_id_seq.nextval
+ into retval
+ from dual;
+
+ insert into rhnConfigFile(id, config_channel_id, config_file_name_id,
+ state_id
+ ) (
+ select retval,
+ config_channel_id_in,
+ lookup_config_filename(name_in),
+ id
+ from rhnConfigFileState
+ where label = 'alive'
+ );
+
+ return retval;
+ end insert_file;
+
+ procedure delete_file (
+ config_file_id_in in number
+ ) is
+ cursor revisions is
+ select cr.id, cc.org_id
+ from rhnConfigChannel cc,
+ rhnConfigRevision cr,
+ rhnConfigFile cf
+ where cf.id = config_file_id_in
+ and cf.config_channel_id = cc.id
+ and cr.config_file_id = cf.id;
+ org_id number;
+ begin
+ for revision in revisions loop
+ rhn_config.delete_revision(revision.id, revision.org_id);
+ org_id := revision.org_id;
+ end loop;
+ rhn_quota.update_org_quota(org_id);
+ delete from rhnConfigFile where id = config_file_id_in;
+ end delete_file;
+
+ function insert_channel (
+ org_id_in in number,
+ type_in in varchar2,
+ name_in in varchar2,
+ label_in in varchar2,
+ description_in in varchar2
+ ) return number is
+ retval number;
+ begin
+ select rhn_confchan_id_seq.nextval
+ into retval
+ from dual;
+
+ insert into rhnConfigChannel(id, org_id, confchan_type_id,
+ name, label, description
+ ) (
+ select retval,
+ org_id_in,
+ cct.id,
+ name_in,
+ label_in,
+ description_in
+ from rhnConfigChannelType cct
+ where label = type_in
+ );
+ return retval;
+ end insert_channel;
+
+ procedure delete_channel (
+ config_channel_id_in in number
+ ) is
+ cursor config_files is
+ select id
+ from rhnConfigFile
+ where config_channel_id = config_channel_id_in;
+ begin
+ for config_file in config_files loop
+ rhn_config.delete_file(config_file.id);
+ end loop;
+ delete from rhnConfigChannel where id = config_channel_id_in;
+ end delete_channel;
+end rhn_config;
+/
+show errors
+
+--
+--
+-- Revision 1.9 2005/02/16 14:03:35 jslagle
+-- bz #148844
+-- Changed insert_revision function to take a config_file_type_id instead of label
+--
+-- Revision 1.8 2005/02/15 02:42:59 jslagle
+-- bz #147860
+-- insert_revision function now takes a rhnConfigFileType label as a parameter instead of an id
+--
+-- Revision 1.7 2005/02/14 22:45:23 jslagle
+-- bz#147860
+-- Update rhn_config package body and specification for additional column to rhnConfigRevision
+--
+-- Revision 1.6 2004/10/11 14:02:53 pjones
+-- bugzilla: 133169 -- somehow, we just never update the quota in this case.
+-- Amazingly, I thought this worked _and_ QA passed it...
+--
+-- Revision 1.5 2004/01/09 17:39:45 pjones
+-- bugzilla: 113029 -- need to do functions for deleting rhnConfigChannel,
+-- too, or we can't prune rhnConfigFile when we do.
+--
+-- Revision 1.4 2004/01/08 19:46:31 pjones
+-- bugzilla: 113029 -- insert/delete for rhnConfigFile and rhnConfigRevision
+--
+-- Revision 1.3 2004/01/08 00:30:10 pjones
+-- bugzilla: 113029 -- more deletion of config files and revisions
+--
+-- Revision 1.2 2004/01/08 00:03:37 pjones
+-- bugzilla: 113029 -- rhn_config.delete_revision() and delete trigger on
+-- rhnConfigFile
+--
+-- Revision 1.1 2003/12/19 22:07:30 pjones
+-- bugzilla: 112392 -- quota support for config files
+--
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/104-rhnconfigrevision-trigger.sql b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/104-rhnconfigrevision-trigger.sql
new file mode 100644
index 0000000..939f3bf
--- /dev/null
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/104-rhnconfigrevision-trigger.sql
@@ -0,0 +1,102 @@
+--
+-- Copyright (c) 2008 Red Hat, Inc.
+--
+-- This software is licensed to you under the GNU General Public License,
+-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
+-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
+-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+-- along with this software; if not, see
+-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+--
+-- Red Hat trademarks are not licensed under GPLv2. No permission is
+-- granted to use or replicate Red Hat trademarks that are incorporated
+-- in this software or its documentation.
+--
+--
+--
+--
+
+create or replace trigger
+rhn_confrevision_mod_trig
+before insert or update on rhnConfigRevision
+for each row
+begin
+ :new.modified := sysdate;
+end;
+/
+show errors
+
+-- right now we're not doing accounting for rhnConfigRevision updates.
+-- we shouldn't ever _do_ updates, but right now the perms exist.
+create or replace trigger
+rhn_confrevision_acct_trig
+after insert on rhnConfigRevision
+for each row
+declare
+ org_id number;
+ available number := 0;
+ added number := 0;
+begin
+ -- find the current amount of quota available
+ begin
+ select cc.org_id id,
+ oq.total + oq.bonus - oq.used available,
+ content.file_size added
+ into org_id, available, added
+ from rhnConfigContent content,
+ rhnOrgQuota oq,
+ rhnConfigChannel cc,
+ rhnConfigFile cf
+ where cf.id = :new.config_file_id
+ and cf.config_channel_id = cc.id
+ and cc.org_id = oq.org_id
+ and :new.config_file_type_id = (select id from rhnConfigFileType where label='file')
+ and :new.config_content_id = content.id;
+ exception
+ when no_data_found then
+ added := 0;
+ available := 0;
+ end;
+ if added > available then
+ rhn_exception.raise_exception('not_enough_quota');
+ end if;
+end;
+/
+show errors
+
+create or replace trigger
+rhn_confrevision_del_trig
+before delete on rhnConfigRevision
+for each row
+declare
+ cursor snapshots is
+ select snapshot_id id
+ from rhnSnapshotConfigRevision
+ where config_revision_id = :old.id;
+begin
+ for snapshot in snapshots loop
+ update rhnSnapshot
+ set invalid = lookup_snapshot_invalid_reason('cr_removed')
+ where id = snapshot.id;
+ delete from rhnSnapshotConfigRevision
+ where snapshot_id = snapshot.id
+ and config_revision_id = :old.id;
+ end loop;
+end;
+/
+show errors
+
+--
+--
+-- Revision 1.4 2004/01/07 20:49:12 pjones
+-- bugzilla: none -- this needs to be done in application code
+--
+-- Revision 1.3 2004/01/05 20:35:41 pjones
+-- bugzilla: 112553 -- fix the insert case for quota
+--
+-- Revision 1.2 2003/12/19 22:07:30 pjones
+-- bugzilla: 112392 -- quota support for config files
+--
+-- Revision 1.1 2003/11/14 21:00:44 pjones
+-- bugzilla: none -- snapshot invalid on config rev removal
+--
diff --git a/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/105-lookup_config_info.sql b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/105-lookup_config_info.sql
new file mode 100644
index 0000000..5121f04
--- /dev/null
+++ b/schema/spacewalk/upgrade/spacewalk-schema-1.0-to-spacewalk-schema-1.1/105-lookup_config_info.sql
@@ -0,0 +1,64 @@
+--
+-- Copyright (c) 2008 Red Hat, Inc.
+--
+-- This software is licensed to you under the GNU General Public License,
+-- version 2 (GPLv2). There is NO WARRANTY for this software, express or
+-- implied, including the implied warranties of MERCHANTABILITY or FITNESS
+-- FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+-- along with this software; if not, see
+-- http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+--
+-- Red Hat trademarks are not licensed under GPLv2. No permission is
+-- granted to use or replicate Red Hat trademarks that are incorporated
+-- in this software or its documentation.
+--
+--
+--
+--
+
+create or replace function
+lookup_config_info (
+ username_in in varchar2,
+ groupname_in in varchar2,
+ filemode_in in varchar2,
+ selinux_ctx_in in varchar2,
+ symlink_target_id in number
+) return number
+deterministic
+is
+ pragma autonomous_transaction;
+ v_id number;
+ cursor lookup_cursor is
+ select id
+ from rhnConfigInfo
+ where 1=1
+ and nvl(username, ' ') = nvl(username_in, ' ')
+ and nvl(groupname,' ') = nvl(groupname_in, ' ')
+ and nvl(filemode, -1) = nvl(filemode_in, -1)
+ and nvl(selinux_ctx, ' ') = nvl(selinux_ctx_in, ' ')
+ and nvl(symlink_target_filename_id, -1) = nvl(symlink_target_id, -1)
+ ;
+begin
+ for r in lookup_cursor loop
+ return r.id;
+ end loop;
+ -- If we got here, we don't have the id
+ select rhn_confinfo_id_seq.nextval
+ into v_id
+ from dual;
+ insert into rhnConfigInfo (id, username, groupname, filemode, selinux_ctx, symlink_target_filename_id)
+ values (v_id, username_in, groupname_in, filemode_in, selinux_ctx_in, symlink_target_id);
+ commit;
+ return v_id;
+end lookup_config_info;
+/
+show errors
+
+--
+-- Revision 1.1 2003/11/10 15:36:27 pjones
+-- bugzilla: 109083 -- lookup for rhnConfigInfo
+--
+-- Revision 1.1 2003/10/15 18:30:34 misa
+-- bugzilla: 106911 Added a lookup function for rhnConfigFileInfo
+--
+--
diff --git a/scripts/update_symlinks.py b/scripts/update_symlinks.py
new file mode 100644
index 0000000..872257b
--- /dev/null
+++ b/scripts/update_symlinks.py
@@ -0,0 +1,134 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2008 Red Hat, Inc.
+#
+# This software is licensed to you under the GNU General Public License,
+# version 2 (GPLv2). There is NO WARRANTY for this software, express or
+# implied, including the implied warranties of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
+# along with this software; if not, see
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# Red Hat trademarks are not licensed under GPLv2. No permission is
+# granted to use or replicate Red Hat trademarks that are incorporated
+# in this software or its documentation.
+#
+#
+# Test for blob updates
+#
+# $Id$
+
+"""
+Test module for blob updates.
+To create the table for this test run:
+
+drop table test_blob_update;
+
+create table test_blob_update
+ (id1 int not null, id2 int, val1 blob, val2 blob, nval int not null);
+"""
+
+import sys
+sys.path.insert(0, "/usr/share/rhn")
+from common.rhnConfig import CFG, initCFG
+from server import rhnSQL
+from server.importlib.backendLib import Table, DBblob, DBint, TableUpdate, \
+ TableInsert
+from pprint import pprint
+from os.path import isabs
+
+def setupDb():
+ initCFG('server.satellite')
+ db_backend = CFG.DB_BACKEND
+ db_host = CFG.DB_HOST
+ db_port = CFG.DB_PORT
+ db_user = CFG.DB_user
+ db_password = CFG.DB_PASSWORD
+ database = CFG.DB_NAME
+ rhnSQL.initDB(backend=db_backend, host=db_host, port=db_port,
+ username=db_user, password=db_password, database=database)
+
+def main():
+ setupDb()
+ q = """select cr.id as rev_id,
+ ccon.id as content_id,
+ ccon.contents,
+ cr.CONFIG_INFO_ID as info_id,
+ cf.id as file_id,
+ cc.org_id,
+ wc.name as org_name,
+ ci.SELINUX_CTX as selinux,
+ cfn.path as path,
+ ci.SYMLINK_TARGET_FILENAME_ID as info_target,
+ nvl( (select path from rhnCOnfigFileName where id = ci.SYMLINK_TARGET_FILENAME_ID), 'None') as name_target
+ from rhnConfigContent ccon
+ inner join rhnConfigRevision cr on cr.config_content_id = ccon.id
+ inner join rhnConfigFile cf on cr.CONFIG_FILE_ID = cf.id
+ inner join rhnConfigFileName cfn on cfn.id = cf.config_file_name_id
+ inner join rhnConfigInfo ci on ci.id = cr.CONFIG_INFO_ID
+ inner join rhnConfigChannel cc on cf.CONFIG_CHANNEL_ID = cc.id
+ inner join web_customer wc on cc.org_id = wc.id
+ where
+ cr.CONFIG_FILE_TYPE_ID in (select id from rhnConfigFileType where label='symlink')"""
+ h = rhnSQL.prepare(q)
+ if h.execute() == 0:
+ return
+ contents = []
+ for row in h.fetchall_dict():
+ contents.append( dict(revision_id = row["rev_id"],
+ file_id = row ["file_id"],
+ info_id = row ["info_id"],
+ content_id = row ["content_id"],
+ path = row['path'],
+ info_target = row['info_target'],
+ name_target = row['name_target'],
+ selinux = row['selinux'],
+ org_id = row['org_id'],
+ org_name = row['org_name'],
+ symlink_target = rhnSQL.read_lob(row["contents"])))
+
+
+ update_query = """update rhnConfigRevision set config_info_id =
+ lookup_config_info(null, null, null, :selinux, lookup_config_filename(:symlink_target)) where id = :revision_id"""
+
+ null_symlink_update_query = """update rhnConfigRevision set config_info_id =
+ lookup_config_info(null, null, null, :selinux, null) where id = :revision_id"""
+
+ update_cr = """ update rhnConfigRevision set config_content_id = null where id = :revision_id"""
+ delete_content = """ delete from rhnConfigContent where id = :content_id"""
+ bad_items = list()
+ for item in contents:
+ if item['symlink_target'] is None:
+ bad_items.append(item)
+ rhnSQL.prepare(null_symlink_update_query).execute(**item)
+ else:
+ if not isabs(item['symlink_target']) or len(item['symlink_target']) >= 1024:
+ bad_items.append(item)
+ item['symlink_target'] = item['symlink_target'][:1024]
+ rhnSQL.prepare(update_query).execute(**item)
+ rhnSQL.prepare(update_cr).execute(**item)
+ rhnSQL.prepare(delete_content).execute(**item)
+
+ rhnSQL.commit()
+ rhnSQL.closeDB()
+
+ msg = """
+ The following symbolic link paths are either null or not absolute or above 1024 characters in length.
+ While entries have been added in the DB, the values have to be updated for them in the Web UI.
+ Please go to the provided url, logging in as a user with config admin/org admin role in the specified organization
+ and update the target path value accordingly.
+ """
+ format = """
+ Path: [%(path)s]
+ Symbolic link:[%(symlink_target)s]
+ Update URL: https://<FQDN>/rhn/configuration/file/FileDetails.do?cfid=%(file_id)d&crid=%(revision_id)d
+ Organization Id : [%(org_id)d]
+ Organization Name : [%(org_name)s]
+ """
+ if bad_items:
+ print msg
+ for item in bad_items:
+ print format % item
+
+if __name__ == '__main__':
+ sys.exit(main() or 0)
13 years, 9 months
Changes to 'refs/tags/spacewalk-java-1.0.8-1'
by Justin Sherrill
Tag 'spacewalk-java-1.0.8-1' created by Justin Sherrill <jsherril(a)redhat.com> at 2010-07-29 20:13 +0000
Tagging package [spacewalk-java] version [1.0.8-1] in directory [java/].
Changes since spacewalk-java-1.0.7-1:
Justin Sherrill (2):
making the editarea not highlight by default
Automatic commit of package [spacewalk-java] release [1.0.8-1].
---
java/code/webapp/WEB-INF/pages/common/fragments/editarea.jspf | 1 -
java/spacewalk-java.spec | 5 ++++-
rel-eng/packages/spacewalk-java | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
---
13 years, 9 months
Branch 'SPACEWALK-1.0' - java/spacewalk-java.spec rel-eng/packages
by Justin Sherrill
java/spacewalk-java.spec | 5 ++++-
rel-eng/packages/spacewalk-java | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
New commits:
commit 527cbff2934c02171955dbe8c791007739862a00
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Thu Jul 29 16:13:43 2010 -0400
Automatic commit of package [spacewalk-java] release [1.0.8-1].
diff --git a/java/spacewalk-java.spec b/java/spacewalk-java.spec
index 5833553..33f8f82 100644
--- a/java/spacewalk-java.spec
+++ b/java/spacewalk-java.spec
@@ -19,7 +19,7 @@ Name: spacewalk-java
Summary: Spacewalk Java site packages
Group: Applications/Internet
License: GPLv2
-Version: 1.0.7
+Version: 1.0.8
Release: 1%{?dist}
URL: https://fedorahosted.org/spacewalk
Source0: https://fedorahosted.org/releases/s/p/spacewalk/%{name}-%{version}.tar.gz
@@ -310,6 +310,9 @@ fi
%{jardir}/postgresql-jdbc.jar
%changelog
+* Thu Jul 29 2010 Justin Sherrill <jsherril(a)redhat.com> 1.0.8-1
+- making the editarea not highlight by default (jsherril(a)redhat.com)
+
* Fri Jul 16 2010 Justin Sherrill <jsherril(a)redhat.com> 1.0.7-1
- fixing un-escaped dollar sign in %post script that deals with rewriting
/etc/sysconfig/rhn/up2date (jsherril(a)redhat.com)
diff --git a/rel-eng/packages/spacewalk-java b/rel-eng/packages/spacewalk-java
index f179f86..29fdaee 100644
--- a/rel-eng/packages/spacewalk-java
+++ b/rel-eng/packages/spacewalk-java
@@ -1 +1 @@
-1.0.7-1 java/
+1.0.8-1 java/
13 years, 9 months
Branch 'SPACEWALK-1.0' - java/code
by Justin Sherrill
java/code/webapp/WEB-INF/pages/common/fragments/editarea.jspf | 1 -
1 file changed, 1 deletion(-)
New commits:
commit 15eb69a7ba6bc832c3f56d59b55dccc5b6c780c1
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Thu Jul 29 16:09:01 2010 -0400
making the editarea not highlight by default
diff --git a/java/code/webapp/WEB-INF/pages/common/fragments/editarea.jspf b/java/code/webapp/WEB-INF/pages/common/fragments/editarea.jspf
index 8d45a8c..b7c0708 100644
--- a/java/code/webapp/WEB-INF/pages/common/fragments/editarea.jspf
+++ b/java/code/webapp/WEB-INF/pages/common/fragments/editarea.jspf
@@ -3,7 +3,6 @@
<script language="javascript" type="text/javascript">
editAreaLoader.init({
id : "contents"
- ,start_highlight: true
,allow_toggle: true
,allow_resize: "both"
,word_wrap: true
13 years, 9 months
java/code
by Justin Sherrill
java/code/src/com/redhat/rhn/common/db/datasource/xml/SystemGroup_queries.xml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
New commits:
commit d10471dd873d2cd8ec05bd831146dc2940c922aa
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Thu Jul 29 14:57:20 2010 -0400
603133 - fixing issue where system within a group that were unentitled would still factor into whether the group would show up with an exclamation point
diff --git a/java/code/src/com/redhat/rhn/common/db/datasource/xml/SystemGroup_queries.xml b/java/code/src/com/redhat/rhn/common/db/datasource/xml/SystemGroup_queries.xml
index f72d2b2..f0bf857 100644
--- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/SystemGroup_queries.xml
+++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/SystemGroup_queries.xml
@@ -29,8 +29,10 @@
1, 'Product Enhancement Advisory') as type_value
from rhnErrata E inner join
rhnServerNeededCache SNPC on E.id = SNPC.errata_id inner join
- rhnServerGroupMembers SGM on SGM.server_id = SNPC.server_id
- where sgm.server_group_id = G.id) as MOST_SEVERE_ERRATA
+ rhnServerGroupMembers SGM on SGM.server_id = SNPC.server_id inner join
+ rhnServerFeaturesView SFV on SGM.server_id = SFV.server_id
+ where sgm.server_group_id = G.id
+ AND SFV.label = 'ftr_system_grouping') as MOST_SEVERE_ERRATA
FROM rhnServerGroup G, rhnUserManagedServerGroups UMSG
WHERE G.ORG_ID = :org_id
AND UMSG.user_id = :user_id
13 years, 9 months