summaryrefslogtreecommitdiffstats
path: root/release
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1997-06-05 09:48:03 +0000
committerjkh <jkh@FreeBSD.org>1997-06-05 09:48:03 +0000
commit9160ca00b5da185787c84ae5e1b1d848847dd262 (patch)
tree3707fb988b7a0ae5cc4e493af9c486da9892a1dd /release
parent4caf82f971a9e9d7368fa7667e4e43f98857e620 (diff)
downloadFreeBSD-src-9160ca00b5da185787c84ae5e1b1d848847dd262.zip
FreeBSD-src-9160ca00b5da185787c84ae5e1b1d848847dd262.tar.gz
Resurrect / implement some of the more esoteric scripting features,
such as partitioning a disk or overriding an interactive prompt.
Diffstat (limited to 'release')
-rw-r--r--release/sysinstall/config.c10
-rw-r--r--release/sysinstall/disks.c95
-rw-r--r--release/sysinstall/dispatch.c23
-rw-r--r--release/sysinstall/dist.c52
-rw-r--r--release/sysinstall/label.c117
-rw-r--r--release/sysinstall/main.c4
-rw-r--r--release/sysinstall/media.c7
-rw-r--r--release/sysinstall/sysinstall.h8
-rw-r--r--release/sysinstall/variable.c9
-rw-r--r--release/sysinstall/variable_load.c5
10 files changed, 309 insertions, 21 deletions
diff --git a/release/sysinstall/config.c b/release/sysinstall/config.c
index 05a3e55..50a874d 100644
--- a/release/sysinstall/config.c
+++ b/release/sysinstall/config.c
@@ -4,7 +4,7 @@
* This is probably the last program in the `sysinstall' line - the next
* generation being essentially a complete rewrite.
*
- * $Id: config.c,v 1.96 1997/05/27 16:41:47 jkh Exp $
+ * $Id: config.c,v 1.97 1997/05/30 01:03:07 jkh Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -355,6 +355,14 @@ configEnvironmentResolv(char *config)
}
}
+/* Version of below for dispatch routines */
+int
+configRC(dialogMenuItem *unused)
+{
+ configRC_conf("/etc/rc.conf");
+ return DITEM_SUCCESS;
+}
+
/*
* This sucks in /etc/rc.conf, substitutes anything needing substitution, then
* writes it all back out. It's pretty gross and needs re-writing at some point.
diff --git a/release/sysinstall/disks.c b/release/sysinstall/disks.c
index 34a0c1d..036268d 100644
--- a/release/sysinstall/disks.c
+++ b/release/sysinstall/disks.c
@@ -4,7 +4,7 @@
* This is probably the last program in the `sysinstall' line - the next
* generation being essentially a complete rewrite.
*
- * $Id: disks.c,v 1.84 1997/05/05 05:16:00 pst Exp $
+ * $Id: disks.c,v 1.85 1997/05/10 17:11:24 pst Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -45,6 +45,8 @@
static struct chunk *chunk_info[16];
static int current_chunk;
+static void diskPartitionNonInteractive(Device *dev, Disk *d);
+
static void
record_chunks(Disk *d)
{
@@ -509,7 +511,10 @@ diskPartitionEditor(dialogMenuItem *self)
}
else if (cnt == 1) {
devs[0]->enabled = TRUE;
- diskPartition(devs[0], (Disk *)devs[0]->private);
+ if (variable_get(VAR_NONINTERACTIVE))
+ diskPartitionNonInteractive(devs[0], (Disk *)devs[0]->private);
+ else
+ diskPartition(devs[0], (Disk *)devs[0]->private);
i = DITEM_SUCCESS;
}
else {
@@ -587,3 +592,89 @@ diskPartitionWrite(dialogMenuItem *self)
variable_set2(DISK_PARTITIONED, "written");
return DITEM_SUCCESS;
}
+
+/* Partition a disk based wholly on which variables are set */
+static void
+diskPartitionNonInteractive(Device *dev, Disk *d)
+{
+ char *cp;
+ int i, sz;
+
+ record_chunks(d);
+ cp = variable_get(VAR_GEOMETRY);
+ if (cp) {
+ msgDebug("Setting geometry from script to: %s\n", cp);
+ d->bios_cyl = strtol(cp, &cp, 0);
+ d->bios_hd = strtol(cp + 1, &cp, 0);
+ d->bios_sect = strtol(cp + 1, 0, 0);
+ }
+
+ cp = variable_get(VAR_PARTITION);
+ if (cp) {
+ if (!strcmp(cp, "free")) {
+ /* Do free disk space case */
+ for (i = 0; chunk_info[i]; i++) {
+ /* If a chunk is at least 10MB in size, use it. */
+ if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
+ Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size, freebsd, 3,
+ (chunk_info[i]->flags & CHUNK_ALIGN));
+ variable_set2(DISK_PARTITIONED, "yes");
+ break;
+ }
+ }
+ if (!chunk_info[i]) {
+ dialog_clear();
+ msgConfirm("Unable to find any free space on this disk!");
+ return;
+ }
+ }
+ else if (!strcmp(cp, "all")) {
+ /* Do all disk space case */
+ msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
+
+ All_FreeBSD(d, FALSE);
+ }
+ else if (!strcmp(cp, "exclusive")) {
+ /* Do really-all-the-disk-space case */
+ msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
+
+ All_FreeBSD(d, TRUE);
+ }
+ else if ((sz = strtol(cp, &cp, 0))) {
+ /* Look for sz bytes free */
+ if (*cp && toupper(*cp) == 'M')
+ sz *= ONE_MEG;
+ for (i = 0; chunk_info[i]; i++) {
+ /* If a chunk is at least sz MB, use it. */
+ if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
+ Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3, (chunk_info[i]->flags & CHUNK_ALIGN));
+ variable_set2(DISK_PARTITIONED, "yes");
+ break;
+ }
+ }
+ if (!chunk_info[i]) {
+ dialog_clear();
+ msgConfirm("Unable to find %d free blocks on this disk!", sz);
+ return;
+ }
+ }
+ else if (!strcmp(cp, "existing")) {
+ /* Do existing FreeBSD case */
+ for (i = 0; chunk_info[i]; i++) {
+ if (chunk_info[i]->type == freebsd)
+ break;
+ }
+ if (!chunk_info[i]) {
+ dialog_clear();
+ msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
+ return;
+ }
+ }
+ else {
+ dialog_clear();
+ msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
+ return;
+ }
+ variable_set2(DISK_PARTITIONED, "yes");
+ }
+}
diff --git a/release/sysinstall/dispatch.c b/release/sysinstall/dispatch.c
index 7e8c446..4776dad 100644
--- a/release/sysinstall/dispatch.c
+++ b/release/sysinstall/dispatch.c
@@ -4,7 +4,7 @@
* This is probably the last program in the `sysinstall' line - the next
* generation being essentially a complete rewrite.
*
- * $Id: dispatch.c,v 1.12 1997/03/10 21:11:52 jkh Exp $
+ * $Id: dispatch.c,v 1.13 1997/05/22 00:17:06 jkh Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -47,13 +47,20 @@ static struct _word {
{ "configRouter", configRouter },
{ "configNFSServer", configNFSServer },
{ "configSamba", configSamba },
- { "configRegister", configRegister },
+ { "configNTP", configNTP },
+ { "configPCNFSD", configPCNFSD },
+ { "configNFSServer", configNFSServer },
{ "configPackages", configPackages },
+ { "configRegister", configRegister },
+ { "configRouter", configRouter },
+ { "configUsers", configUsers },
+ { "configXFree86", configXFree86 },
{ "diskPartitionEditor", diskPartitionEditor },
{ "diskPartitionWrite", diskPartitionWrite },
{ "diskLabelEditor", diskLabelEditor },
{ "diskLabelCommit", diskLabelCommit },
{ "distReset", distReset },
+ { "distSetCustom", distSetDeveloper },
{ "distSetDeveloper", distSetDeveloper },
{ "distSetXDeveloper", distSetXDeveloper },
{ "distSetKernDeveloper", distSetKernDeveloper },
@@ -69,9 +76,14 @@ static struct _word {
{ "docShowDocument", docShowDocument },
{ "installCommit", installCommit },
{ "installExpress", installExpress },
+ { "installNovice", installNovice },
{ "installUpgrade", installUpgrade },
{ "installFixup", installFixup },
+ { "installFixitHoloShell", installFixitHoloShell },
+ { "installFixitCDROM", installFixitCDROM },
+ { "installFixitFloppy", installFixitFloppy },
{ "installFilesystems", installFilesystems },
+ { "installVarDefaults", installVarDefaults },
{ "mediaSetCDROM", mediaSetCDROM },
{ "mediaSetFloppy", mediaSetFloppy },
{ "mediaSetDOS", mediaSetDOS },
@@ -130,16 +142,17 @@ dispatchCommand(char *str)
if ((cp = index(str, '\n')) != NULL)
*cp = '\0';
- /* A command might be a pathname if it's encoded in argv[0], as we also support */
+ /* If it's got a `=' sign in there, assume it's a variable setting */
if (index(str, '=')) {
variable_set(str);
i = DITEM_SUCCESS;
}
else {
- if ((cp = index(str, '/')) != NULL)
+ /* A command might be a pathname if it's encoded in argv[0], which we also support */
+ if ((cp = rindex(str, '/')) != NULL)
str = cp + 1;
if (!call_possible_resword(str, NULL, &i)) {
- msgConfirm("No such command: %s", str);
+ msgNotify("Warning: No such command ``%s''", str);
i = DITEM_FAILURE;
}
}
diff --git a/release/sysinstall/dist.c b/release/sysinstall/dist.c
index 09f5a29..aeb8175 100644
--- a/release/sysinstall/dist.c
+++ b/release/sysinstall/dist.c
@@ -4,7 +4,7 @@
* This is probably the last program in the `sysinstall' line - the next
* generation being essentially a complete rewrite.
*
- * $Id: dist.c,v 1.106 1997/04/20 16:46:28 jkh Exp $
+ * $Id: dist.c,v 1.107 1997/05/05 05:16:01 pst Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -380,6 +380,56 @@ distMaybeSetPorts(dialogMenuItem *self)
return DITEM_SUCCESS | DITEM_RESTORE;
}
+static Boolean
+distSetByName(Distribution *dist, char *name)
+{
+ int i, status = FALSE;
+
+ /* Loop through current set */
+ for (i = 0; dist[i].my_name; i++) {
+ /* This is shorthand for "dist currently disabled" */
+ if (!dist[i].my_dir)
+ continue;
+ else if (!strcmp(dist[i].my_name, name)) {
+ *(dist[i].my_mask) &= ~(dist[i].my_bit);
+ status = TRUE;
+ break;
+ }
+ else if (dist[i].my_dist) {
+ if (distSetByName(dist[i].my_dist, name)) {
+ status = TRUE;
+ break;
+ }
+ }
+ }
+ return status;
+}
+
+/* Just for the dispatch stuff */
+int
+distSetCustom(dialogMenuItem *self)
+{
+ char *cp, *cp2, *tmp;
+
+ if (!(tmp = variable_get(VAR_DISTS))) {
+ msgDebug("distSetCustom() called without %s variable set.\n", VAR_DISTS);
+ return DITEM_FAILURE;
+ }
+
+ cp = alloca(strlen(tmp) + 1);
+ if (!cp)
+ msgFatal("Couldn't alloca() %d bytes!\n", strlen(tmp) + 1);
+ strcpy(cp, tmp);
+ while (cp) {
+ if ((cp2 = index(cp, ' ')) != NULL)
+ *(cp2++) = '\0';
+ if (!distSetByName(DistTable, cp))
+ msgDebug("distSetCustom: Warning, no such release \"%s\"\n", cp);
+ cp = cp2;
+ }
+ return DITEM_SUCCESS;
+}
+
int
distSetSrc(dialogMenuItem *self)
{
diff --git a/release/sysinstall/label.c b/release/sysinstall/label.c
index c57abf1..582e561 100644
--- a/release/sysinstall/label.c
+++ b/release/sysinstall/label.c
@@ -4,7 +4,7 @@
* This is probably the last program in the `sysinstall' line - the next
* generation being essentially a complete rewrite.
*
- * $Id: label.c,v 1.69 1997/03/08 16:17:49 jkh Exp $
+ * $Id: label.c,v 1.70 1997/03/11 17:51:01 jkh Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -81,6 +81,7 @@ static int ChunkPartStartRow;
static WINDOW *ChunkWin;
static int diskLabel(char *str);
+static int diskLabelNonInteractive(char *str);
int
diskLabelEditor(dialogMenuItem *self)
@@ -107,7 +108,10 @@ diskLabelEditor(dialogMenuItem *self)
"editor first to specify which disks you wish to operate on.");
return DITEM_FAILURE;
}
- i = diskLabel(devs[0]->name);
+ if (variable_get(VAR_NONINTERACTIVE))
+ i = diskLabelNonInteractive(devs[0]->name);
+ else
+ i = diskLabel(devs[0]->name);
if (DITEM_STATUS(i) != DITEM_FAILURE) {
char *cp;
@@ -936,3 +940,112 @@ diskLabel(char *str)
}
return DITEM_SUCCESS | DITEM_RESTORE;
}
+
+static int
+diskLabelNonInteractive(char *str)
+{
+ char *cp;
+ PartType type;
+ PartInfo *p;
+ u_long flags = 0;
+ int i, status;
+ Device **devs;
+ Disk *d;
+
+ status = DITEM_SUCCESS;
+ cp = variable_get(VAR_DISK);
+ if (!cp) {
+ dialog_clear();
+ msgConfirm("diskLabel: No disk selected - can't label automatically.");
+ return DITEM_FAILURE;
+ }
+
+ devs = deviceFind(cp, DEVICE_TYPE_DISK);
+ if (!devs) {
+ msgConfirm("diskLabel: No disk device %s found!", cp);
+ return DITEM_FAILURE;
+ }
+ d = devs[0]->private;
+
+ record_label_chunks(devs);
+ for (i = 0; label_chunk_info[i].c; i++) {
+ Chunk *c1 = label_chunk_info[i].c;
+
+ if (label_chunk_info[i].type == PART_SLICE) {
+ if ((cp = variable_get(c1->name)) != NULL) {
+ int sz;
+ char typ[10], mpoint[50];
+
+ if (sscanf(cp, "%s %d %s", typ, &sz, mpoint) != 3) {
+ msgConfirm("For slice entry %s, got an invalid detail entry of: %s", c1->name, cp);
+ status = DITEM_FAILURE;
+ continue;
+ }
+ else {
+ Chunk *tmp;
+
+ if (!strcmp(typ, "swap")) {
+ type = PART_SWAP;
+ strcpy(mpoint, "SWAP");
+ }
+ else {
+ type = PART_FILESYSTEM;
+ if (!strcmp(mpoint, "/"))
+ flags |= CHUNK_IS_ROOT;
+ }
+ if (!sz)
+ sz = space_free(c1);
+ if (sz > space_free(c1)) {
+ msgConfirm("Not enough free space to create partition: %s", mpoint);
+ status = DITEM_FAILURE;
+ continue;
+ }
+ if (!(tmp = Create_Chunk_DWIM(d, c1, sz, part,
+ (type == PART_SWAP) ? FS_SWAP : FS_BSDFFS, flags))) {
+ msgConfirm("Unable to create from partition spec: %s. Too big?", cp);
+ status = DITEM_FAILURE;
+ break;
+ }
+ else {
+ tmp->private_data = new_part(mpoint, TRUE, sz);
+ tmp->private_free = safe_free;
+ status = DITEM_SUCCESS;
+ }
+ }
+ }
+ }
+ else {
+ /* Must be something we can set a mountpoint */
+ cp = variable_get(c1->name);
+ if (cp) {
+ char mpoint[50], nwfs[8];
+ Boolean newfs = FALSE;
+
+ nwfs[0] = '\0';
+ if (sscanf(cp, "%s %s", mpoint, nwfs) != 2) {
+ dialog_clear();
+ msgConfirm("For slice entry %s, got an invalid detail entry of: %s", c1->name, cp);
+ status = DITEM_FAILURE;
+ continue;
+ }
+ newfs = toupper(nwfs[0]) == 'Y' ? TRUE : FALSE;
+ if (c1->private_data) {
+ p = c1->private_data;
+ p->newfs = newfs;
+ strcpy(p->mountpoint, mpoint);
+ }
+ else {
+ c1->private_data = new_part(mpoint, newfs, 0);
+ c1->private_free = safe_free;
+ }
+ if (!strcmp(mpoint, "/"))
+ c1->flags |= CHUNK_IS_ROOT;
+ else
+ c1->flags &= ~CHUNK_IS_ROOT;
+ }
+ }
+ }
+ if (status == DITEM_SUCCESS)
+ variable_set2(DISK_LABELLED, "yes");
+ return status;
+}
diff --git a/release/sysinstall/main.c b/release/sysinstall/main.c
index c267838..e1672d0 100644
--- a/release/sysinstall/main.c
+++ b/release/sysinstall/main.c
@@ -4,7 +4,7 @@
* This is probably the last attempt in the `sysinstall' line, the next
* generation being slated for what's essentially a complete rewrite.
*
- * $Id: main.c,v 1.44 1997/03/19 10:09:17 jkh Exp $
+ * $Id: main.c,v 1.45 1997/04/20 16:46:31 jkh Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -111,6 +111,7 @@ main(int argc, char **argv)
fp = fopen("install.cfg", "r");
if (fp) {
msgNotify("Loading pre-configuration file");
+ variable_set2(VAR_NONINTERACTIVE, "YES");
while (fgets(buf, sizeof buf, fp)) {
if (DITEM_STATUS(dispatchCommand(buf)) != DITEM_SUCCESS) {
msgDebug("Command `%s' failed - rest of script aborted.\n", buf);
@@ -118,6 +119,7 @@ main(int argc, char **argv)
}
}
fclose(fp);
+ variable_unset(VAR_NONINTERACTIVE);
}
}
diff --git a/release/sysinstall/media.c b/release/sysinstall/media.c
index a56e430..242a046 100644
--- a/release/sysinstall/media.c
+++ b/release/sysinstall/media.c
@@ -4,7 +4,7 @@
* This is probably the last attempt in the `sysinstall' line, the next
* generation being slated to essentially a complete rewrite.
*
- * $Id: media.c,v 1.82 1997/03/11 16:43:56 jkh Exp $
+ * $Id: media.c,v 1.83 1997/03/19 10:09:19 jkh Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -295,8 +295,9 @@ mediaSetFTP(dialogMenuItem *self)
mediaClose();
cp = variable_get(VAR_FTP_PATH);
/* If we've been through here before ... */
- if (networkDev && cp && msgYesNo("Re-use old FTP site selection values?"))
- cp = NULL;
+ if (!variable_get(VAR_NONINTERACTIVE))
+ if (networkDev && cp && msgYesNo("Re-use old FTP site selection values?"))
+ cp = NULL;
if (!cp) {
dialog_clear_norefresh();
diff --git a/release/sysinstall/sysinstall.h b/release/sysinstall/sysinstall.h
index 5670fe1..5b8eb2e 100644
--- a/release/sysinstall/sysinstall.h
+++ b/release/sysinstall/sysinstall.h
@@ -4,7 +4,7 @@
* This is probably the last attempt in the `sysinstall' line, the next
* generation being slated to essentially a complete rewrite.
*
- * $Id: sysinstall.h,v 1.129 1997/05/22 00:17:11 jkh Exp $
+ * $Id: sysinstall.h,v 1.130 1997/05/22 21:26:11 jkh Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -96,6 +96,7 @@
#define VAR_CPIO_VERBOSITY "cpioVerbose"
#define VAR_DEBUG "debug"
#define VAR_DISK "disk"
+#define VAR_DISTS "dists"
#define VAR_DIST_MAIN "distMain"
#define VAR_DIST_DES "distDES"
#define VAR_DIST_SRC "distSRC"
@@ -133,8 +134,10 @@
#define VAR_NFS_SECURE "nfsSecure"
#define VAR_NFS_SERVER "nfs_server_enable"
#define VAR_NO_CONFIRM "noConfirm"
+#define VAR_NONINTERACTIVE "nonInteractive"
#define VAR_NOVELL "novell"
#define VAR_NTPDATE "ntpdate"
+#define VAR_PARTITION "partition"
#define VAR_PCNFSD "pcnfsd"
#define VAR_PCNFSD_PKG "pcnfsd_pkg"
#define VAR_PKG_TMPDIR "PKG_TMPDIR"
@@ -412,6 +415,7 @@ extern int configFstab(void);
extern void configEnvironmentRC_conf(char *config);
extern void configEnvironmentResolv(char *config);
extern void configRC_conf(char *config);
+extern int configRC(dialogMenuItem *self);
extern int configRegister(dialogMenuItem *self);
extern void configResolv(void);
extern int configPackages(dialogMenuItem *self);
@@ -460,7 +464,7 @@ extern int dispatchCommand(char *command);
/* dist.c */
extern int distReset(dialogMenuItem *self);
extern int distConfig(dialogMenuItem *self);
-extern int distSetCustom(char *str);
+extern int distSetCustom(dialogMenuItem *self);
extern int distSetDeveloper(dialogMenuItem *self);
extern int distSetXDeveloper(dialogMenuItem *self);
extern int distSetKernDeveloper(dialogMenuItem *self);
diff --git a/release/sysinstall/variable.c b/release/sysinstall/variable.c
index 7a3e80a..4bd2e78 100644
--- a/release/sysinstall/variable.c
+++ b/release/sysinstall/variable.c
@@ -4,7 +4,7 @@
* This is probably the last program in the `sysinstall' line - the next
* generation being essentially a complete rewrite.
*
- * $Id$
+ * $Id: variable.c,v 1.17 1997/02/22 14:12:38 peter Exp $
*
* Copyright (c) 1995
* Jordan Hubbard. All rights reserved.
@@ -146,8 +146,11 @@ char *
variable_get_value(char *var, char *prompt)
{
char *cp;
-
- if ((cp = msgGetInput(variable_get(var), prompt)) != NULL)
+
+ cp = variable_get(var);
+ if (cp && variable_get(VAR_NONINTERACTIVE))
+ return cp;
+ else if ((cp = msgGetInput(cp, prompt)) != NULL)
variable_set2(var, cp);
else
cp = NULL;
diff --git a/release/sysinstall/variable_load.c b/release/sysinstall/variable_load.c
index 95aeca9..b221441 100644
--- a/release/sysinstall/variable_load.c
+++ b/release/sysinstall/variable_load.c
@@ -4,7 +4,7 @@
* This is probably the last attempt in the `sysinstall' line, the next
* generation being slated for what's essentially a complete rewrite.
*
- * $Id: variable_load.c,v 1.4 1997/05/16 20:40:00 pst Exp $
+ * $Id: variable_load.c,v 1.5 1997/05/22 22:11:17 pst Exp $
*
* Copyright (c) 1997
* Paul Traina. All rights reserved.
@@ -83,6 +83,8 @@ variableLoad(dialogMenuItem * self)
msgNotify("Loading %s pre-configuration file", cp);
+ /* Hint to others that we're running from a script, should they care */
+ variable_set2(VAR_NONINTERACTIVE, "YES");
while (fgets(buf, sizeof buf, fp)) {
if ((cp = strchr(buf, '\n')) != NULL)
*cp = '\0';
@@ -102,5 +104,6 @@ terminate_file:
terminate_device:
mediaClose();
+ variable_unset(VAR_NONINTERACTIVE);
return what;
}
OpenPOWER on IntegriCloud