installer: create namespaces with kube client
diff --git a/core/installer/app_manager.go b/core/installer/app_manager.go
index 5c1822a..d2feccc 100644
--- a/core/installer/app_manager.go
+++ b/core/installer/app_manager.go
@@ -12,26 +12,19 @@
 const kustomizationFileName = "kustomization.yaml"
 
 type AppManager struct {
-	repoIO RepoIO
+	repoIO    RepoIO
+	nsCreator NamespaceCreator
 }
 
-func NewAppManager(repoIO RepoIO) (*AppManager, error) {
+func NewAppManager(repoIO RepoIO, nsCreator NamespaceCreator) (*AppManager, error) {
 	return &AppManager{
 		repoIO,
+		nsCreator,
 	}, nil
 }
 
 func (m *AppManager) Config() (Config, error) {
-	configF, err := m.repoIO.Reader(configFileName)
-	if err != nil {
-		return Config{}, err
-	}
-	defer configF.Close()
-	config, err := ReadConfig(configF)
-	if err != nil {
-		return Config{}, err
-	}
-	return config, nil
+	return m.repoIO.ReadConfig()
 }
 
 func (m *AppManager) AppConfig(name string) (map[string]any, error) {
@@ -49,11 +42,24 @@
 	return cfg, err
 }
 
-func (m *AppManager) Install(app App, config map[string]any) error {
+func (m *AppManager) Install(app App, ns NamespaceGenerator, config map[string]any) error {
 	// if err := m.repoIO.Fetch(); err != nil {
 	// 	return err
 	// }
-	globalConfig, err := m.Config()
+	namespaces := make([]string, len(app.Namespaces))
+	for i, n := range app.Namespaces {
+		var err error
+		namespaces[i], err = ns.Generate(n)
+		if err != nil {
+			return err
+		}
+	}
+	for _, n := range namespaces {
+		if err := m.nsCreator.Create(n); err != nil {
+			return err
+		}
+	}
+	globalConfig, err := m.repoIO.ReadConfig()
 	if err != nil {
 		return err
 	}
@@ -61,5 +67,10 @@
 		"Global": globalConfig.Values,
 		"Values": config,
 	}
+	if len(namespaces) > 0 {
+		all["Release"] = map[string]any{
+			"Namespace": namespaces[0],
+		}
+	}
 	return m.repoIO.InstallApp(app, "apps", all)
 }