Пример #1
0
// serviceManip allows services manipulation either over chroot
// (in case we need modify service state on an off-line image) or
// without chrooting (in case we are deploying upon a running system)
// Example:
//<services>
//	<service>
//     <name>iptables</name>
//     <type>sysv</type>
//     <status>off</status>
//	   <action></action>
//	</service>
//	<service>
//     <name>ip6tables</name>
//     <type>sysv</type>
//     <status>off</status>
//	   <action></action>
//	   <chroot>false</chroot>
//	</service>
//	<service>
//     <name>ssh</name>
//     <type>upstart</type>
//     <status></status>
//	   <action>reload</action>
//	   <chroot>false</chroot>
//	</service>
//</services>
func serviceManip(pathToXml, pathToSlash string) error {
	dataBuf, err := ioutil.ReadFile(pathToXml)
	if err != nil {
		return utils.FormatError(err)
	}
	servicesStruct := Services{}
	if err := xml.Unmarshal(dataBuf, &servicesStruct); err != nil {
		return utils.FormatError(err)
	}
	for _, val := range servicesStruct.Srvcs {
		// switch the service type
		switch val.Type {
		case SVC_TYPE_SYSV:
			switch val.Status {
			case SVC_STATUS_ON, SVC_STATUS_OFF:
				var cmd string
				var action string
				if val.Chroot {
					if err := exec.Command("chroot", pathToSlash, "which", "update-rc.d").Run(); err != nil {
						cmd = "chkconfig"
						action = val.Status
					} else {
						cmd = "update-rc.d"
						switch val.Status {
						case SVC_STATUS_ON:
							action = "enable"
						case SVC_STATUS_OFF:
							action = "disable"
						}
					}
					if err := exec.Command("chroot", pathToSlash, cmd, val.Name, action).Run(); err != nil {
						return utils.FormatError(fmt.Errorf("chroot %s %s %s %s", pathToSlash, cmd, val.Name, action))
					}
				} else {
					if err := exec.Command(cmd, val.Name, action).Run(); err != nil {
						return utils.FormatError(fmt.Errorf("%s %s %s", cmd, val.Name, action))
					}
				}
			default:
				return utils.FormatError(errors.New(`ServiceManip :sysv:status configuration error - unsupported service status`))
			}
			// switch appropriate action towards the service
			switch val.Action {
			case ACTION_STOP, ACTION_START, ACTION_RESTART, ACTION_RELOAD:
				if err := exec.Command("service",
					val.Name, val.Action).Run(); err != nil {
					return utils.FormatError(fmt.Errorf("service %s %s", val.Name, val.Action))
				}
			case "":
			default:
				return utils.FormatError(errors.New(`ServiceManip :sysv:action: configuration error - unsupported action ` + val.Action))
			}

		case SVC_TYPE_UPSTART:
			fullPathToChrootDir := filepath.Join(pathToSlash, "/etc/init/")
			servicePath := filepath.Join(fullPathToChrootDir, val.Name+".conf")
			dummyServicePath := filepath.Join(fullPathToChrootDir, val.Name+".override")
			switch val.Status {
			case SVC_STATUS_OFF:
				if _, err := os.Stat(servicePath); err == nil {
					if err := ioutil.WriteFile(dummyServicePath, []byte("manual"), 0644); err != nil {
						return utils.FormatError(err)
					}
				}
			case SVC_STATUS_ON:
				if err := ioutils.RemoveIfExists(false, dummyServicePath); err != nil {
					return utils.FormatError(err)
				}
			default:
				return utils.FormatError(errors.New(`configuration error - unsupported service status`))
			}
			switch val.Action {
			case ACTION_STOP, ACTION_START, ACTION_RESTART, ACTION_RELOAD:
				if err := exec.Command("initctl", val.Name,
					val.Action).Run(); err != nil {
					return utils.FormatError(fmt.Errorf("initctl %s %s", val.Name, val.Action))
				}
			case "":
			default:
				return utils.FormatError(errors.New(`ServiceManip : upstart :configuration error - unsupported action`))
			}
		}
	}
	return nil
}
Пример #2
0
// injectStuff modifies a RAW image "on-the-fly"
// by injecting appropriate stuff to the mounted vHDD
// 1) it receives src and dst directories paths
// 2) it looks for a file inject.config inside the src directory
// 3) in case the file found parses it and inject appropriate stuff
//    according to the file.
// Example:
//<inject_items>
//	<inject_item>
//      <name>file1</name>
//	 	<bkp_name>file1.bkp</bkp_name>
//	  	<action>upload</action>
//      <type>file</type>
// 		<location>/opt</location>
//		<permissions>0755</permissions>
//  	<owner_id>0</owner_id>
//		<group_id>0</group_id>
//	</inject_item>
//</inject_items
func injectManip(pathToXml, pathToSlash string) error {
	dataBuf, err := ioutil.ReadFile(pathToXml)
	if err != nil {
		return utils.FormatError(err)
	}
	itemsStruct := InjectItems{}
	if err := xml.Unmarshal(dataBuf, &itemsStruct); err != nil {
		return utils.FormatError(err)
	}
	for _, val := range itemsStruct.InjItems {
		baseDir := filepath.Dir(pathToXml)
		srcPath := baseDir + "/items/" + val.Name
		targetLocationPath := filepath.Join(pathToSlash, val.Location)
		dstPath := filepath.Join(targetLocationPath, val.Name)
		dstBkpPath := filepath.Join(targetLocationPath, val.BkpName)
		switch val.Action {
		case ACTION_REMOVE:
			if val.BkpName == "" {
				if err := ioutils.RemoveIfExists(true, dstPath); err != nil {
					return utils.FormatError(err)
				}
			} else {
				if _, err := os.Stat(dstPath); err == nil {
					if err := os.Rename(dstPath, dstBkpPath); err != nil {
						return utils.FormatError(err)
					}
				}
			}
		case ACTION_UPLOAD, ACTION_CREATE:
			switch val.Type {
			case ITEM_TYPE_FILE:
				if err := ioutils.CreateDirRecursively(targetLocationPath, 0755,
					val.UID, val.GID, false); err != nil {
					if err != os.ErrExist {
						return utils.FormatError(err)
					}
				}
				if val.Action == ACTION_UPLOAD {
					if val.BkpName != "" {
						if _, err := os.Stat(dstPath); err == nil {
							if err := os.Rename(dstPath, dstBkpPath); err != nil {
								return utils.FormatError(err)
							}
						}
					}
					if err := ioutils.CopyFile(srcPath, dstPath, 0,
						val.UID, val.GID, false); err != nil {
						return utils.FormatError(err)
					}
				} else {
					fd, err := os.Create(dstPath)
					if err != nil {
						return utils.FormatError(err)
					}
					fd.Close()
				}
				// FIXME:
				// we shuld use val.Permissions for setting permissions ,example
				// if err := CopyFile(srcFilePath, dstFilePath,
				//	val.Permissions, val.UID, val.GID); err != nil {
				//	return err
				//}
				// Currently , it copies permission flags from the source
			case ITEM_TYPE_DIR:
				if err := ioutils.CreateDirRecursively(filepath.Join(targetLocationPath, val.Name),
					val.Permissions, val.UID, val.GID, false); err != nil {
					return utils.FormatError(err)
				}
				if val.Action == ACTION_UPLOAD {
					if val.BkpName != "" {
						if _, err := os.Stat(dstPath); err == nil {
							if err := os.Rename(dstPath, dstBkpPath); err != nil {
								return utils.FormatError(err)
							}
						}
					}
					if err := ioutils.CopyDir(srcPath, dstPath); err != nil {
						return utils.FormatError(err)
					}
				}
			case ITEM_TYPE_LINK:
				if _, err := os.Stat(val.BkpName); err != nil {
					return utils.FormatError(err)
				}
				if err := ioutils.RemoveIfExists(false, dstPath); err != nil {
					return utils.FormatError(err)
				}
				if err := ioutils.CreateDirRecursively(targetLocationPath,
					val.Permissions, val.UID, val.GID, false); err != nil {
					return utils.FormatError(err)
				}
				if err := os.Symlink(val.BkpName, dstPath); err != nil {
					return utils.FormatError(err)
				}
			default:
				return utils.FormatError(errors.New("injectManip: configuration error - unexpected element type"))
			}
		default:
			return utils.FormatError(errors.New("injectManip: configuration error - unexpected action"))
		}
	}
	return nil
}